xref: /freebsd/lib/libsys/pdfork.2 (revision 592ae60e2b2eff6c2ec467c34be9a457ce24b044)
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.Pp
118A consequence of not setting the flag is that the child' zombie is
119not reaped until the
120.Xr waitpid 2
121call is performed on the child' PID.
122Setting the
123.Dv
124kern.pdfork_implicit_nowaitpid
125sysctl MIB to
126.Dv true
127makes the system behave as if the flag is always passed.
128.It Dv PD_PTRACE_CAP
129Enable
130.Xr pdptrace 2
131requests on the resulting file descriptor.
132Otherwise the descriptor cannot be used to debug the child process.
133See
134.Xr rights 4
135for the description of the
136.Dv CAP_PTRACE
137capability.
138.El
139.Pp
140The
141.Fn pdrfork
142system call is a variant of
143.Fn pdfork
144that also takes the
145.Fa rfflags
146argument to control sharing of process resources between the caller
147and the new process.
148Like
149.Fn pdfork ,
150the function writes the process descriptor referencing the created
151process into the location pointed to by the
152.Fa fdp
153argument.
154See
155.Xr rfork 2
156for a description of the possible
157.Fa rfflag
158flags.
159The
160.Fn pdrfork
161system call requires that both the
162.Va RFPROC
163and
164.Va RFPROCDESC
165flags, or
166.Va RFSPAWN
167flag are specified.
168.Pp
169The
170.Fn pdopenpid
171function opens the process descriptor for the process
172specified by the argument
173.Fa pid .
174It takes the same flags in the
175.Fa pdflags
176argument as
177.Fn pdfork .
178The caller must have permission to debug the target process in order for
179.Fn pdopenpid
180to succeed.
181Zombie processes cannot be opened.
182.Pp
183There might be more that one file descriptor referencing the process.
184After the zombie is reaped, calls to
185.Fn pdwait
186specifying any file descriptors for the same process fail with the
187.Er ESRCH
188error.
189.Pp
190The
191.Fn pdopenpid
192system call is allowed in the capability mode
193.Pq see Xr capsicum 4
194when the target process is the child of the calling process, or
195when the calling process is the debugger of the target process.
196The debugger is attached to its target by
197.Xr ptrace 2 ,
198.Xr pdptrace 2 ,
199or by other means, e.g., by debugging the target process' parent with
200the follow-on-fork mode enabled.
201.Pp
202.Fn pdgetpid
203queries the process ID (PID) in the process descriptor
204.Fa fd .
205.Pp
206.Fn pdkill
207is functionally identical to
208.Xr kill 2 ,
209except that it accepts a process descriptor,
210.Fa fd ,
211rather than a PID.
212.Pp
213The
214.Fn pdwait
215system call allows the calling thread to wait and retrieve
216the status information on the process referenced by the
217.Fa fd
218process descriptor.
219See the description of the
220.Xr wait6 2
221system call for the behavior specification.
222.Pp
223The
224.Fn pddupfd
225function allows the caller to duplicate a file descriptor
226across the process boundaries.
227The function returns the new file descriptor that points to the same file
228as the file descriptor
229.Fa remotefd
230in the process specified by the
231.Fa fd
232process descriptor.
233The returned file descriptor has the
234.Va O_CLOEXEC
235flag set.
236The
237.Fa flags
238argument is reserved and must be zero.
239Certain file descriptor types cannot be copied this way, namely
240kqueues.
241.Pp
242The
243.Fn pdptrace
244function enables execution of
245.Xr ptrace 2
246requests on the process specified by the process descriptor
247.Fa fd .
248.Pp
249In addition to the arguments taken by the
250.Xr ptrace 2 ,
251system call, the
252.Fa lwpid
253thread identifier can designate the thread on which the request
254must operate.
255The
256.Fa lwpid
257argument can be specified as \-1 if the call is not thread-specific,
258or kernel is allowed to select some thread on its own.
259.Pp
260Unlike the
261.Xr ptrace 2
262implementation,
263.Fn pdptrace
264does not clear the
265.Dv errno
266variable before executing the system call.
267.Sh INTERACTION OF PROCESS DESCRIPTORS AND Xr WAITPID 2
268.Pp
269The
270.Fn pdwait
271system call may be called on a process descriptor
272an unlimited number of times.
273In particular, it does not reap the target process,
274even if that process has exited.
275Each time, it returns the same status.
276.Bl -dash
277.It
278If the process was forked with
279.Fn pdfork ,
280and the
281.Dv PD_NOWAITPID
282flag was specified, then the process is automatically reaped after the
283last process descriptor referencing that process is closed.
284No
285.Xr waitpid 2
286call
287.Pq or a call from the same family of the wait functions which operate on PIDs
288are needed to reap the zombie process.
289.It
290If the process was created by
291.Fn pdfork ,
292and the
293.Dv PD_NOWAITPID
294flag was not specified, then after exiting,
295the process will not be reaped until the parent or reaper has called
296.Xr waitpid 2
297and all process descriptors referencing the process are closed.
298.It
299If the process was created by the
300.Xr fork 2
301system call
302.Pq which does not allocate a process descriptor for the child ,
303and later the process was opened by
304.Fn pdopenpid ,
305then a
306.Xr waitpid 2
307call from the parent is needed to reap the exited child.
308.El
309.Pp
310In any case, the PID of the process is not reused until its zombie
311is reaped, and all its process descriptors are closed.
312.Pp
313A debugger attached by
314.Xr ptrace 2
315can execute the
316.Fn waitpid
317calls against the alive target regardless of the way
318the target process was forked.
319.Sh INTERACTION OF PROCESS DESCRIPTORS WITH OTHER SYSTEM CALLS
320.Pp
321The following system calls also have effects specific to process descriptors:
322.Pp
323.Xr fstat 2
324queries status of a process descriptor; currently only the
325.Fa st_mode ,
326.Fa st_birthtime ,
327.Fa st_atime ,
328.Fa st_ctime
329and
330.Fa st_mtime
331fields are defined.
332If the owner read, write, and execute bits are set then the
333process represented by the process descriptor is still alive.
334.Pp
335.Xr poll 2
336and
337.Xr select 2
338allow waiting for process state transitions; currently only
339.Dv POLLHUP
340is defined, and will be raised when the process dies.
341Process state transitions can also be monitored using
342.Xr kqueue 2
343filter
344.Dv EVFILT_PROCDESC ;
345currently only
346.Dv NOTE_EXIT
347is implemented.
348.Pp
349.Xr close 2
350will close the process descriptor unless
351.Dv PD_DAEMON
352is set; if the process is still alive and this is
353the last reference to the process descriptor, the process will be terminated
354with the signal
355.Dv SIGKILL .
356The PID of the referenced process is not reused until the process
357descriptor is closed,
358whether or not the zombie process is reaped by
359.Fn pdwait ,
360.Xr wait6 ,
361or similar system calls.
362.Sh RETURN VALUES
363.Fn pdfork
364and
365.Fn pdrfork
366return a PID, 0 or -1, as
367.Xr fork 2
368does.
369.Pp
370.Fn pdopenpid ,
371.Fn pdgetpid ,
372.Fn pdkill ,
373.Fn pdwait ,
374and
375.Fn pddupfd
376return 0 on success and -1 on failure.
377.Sh ERRORS
378These functions may return the same error numbers as their PID-based equivalents
379(e.g.
380.Fn pdfork
381may return the same error numbers as
382.Xr fork 2 ) ,
383with the following additions:
384.Bl -tag -width Er
385.It Bq Er EFAULT
386The copyout of the resulting file descriptor value to the memory pointed
387to by
388.Fa fdp
389failed.
390.Pp
391Note that the child process was already created when this condition
392is detected,
393and the child continues execution, same as the parent.
394If this error must be handled, it is advisable to memoize the
395.Fn getpid
396result before the call to
397.Fn pdfork
398or
399.Fn pdrfork ,
400and compare it to the value returned by
401.Fn getpid
402after, to see if code is executing in parent or child.
403.It Bq Er EINVAL
404The signal number given to
405.Fn pdkill
406is invalid.
407.It Bq Er ENOTCAPABLE
408The process descriptor being operated on has insufficient rights (e.g.
409.Dv CAP_PDKILL
410for
411.Fn pdkill ) .
412.It Bq Er EINVAL
413The
414.Fn pdwait
415function is called with reserved bits set in
416.Fa options .
417.El
418.Pp
419The
420.Fn pdopenpid
421might return the same errors as
422.Xr open 2 ,
423related to the file descriptor allocation problems, as well as the
424following specific errors:
425.Bl -tag -width Er
426.It Bq Er EINVAL
427The
428.Fa flags
429argument has reserved bits set.
430.It Bq Er ECAPMODE
431.Fn pdopenpid
432is called by the process in capability mode.
433.It Bq Er EBUSY
434The process specified by the
435.Fa pid
436argument already terminated.
437.It Bq Er ESRCH
438The process specified by the
439.Fa pid
440argument does not exist, or the caller does not have enough privileges
441to open the process.
442.It Bq Er EMFILE
443The calling process already reached its limit for open file descriptors.
444.Pp
445Current implementation installs the opened process descriptor into the
446calling process's file descriptors table.
447If the descriptor cannot be installed, the process descriptor is closed,
448which executes all actions performed by
449.Xr close 2
450on it.
451.El
452.Pp
453The
454.Fn pddupfd
455returns the following errors:
456.Bl -tag -width Er
457.It Bq Er EINVAL
458The
459.Fa flags
460argument is not zero.
461.It Bq Er EINVAL
462The file descriptor
463.Fa fd
464is not a process file descriptor.
465.It Bq Er ESRCH
466The process specified by the file descriptor
467.Fa fd
468exited.
469.It Bq Er EBADF
470The file descriptor
471.Fa remotefd
472is not a valid file descriptor in the specified process.
473.It Bq Er ENOENT
474The specified process does not have a file descriptor table.
475.It Bq Er EOPNOTSUPP
476.Fa remotefd
477refers to a file that cannot be duplicated across a process boundary,
478such as a kqueue.
479.El
480.Pp
481The
482.Fn pdptrace
483system call returns the same errors as
484.Xr ptrace 2 ,
485as well as the following specific errors:
486.Bl -tag -width Er
487.It Bq Er ECAPMODE
488The process issuing the
489.Fn pdptrace
490call is in capability mode,
491and the
492.Dv security.bsd.allow_ptrace_in_cap_mode
493tunable is set to
494.Dv false .
495.It Bq Er ENOTCAPABLE
496The process called
497.Fn pdptrace
498on the process descriptor that does not have the
499.Dv CAP_PTRACE
500capability enabled.
501.Sh SEE ALSO
502.Xr close 2 ,
503.Xr fork 2 ,
504.Xr fstat 2 ,
505.Xr kill 2 ,
506.Xr kqueue 2 ,
507.Xr poll 2 ,
508.Xr wait4 2 ,
509.Xr capsicum 4 ,
510.Xr procdesc 4
511.Sh HISTORY
512The
513.Fn pdfork ,
514.Fn pdgetpid ,
515and
516.Fn pdkill
517system calls first appeared in
518.Fx 9.0 .
519The
520.Fn pdrfork
521and
522.Fn pdwait
523system calls first appeared in
524.Fx 15.1 .
525The
526.Fn pdopenpid
527and
528.Fn pddupfd
529system calls first appeared in
530.Fx 16.0 .
531.Pp
532Support for process descriptors mode was developed as part of the
533.Tn TrustedBSD
534Project.
535.Sh AUTHORS
536.An -nosplit
537These functions and the capability facility were created by
538.An Robert N. M. Watson Aq Mt rwatson@FreeBSD.org
539and
540.An Jonathan Anderson Aq Mt jonathan@FreeBSD.org
541at the University of Cambridge Computer Laboratory with support from a grant
542from Google, Inc.
543The
544.Fn pdrfork
545and
546.Fn pdwait
547functions were developed by
548.An Konstantin Belousov Aq Mt kib@FreeBSD.org
549with input from
550.An Alan Somers Aq Mt asomers@FreeBSD.org .
551The
552.Fn pdopenpid ,
553.Fn pddupfd ,
554and
555.Fn pdptrace
556functions were developed by
557.An Konstantin Belousov Aq Mt kib@FreeBSD.org .
558