xref: /freebsd/lib/libsys/pdfork.2 (revision 32b99a26c37ffcba4b1437f548cbbe7fcf1323dc)
1.\"
2.\" Copyright (c) 2009-2010, 2012-2013 Robert N. M. Watson
3.\" All rights reserved.
4.\"
5.\" This software was developed at the University of Cambridge Computer
6.\" Laboratory with support from a grant from Google, Inc.
7.\"
8.\" This software was developed by SRI International and the University of
9.\" Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
10.\" ("CTSRD"), as part of the DARPA CRASH research programme.
11.\"
12.\" Redistribution and use in source and binary forms, with or without
13.\" modification, are permitted provided that the following conditions
14.\" are met:
15.\" 1. Redistributions of source code must retain the above copyright
16.\"    notice, this list of conditions and the following disclaimer.
17.\" 2. Redistributions in binary form must reproduce the above copyright
18.\"    notice, this list of conditions and the following disclaimer in the
19.\"    documentation and/or other materials provided with the distribution.
20.\"
21.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31.\" SUCH DAMAGE.
32.\"
33.Dd April 19, 2026
34.Dt PDFORK 2
35.Os
36.Sh NAME
37.Nm pdfork ,
38.Nm pdrfork ,
39.Nm pdopenpid ,
40.Nm pdgetpid ,
41.Nm pdkill ,
42.Nm pdwait ,
43.Nm pddupfd
44.Nd System calls to manage process descriptors
45.Sh LIBRARY
46.Lb libc
47.Sh SYNOPSIS
48.In sys/procdesc.h
49.Ft pid_t
50.Fn pdfork "int *fdp" "int pdflags"
51.Ft pid_t
52.Fn pdrfork "int *fdp" "int pdflags" "int rfflags"
53.Ft int
54.Fn pdopenpid "pid_t pid" "int pdflags"
55.Ft int
56.Fn pdgetpid "int fd" "pid_t *pidp"
57.Ft int
58.Fn pdkill "int fd" "int signum"
59.Ft int
60.Fo pdwait
61.Fa "int fd"
62.Fa "int *status"
63.Fa "int options"
64.Fa "struct __wrusage *wrusage"
65.Fa "struct __siginfo *info"
66.Fc
67.Ft int
68.Fn pddupfd "int fd" "int remotefd" "int flags"
69.Ft int
70.Fo pdptrace
71.Fa "int req"
72.Fa "int fd"
73.Fa "int lwpid"
74.Fa "void *addr"
75.Fa "int data"
76.Fc
77.Sh DESCRIPTION
78Process descriptors are special file descriptors that represent processes,
79and are created using
80.Fn pdfork ,
81a variant of
82.Xr fork 2 ,
83which, if successful, returns a process descriptor in the integer pointed to
84by
85.Fa fdp .
86Processes created via
87.Fn pdfork
88will not cause
89.Dv SIGCHLD
90on termination.
91.Fn pdfork
92can accept the
93.Fa pdflags:
94.Bl -tag -width PD_PTRACE_CAP
95.It Dv PD_DAEMON
96Instead of the default terminate-on-close behaviour, allow the process to
97live until it is explicitly killed with
98.Xr kill 2 .
99.Pp
100This option is not permitted in
101.Xr capsicum 4
102capability mode (see
103.Xr cap_enter 2 ) .
104.Pp
105Note: the option changes the behavior of
106.Xr close 2
107for the process descriptor returned by the operation.
108If there is another process descriptor for the same process, created without
109specifying the
110.Dv PD_DAEMON
111flag, closing that descriptor kills the process.
112.It Dv PD_CLOEXEC
113Set close-on-exec on process descriptor.
114.It Dv PD_NOWAITPID
115The parent cannot obtain the child's status with
116.Xr waitpid 2 .
117.It Dv PD_PTRACE_CAP
118Enable
119.Xr pdptrace 2
120requests on the resulting file descriptor.
121Otherwise the descriptor cannot be used to debug the child process.
122See
123.Xr rights 4
124for the description of the
125.Dv CAP_PTRACE
126capability.
127.El
128.Pp
129The
130.Fn pdrfork
131system call is a variant of
132.Fn pdfork
133that also takes the
134.Fa rfflags
135argument to control sharing of process resources between the caller
136and the new process.
137Like
138.Fn pdfork ,
139the function writes the process descriptor referencing the created
140process into the location pointed to by the
141.Fa fdp
142argument.
143See
144.Xr rfork 2
145for a description of the possible
146.Fa rfflag
147flags.
148The
149.Fn pdrfork
150system call requires that both the
151.Va RFPROC
152and
153.Va RFPROCDESC
154flags, or
155.Va RFSPAWN
156flag are specified.
157.Pp
158The
159.Fn pdopenpid
160function opens the process descriptor for the process
161specified by the argument
162.Fa pid .
163It takes the same flags in the
164.Fa pdflags
165argument as
166.Fn pdfork .
167The caller must have permission to debug the target process in order for
168.Fn pdopenpid
169to succeed.
170Zombie processes cannot be opened.
171.Pp
172There might be more that one file descriptor referencing the process.
173After the zombie is reaped, calls to
174.Fn pdwait
175specifying any file descriptors for the same process fail with the
176.Er ESRCH
177error.
178.Pp
179The
180.Fn pdopenpid
181system call is allowed in the capability mode
182.Pq see Xr capsicum 4
183when the target process is the child of the calling process, or
184when the calling process is the debugger of the target process.
185The debugger is attached to its target by
186.Xr ptrace 2 ,
187.Xr pdptrace 2 ,
188or by other means, e.g., by debugging the target process' parent with
189the follow-on-fork mode enabled.
190.Pp
191.Fn pdgetpid
192queries the process ID (PID) in the process descriptor
193.Fa fd .
194.Pp
195.Fn pdkill
196is functionally identical to
197.Xr kill 2 ,
198except that it accepts a process descriptor,
199.Fa fd ,
200rather than a PID.
201.Pp
202The
203.Fn pdwait
204system call allows the calling thread to wait and retrieve
205the status information on the process referenced by the
206.Fa fd
207process descriptor.
208See the description of the
209.Xr wait6 2
210system call for the behavior specification.
211.Pp
212The
213.Fn pddupfd
214function allows the caller to duplicate a file descriptor
215across the process boundaries.
216The function returns the new file descriptor that points to the same file
217as the file descriptor
218.Fa remotefd
219in the process specified by the
220.Fa fd
221process descriptor.
222The returned file descriptor has the
223.Va O_CLOEXEC
224flag set.
225The
226.Fa flags
227argument is reserved and must be zero.
228Certain file descriptor types cannot be copied this way, namely
229kqueues.
230.Pp
231The
232.Fn pdptrace
233function enables execution of
234.Xr ptrace 2
235requests on the process specified by the process descriptor
236.Fa fd .
237.Pp
238In addition to the arguments taken by the
239.Xr ptrace 2 ,
240system call, the
241.Fa lwpid
242thread identifier can designate the thread on which the request
243must operate.
244The
245.Fa lwpid
246argument can be specified as \-1 if the call is not thread-specific,
247or kernel is allowed to select some thread on its own.
248.Pp
249Unlike the
250.Xr ptrace 2
251implementation,
252.Fn pdptrace
253does not clear the
254.Dv errno
255variable before executing the system call.
256.Sh INTERACTION OF PROCESS DESCRIPTORS AND Xr WAITPID 2
257.Pp
258The
259.Fn pdwait
260system call may be called on a process descriptor
261an unlimited number of times.
262In particular, it does not reap the target process,
263even if that process has exited.
264Each time, it returns the same status.
265.Bl -dash
266.It
267If the process was forked with
268.Fn pdfork ,
269and the
270.Dv PD_NOWAITPID
271flag was specified, then the process is automatically reaped after the
272last process descriptor referencing that process is closed.
273No
274.Xr waitpid 2
275call
276.Pq or a call from the same family of the wait functions which operate on PIDs
277are needed to reap the zombie process.
278.It
279If the process was created by
280.Fn pdfork ,
281and the
282.Dv PD_NOWAITPID
283flag was not specified, then after exiting,
284the process will not be reaped until the parent or reaper has called
285.Xr waitpid 2
286and all process descriptors referencing the process are closed.
287.It
288If the process was created by the
289.Xr fork 2
290system call
291.Pq which does not allocate a process descriptor for the child ,
292and later the process was opened by
293.Fn pdopenpid ,
294then a
295.Xr waitpid 2
296call from the parent is needed to reap the exited child.
297.El
298.Pp
299In any case, the PID of the process is not reused until its zombie
300is reaped, and all its process descriptors are closed.
301.Pp
302A debugger attached by
303.Xr ptrace 2
304can execute the
305.Fn waitpid
306calls against the alive target regardless of the way
307the target process was forked.
308.Sh INTERACTION OF PROCESS DESCRIPTORS WITH OTHER SYSTEM CALLS
309.Pp
310The following system calls also have effects specific to process descriptors:
311.Pp
312.Xr fstat 2
313queries status of a process descriptor; currently only the
314.Fa st_mode ,
315.Fa st_birthtime ,
316.Fa st_atime ,
317.Fa st_ctime
318and
319.Fa st_mtime
320fields are defined.
321If the owner read, write, and execute bits are set then the
322process represented by the process descriptor is still alive.
323.Pp
324.Xr poll 2
325and
326.Xr select 2
327allow waiting for process state transitions; currently only
328.Dv POLLHUP
329is defined, and will be raised when the process dies.
330Process state transitions can also be monitored using
331.Xr kqueue 2
332filter
333.Dv EVFILT_PROCDESC ;
334currently only
335.Dv NOTE_EXIT
336is implemented.
337.Pp
338.Xr close 2
339will close the process descriptor unless
340.Dv PD_DAEMON
341is set; if the process is still alive and this is
342the last reference to the process descriptor, the process will be terminated
343with the signal
344.Dv SIGKILL .
345The PID of the referenced process is not reused until the process
346descriptor is closed,
347whether or not the zombie process is reaped by
348.Fn pdwait ,
349.Xr wait6 ,
350or similar system calls.
351.Sh RETURN VALUES
352.Fn pdfork
353and
354.Fn pdrfork
355return a PID, 0 or -1, as
356.Xr fork 2
357does.
358.Pp
359.Fn pdopenpid ,
360.Fn pdgetpid ,
361.Fn pdkill ,
362.Fn pdwait ,
363and
364.Fn pddupfd
365return 0 on success and -1 on failure.
366.Sh ERRORS
367These functions may return the same error numbers as their PID-based equivalents
368(e.g.
369.Fn pdfork
370may return the same error numbers as
371.Xr fork 2 ) ,
372with the following additions:
373.Bl -tag -width Er
374.It Bq Er EFAULT
375The copyout of the resulting file descriptor value to the memory pointed
376to by
377.Fa fdp
378failed.
379.Pp
380Note that the child process was already created when this condition
381is detected,
382and the child continues execution, same as the parent.
383If this error must be handled, it is advisable to memoize the
384.Fn getpid
385result before the call to
386.Fn pdfork
387or
388.Fn pdrfork ,
389and compare it to the value returned by
390.Fn getpid
391after, to see if code is executing in parent or child.
392.It Bq Er EINVAL
393The signal number given to
394.Fn pdkill
395is invalid.
396.It Bq Er ENOTCAPABLE
397The process descriptor being operated on has insufficient rights (e.g.
398.Dv CAP_PDKILL
399for
400.Fn pdkill ) .
401.It Bq Er EINVAL
402The
403.Fn pdwait
404function is called with reserved bits set in
405.Fa options .
406.El
407.Pp
408The
409.Fn pdopenpid
410might return the same errors as
411.Xr open 2 ,
412related to the file descriptor allocation problems, as well as the
413following specific errors:
414.Bl -tag -width Er
415.It Bq Er EINVAL
416The
417.Fa flags
418argument has reserved bits set.
419.It Bq Er ECAPMODE
420.Fn pdopenpid
421is called by the process in capability mode.
422.It Bq Er EBUSY
423The process specified by the
424.Fa pid
425argument already terminated.
426.It Bq Er ESRCH
427The process specified by the
428.Fa pid
429argument does not exist, or the caller does not have enough privileges
430to open the process.
431.It Bq Er EMFILE
432The calling process already reached its limit for open file descriptors.
433.Pp
434Current implementation installs the opened process descriptor into the
435calling process's file descriptors table.
436If the descriptor cannot be installed, the process descriptor is closed,
437which executes all actions performed by
438.Xr close 2
439on it.
440.El
441.Pp
442The
443.Fn pddupfd
444returns the following errors:
445.Bl -tag -width Er
446.It Bq Er EINVAL
447The
448.Fa flags
449argument is not zero.
450.It Bq Er EINVAL
451The file descriptor
452.Fa fd
453is not a process file descriptor.
454.It Bq Er ESRCH
455The process specified by the file descriptor
456.Fa fd
457exited.
458.It Bq Er EBADF
459The file descriptor
460.Fa remotefd
461is not a valid file descriptor in the specified process.
462.It Bq Er ENOENT
463The specified process does not have a file descriptor table.
464.It Bq Er EOPNOTSUPP
465.Fa remotefd
466refers to a file that cannot be duplicated across a process boundary,
467such as a kqueue.
468.El
469.Pp
470The
471.Fn pdptrace
472system call returns the same errors as
473.Xr ptrace 2 ,
474as well as the following specific errors:
475.Bl -tag -width Er
476.It Bq Er ECAPMODE
477The process issuing the
478.Fn pdptrace
479call is in capability mode,
480and the
481.Dv security.bsd.allow_ptrace_in_cap_mode
482tunable is set to
483.Dv false .
484.It Bq Er ENOTCAPABLE
485The process called
486.Fn pdptrace
487on the process descriptor that does not have the
488.Dv CAP_PTRACE
489capability enabled.
490.Sh SEE ALSO
491.Xr close 2 ,
492.Xr fork 2 ,
493.Xr fstat 2 ,
494.Xr kill 2 ,
495.Xr kqueue 2 ,
496.Xr poll 2 ,
497.Xr wait4 2 ,
498.Xr capsicum 4 ,
499.Xr procdesc 4
500.Sh HISTORY
501The
502.Fn pdfork ,
503.Fn pdgetpid ,
504and
505.Fn pdkill
506system calls first appeared in
507.Fx 9.0 .
508The
509.Fn pdrfork
510and
511.Fn pdwait
512system calls first appeared in
513.Fx 15.1 .
514The
515.Fn pdopenpid
516and
517.Fn pddupfd
518system calls first appeared in
519.Fx 16.0 .
520.Pp
521Support for process descriptors mode was developed as part of the
522.Tn TrustedBSD
523Project.
524.Sh AUTHORS
525.An -nosplit
526These functions and the capability facility were created by
527.An Robert N. M. Watson Aq Mt rwatson@FreeBSD.org
528and
529.An Jonathan Anderson Aq Mt jonathan@FreeBSD.org
530at the University of Cambridge Computer Laboratory with support from a grant
531from Google, Inc.
532The
533.Fn pdrfork
534and
535.Fn pdwait
536functions were developed by
537.An Konstantin Belousov Aq Mt kib@FreeBSD.org
538with input from
539.An Alan Somers Aq Mt asomers@FreeBSD.org .
540The
541.Fn pdopenpid ,
542.Fn pddupfd ,
543and
544.Fn pdptrace
545functions were developed by
546.An Konstantin Belousov Aq Mt kib@FreeBSD.org .
547