Skip site navigation (1)Skip section navigation (2)
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>