Check out my first novel, midnight's simulacra!

Pidfd: Difference between revisions

From dankwiki
No edit summary
No edit summary
Line 1: Line 1:
Since [[Linux_APIs|Linux 5.2]], 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.
Since [[Linux_APIs|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.


At the heart of the 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>.
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).
 
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.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>.
 
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.

Revision as of 19:47, 30 June 2023

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).

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.

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.

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.