LWN: Comments on "Grabbing file descriptors with pidfd_getfd()" https://lwn.net/Articles/808997/ This is a special feed containing comments posted to the individual LWN article titled "Grabbing file descriptors with pidfd_getfd()". en-us Mon, 03 Nov 2025 07:15:58 +0000 Mon, 03 Nov 2025 07:15:58 +0000 https://www.rssboard.org/rss-specification lwn@lwn.net Grabbing file descriptors with pidfd_getfd() https://lwn.net/Articles/864412/ https://lwn.net/Articles/864412/ mathstuf <div class="FormattedComment"> Meddling from &quot;outside&quot; is likely to interfere with guarantees made by any language. I think once you introduce an &quot;interloper&quot; into your process space (either via ptrace, VM managers, OOM killer, interrupts, etc.), you&#x27;re playing with fire. Sure, we know how to manage it most of the time and can keep it contained, but if it gets loose…well, I hope you have insurance[1].<br> <p> [1] In code, that would be &quot;sanity checks on top of the language guarantees&quot;. IMO, it&#x27;s just normal defensive coding and the amount you put in depends on how paranoid you tend (or need) to be.<br> </div> Tue, 27 Jul 2021 15:03:37 +0000 Grabbing file descriptors with pidfd_getfd() https://lwn.net/Articles/864389/ https://lwn.net/Articles/864389/ taladar <div class="FormattedComment"> Closing a file descriptor from another process would also circumvent any static analysis a language (like Haskell or Rust) might have done to ensure certain operations are only done on open file descriptors.<br> </div> Tue, 27 Jul 2021 08:13:33 +0000 Grabbing file descriptors with pidfd_getfd() https://lwn.net/Articles/810785/ https://lwn.net/Articles/810785/ cyphar <div class="FormattedComment"> You're right about how magic-links work (and re-opening through /proc/$pid/fd does work for pipes), but this does not work for sockets or anonfds -- you'll get -ENXIO when you try to re-open them. Additionally, there is still a pid recycling race condition if you use procfs (unless you have a first-generation /proc/$pid-style pidfd).<br> </div> Wed, 29 Jan 2020 01:35:01 +0000 Grabbing file descriptors with pidfd_getfd() https://lwn.net/Articles/809449/ https://lwn.net/Articles/809449/ dona73110 <div class="FormattedComment"> <font class="QuotedText">&gt;One thing that is possible in current kernels is to open a file that another process also has open; the information needed to do that is in each process's /proc directory. That does not work, though, for file descriptors referring to pipes, sockets, or other objects that do not appear in the filesystem hierarchy.</font><br> <p> You sure can open a pipe that another process has open, by opening /proc/PID/fd/FD ... open(2) opens the actual files that these symlinks represent, which in the case of deleted files or pipes, etc, do not correspond to the path in the symlink target returned by readlink.<br> </div> Tue, 14 Jan 2020 14:52:41 +0000 Grabbing file descriptors with pidfd_getfd() https://lwn.net/Articles/809265/ https://lwn.net/Articles/809265/ cortana <div class="FormattedComment"> It may be interesting to note another alternative: a Mandatory Access Control system such as SELinux, where confined processes are only allowed to bind to ports permitted by the policy (e.g., Apache running in the http_t domain can only listen to ports labelled with httpd_port_t).<br> </div> Mon, 13 Jan 2020 09:24:23 +0000 Grabbing file descriptors with pidfd_getfd() https://lwn.net/Articles/809234/ https://lwn.net/Articles/809234/ rra <div class="FormattedComment"> To ask what's probably the same question in a slightly different way: is the rule that only root can bind to ports below 1024 still useful?<br> <p> Back when that was added to UNIX's security model, there were a wealth of programs that used the ability to bind to specific ports as an authorization control of various kinds (remember identd?). Most of those protocols are thoroughly obsolete (I hope no one is using traditional rlogin with rhosts authentication these days), so protecting those ports doesn't serve the same purpose.<br> <p> I would argue that, today, the security concern is preventing programs from grabbing ports they're not "supposed" to have, but that problem is not limited to ports under 1024 except by history and convention. There are a lot of services that listen to ports above 1024 where some race condition allowing a user process to bind to that port is equally problematic.<br> <p> It feels like a more useful security primitive now would be controlling the specific ports to which a process can bind, which looks more like socket activation (as you describe), or like a container where the process can bind to any port it wants but only expected ports are routed outside the container, so binding to other ports is futile.<br> </div> Sat, 11 Jan 2020 23:12:18 +0000 Grabbing file descriptors with pidfd_getfd() https://lwn.net/Articles/809210/ https://lwn.net/Articles/809210/ cyphar <div class="FormattedComment"> Using sendmsg(2) requires co-operation from the other side (or the injection of parasitic code a-la CRIU or rr). Those approaches are really suboptimal for a bunch of reasons, and having an interface which does this properly and doesn't require shellcode injection as part of normal code execution is a massive benefit. Not to mention that seccomp filters on the target process may block some of the syscalls needed for that to work.<br> </div> Fri, 10 Jan 2020 22:30:53 +0000 Grabbing file descriptors with pidfd_getfd() https://lwn.net/Articles/809203/ https://lwn.net/Articles/809203/ kylebot <div class="FormattedComment"> If I remember correctly, one process can send file descriptors through sendmsg syscall?<br> Then what's the difference between these two methods.<br> </div> Fri, 10 Jan 2020 20:53:56 +0000 Grabbing file descriptors with pidfd_getfd() https://lwn.net/Articles/809158/ https://lwn.net/Articles/809158/ nix <div class="FormattedComment"> innbind is usually installed mode 1550, group news, so it's only executable by things in the Usenet news subsystem, which are all in the same trust domain.<br> </div> Fri, 10 Jan 2020 15:14:01 +0000 Grabbing file descriptors with pidfd_getfd() https://lwn.net/Articles/809153/ https://lwn.net/Articles/809153/ Karellen <p>Thanks for pointing to those! <p>However, I'd have reservations about using authbind - LD_PRELOAD is handy for debugging and trying weird tricks out, but I'm wary about using it in production systems. <p>innbind looks much cleaner, and certainly would allow you to write a program that could bind to privileged ports without needing to run as root, but as far as I can tell it allows <em>any</em> program on the system to bind privileged ports. If you installed it so that only members of a specific group were able to run it, and limited which programs ran as members of that group, that could work. Fri, 10 Jan 2020 14:29:27 +0000 Grabbing file descriptors with pidfd_getfd() https://lwn.net/Articles/809152/ https://lwn.net/Articles/809152/ miquels Or things like <a href = "http://manpages.ubuntu.com/manpages/xenial/man1/authbind.1.html"> authbind</a> and <a href = "https://sarata.com/manpages/innbind.8.html ">innbind</a> ? Fri, 10 Jan 2020 13:39:16 +0000 Grabbing file descriptors with pidfd_getfd() https://lwn.net/Articles/809126/ https://lwn.net/Articles/809126/ roc <div class="FormattedComment"> This sounds great. We have code to do this in rr already:<br> <a href="https://github.com/mozilla/rr/blob/79eea40fe0d496abb6fcb0bbb110fd6ad489d8bc/src/AutoRemoteSyscalls.cc#L435">https://github.com/mozilla/rr/blob/79eea40fe0d496abb6fcb0...</a><br> It's not nice, especially because we want it to work whether the tracee is 64-bit or 32-bit.<br> <p> Of course it will be years before the new syscall is widely deployed enough that we can actually rip out our code, but ... progress.<br> </div> Thu, 09 Jan 2020 21:23:08 +0000 Grabbing file descriptors with pidfd_getfd() https://lwn.net/Articles/809113/ https://lwn.net/Articles/809113/ Karellen <blockquote>I still believe that binding sockets (to well known ports) ought to be something that is handled by system infrastructure and not separately by each individual server.</blockquote> <p>So, like <a href="http://0pointer.de/public/systemd-man/sd_listen_fds.html">sd_listen_fds()</a>? Thu, 09 Jan 2020 19:04:46 +0000 Grabbing file descriptors with pidfd_getfd() https://lwn.net/Articles/809109/ https://lwn.net/Articles/809109/ zblaxell <div class="FormattedComment"> <font class="QuotedText">&gt; One would cause the file descriptor to be closed in the target process after being copied to the caller, thus truly "stealing" the descriptor from the target.</font><br> <p> That sounds messy--the FD could end up being used again by an open in<br> some other thread of the target process, causing hilarious confusion on<br> the target side if the target is not expecting FD thievery.<br> <p> Why not do an atomic FD swap? <br> <p> int stolen_fd = pidfd_swapfd(int pid_fd, int target_fd, int flags, int caller_fd)<br> <p> Set caller_fd = NOFD if you really want the FD closed in the target process;<br> otherwise, the caller's caller_fd becomes the target's target_fd, while the<br> former target's target_fd is returned in stolen_fd.<br> <p> Set target_fd = NOFD to copy caller_fd to the target process, assigning<br> a new FD as if the target process had performed an open(). The new FD<br> number in the target is returned in stolen_fd.<br> <p> caller_fd isn't closed in the calling process--close() is fine for that.<br> <p> </div> Thu, 09 Jan 2020 18:57:02 +0000 Grabbing file descriptors with pidfd_getfd() https://lwn.net/Articles/809107/ https://lwn.net/Articles/809107/ NYKevin <div class="FormattedComment"> <font class="QuotedText">&gt; That distinction matters if the objective is to modify that particular file descriptor. One use case mentioned in the patch series is using seccomp to intercept attempts to bind a socket to a privileged port. A privileged supervisor process could, if it so chose, grab the file descriptor for that socket from the target process and actually perform the bind — something the target process would not have the privilege to do on its own. Since the grabbed file descriptor is essentially identical to the original, the bind operation will be visible to the target process as well.</font><br> <font class="QuotedText">&gt; </font><br> <font class="QuotedText">&gt; For the sufficiently determined, it is actually possible to extract a file descriptor from another process now. The technique involves using ptrace() to attach to that process, stop it from executing, inject some code that opens a connection to the supervisor process and sends the file descriptor via an SCM_RIGHTS datagram, then running that code. This solution might justly be said to be slightly lacking in elegance. It also requires stopping the target process, which is likely to be unwelcome.</font><br> <p> On first read, I found this rather confusing. Surely the sandboxed process would be able to open that AF_UNIX connection itself, right?<br> <p> But no, because they're not talking about a sandboxed process that is cooperating with the supervisor. They're (I think) talking about a sandboxed process that is ignorant of its sandbox and thinks it can "just call bind(2)." In that case, you actually need to intercept that call and emulate it outside the sandbox, without the sandboxed process noticing.<br> <p> What bothers me most, however, is that this still feels like an antiquated system design. In the great before-times, inetd would spawn your server with the socket already hooked to stdin, and you wouldn't need to think about calling bind() or indeed any part of the sockets interface. While there are obvious scalability concerns with that approach, I still believe that binding sockets (to well known ports) ought to be something that is handled by system infrastructure and not separately by each individual server.<br> </div> Thu, 09 Jan 2020 18:44:55 +0000