Date: Tue, 23 Dec 2025 23:51:45 +0300 From: Vadim Goncharov <vadimnuclight@gmail.com> To: Andrea Cocito <andrea@cocito.eu> Cc: freebsd-hackers@freebsd.org Subject: Re: Retrieving the kid/jailname of connected peer for a unix socket Message-ID: <20251223235145.33f8cf3d@nuclight.lan> In-Reply-To: <7878EFBC-2BCF-42ED-9BFC-D96DC0DDC23A@cocito.eu> References: <7878EFBC-2BCF-42ED-9BFC-D96DC0DDC23A@cocito.eu>
index | next in thread | previous in thread | raw e-mail
On Tue, 23 Dec 2025 13:54:31 +0100
Andrea Cocito <andrea@cocito.eu> wrote:
> Hello hackers,
>
> I am working on a project in which I run a “web server” bound to a unix
> socket; the socket lives in a directory that is re-mounted as a read only
> nulls in various jails, so processes in each jail can make requests to this
> “server”.
>
> I need the server to be able to know from which jail the request comes, and
> this is needed as an authentication method.
>
> So far the best I could do is a three-step approach:
> 1. I retrieve the pid of the process connected to the other side of the
> socket: getsockopt(fd, SOL_LOCAL, LOCAL_PEERCRED,…) 2. I map that pid to a
> jid: int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID,
> static_cast<int>(pid) }; sysctl(mib, 4, &kp, &len, nullptr, 0) 3. I map the
> kid to jail name with jail_getname()
>
> As LOCAL_PEERCRED returns the peers’ credentials "as they were captured when
> the socket connection was established” and there could be a small delay
> before we accept() there is an unlikely but formally possible TOC-TOU issue
> that potentially could be exploited as follows: a. A process with pid P in a
> jail starts and attempts a connect() b. In the meanwhile a connect-bomb or
> other “overloading” technique slows down the server c. Process P passes the
> fd to process Q and exit()s d. If when we accept() another process
> (potentially in another jail) has got pid P... we get the wrong information
>
> As a mitigation I am currently resolving fd->credentials->jid->name as soon
> as possible server-side and obviously using randomized pids, but there is
> still a formal delay in accept() and I understand I am violating the golden
> rule “do not use a pid to grant permissions/authenticate”. I also tried to
> investigate other safety options (like check that pid actually started
> before the connection took place) but it seems that nothing from the kernel
> exposes the “timestamp when connect() was called”, so I always have the
> connect()-to-accept() windows of risk.
>
> So the question is: am I missing some simpler or safer way to get the "jail
> id of the process which connected to the other side of this unix socket",
> besides embarking into “set LOCAL_CREDS_PERSISTENT and check LOCAL_CREDS on
> received traffic”, which would be quite complex to plumb into Crow-http?
What about trusted per-jail proxy which has separate socket in each jail?
Or even just per-jail sockets without null mounts.
--
WBR, @nuclight
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20251223235145.33f8cf3d>
