Start of man-pages-5.14: renaming .Announce and .lsm files
[man-pages.git] / man2 / seccomp_unotify.2
blob6e0a5ebad4f9c534f4b487eb2c5f2f4aaa055a57
1 .\" Copyright (C) 2020 Michael Kerrisk <mtk.manpages@gmail.com>
2 .\"
3 .\" %%%LICENSE_START(VERBATIM)
4 .\" Permission is granted to make and distribute verbatim copies of this
5 .\" manual provided the copyright notice and this permission notice are
6 .\" preserved on all copies.
7 .\"
8 .\" Permission is granted to copy and distribute modified versions of this
9 .\" manual under the conditions for verbatim copying, provided that the
10 .\" entire resulting derived work is distributed under the terms of a
11 .\" permission notice identical to this one.
12 .\"
13 .\" Since the Linux kernel and libraries are constantly changing, this
14 .\" manual page may be incorrect or out-of-date.  The author(s) assume no
15 .\" responsibility for errors or omissions, or for damages resulting from
16 .\" the use of the information contained herein.  The author(s) may not
17 .\" have taken the same level of care in the production of this manual,
18 .\" which is licensed free of charge, as they might when working
19 .\" professionally.
20 .\"
21 .\" Formatted or processed versions of this manual, if unaccompanied by
22 .\" the source, must acknowledge the copyright and authors of this work.
23 .\" %%%LICENSE_END
24 .\"
25 .TH SECCOMP_UNOTIFY 2 2021-06-20 "Linux" "Linux Programmer's Manual"
26 .SH NAME
27 seccomp_unotify \- Seccomp user-space notification mechanism
28 .SH SYNOPSIS
29 .nf
30 .B #include <linux/seccomp.h>
31 .B #include <linux/filter.h>
32 .B #include <linux/audit.h>
33 .PP
34 .BI "int seccomp(unsigned int " operation ", unsigned int " flags \
35 ", void *" args );
36 .PP
37 .B #include <sys/ioctl.h>
38 .PP
39 .BI "int ioctl(int " fd ", SECCOMP_IOCTL_NOTIF_RECV,"
40 .BI "          struct seccomp_notif *" req );
41 .BI "int ioctl(int " fd ", SECCOMP_IOCTL_NOTIF_SEND,"
42 .BI "          struct seccomp_notif_resp *" resp );
43 .BI "int ioctl(int " fd ", SECCOMP_IOCTL_NOTIF_ID_VALID, __u64 *" id );
44 .BI "int ioctl(int " fd ", SECCOMP_IOCTL_NOTIF_ADDFD,"
45 .BI "          struct seccomp_notif_addfd *" addfd );
46 .fi
47 .SH DESCRIPTION
48 This page describes the user-space notification mechanism provided by the
49 Secure Computing (seccomp) facility.
50 As well as the use of the
51 .B SECCOMP_FILTER_FLAG_NEW_LISTENER
52 flag, the
53 .BR SECCOMP_RET_USER_NOTIF
54 action value, and the
55 .B SECCOMP_GET_NOTIF_SIZES
56 operation described in
57 .BR seccomp (2),
58 this mechanism involves the use of a number of related
59 .BR ioctl (2)
60 operations (described below).
61 .\"
62 .SS Overview
63 In conventional usage of a seccomp filter,
64 the decision about how to treat a system call is made by the filter itself.
65 By contrast, the user-space notification mechanism allows
66 the seccomp filter to delegate
67 the handling of the system call to another user-space process.
68 Note that this mechanism is explicitly
69 .B not
70 intended as a method implementing security policy; see NOTES.
71 .PP
72 In the discussion that follows,
73 the thread(s) on which the seccomp filter is installed is (are)
74 referred to as the
75 .IR target ,
76 and the process that is notified by the user-space notification
77 mechanism is referred to as the
78 .IR supervisor .
79 .PP
80 A suitably privileged supervisor can use the user-space notification
81 mechanism to perform actions on behalf of the target.
82 The advantage of the user-space notification mechanism is that
83 the supervisor will
84 usually be able to retrieve information about the target and the
85 performed system call that the seccomp filter itself cannot.
86 (A seccomp filter is limited in the information it can obtain and
87 the actions that it can perform because it
88 is running on a virtual machine inside the kernel.)
89 .PP
90 An overview of the steps performed by the target and the supervisor
91 is as follows:
92 .\"-------------------------------------
93 .IP 1. 3
94 The target establishes a seccomp filter in the usual manner,
95 but with two differences:
96 .RS
97 .IP \(bu 2
98 The
99 .BR seccomp (2)
100 .I flags
101 argument includes the flag
102 .BR SECCOMP_FILTER_FLAG_NEW_LISTENER .
103 Consequently, the return value of the (successful)
104 .BR seccomp (2)
105 call is a new "listening"
106 file descriptor that can be used to receive notifications.
107 Only one "listening" seccomp filter can be installed for a thread.
108 .\" FIXME
109 .\" Is the last sentence above correct?
111 .\" Kees Cook (25 Oct 2020) notes:
113 .\" I like this limitation, but I expect that it'll need to change in the
114 .\" future. Even with LSMs, we see the need for arbitrary stacking, and the
115 .\" idea of there being only 1 supervisor will eventually break down. Right
116 .\" now there is only 1 because only container managers are using this
117 .\" feature. But if some daemon starts using it to isolate some thread,
118 .\" suddenly it might break if a container manager is trying to listen to it
119 .\" too, etc. I expect it won't be needed soon, but I do think it'll change.
121 .IP \(bu
122 In cases where it is appropriate, the seccomp filter returns the action value
123 .BR SECCOMP_RET_USER_NOTIF .
124 This return value will trigger a notification event.
126 .\"-------------------------------------
127 .IP 2.
128 In order that the supervisor can obtain notifications
129 using the listening file descriptor,
130 (a duplicate of) that file descriptor must be passed from
131 the target to the supervisor.
132 One way in which this could be done is by passing the file descriptor
133 over a UNIX domain socket connection between the target and the supervisor
134 (using the
135 .BR SCM_RIGHTS
136 ancillary message type described in
137 .BR unix (7)).
138 Another way to do this is through the use of
139 .BR pidfd_getfd (2).
140 .\" Jann Horn:
141 .\"     Instead of using unix domain sockets to send the fd to the
142 .\"     parent, I think you could also use clone3() with
143 .\"     flags==CLONE_FILES|SIGCHLD, dup2() the seccomp fd to an fd
144 .\"     that was reserved in the parent, call unshare(CLONE_FILES)
145 .\"     in the child after setting up the seccomp fd, and wake
146 .\"     up the parent with something like pthread_cond_signal()?
147 .\"     I'm not sure whether that'd look better or worse in the
148 .\"     end though, so maybe just ignore this comment.
149 .\"-------------------------------------
150 .IP 3.
151 The supervisor will receive notification events
152 on the listening file descriptor.
153 These events are returned as structures of type
154 .IR seccomp_notif .
155 Because this structure and its size may evolve over kernel versions,
156 the supervisor must first determine the size of this structure
157 using the
158 .BR seccomp (2)
159 .B SECCOMP_GET_NOTIF_SIZES
160 operation, which returns a structure of type
161 .IR seccomp_notif_sizes .
162 The supervisor allocates a buffer of size
163 .I seccomp_notif_sizes.seccomp_notif
164 bytes to receive notification events.
165 In addition,the supervisor allocates another buffer of size
166 .I seccomp_notif_sizes.seccomp_notif_resp
167 bytes for the response (a
168 .I struct seccomp_notif_resp
169 structure)
170 that it will provide to the kernel (and thus the target).
171 .\"-------------------------------------
172 .IP 4.
173 The target then performs its workload,
174 which includes system calls that will be controlled by the seccomp filter.
175 Whenever one of these system calls causes the filter to return the
176 .B SECCOMP_RET_USER_NOTIF
177 action value, the kernel does
178 .I not
179 (yet) execute the system call;
180 instead, execution of the target is temporarily blocked inside
181 the kernel (in a sleep state that is interruptible by signals)
182 and a notification event is generated on the listening file descriptor.
183 .\"-------------------------------------
184 .IP 5.
185 The supervisor can now repeatedly monitor the
186 listening file descriptor for
187 .BR SECCOMP_RET_USER_NOTIF -triggered
188 events.
189 To do this, the supervisor uses the
190 .B SECCOMP_IOCTL_NOTIF_RECV
191 .BR ioctl (2)
192 operation to read information about a notification event;
193 this operation blocks until an event is available.
194 The operation returns a
195 .I seccomp_notif
196 structure containing information about the system call
197 that is being attempted by the target.
198 (As described in NOTES,
199 the file descriptor can also be monitored with
200 .BR select (2),
201 .BR poll (2),
203 .BR epoll (7).)
204 .\" FIXME
205 .\" Christian Brauner:
207 .\" Do we support O_NONBLOCK with SECCOMP_IOCTL_NOTIF_RECV and if
208 .\" not should we?
210 .\" Michael Kerrisk:
212 .\" A quick test suggests that O_NONBLOCK has no effect on the blocking
213 .\" behavior of SECCOMP_IOCTL_NOTIF_RECV.
215 .\"-------------------------------------
216 .IP 6.
218 .I seccomp_notif
219 structure returned by the
220 .B SECCOMP_IOCTL_NOTIF_RECV
221 operation includes the same information (a
222 .I seccomp_data
223 structure) that was passed to the seccomp filter.
224 This information allows the supervisor to discover the system call number and
225 the arguments for the target's system call.
226 In addition, the notification event contains the ID of the thread
227 that triggered the notification and a unique cookie value that
228 is used in subsequent
229 .B SECCOMP_IOCTL_NOTIF_ID_VALID
231 .B SECCOMP_IOCTL_NOTIF_SEND
232 operations.
234 The information in the notification can be used to discover the
235 values of pointer arguments for the target's system call.
236 (This is something that can't be done from within a seccomp filter.)
237 One way in which the supervisor can do this is to open the corresponding
238 .I /proc/[tid]/mem
239 file (see
240 .BR proc (5))
241 and read bytes from the location that corresponds to one of
242 the pointer arguments whose value is supplied in the notification event.
243 .\" Tycho Andersen mentioned that there are alternatives to /proc/PID/mem,
244 .\" such as ptrace() and /proc/PID/map_files
245 (The supervisor must be careful to avoid
246 a race condition that can occur when doing this;
247 see the description of the
248 .BR SECCOMP_IOCTL_NOTIF_ID_VALID
249 .BR ioctl (2)
250 operation below.)
251 In addition,
252 the supervisor can access other system information that is visible
253 in user space but which is not accessible from a seccomp filter.
254 .\"-------------------------------------
255 .IP 7.
256 Having obtained information as per the previous step,
257 the supervisor may then choose to perform an action in response
258 to the target's system call
259 (which, as noted above, is not executed when the seccomp filter returns the
260 .B SECCOMP_RET_USER_NOTIF
261 action value).
263 One example use case here relates to containers.
264 The target may be located inside a container where
265 it does not have sufficient capabilities to mount a filesystem
266 in the container's mount namespace.
267 However, the supervisor may be a more privileged process that
268 does have sufficient capabilities to perform the mount operation.
269 .\"-------------------------------------
270 .IP 8.
271 The supervisor then sends a response to the notification.
272 The information in this response is used by the kernel to construct
273 a return value for the target's system call and provide
274 a value that will be assigned to the
275 .I errno
276 variable of the target.
278 The response is sent using the
279 .B SECCOMP_IOCTL_NOTIF_SEND
280 .BR ioctl (2)
281 operation, which is used to transmit a
282 .I seccomp_notif_resp
283 structure to the kernel.
284 This structure includes a cookie value that the supervisor obtained in the
285 .I seccomp_notif
286 structure returned by the
287 .B SECCOMP_IOCTL_NOTIF_RECV
288 operation.
289 This cookie value allows the kernel to associate the response with the
290 target.
291 This structure must include the cookie value that the supervisor
292 obtained in the
293 .I seccomp_notif
294 structure returned by the
295 .B SECCOMP_IOCTL_NOTIF_RECV
296 operation;
297 the cookie allows the kernel to associate the response with the target.
298 .\"-------------------------------------
299 .IP 9.
300 Once the notification has been sent,
301 the system call in the target thread unblocks,
302 returning the information that was provided by the supervisor
303 in the notification response.
304 .\"-------------------------------------
306 As a variation on the last two steps,
307 the supervisor can send a response that tells the kernel that it
308 should execute the target thread's system call; see the discussion of
309 .BR SECCOMP_USER_NOTIF_FLAG_CONTINUE ,
310 below.
312 .SH IOCTL OPERATIONS
313 The following
314 .BR ioctl (2)
315 operations are supported by the seccomp user-space
316 notification file descriptor.
317 For each of these operations, the first (file descriptor) argument of
318 .BR ioctl (2)
319 is the listening file descriptor returned by a call to
320 .BR seccomp (2)
321 with the
322 .BR SECCOMP_FILTER_FLAG_NEW_LISTENER
323 flag.
325 .SS SECCOMP_IOCTL_NOTIF_RECV
327 .B SECCOMP_IOCTL_NOTIF_RECV
328 operation (available since Linux 5.0) is used to obtain a user-space
329 notification event.
330 If no such event is currently pending,
331 the operation blocks until an event occurs.
332 The third
333 .BR ioctl (2)
334 argument is a pointer to a structure of the following form
335 which contains information about the event.
336 This structure must be zeroed out before the call.
338 .in +4n
340 struct seccomp_notif {
341     __u64  id;              /* Cookie */
342     __u32  pid;             /* TID of target thread */
343     __u32  flags;           /* Currently unused (0) */
344     struct seccomp_data data;   /* See seccomp(2) */
349 The fields in this structure are as follows:
351 .I id
352 This is a cookie for the notification.
353 Each such cookie is guaranteed to be unique for the corresponding
354 seccomp filter.
356 .IP \(bu 2
357 The cookie can be used with the
358 .B SECCOMP_IOCTL_NOTIF_ID_VALID
359 .BR ioctl (2)
360 operation described below.
361 .IP \(bu
362 When returning a notification response to the kernel,
363 the supervisor must include the cookie value in the
364 .IR seccomp_notif_resp
365 structure that is specified as the argument of the
366 .BR SECCOMP_IOCTL_NOTIF_SEND
367 operation.
370 .I pid
371 This is the thread ID of the target thread that triggered
372 the notification event.
374 .I flags
375 This is a bit mask of flags providing further information on the event.
376 In the current implementation, this field is always zero.
378 .I data
379 This is a
380 .I seccomp_data
381 structure containing information about the system call that
382 triggered the notification.
383 This is the same structure that is passed to the seccomp filter.
385 .BR seccomp (2)
386 for details of this structure.
388 On success, this operation returns 0; on failure, \-1 is returned, and
389 .I errno
390 is set to indicate the cause of the error.
391 This operation can fail with the following errors:
393 .BR EINVAL " (since Linux 5.5)"
394 .\" commit 2882d53c9c6f3b8311d225062522f03772cf0179
396 .I seccomp_notif
397 structure that was passed to the call contained nonzero fields.
399 .B ENOENT
400 The target thread was killed by a signal as the notification information
401 was being generated,
402 or the target's (blocked) system call was interrupted by a signal handler.
403 .\" FIXME
404 .\" From my experiments,
405 .\" it appears that if a SECCOMP_IOCTL_NOTIF_RECV is done after
406 .\" the target thread terminates, then the ioctl() simply
407 .\" blocks (rather than returning an error to indicate that the
408 .\" target no longer exists).
410 .\" I found that surprising, and it required some contortions in
411 .\" the example program.  It was not possible to code my SIGCHLD
412 .\" handler (which reaps the zombie when the worker/target
413 .\" terminates) to simply set a flag checked in the main
414 .\" handleNotifications() loop, since this created an
415 .\" unavoidable race where the child might terminate just after
416 .\" I had checked the flag, but before I blocked (forever!) in the
417 .\" SECCOMP_IOCTL_NOTIF_RECV operation. Instead, I had to code
418 .\" the signal handler to simply call _exit(2) in order to
419 .\" terminate the parent process (the supervisor).
421 .\" Is this expected behavior? It seems to me rather
422 .\" desirable that SECCOMP_IOCTL_NOTIF_RECV should give an error
423 .\" if the target has terminated.
425 .\" Jann posted a patch to rectify this, but there was no response
426 .\" (Lore link: https://bit.ly/3jvUBxk) to his question about fixing
427 .\" this issue. (I've tried building with the patch, but encountered
428 .\" an issue with the target process entering D state after a signal.)
430 .\" For now, this behavior is documented in BUGS.
432 .\" Kees Cook commented: Let's change [this] ASAP!
434 .SS SECCOMP_IOCTL_NOTIF_ID_VALID
436 .B SECCOMP_IOCTL_NOTIF_ID_VALID
437 operation (available since Linux 5.0) is used to check that a notification ID
438 returned by an earlier
439 .B SECCOMP_IOCTL_NOTIF_RECV
440 operation is still valid
441 (i.e., that the target still exists and its system call
442 is still blocked waiting for a response).
444 The third
445 .BR ioctl (2)
446 argument is a pointer to the cookie
447 .RI ( id )
448 returned by the
449 .B SECCOMP_IOCTL_NOTIF_RECV
450 operation.
452 This operation is necessary to avoid race conditions that can occur when the
453 .I pid
454 returned by the
455 .B SECCOMP_IOCTL_NOTIF_RECV
456 operation terminates, and that process ID is reused by another process.
457 An example of this kind of race is the following
458 .IP 1. 3
459 A notification is generated on the listening file descriptor.
460 The returned
461 .I seccomp_notif
462 contains the TID of the target thread (in the
463 .I pid
464 field of the structure).
465 .IP 2.
466 The target terminates.
467 .IP 3.
468 Another thread or process is created on the system that by chance reuses the
469 TID that was freed when the target terminated.
470 .IP 4.
471 The supervisor
472 .BR open (2)s
474 .IR /proc/[tid]/mem
475 file for the TID obtained in step 1, with the intention of (say)
476 inspecting the memory location(s) that containing the argument(s) of
477 the system call that triggered the notification in step 1.
479 In the above scenario, the risk is that the supervisor may try
480 to access the memory of a process other than the target.
481 This race can be avoided by following the call to
482 .BR open (2)
483 with a
484 .B SECCOMP_IOCTL_NOTIF_ID_VALID
485 operation to verify that the process that generated the notification
486 is still alive.
487 (Note that if the target terminates after the latter step,
488 a subsequent
489 .BR read (2)
490 from the file descriptor may return 0, indicating end of file.)
491 .\" Jann Horn:
492 .\"     the PID can be reused, but the /proc/$pid directory is
493 .\"     internally not associated with the numeric PID, but,
494 .\"     conceptually speaking, with a specific incarnation of the
495 .\"     PID, or something like that.  (Actually, it is associated
496 .\"     with the "struct pid", which is not reused, instead of the
497 .\"     numeric PID.
499 See NOTES for a discussion of other cases where
500 .B SECCOMP_IOCTL_NOTIF_ID_VALID
501 checks must be performed.
503 On success (i.e., the notification ID is still valid),
504 this operation returns 0.
505 On failure (i.e., the notification ID is no longer valid),
506 \-1 is returned, and
507 .I errno
508 is set to
509 .BR ENOENT .
511 .SS SECCOMP_IOCTL_NOTIF_SEND
513 .B SECCOMP_IOCTL_NOTIF_SEND
514 operation (available since Linux 5.0)
515 is used to send a notification response back to the kernel.
516 The third
517 .BR ioctl (2)
518 argument of this structure is a pointer to a structure of the following form:
520 .in +4n
522 struct seccomp_notif_resp {
523     __u64 id;           /* Cookie value */
524     __s64 val;          /* Success return value */
525     __s32 error;        /* 0 (success) or negative error number */
526     __u32 flags;        /* See below */
531 The fields of this structure are as follows:
533 .I id
534 This is the cookie value that was obtained using the
535 .B SECCOMP_IOCTL_NOTIF_RECV
536 operation.
537 This cookie value allows the kernel to correctly associate this response
538 with the system call that triggered the user-space notification.
540 .I val
541 This is the value that will be used for a spoofed
542 success return for the target's system call; see below.
544 .I error
545 This is the value that will be used as the error number
546 .RI ( errno )
547 for a spoofed error return for the target's system call; see below.
549 .I flags
550 This is a bit mask that includes zero or more of the following flags:
553 .BR SECCOMP_USER_NOTIF_FLAG_CONTINUE " (since Linux 5.5)"
554 Tell the kernel to execute the target's system call.
555 .\" commit fb3c5386b382d4097476ce9647260fc89b34afdb
558 Two kinds of response are possible:
559 .IP \(bu 2
560 A response to the kernel telling it to execute the
561 target's system call.
562 In this case, the
563 .I flags
564 field includes
565 .B SECCOMP_USER_NOTIF_FLAG_CONTINUE
566 and the
567 .I error
569 .I val
570 fields must be zero.
572 This kind of response can be useful in cases where the supervisor needs
573 to do deeper analysis of the target's system call than is possible
574 from a seccomp filter (e.g., examining the values of pointer arguments),
575 and, having decided that the system call does not require emulation
576 by the supervisor, the supervisor wants the system call to
577 be executed normally in the target.
580 .B SECCOMP_USER_NOTIF_FLAG_CONTINUE
581 flag should be used with caution; see NOTES.
582 .IP \(bu
583 A spoofed return value for the target's system call.
584 In this case, the kernel does not execute the target's system call,
585 instead causing the system call to return a spoofed value as specified by
586 fields of the
587 .I seccomp_notif_resp
588 structure.
589 The supervisor should set the fields of this structure as follows:
591 .IP + 3
592 .I flags
593 does not contain
594 .BR SECCOMP_USER_NOTIF_FLAG_CONTINUE .
595 .IP +
596 .I error
597 is set either to 0 for a spoofed "success" return or to a negative
598 error number for a spoofed "failure" return.
599 In the former case, the kernel causes the target's system call
600 to return the value specified in the
601 .I val
602 field.
603 In the latter case, the kernel causes the target's system call
604 to return \-1, and
605 .I errno
606 is assigned the negated
607 .I error
608 value.
609 .IP +
610 .I val
611 is set to a value that will be used as the return value for a spoofed
612 "success" return for the target's system call.
613 The value in this field is ignored if the
614 .I error
615 field contains a nonzero value.
616 .\" FIXME
617 .\" Kees Cook suggested:
619 .\" Strictly speaking, this is architecture specific, but
620 .\" all architectures do it this way. Should seccomp enforce
621 .\" val == 0 when err != 0 ?
623 .\" Christian Brauner
625 .\" Feels like it should, at least for the SEND ioctl where we already
626 .\" verify that val and err are both 0 when CONTINUE is specified (as you
627 .\" pointed out correctly above).
630 On success, this operation returns 0; on failure, \-1 is returned, and
631 .I errno
632 is set to indicate the cause of the error.
633 This operation can fail with the following errors:
635 .B EINPROGRESS
636 A response to this notification has already been sent.
638 .B EINVAL
639 An invalid value was specified in the
640 .I flags field.
643 .B EINVAL
645 .I flags
646 field contained
647 .BR SECCOMP_USER_NOTIF_FLAG_CONTINUE ,
648 and the
649 .I error
651 .I val
652 field was not zero.
654 .B ENOENT
655 The blocked system call in the target
656 has been interrupted by a signal handler
657 or the target has terminated.
658 .\" Jann Horn notes:
659 .\"     you could also get this [ENOENT] if a response has already
660 .\"     been sent, instead of EINPROGRESS - the only difference is
661 .\"     whether the target thread has picked up the response yet
663 .SS SECCOMP_IOCTL_NOTIF_ADDFD
665 .B SECCOMP_IOCTL_NOTIF_ADDFD
666 operation (available since Linux 5.9)
667 allows the supervisor to install a file descriptor
668 into the target's file descriptor table.
669 Much like the use of
670 .BR SCM_RIGHTS
671 messages described in
672 .BR unix (7),
673 this operation is semantically equivalent to duplicating
674 a file descriptor from the supervisor's file descriptor table
675 into the target's file descriptor table.
678 .BR SECCOMP_IOCTL_NOTIF_ADDFD
679 operation permits the supervisor to emulate a target system call (such as
680 .BR socket (2)
682 .BR openat (2))
683 that generates a file descriptor.
684 The supervisor can perform the system call that generates
685 the file descriptor (and associated open file description)
686 and then use this operation to allocate
687 a file descriptor that refers to the same open file description in the target.
688 (For an explanation of open file descriptions, see
689 .BR open (2).)
691 Once this operation has been performed,
692 the supervisor can close its copy of the file descriptor.
694 In the target,
695 the received file descriptor is subject to the same
696 Linux Security Module (LSM) checks as are applied to a file descriptor
697 that is received in an
698 .BR SCM_RIGHTS
699 ancillary message.
700 If the file descriptor refers to a socket,
701 it inherits the cgroup version 1 network controller settings
702 .RI ( classid
704 .IR netprioidx )
705 of the target.
707 The third
708 .BR ioctl (2)
709 argument is a pointer to a structure of the following form:
711 .in +4n
713 struct seccomp_notif_addfd {
714     __u64 id;           /* Cookie value */
715     __u32 flags;        /* Flags */
716     __u32 srcfd;        /* Local file descriptor number */
717     __u32 newfd;        /* 0 or desired file descriptor
718                            number in target */
719     __u32 newfd_flags;  /* Flags to set on target file
720                            descriptor */
725 The fields in this structure are as follows:
727 .I id
728 This field should be set to the notification ID
729 (cookie value) that was obtained via
730 .BR SECCOMP_IOCTL_NOTIF_RECV .
732 .I flags
733 This field is a bit mask of flags that modify the behavior of the operation.
734 Currently, only one flag is supported:
737 .BR SECCOMP_ADDFD_FLAG_SETFD
738 When allocating the file descriptor in the target,
739 use the file descriptor number specified in the
740 .I newfd
741 field.
743 .BR SECCOMP_ADDFD_FLAG_SEND " (since Linux 5.14)"
744 .\" commit 0ae71c7720e3ae3aabd2e8a072d27f7bd173d25c
745 Perform the equivalent of
746 .B SECCOMP_IOCTL_NOTIF_ADDFD
747 plus
748 .B SECCOMP_IOCTL_NOTIF_SEND
749 as an atomic operation.
750 On successful invocation, the target process's
751 .I errno
752 will be 0
753 and the return value will be the file descriptor number
754 that was allocated in the target.
755 If allocating the file descriptor in the target fails,
756 the target's system call continues to be blocked
757 until a successful response is sent.
760 .I srcfd
761 This field should be set to the number of the file descriptor
762 in the supervisor that is to be duplicated.
764 .I newfd
765 This field determines which file descriptor number is allocated in the target.
766 If the
767 .BR SECCOMP_ADDFD_FLAG_SETFD
768 flag is set,
769 then this field specifies which file descriptor number should be allocated.
770 If this file descriptor number is already open in the target,
771 it is atomically closed and reused.
772 If the descriptor duplication fails due to an LSM check, or if
773 .I srcfd
774 is not a valid file descriptor,
775 the file descriptor
776 .I newfd
777 will not be closed in the target process.
779 If the
780 .BR SECCOMP_ADDFD_FLAG_SETFD
781 flag it not set, then this field must be 0,
782 and the kernel allocates the lowest unused file descriptor number
783 in the target.
785 .I newfd_flags
786 This field is a bit mask specifying flags that should be set on
787 the file descriptor that is received in the target process.
788 Currently, only the following flag is implemented:
791 .B O_CLOEXEC
792 Set the close-on-exec flag on the received file descriptor.
795 On success, this
796 .BR ioctl (2)
797 call returns the number of the file descriptor that was allocated
798 in the target.
799 Assuming that the emulated system call is one that returns
800 a file descriptor as its function result (e.g.,
801 .BR socket (2)),
802 this value can be used as the return value
803 .RI ( resp.val )
804 that is supplied in the response that is subsequently sent with the
805 .BR SECCOMP_IOCTL_NOTIF_SEND
806 operation.
808 On error, \-1 is returned and
809 .I errno
810 is set to indicate the cause of the error.
812 This operation can fail with the following errors:
814 .B EBADF
815 Allocating the file descriptor in the target would cause the target's
816 .BR RLIMIT_NOFILE
817 limit to be exceeded (see
818 .BR getrlimit (2)).
820 .B EBUSY
821 If the flag
822 .B SECCOMP_IOCTL_NOTIF_SEND
823 is used, this means the operation can't proceed until other
824 .B SECCOMP_IOCTL_NOTIF_ADDFD
825 requests are processed.
827 .B EINPROGRESS
828 The user-space notification specified in the
829 .I id
830 field exists but has not yet been fetched (by a
831 .BR SECCOMP_IOCTL_NOTIF_RECV )
832 or has already been responded to (by a
833 .BR SECCOMP_IOCTL_NOTIF_SEND ).
835 .B EINVAL
836 An invalid flag was specified in the
837 .I flags
839 .I newfd_flags
840 field, or the
841 .I newfd
842 field is nonzero and the
843 .B SECCOMP_ADDFD_FLAG_SETFD
844 flag was not specified in the
845 .I flags
846 field.
848 .B EMFILE
849 The file descriptor number specified in
850 .I newfd
851 exceeds the limit specified in
852 .IR /proc/sys/fs/nr_open .
854 .B ENOENT
855 The blocked system call in the target
856 has been interrupted by a signal handler
857 or the target has terminated.
859 Here is some sample code (with error handling omitted) that uses the
860 .B SECCOMP_ADDFD_FLAG_SETFD
861 operation (here, to emulate a call to
862 .BR openat (2)):
865 .in +4n
866 int fd, removeFd;
868 fd = openat(req->data.args[0], path, req->data.args[2],
869                 req->data.args[3]);
871 struct seccomp_notif_addfd addfd;
872 addfd.id = req->id; /* Cookie from SECCOMP_IOCTL_NOTIF_RECV */
873 addfd.srcfd = fd;
874 addfd.newfd = 0;
875 addfd.flags = 0;
876 addfd.newfd_flags = O_CLOEXEC;
878 targetFd = ioctl(notifyFd, SECCOMP_IOCTL_NOTIF_ADDFD, &addfd);
880 close(fd);          /* No longer needed in supervisor */
882 struct seccomp_notif_resp *resp;
883     /* Code to allocate 'resp' omitted */
884 resp->id = req->id;
885 resp->error = 0;        /* "Success" */
886 resp->val = targetFd;
887 resp->flags = 0;
888 ioctl(notifyFd, SECCOMP_IOCTL_NOTIF_SEND, resp);
891 .SH NOTES
892 One example use case for the user-space notification
893 mechanism is to allow a container manager
894 (a process which is typically running with more privilege than
895 the processes inside the container)
896 to mount block devices or create device nodes for the container.
897 The mount use case provides an example of where the
898 .BR SECCOMP_USER_NOTIF_FLAG_CONTINUE
899 .BR ioctl (2)
900 operation is useful.
901 Upon receiving a notification for the
902 .BR mount (2)
903 system call, the container manager (the "supervisor") can distinguish
904 a request to mount a block filesystem
905 (which would not be possible for a "target" process inside the container)
906 and mount that file system.
907 If, on the other hand, the container manager detects that the operation
908 could be performed by the process inside the container
909 (e.g., a mount of a
910 .BR tmpfs (5)
911 filesystem), it can notify the kernel that the target process's
912 .BR mount (2)
913 system call can continue.
915 .SS select()/poll()/epoll semantics
916 The file descriptor returned when
917 .BR seccomp (2)
918 is employed with the
919 .B SECCOMP_FILTER_FLAG_NEW_LISTENER
920 flag can be monitored using
921 .BR poll (2),
922 .BR epoll (7),
924 .BR select (2).
925 These interfaces indicate that the file descriptor is ready as follows:
926 .IP \(bu 2
927 When a notification is pending,
928 these interfaces indicate that the file descriptor is readable.
929 Following such an indication, a subsequent
930 .B SECCOMP_IOCTL_NOTIF_RECV
931 .BR ioctl (2)
932 will not block, returning either information about a notification
933 or else failing with the error
934 .B EINTR
935 if the target has been killed by a signal or its system call
936 has been interrupted by a signal handler.
937 .IP \(bu
938 After the notification has been received (i.e., by the
939 .B SECCOMP_IOCTL_NOTIF_RECV
940 .BR ioctl (2)
941 operation), these interfaces indicate that the file descriptor is writable,
942 meaning that a notification response can be sent using the
943 .B SECCOMP_IOCTL_NOTIF_SEND
944 .BR ioctl (2)
945 operation.
946 .IP \(bu
947 After the last thread using the filter has terminated and been reaped using
948 .BR waitpid (2)
949 (or similar),
950 the file descriptor indicates an end-of-file condition (readable in
951 .BR select (2);
952 .BR POLLHUP / EPOLLHUP
954 .BR poll (2)/
955 .BR epoll_wait (2)).
956 .SS Design goals; use of SECCOMP_USER_NOTIF_FLAG_CONTINUE
957 The intent of the user-space notification feature is
958 to allow system calls to be performed on behalf of the target.
959 The target's system call should either be handled by the supervisor or
960 allowed to continue normally in the kernel (where standard security
961 policies will be applied).
963 .BR "Note well" :
964 this mechanism must not be used to make security policy decisions
965 about the system call,
966 which would be inherently race-prone for reasons described next.
969 .B SECCOMP_USER_NOTIF_FLAG_CONTINUE
970 flag must be used with caution.
971 If set by the supervisor, the target's system call will continue.
972 However, there is a time-of-check, time-of-use race here,
973 since an attacker could exploit the interval of time where the target is
974 blocked waiting on the "continue" response to do things such as
975 rewriting the system call arguments.
977 Note furthermore that a user-space notifier can be bypassed if
978 the existing filters allow the use of
979 .BR seccomp (2)
981 .BR prctl (2)
982 to install a filter that returns an action value with a higher precedence than
983 .B SECCOMP_RET_USER_NOTIF
984 (see
985 .BR seccomp (2)).
987 It should thus be absolutely clear that the
988 seccomp user-space notification mechanism
989 .B can not
990 be used to implement a security policy!
991 It should only ever be used in scenarios where a more privileged process
992 supervises the system calls of a lesser privileged target to
993 get around kernel-enforced security restrictions when
994 the supervisor deems this safe.
995 In other words,
996 in order to continue a system call, the supervisor should be sure that
997 another security mechanism or the kernel itself will sufficiently block
998 the system call if its arguments are rewritten to something unsafe.
1000 .SS Caveats regarding the use of /proc/[tid]/mem
1001 The discussion above noted the need to use the
1002 .BR SECCOMP_IOCTL_NOTIF_ID_VALID
1003 .BR ioctl (2)
1004 when opening the
1005 .IR /proc/[tid]/mem
1006 file of the target
1007 to avoid the possibility of accessing the memory of the wrong process
1008 in the event that the target terminates and its ID
1009 is recycled by another (unrelated) thread.
1010 However, the use of this
1011 .BR ioctl (2)
1012 operation is also necessary in other situations,
1013 as explained in the following paragraphs.
1015 Consider the following scenario, where the supervisor
1016 tries to read the pathname argument of a target's blocked
1017 .BR mount (2)
1018 system call:
1019 .IP \(bu 2
1020 From one of its functions
1021 .RI ( func() ),
1022 the target calls
1023 .BR mount (2),
1024 which triggers a user-space notification and causes the target to block.
1025 .IP \(bu
1026 The supervisor receives the notification, opens
1027 .IR /proc/[tid]/mem ,
1028 and (successfully) performs the
1029 .BR SECCOMP_IOCTL_NOTIF_ID_VALID
1030 check.
1031 .IP \(bu
1032 The target receives a signal, which causes the
1033 .BR mount (2)
1034 to abort.
1035 .IP \(bu
1036 The signal handler executes in the target, and returns.
1037 .IP \(bu
1038 Upon return from the handler, the execution of
1039 .I func()
1040 resumes, and it returns (and perhaps other functions are called,
1041 overwriting the memory that had been used for the stack frame of
1042 .IR func() ).
1043 .IP \(bu
1044 Using the address provided in the notification information,
1045 the supervisor reads from the target's memory location that used to
1046 contain the pathname.
1047 .IP \(bu
1048 The supervisor now calls
1049 .BR mount (2)
1050 with some arbitrary bytes obtained in the previous step.
1052 The conclusion from the above scenario is this:
1053 since the target's blocked system call may be interrupted by a signal handler,
1054 the supervisor must be written to expect that the
1055 target may abandon its system call at
1056 .B any
1057 time;
1058 in such an event, any information that the supervisor obtained from
1059 the target's memory must be considered invalid.
1061 To prevent such scenarios,
1062 every read from the target's memory must be separated from use of
1063 the bytes so obtained by a
1064 .BR SECCOMP_IOCTL_NOTIF_ID_VALID
1065 check.
1066 In the above example, the check would be placed between the two final steps.
1067 An example of such a check is shown in EXAMPLES.
1069 Following on from the above, it should be clear that
1070 a write by the supervisor into the target's memory can
1071 .B never
1072 be considered safe.
1074 .SS Caveats regarding blocking system calls
1075 Suppose that the target performs a blocking system call (e.g.,
1076 .BR accept (2))
1077 that the supervisor should handle.
1078 The supervisor might then in turn execute the same blocking system call.
1080 In this scenario,
1081 it is important to note that if the target's system call is now
1082 interrupted by a signal, the supervisor is
1083 .I not
1084 informed of this.
1085 If the supervisor does not take suitable steps to
1086 actively discover that the target's system call has been canceled,
1087 various difficulties can occur.
1088 Taking the example of
1089 .BR accept (2),
1090 the supervisor might remain blocked in its
1091 .BR accept (2)
1092 holding a port number that the target
1093 (which, after the interruption by the signal handler,
1094 perhaps closed  its listening socket) might expect to be able to reuse in a
1095 .BR bind (2)
1096 call.
1098 Therefore, when the supervisor wishes to emulate a blocking system call,
1099 it must do so in such a way that it gets informed if the target's
1100 system call is interrupted by a signal handler.
1101 For example, if the supervisor itself executes the same
1102 blocking system call, then it could employ a separate thread
1103 that uses the
1104 .B SECCOMP_IOCTL_NOTIF_ID_VALID
1105 operation to check if the target is still blocked in its system call.
1106 Alternatively, in the
1107 .BR accept (2)
1108 example, the supervisor might use
1109 .BR poll (2)
1110 to monitor both the notification file descriptor
1111 (so as to discover when the target's
1112 .BR accept (2)
1113 call has been interrupted) and the listening file descriptor
1114 (so as to know when a connection is available).
1116 If the target's system call is interrupted,
1117 the supervisor must take care to release resources (e.g., file descriptors)
1118 that it acquired on behalf of the target.
1120 .SS Interaction with SA_RESTART signal handlers
1121 Consider the following scenario:
1122 .IP \(bu 2
1123 The target process has used
1124 .BR sigaction (2)
1125 to install a signal handler with the
1126 .B SA_RESTART
1127 flag.
1128 .IP \(bu
1129 The target has made a system call that triggered a seccomp
1130 user-space notification and the target is currently blocked
1131 until the supervisor sends a notification response.
1132 .IP \(bu
1133 A signal is delivered to the target and the signal handler is executed.
1134 .IP \(bu
1135 When (if) the supervisor attempts to send a notification response, the
1136 .B SECCOMP_IOCTL_NOTIF_SEND
1137 .BR ioctl (2))
1138 operation will fail with the
1139 .BR ENOENT
1140 error.
1142 In this scenario, the kernel will restart the target's system call.
1143 Consequently, the supervisor will receive another user-space notification.
1144 Thus, depending on how many times the blocked system call
1145 is interrupted by a signal handler,
1146 the supervisor may receive multiple notifications for
1147 the same instance of a system call in the target.
1149 One oddity is that system call restarting as described in this scenario
1150 will occur even for the blocking system calls listed in
1151 .BR signal (7)
1152 that would
1153 .B never
1154 normally be restarted by the
1155 .BR SA_RESTART
1156 flag.
1157 .\" FIXME
1158 .\" About the above, Kees Cook commented:
1160 .\" Does this need fixing? I imagine the correct behavior for this case
1161 .\" would be a response to _SEND of EINPROGRESS and the target would see
1162 .\" EINTR normally?
1164 .\" I mean, it's not like seccomp doesn't already expose weirdness with
1165 .\" syscall restarts. Not even arm64 compat agrees[3] with arm32 in this
1166 .\" regard. :(
1168 .\" FIXME
1169 .\" Michael Kerrisk:
1170 .\" I wonder about the effect of this oddity for system calls that
1171 .\" are normally nonrestartable because they have timeouts. My
1172 .\" understanding is that the kernel doesn't restart those system
1173 .\" calls because it's impossible for the kernel to restart the call
1174 .\" with the right timeout value. I wonder what happens when those
1175 .\" system calls are restarted in the scenario we're discussing.)
1177 Furthermore, if the supervisor response is a file descriptor
1178 added with
1179 .BR SECCOMP_IOCTL_NOTIF_ADDFD ,
1180 then the flag
1181 .B SECCOMP_ADDFD_FLAG_SEND
1182 can be used to atomically add the file descriptor and return that value,
1183 making sure no file descriptors are inadvertently leaked into the target.
1184 .SH BUGS
1185 If a
1186 .BR SECCOMP_IOCTL_NOTIF_RECV
1187 .BR ioctl (2)
1188 operation
1189 .\" or a poll/epoll/select
1190 is performed after the target terminates, then the
1191 .BR ioctl (2)
1192 call simply blocks (rather than returning an error to indicate that the
1193 target no longer exists).
1194 .\" FIXME
1195 .\" Comment from Kees Cook:
1197 .\" I want this fixed. It caused me no end of pain when building the
1198 .\" selftests, and ended up spawning my implementing a global test timeout
1199 .\" in kselftest. :P Before the usage counter refactor, there was no sane
1200 .\" way to deal with this, but now I think we're close.
1202 .SH EXAMPLES
1203 The (somewhat contrived) program shown below demonstrates the use of
1204 the interfaces described in this page.
1205 The program creates a child process that serves as the "target" process.
1206 The child process installs a seccomp filter that returns the
1207 .B SECCOMP_RET_USER_NOTIF
1208 action value if a call is made to
1209 .BR mkdir (2).
1210 The child process then calls
1211 .BR mkdir (2)
1212 once for each of the supplied command-line arguments,
1213 and reports the result returned by the call.
1214 After processing all arguments, the child process terminates.
1216 The parent process acts as the supervisor, listening for the notifications
1217 that are generated when the target process calls
1218 .BR mkdir (2).
1219 When such a notification occurs,
1220 the supervisor examines the memory of the target process (using
1221 .IR /proc/[pid]/mem )
1222 to discover the pathname argument that was supplied to the
1223 .BR mkdir (2)
1224 call, and performs one of the following actions:
1225 .IP \(bu 2
1226 If the pathname begins with the prefix "/tmp/",
1227 then the supervisor attempts to create the specified directory,
1228 and then spoofs a return for the target process based on the return
1229 value of the supervisor's
1230 .BR mkdir (2)
1231 call.
1232 In the event that that call succeeds,
1233 the spoofed success return value is the length of the pathname.
1234 .IP \(bu
1235 If the pathname begins with "./" (i.e., it is a relative pathname),
1236 the supervisor sends a
1237 .B SECCOMP_USER_NOTIF_FLAG_CONTINUE
1238 response to the kernel to say that the kernel should execute
1239 the target process's
1240 .BR mkdir (2)
1241 call.
1242 .IP \(bu
1243 If the pathname begins with some other prefix,
1244 the supervisor spoofs an error return for the target process,
1245 so that the target process's
1246 .BR mkdir (2)
1247 call appears to fail with the error
1248 .BR EOPNOTSUPP
1249 ("Operation not supported").
1250 Additionally, if the specified pathname is exactly "/bye",
1251 then the supervisor terminates.
1253 This program can be used to demonstrate various aspects of the
1254 behavior of the seccomp user-space notification mechanism.
1255 To help aid such demonstrations,
1256 the program logs various messages to show the operation
1257 of the target process (lines prefixed "T:") and the supervisor
1258 (indented lines prefixed "S:").
1260 In the following example, the target attempts to create the directory
1261 .IR /tmp/x .
1262 Upon receiving the notification, the supervisor creates the directory on the
1263 target's behalf,
1264 and spoofs a success return to be received by the target process's
1265 .BR mkdir (2)
1266 call.
1268 .in +4n
1270 $ \fB./seccomp_unotify /tmp/x\fP
1271 T: PID = 23168
1273 T: about to mkdir("/tmp/x")
1274         S: got notification (ID 0x17445c4a0f4e0e3c) for PID 23168
1275         S: executing: mkdir("/tmp/x", 0700)
1276         S: success! spoofed return = 6
1277         S: sending response (flags = 0; val = 6; error = 0)
1278 T: SUCCESS: mkdir(2) returned 6
1280 T: terminating
1281         S: target has terminated; bye
1285 In the above output, note that the spoofed return value seen by the target
1286 process is 6 (the length of the pathname
1287 .IR /tmp/x ),
1288 whereas a normal
1289 .BR mkdir (2)
1290 call returns 0 on success.
1292 In the next example, the target attempts to create a directory using the
1293 relative pathname
1294 .IR ./sub .
1295 Since this pathname starts with "./",
1296 the supervisor sends a
1297 .B SECCOMP_USER_NOTIF_FLAG_CONTINUE
1298 response to the kernel,
1299 and the kernel then (successfully) executes the target process's
1300 .BR mkdir (2)
1301 call.
1303 .in +4n
1305 $ \fB./seccomp_unotify ./sub\fP
1306 T: PID = 23204
1308 T: about to mkdir("./sub")
1309         S: got notification (ID 0xddb16abe25b4c12) for PID 23204
1310         S: target can execute system call
1311         S: sending response (flags = 0x1; val = 0; error = 0)
1312 T: SUCCESS: mkdir(2) returned 0
1314 T: terminating
1315         S: target has terminated; bye
1319 If the target process attempts to create a directory with
1320 a pathname that doesn't start with "." and doesn't begin with the prefix
1321 "/tmp/", then the supervisor spoofs an error return
1322 .RB ( EOPNOTSUPP ,
1323 "Operation not  supported")
1324 for the target's
1325 .BR mkdir (2)
1326 call (which is not executed):
1328 .in +4n
1330 $ \fB./seccomp_unotify /xxx\fP
1331 T: PID = 23178
1333 T: about to mkdir("/xxx")
1334         S: got notification (ID 0xe7dc095d1c524e80) for PID 23178
1335         S: spoofing error response (Operation not supported)
1336         S: sending response (flags = 0; val = 0; error = \-95)
1337 T: ERROR: mkdir(2): Operation not supported
1339 T: terminating
1340         S: target has terminated; bye
1344 In the next example,
1345 the target process attempts to create a directory with the pathname
1346 .BR /tmp/nosuchdir/b .
1347 Upon receiving the notification,
1348 the supervisor attempts to create that directory, but the
1349 .BR mkdir (2)
1350 call fails because the directory
1351 .BR /tmp/nosuchdir
1352 does not exist.
1353 Consequently, the supervisor spoofs an error return that passes the error
1354 that it received back to the target process's
1355 .BR mkdir (2)
1356 call.
1358 .in +4n
1360 $ \fB./seccomp_unotify /tmp/nosuchdir/b\fP
1361 T: PID = 23199
1363 T: about to mkdir("/tmp/nosuchdir/b")
1364         S: got notification (ID 0x8744454293506046) for PID 23199
1365         S: executing: mkdir("/tmp/nosuchdir/b", 0700)
1366         S: failure! (errno = 2; No such file or directory)
1367         S: sending response (flags = 0; val = 0; error = \-2)
1368 T: ERROR: mkdir(2): No such file or directory
1370 T: terminating
1371         S: target has terminated; bye
1375 If the supervisor receives a notification and sees that the
1376 argument of the target's
1377 .BR mkdir (2)
1378 is the string "/bye", then (as well as spoofing an
1379 .B EOPNOTSUPP
1380 error), the supervisor terminates.
1381 If the target process subsequently executes another
1382 .BR mkdir (2)
1383 that triggers its seccomp filter to return the
1384 .B SECCOMP_RET_USER_NOTIF
1385 action value, then the kernel causes the target process's system call to
1386 fail with the error
1387 .B ENOSYS
1388 ("Function not implemented").
1389 This is demonstrated by the following example:
1391 .in +4n
1393 $ \fB./seccomp_unotify /bye /tmp/y\fP
1394 T: PID = 23185
1396 T: about to mkdir("/bye")
1397         S: got notification (ID 0xa81236b1d2f7b0f4) for PID 23185
1398         S: spoofing error response (Operation not supported)
1399         S: sending response (flags = 0; val = 0; error = \-95)
1400         S: terminating **********
1401 T: ERROR: mkdir(2): Operation not supported
1403 T: about to mkdir("/tmp/y")
1404 T: ERROR: mkdir(2): Function not implemented
1406 T: terminating
1410 .SS Program source
1412 #define _GNU_SOURCE
1413 #include <errno.h>
1414 #include <fcntl.h>
1415 #include <limits.h>
1416 #include <linux/audit.h>
1417 #include <linux/filter.h>
1418 #include <linux/seccomp.h>
1419 #include <signal.h>
1420 #include <stdbool.h>
1421 #include <stddef.h>
1422 #include <stdint.h>
1423 #include <stdio.h>
1424 #include <stdlib.h>
1425 #include <sys/socket.h>
1426 #include <sys/ioctl.h>
1427 #include <sys/prctl.h>
1428 #include <sys/stat.h>
1429 #include <sys/types.h>
1430 #include <sys/un.h>
1431 #include <sys/syscall.h>
1432 #include <unistd.h>
1434 #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \e
1435                         } while (0)
1437 /* Send the file descriptor \(aqfd\(aq over the connected UNIX domain socket
1438    \(aqsockfd\(aq. Returns 0 on success, or \-1 on error. */
1440 static int
1441 sendfd(int sockfd, int fd)
1443     struct msghdr msgh;
1444     struct iovec iov;
1445     int data;
1446     struct cmsghdr *cmsgp;
1448     /* Allocate a char array of suitable size to hold the ancillary data.
1449        However, since this buffer is in reality a \(aqstruct cmsghdr\(aq, use a
1450        union to ensure that it is suitably aligned. */
1451     union {
1452         char   buf[CMSG_SPACE(sizeof(int))];
1453                         /* Space large enough to hold an \(aqint\(aq */
1454         struct cmsghdr align;
1455     } controlMsg;
1457     /* The \(aqmsg_name\(aq field can be used to specify the address of the
1458        destination socket when sending a datagram. However, we do not
1459        need to use this field because \(aqsockfd\(aq is a connected socket. */
1461     msgh.msg_name = NULL;
1462     msgh.msg_namelen = 0;
1464     /* On Linux, we must transmit at least one byte of real data in
1465        order to send ancillary data. We transmit an arbitrary integer
1466        whose value is ignored by recvfd(). */
1468     msgh.msg_iov = &iov;
1469     msgh.msg_iovlen = 1;
1470     iov.iov_base = &data;
1471     iov.iov_len = sizeof(int);
1472     data = 12345;
1474     /* Set \(aqmsghdr\(aq fields that describe ancillary data */
1476     msgh.msg_control = controlMsg.buf;
1477     msgh.msg_controllen = sizeof(controlMsg.buf);
1479     /* Set up ancillary data describing file descriptor to send */
1481     cmsgp = CMSG_FIRSTHDR(&msgh);
1482     cmsgp\->cmsg_level = SOL_SOCKET;
1483     cmsgp\->cmsg_type = SCM_RIGHTS;
1484     cmsgp\->cmsg_len = CMSG_LEN(sizeof(int));
1485     memcpy(CMSG_DATA(cmsgp), &fd, sizeof(int));
1487     /* Send real plus ancillary data */
1489     if (sendmsg(sockfd, &msgh, 0) == \-1)
1490         return \-1;
1492     return 0;
1495 /* Receive a file descriptor on a connected UNIX domain socket. Returns
1496    the received file descriptor on success, or \-1 on error. */
1498 static int
1499 recvfd(int sockfd)
1501     struct msghdr msgh;
1502     struct iovec iov;
1503     int data, fd;
1504     ssize_t nr;
1506     /* Allocate a char buffer for the ancillary data. See the comments
1507        in sendfd() */
1508     union {
1509         char   buf[CMSG_SPACE(sizeof(int))];
1510         struct cmsghdr align;
1511     } controlMsg;
1512     struct cmsghdr *cmsgp;
1514     /* The \(aqmsg_name\(aq field can be used to obtain the address of the
1515        sending socket. However, we do not need this information. */
1517     msgh.msg_name = NULL;
1518     msgh.msg_namelen = 0;
1520     /* Specify buffer for receiving real data */
1522     msgh.msg_iov = &iov;
1523     msgh.msg_iovlen = 1;
1524     iov.iov_base = &data;       /* Real data is an \(aqint\(aq */
1525     iov.iov_len = sizeof(int);
1527     /* Set \(aqmsghdr\(aq fields that describe ancillary data */
1529     msgh.msg_control = controlMsg.buf;
1530     msgh.msg_controllen = sizeof(controlMsg.buf);
1532     /* Receive real plus ancillary data; real data is ignored */
1534     nr = recvmsg(sockfd, &msgh, 0);
1535     if (nr == \-1)
1536         return \-1;
1538     cmsgp = CMSG_FIRSTHDR(&msgh);
1540     /* Check the validity of the \(aqcmsghdr\(aq */
1542     if (cmsgp == NULL ||
1543             cmsgp\->cmsg_len != CMSG_LEN(sizeof(int)) ||
1544             cmsgp\->cmsg_level != SOL_SOCKET ||
1545             cmsgp\->cmsg_type != SCM_RIGHTS) {
1546         errno = EINVAL;
1547         return \-1;
1548     }
1550     /* Return the received file descriptor to our caller */
1552     memcpy(&fd, CMSG_DATA(cmsgp), sizeof(int));
1553     return fd;
1556 static void
1557 sigchldHandler(int sig)
1559     char msg[] = "\etS: target has terminated; bye\en";
1561     write(STDOUT_FILENO, msg, sizeof(msg) - 1);
1562     _exit(EXIT_SUCCESS);
1565 static int
1566 seccomp(unsigned int operation, unsigned int flags, void *args)
1568     return syscall(__NR_seccomp, operation, flags, args);
1571 /* The following is the x86\-64\-specific BPF boilerplate code for checking
1572    that the BPF program is running on the right architecture + ABI. At
1573    completion of these instructions, the accumulator contains the system
1574    call number. */
1576 /* For the x32 ABI, all system call numbers have bit 30 set */
1578 #define X32_SYSCALL_BIT         0x40000000
1580 #define X86_64_CHECK_ARCH_AND_LOAD_SYSCALL_NR \e
1581         BPF_STMT(BPF_LD | BPF_W | BPF_ABS, \e
1582                 (offsetof(struct seccomp_data, arch))), \e
1583         BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, AUDIT_ARCH_X86_64, 0, 2), \e
1584         BPF_STMT(BPF_LD | BPF_W | BPF_ABS, \e
1585                  (offsetof(struct seccomp_data, nr))), \e
1586         BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, X32_SYSCALL_BIT, 0, 1), \e
1587         BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL_PROCESS)
1589 /* installNotifyFilter() installs a seccomp filter that generates
1590    user\-space notifications (SECCOMP_RET_USER_NOTIF) when the process
1591    calls mkdir(2); the filter allows all other system calls.
1593    The function return value is a file descriptor from which the
1594    user\-space notifications can be fetched. */
1596 static int
1597 installNotifyFilter(void)
1599     struct sock_filter filter[] = {
1600         X86_64_CHECK_ARCH_AND_LOAD_SYSCALL_NR,
1602         /* mkdir() triggers notification to user\-space supervisor */
1604         BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_mkdir, 0, 1),
1605         BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_USER_NOTIF),
1607         /* Every other system call is allowed */
1609         BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
1610     };
1612     struct sock_fprog prog = {
1613         .len = sizeof(filter) / sizeof(filter[0]),
1614         .filter = filter,
1615     };
1617     /* Install the filter with the SECCOMP_FILTER_FLAG_NEW_LISTENER flag;
1618        as a result, seccomp() returns a notification file descriptor. */
1620     int notifyFd = seccomp(SECCOMP_SET_MODE_FILTER,
1621                            SECCOMP_FILTER_FLAG_NEW_LISTENER, &prog);
1622     if (notifyFd == \-1)
1623         errExit("seccomp\-install\-notify\-filter");
1625     return notifyFd;
1628 /* Close a pair of sockets created by socketpair() */
1630 static void
1631 closeSocketPair(int sockPair[2])
1633     if (close(sockPair[0]) == \-1)
1634         errExit("closeSocketPair\-close\-0");
1635     if (close(sockPair[1]) == \-1)
1636         errExit("closeSocketPair\-close\-1");
1639 /* Implementation of the target process; create a child process that:
1641    (1) installs a seccomp filter with the
1642        SECCOMP_FILTER_FLAG_NEW_LISTENER flag;
1643    (2) writes the seccomp notification file descriptor returned from
1644        the previous step onto the UNIX domain socket, \(aqsockPair[0]\(aq;
1645    (3) calls mkdir(2) for each element of \(aqargv\(aq.
1647    The function return value in the parent is the PID of the child
1648    process; the child does not return from this function. */
1650 static pid_t
1651 targetProcess(int sockPair[2], char *argv[])
1653     pid_t targetPid = fork();
1654     if (targetPid == \-1)
1655         errExit("fork");
1657     if (targetPid > 0)          /* In parent, return PID of child */
1658         return targetPid;
1660     /* Child falls through to here */
1662     printf("T: PID = %ld\en", (long) getpid());
1664     /* Install seccomp filter(s) */
1666     if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0))
1667         errExit("prctl");
1669     int notifyFd = installNotifyFilter();
1671     /* Pass the notification file descriptor to the tracing process over
1672        a UNIX domain socket */
1674     if (sendfd(sockPair[0], notifyFd) == \-1)
1675         errExit("sendfd");
1677     /* Notification and socket FDs are no longer needed in target */
1679     if (close(notifyFd) == \-1)
1680         errExit("close\-target\-notify\-fd");
1682     closeSocketPair(sockPair);
1684     /* Perform a mkdir() call for each of the command\-line arguments */
1686     for (char **ap = argv; *ap != NULL; ap++) {
1687         printf("\enT: about to mkdir(\e"%s\e")\en", *ap);
1689         int s = mkdir(*ap, 0700);
1690         if (s == \-1)
1691             perror("T: ERROR: mkdir(2)");
1692         else
1693             printf("T: SUCCESS: mkdir(2) returned %d\en", s);
1694     }
1696     printf("\enT: terminating\en");
1697     exit(EXIT_SUCCESS);
1700 /* Check that the notification ID provided by a SECCOMP_IOCTL_NOTIF_RECV
1701    operation is still valid. It will no longer be valid if the target
1702    process has terminated or is no longer blocked in the system call that
1703    generated the notification (because it was interrupted by a signal).
1705    This operation can be used when doing such things as accessing
1706    /proc/PID files in the target process in order to avoid TOCTOU race
1707    conditions where the PID that is returned by SECCOMP_IOCTL_NOTIF_RECV
1708    terminates and is reused by another process. */
1710 static bool
1711 cookieIsValid(int notifyFd, uint64_t id)
1713     return ioctl(notifyFd, SECCOMP_IOCTL_NOTIF_ID_VALID, &id) == 0;
1716 /* Access the memory of the target process in order to fetch the
1717    pathname referred to by the system call argument \(aqargNum\(aq in
1718    \(aqreq\->data.args[]\(aq.  The pathname is returned in \(aqpath\(aq,
1719    a buffer of \(aqlen\(aq bytes allocated by the caller.
1721    Returns true if the pathname is successfully fetched, and false
1722    otherwise. For possible causes of failure, see the comments below. */
1724 static bool
1725 getTargetPathname(struct seccomp_notif *req, int notifyFd,
1726                   int argNum, char *path, size_t len)
1728     char procMemPath[PATH_MAX];
1730     snprintf(procMemPath, sizeof(procMemPath), "/proc/%d/mem", req\->pid);
1732     int procMemFd = open(procMemPath, O_RDONLY | O_CLOEXEC);
1733     if (procMemFd == \-1)
1734         return false;
1736     /* Check that the process whose info we are accessing is still alive
1737        and blocked in the system call that caused the notification.
1738        If the SECCOMP_IOCTL_NOTIF_ID_VALID operation (performed in
1739        cookieIsValid()) succeeded, we know that the /proc/PID/mem file
1740        descriptor that we opened corresponded to the process for which we
1741        received a notification. If that process subsequently terminates,
1742        then read() on that file descriptor will return 0 (EOF). */
1744     if (!cookieIsValid(notifyFd, req\->id)) {
1745         close(procMemFd);
1746         return false;
1747     }
1749     /* Read bytes at the location containing the pathname argument */
1751     ssize_t nread = pread(procMemFd, path, len, req\->data.args[argNum]);
1753     close(procMemFd);
1755     if (nread <= 0)
1756         return false;
1758     /* Once again check that the notification ID is still valid. The
1759        case we are particularly concerned about here is that just
1760        before we fetched the pathname, the target\(aqs blocked system
1761        call was interrupted by a signal handler, and after the handler
1762        returned, the target carried on execution (past the interrupted
1763        system call). In that case, we have no guarantees about what we
1764        are reading, since the target\(aqs memory may have been arbitrarily
1765        changed by subsequent operations. */
1767     if (!cookieIsValid(notifyFd, req\->id)) {
1768         perror("\etS: notification ID check failed!!!");
1769         return false;
1770     }
1772     /* Even if the target\(aqs system call was not interrupted by a signal,
1773        we have no guarantees about what was in the memory of the target
1774        process. (The memory may have been modified by another thread, or
1775        even by an external attacking process.) We therefore treat the
1776        buffer returned by pread() as untrusted input. The buffer should
1777        contain a terminating null byte; if not, then we will trigger an
1778        error for the target process. */
1780     if (strnlen(path, nread) < nread)
1781         return true;
1783     return false;
1786 /* Allocate buffers for the seccomp user\-space notification request and
1787    response structures. It is the caller\(aqs responsibility to free the
1788    buffers returned via \(aqreq\(aq and \(aqresp\(aq. */
1790 static void
1791 allocSeccompNotifBuffers(struct seccomp_notif **req,
1792         struct seccomp_notif_resp **resp,
1793         struct seccomp_notif_sizes *sizes)
1795     /* Discover the sizes of the structures that are used to receive
1796        notifications and send notification responses, and allocate
1797        buffers of those sizes. */
1799     if (seccomp(SECCOMP_GET_NOTIF_SIZES, 0, sizes) == \-1)
1800         errExit("seccomp\-SECCOMP_GET_NOTIF_SIZES");
1802     *req = malloc(sizes\->seccomp_notif);
1803     if (*req == NULL)
1804         errExit("malloc\-seccomp_notif");
1806     /* When allocating the response buffer, we must allow for the fact
1807        that the user\-space binary may have been built with user\-space
1808        headers where \(aqstruct seccomp_notif_resp\(aq is bigger than the
1809        response buffer expected by the (older) kernel. Therefore, we
1810        allocate a buffer that is the maximum of the two sizes. This
1811        ensures that if the supervisor places bytes into the response
1812        structure that are past the response size that the kernel expects,
1813        then the supervisor is not touching an invalid memory location. */
1815     size_t resp_size = sizes\->seccomp_notif_resp;
1816     if (sizeof(struct seccomp_notif_resp) > resp_size)
1817         resp_size = sizeof(struct seccomp_notif_resp);
1819     *resp = malloc(resp_size);
1820     if (resp == NULL)
1821         errExit("malloc\-seccomp_notif_resp");
1825 /* Handle notifications that arrive via the SECCOMP_RET_USER_NOTIF file
1826    descriptor, \(aqnotifyFd\(aq. */
1828 static void
1829 handleNotifications(int notifyFd)
1831     struct seccomp_notif_sizes sizes;
1832     struct seccomp_notif *req;
1833     struct seccomp_notif_resp *resp;
1834     char path[PATH_MAX];
1836     allocSeccompNotifBuffers(&req, &resp, &sizes);
1838     /* Loop handling notifications */
1840     for (;;) {
1842         /* Wait for next notification, returning info in \(aq*req\(aq */
1844         memset(req, 0, sizes.seccomp_notif);
1845         if (ioctl(notifyFd, SECCOMP_IOCTL_NOTIF_RECV, req) == \-1) {
1846             if (errno == EINTR)
1847                 continue;
1848             errExit("\etS: ioctl\-SECCOMP_IOCTL_NOTIF_RECV");
1849         }
1851         printf("\etS: got notification (ID %#llx) for PID %d\en",
1852                 req\->id, req\->pid);
1854         /* The only system call that can generate a notification event
1855            is mkdir(2). Nevertheless, we check that the notified system
1856            call is indeed mkdir() as kind of future\-proofing of this
1857            code in case the seccomp filter is later modified to
1858            generate notifications for other system calls. */
1860         if (req\->data.nr != __NR_mkdir) {
1861             printf("\etS: notification contained unexpected "
1862                     "system call number; bye!!!\en");
1863             exit(EXIT_FAILURE);
1864         }
1866         bool pathOK = getTargetPathname(req, notifyFd, 0, path,
1867                                         sizeof(path));
1869         /* Prepopulate some fields of the response */
1871         resp\->id = req\->id;     /* Response includes notification ID */
1872         resp\->flags = 0;
1873         resp\->val = 0;
1875         /* If getTargetPathname() failed, trigger an EINVAL error
1876            response (sending this response may yield an error if the
1877            failure occurred because the notification ID was no longer
1878            valid); if the directory is in /tmp, then create it on behalf
1879            of the supervisor; if the pathname starts with \(aq.\(aq, tell the
1880            kernel to let the target process execute the mkdir();
1881            otherwise, give an error for a directory pathname in any other
1882            location. */
1884         if (!pathOK) {
1885             resp->error = -EINVAL;
1886             printf("\etS: spoofing error for invalid pathname (%s)\en",
1887                     strerror(-resp->error));
1888         } else if (strncmp(path, "/tmp/", strlen("/tmp/")) == 0) {
1889             printf("\etS: executing: mkdir(\e"%s\e", %#llo)\en",
1890                     path, req\->data.args[1]);
1892             if (mkdir(path, req\->data.args[1]) == 0) {
1893                 resp\->error = 0;            /* "Success" */
1894                 resp\->val = strlen(path);   /* Used as return value of
1895                                                mkdir() in target */
1896                 printf("\etS: success! spoofed return = %lld\en",
1897                         resp\->val);
1898             } else {
1900                 /* If mkdir() failed in the supervisor, pass the error
1901                    back to the target */
1903                 resp\->error = \-errno;
1904                 printf("\etS: failure! (errno = %d; %s)\en", errno,
1905                         strerror(errno));
1906             }
1907         } else if (strncmp(path, "./", strlen("./")) == 0) {
1908             resp\->error = resp\->val = 0;
1909             resp\->flags = SECCOMP_USER_NOTIF_FLAG_CONTINUE;
1910             printf("\etS: target can execute system call\en");
1911         } else {
1912             resp\->error = \-EOPNOTSUPP;
1913             printf("\etS: spoofing error response (%s)\en",
1914                     strerror(\-resp\->error));
1915         }
1917         /* Send a response to the notification */
1919         printf("\etS: sending response "
1920                 "(flags = %#x; val = %lld; error = %d)\en",
1921                 resp\->flags, resp\->val, resp\->error);
1923         if (ioctl(notifyFd, SECCOMP_IOCTL_NOTIF_SEND, resp) == \-1) {
1924             if (errno == ENOENT)
1925                 printf("\etS: response failed with ENOENT; "
1926                         "perhaps target process\(aqs syscall was "
1927                         "interrupted by a signal?\en");
1928             else
1929                 perror("ioctl\-SECCOMP_IOCTL_NOTIF_SEND");
1930         }
1932         /* If the pathname is just "/bye", then the supervisor breaks out
1933            of the loop and terminates. This allows us to see what happens
1934            if the target process makes further calls to mkdir(2). */
1936         if (strcmp(path, "/bye") == 0)
1937             break;
1938     }
1940     free(req);
1941     free(resp);
1942     printf("\etS: terminating **********\en");
1943     exit(EXIT_FAILURE);
1946 /* Implementation of the supervisor process:
1948    (1) obtains the notification file descriptor from \(aqsockPair[1]\(aq
1949    (2) handles notifications that arrive on that file descriptor. */
1951 static void
1952 supervisor(int sockPair[2])
1954     int notifyFd = recvfd(sockPair[1]);
1955     if (notifyFd == \-1)
1956         errExit("recvfd");
1958     closeSocketPair(sockPair);  /* We no longer need the socket pair */
1960     handleNotifications(notifyFd);
1964 main(int argc, char *argv[])
1966     int sockPair[2];
1968     setbuf(stdout, NULL);
1970     if (argc < 2) {
1971         fprintf(stderr, "At least one pathname argument is required\en");
1972         exit(EXIT_FAILURE);
1973     }
1975     /* Create a UNIX domain socket that is used to pass the seccomp
1976        notification file descriptor from the target process to the
1977        supervisor process. */
1979     if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockPair) == \-1)
1980         errExit("socketpair");
1982     /* Create a child process\-\-the "target"\-\-that installs seccomp
1983        filtering. The target process writes the seccomp notification
1984        file descriptor onto \(aqsockPair[0]\(aq and then calls mkdir(2) for
1985        each directory in the command\-line arguments. */
1987     (void) targetProcess(sockPair, &argv[optind]);
1989     /* Catch SIGCHLD when the target terminates, so that the
1990        supervisor can also terminate. */
1992     struct sigaction sa;
1993     sa.sa_handler = sigchldHandler;
1994     sa.sa_flags = 0;
1995     sigemptyset(&sa.sa_mask);
1996     if (sigaction(SIGCHLD, &sa, NULL) == \-1)
1997         errExit("sigaction");
1999     supervisor(sockPair);
2001     exit(EXIT_SUCCESS);
2004 .SH SEE ALSO
2005 .BR ioctl (2),
2006 .BR pidfd_getfd (2),
2007 .BR pidfd_open (2),
2008 .BR seccomp (2)
2010 A further example program can be found in the kernel source file
2011 .IR samples/seccomp/user-trap.c .