Check out my first novel, midnight's simulacra!

Pidfd: Difference between revisions

From dankwiki
No edit summary
No edit summary
Line 3: Line 3:
The first "pidfds" were created by opening a <tt>/proc/PID</tt> directory, and used with <tt>pidfd_send_signal(2)</tt>. These pidfds are now considered incomplete (they cannot be polled for process termination, nor can they be used with the <tt>waitid(2)</tt> system call).
The first "pidfds" were created by opening a <tt>/proc/PID</tt> directory, and used with <tt>pidfd_send_signal(2)</tt>. These pidfds are now considered incomplete (they cannot be polled for process termination, nor can they be used with the <tt>waitid(2)</tt> system call).


==Kernel==
At the heart of the modern pidfd abstraction is the <tt>CLONE_PIDFD</tt> flag to the <tt>clone(2)</tt> system call (note that this recycles the deprecated <tt>CLONE_PID</tt> bit). It is not possible to use this flag with <tt>CLONE_THREAD</tt>, and thus the created process will always be a thread group leader. It cannot be used together with the (deprecated) <tt>CLONE_DETACHED</tt> flag. The resulting file descriptor is placed in <tt>parent_tid</tt> when used with <tt>clone(2)</tt> (and thus it cannot there be used together with <tt>CLONE_PARENT_SETTID</tt>) and <tt>cl_args.pidfd</tt> when used with <tt>clone3(2)</tt>.
At the heart of the modern pidfd abstraction is the <tt>CLONE_PIDFD</tt> flag to the <tt>clone(2)</tt> system call (note that this recycles the deprecated <tt>CLONE_PID</tt> bit). It is not possible to use this flag with <tt>CLONE_THREAD</tt>, and thus the created process will always be a thread group leader. It cannot be used together with the (deprecated) <tt>CLONE_DETACHED</tt> flag. The resulting file descriptor is placed in <tt>parent_tid</tt> when used with <tt>clone(2)</tt> (and thus it cannot there be used together with <tt>CLONE_PARENT_SETTID</tt>) and <tt>cl_args.pidfd</tt> when used with <tt>clone3(2)</tt>.


Kernel 5.3 introduced <tt>pidfd_open(2)</tt>, allowing a pidfd to be opened for an arbitrary existing process. If you for some reason can't use <tt>clone3(2)</tt>, this can be employed together with <tt>fork(2)</tt> for a race-free pidfd acquisition on children.
Kernel 5.3 introduced <tt>pidfd_open(2)</tt>, allowing a pidfd to be opened for an arbitrary existing process. If you for some reason can't use <tt>clone3(2)</tt>, this can be employed together with <tt>fork(2)</tt> for a race-free pidfd acquisition on children (see <tt>pidfd_spawn(3)</tt> below).


Kernel 5.6 added <tt>pidfd_getfd(2)</tt>, supporting duplication of an existing file descriptor in a process identified by a pidfd. This operation requires <tt>PTRACE_MODE_ATTACH_REALCREDS</tt>.
Kernel 5.6 added <tt>pidfd_getfd(2)</tt>, supporting duplication of an existing file descriptor in a process identified by a pidfd. This operation requires <tt>PTRACE_MODE_ATTACH_REALCREDS</tt>.
Line 14: Line 15:


As of 6.5, credentials can be sent using pidfds rather than <tt>SCM_CREDENTIALS</tt>-style PIDs using the <tt>SCM_PIDFD</tt> type. <tt>getsockopt(2)</tt> can use <tt>SO_PEERPIDFD</tt> to get a pidfd for the peer process on a <tt>unix(7)</tt> socket.
As of 6.5, credentials can be sent using pidfds rather than <tt>SCM_CREDENTIALS</tt>-style PIDs using the <tt>SCM_PIDFD</tt> type. <tt>getsockopt(2)</tt> can use <tt>SO_PEERPIDFD</tt> to get a pidfd for the peer process on a <tt>unix(7)</tt> socket.
==[[Glibc]]==
GNU libc added pidfd system call support in 2.36. Glibc 2.39 added several functions for pidfds, complementing <tt>posix_spawn(3)</tt>:
* <tt>pidfd_spawn(3)</tt>:analogous to <tt>posix_spawn(3)</tt>
* <tt>pidfd_spawnp(3)</tt>: analogous to <tt>posix_spawnp(3)</tt>
* <tt>pid_t pidfd_getpid(3)</tt>: get the PID from a pidfd
==See also==
"[https://lwn.net/Articles/943022/ Race-free process creation in the GNU C library]", LWN
"[https://lwn.net/Articles/943022/ GNU C Library version 2.39]", LWN


[[Category: Linux]]
[[Category: Linux]]

Revision as of 02:20, 7 February 2024

Since Linux 5.1, pidfds have more or less allowed one to refer to a process using a file descriptor, making it possible to eliminate a set of race conditions and ambiguities.

The first "pidfds" were created by opening a /proc/PID directory, and used with pidfd_send_signal(2). These pidfds are now considered incomplete (they cannot be polled for process termination, nor can they be used with the waitid(2) system call).

Kernel

At the heart of the modern pidfd abstraction is the CLONE_PIDFD flag to the clone(2) system call (note that this recycles the deprecated CLONE_PID bit). It is not possible to use this flag with CLONE_THREAD, and thus the created process will always be a thread group leader. It cannot be used together with the (deprecated) CLONE_DETACHED flag. The resulting file descriptor is placed in parent_tid when used with clone(2) (and thus it cannot there be used together with CLONE_PARENT_SETTID) and cl_args.pidfd when used with clone3(2).

Kernel 5.3 introduced pidfd_open(2), allowing a pidfd to be opened for an arbitrary existing process. If you for some reason can't use clone3(2), this can be employed together with fork(2) for a race-free pidfd acquisition on children (see pidfd_spawn(3) below).

Kernel 5.6 added pidfd_getfd(2), supporting duplication of an existing file descriptor in a process identified by a pidfd. This operation requires PTRACE_MODE_ATTACH_REALCREDS.

Kernel 5.8 added support for supplying a pidfd to setns(2).

Kernel 5.10 brought process_madvise(2), generalizing madvise(2) to multiple memory regions and allowing it to be applied to another process's address space. When used on another process (as opposed to oneself), it requires PTRACE_MODE_READ_FSCREDS and CAP_SYS_NICE.

As of 6.5, credentials can be sent using pidfds rather than SCM_CREDENTIALS-style PIDs using the SCM_PIDFD type. getsockopt(2) can use SO_PEERPIDFD to get a pidfd for the peer process on a unix(7) socket.

Glibc

GNU libc added pidfd system call support in 2.36. Glibc 2.39 added several functions for pidfds, complementing posix_spawn(3):

  • pidfd_spawn(3):analogous to posix_spawn(3)
  • pidfd_spawnp(3): analogous to posix_spawnp(3)
  • pid_t pidfd_getpid(3): get the PID from a pidfd

See also

"Race-free process creation in the GNU C library", LWN "GNU C Library version 2.39", LWN