A supervisor records a worker PID, performs unrelated work, then sends a signal to that number. If the original worker exited and the kernel reused its numeric PID, a later operation can address a different process. The number identifies an entry in a PID namespace at a moment in time; it is not, by itself, a durable process handle.
Linux pidfds add a file-descriptor representation of process identity. A pidfd obtained for a process continues to refer to that process rather than being retargeted when its numeric PID is recycled. This changes the identity boundary for supervision, but it does not grant broad authority over the referenced process.
A pidfd pins the reference, not the process lifetime
pidfd_open(pid, 0) asks the kernel for a file descriptor referring to the process identified by pid. Once returned, that descriptor can be stored, passed through descriptor-capable IPC, polled, and supplied to pidfd-aware system calls.
The reference remains associated with the same process object. Numeric PID reuse therefore cannot silently redirect an already acquired pidfd to a later process.
The descriptor does not keep the process running. The target can exit while the pidfd remains open. This is a useful distinction for supervisors: stable identity and process liveness are separate properties.
A pidfd is also not a snapshot of credentials, memory, namespaces, or executable image. Those properties can change during the lifetime of the referenced process. The stable property is the process reference itself.
Acquisition still has a boundary before the descriptor exists
pidfd_open() starts from a numeric PID. If software first receives a PID through an untrusted or delayed channel and only later calls pidfd_open(), the target associated with that number can already have changed before acquisition. Pidfds remove reuse ambiguity after successful acquisition; they do not retroactively secure the interval before it.
Process creation can avoid that gap. Linux clone3() with CLONE_PIDFD can return a pidfd for the newly created child as part of the creation operation. A parent using that interface does not need a later lookup of the child from a bare numeric PID.
This difference matters in process managers. A pidfd obtained at creation establishes a direct continuity from child creation to later supervision. A pidfd opened from a number supplied afterward inherits the trust assumptions attached to that number and its timing.
pidfd_open() also has documented lifecycle conditions around exited processes. Software that needs reliable child reaping should treat pidfd acquisition, exit observation, and wait operations as one lifecycle design rather than assuming any late lookup can recover a lost relationship.
Polling turns exit into descriptor state
A pidfd can participate in poll(), select(), and epoll(). When the referenced process terminates, the descriptor becomes readable. This lets a supervisor combine process-exit observation with other descriptor-driven events without mapping readiness back from a reused PID.
Readability is an exit indication, not process output. Reading ordinary bytes from a pidfd is not the interface for collecting status. For a child process, waitid() with P_PIDFD can use the pidfd as the target selector and obtain wait status under the normal child-wait rules.
The distinction between readiness and reaping remains important. Poll notification reports a lifecycle transition. Wait semantics determine whether the caller can collect child status and release the corresponding zombie state. A pidfd does not turn an unrelated process into the caller’s child.
This separation also prevents a common architectural shortcut: treating a process identifier, an exit notification, and a wait relationship as the same concept. Pidfds connect these operations to one stable reference while each operation retains its own kernel rules.
Signal delivery uses stable identity but still checks permission
pidfd_send_signal() directs a signal through a pidfd rather than resolving a numeric PID at send time. The identity benefit is direct: the operation cannot be redirected merely because the old PID number was reused.
Authorization remains independent. Signal permission checks still apply according to the kernel’s signal rules, including credential and capability conditions. Possessing a pidfd is therefore not equivalent to possessing permission to signal its target.
This property makes pidfd transfer security-sensitive without making it all-powerful. Passing a pidfd gives the receiver a stable reference that can be used with supported interfaces, but each interface can impose additional checks. The receiving process gains a durable naming capability, not automatic control over every target resource.
A supervisor should therefore distinguish two policy questions: which process may receive a stable reference, and which operations that holder is authorized to perform. Collapsing those questions can overstate the authority represented by the descriptor.
Descriptor duplication crosses a stronger inspection boundary
pidfd_getfd() can duplicate a file descriptor from the referenced process into the caller. The new descriptor refers to the same underlying open file description as the target descriptor, subject to the semantics of that object.
This operation is deliberately more constrained than simple pidfd possession. Linux applies a ptrace-style access check to pidfd_getfd(). A caller that can hold or receive a pidfd can still be denied access to the target’s descriptor table.
That boundary matters because target descriptors can represent files, sockets, pipes, namespaces, devices, or other kernel objects carrying authority. Stable process identity answers which process is being addressed; it does not answer whether extracting one of its descriptors is permitted.
The same separation appears across the pidfd family. The descriptor supplies identity continuity, while the invoked operation supplies its own authorization and semantic rules. Treating a pidfd as a universal process capability would erase this distinction.
Namespace-relative numbers remain visible at the edges
Numeric PIDs are interpreted relative to PID namespaces. A process can have different visible PID values at different namespace levels, and a PID meaningful to one observer may not name the same way from another namespace.
A pidfd reduces the need to keep translating those numbers after acquisition. Once a process has the descriptor, later pidfd-aware operations can use the descriptor directly. This is especially useful when supervision crosses namespace boundaries through a component that can safely transfer descriptors.
The pidfd itself does not remove namespace policy. Operations on the target can still depend on credentials, capabilities, namespace relationships, and Linux Security Module decisions. It only replaces repeated numeric lookup with a stable kernel reference.
Descriptor passing also introduces its own trust boundary. A receiver must have confidence in the component supplying the pidfd if the receiver’s policy depends on which process it denotes. The kernel preserves the descriptor’s target identity; it does not attest that the sender selected the intended target.
Stable naming narrows one race without merging policy layers
Pidfds address a specific failure mode in process management: a reusable integer is a fragile long-lived identity token. Converting process identity into a file descriptor lets Linux bind later operations to the same process object and integrate lifecycle observation with descriptor-oriented event loops.
That guarantee stays intentionally narrow. A pidfd does not freeze process state, extend process lifetime, create a child relationship, bypass signal checks, or authorize descriptor extraction. Acquisition from a numeric PID can still carry a pre-acquisition race, while creation-time acquisition through CLONE_PIDFD can avoid that particular gap.
The resulting architecture is stronger when identity and authority remain separate. Pidfds make the identity reference durable; signal policy, ptrace-style inspection checks, child-wait rules, namespaces, and LSM policy continue to decide what a holder may actually do with that reference.