summaryrefslogtreecommitdiffstats
path: root/doc/man/man3/seccomp_rule_add.3
blob: 30226996d95542386ab5bcc189c8882aa637693b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
.TH "seccomp_rule_add" 3 "30 May 2020" "paul@paul-moore.com" "libseccomp Documentation"
.\" //////////////////////////////////////////////////////////////////////////
.SH NAME
.\" //////////////////////////////////////////////////////////////////////////
seccomp_rule_add, seccomp_rule_add_exact \- Add a seccomp filter rule
.\" //////////////////////////////////////////////////////////////////////////
.SH SYNOPSIS
.\" //////////////////////////////////////////////////////////////////////////
.nf
.B #include <seccomp.h>
.sp
.B typedef void * scmp_filter_ctx;
.sp
.BI "int SCMP_SYS(" syscall_name ");"
.sp
.BI "struct scmp_arg_cmp SCMP_CMP(unsigned int " arg ","
.BI "                             enum scmp_compare " op ", " ... ");"
.BI "struct scmp_arg_cmp SCMP_A0(enum scmp_compare " op ", " ... ");"
.BI "struct scmp_arg_cmp SCMP_A1(enum scmp_compare " op ", " ... ");"
.BI "struct scmp_arg_cmp SCMP_A2(enum scmp_compare " op ", " ... ");"
.BI "struct scmp_arg_cmp SCMP_A3(enum scmp_compare " op ", " ... ");"
.BI "struct scmp_arg_cmp SCMP_A4(enum scmp_compare " op ", " ... ");"
.BI "struct scmp_arg_cmp SCMP_A5(enum scmp_compare " op ", " ... ");"
.sp
.BI "struct scmp_arg_cmp SCMP_CMP64(unsigned int " arg ","
.BI "                             enum scmp_compare " op ", " ... ");"
.BI "struct scmp_arg_cmp SCMP_A0_64(enum scmp_compare " op ", " ... ");"
.BI "struct scmp_arg_cmp SCMP_A1_64(enum scmp_compare " op ", " ... ");"
.BI "struct scmp_arg_cmp SCMP_A2_64(enum scmp_compare " op ", " ... ");"
.BI "struct scmp_arg_cmp SCMP_A3_64(enum scmp_compare " op ", " ... ");"
.BI "struct scmp_arg_cmp SCMP_A4_64(enum scmp_compare " op ", " ... ");"
.BI "struct scmp_arg_cmp SCMP_A5_64(enum scmp_compare " op ", " ... ");"
.sp
.BI "struct scmp_arg_cmp SCMP_CMP32(unsigned int " arg ","
.BI "                             enum scmp_compare " op ", " ... ");"
.BI "struct scmp_arg_cmp SCMP_A0_32(enum scmp_compare " op ", " ... ");"
.BI "struct scmp_arg_cmp SCMP_A1_32(enum scmp_compare " op ", " ... ");"
.BI "struct scmp_arg_cmp SCMP_A2_32(enum scmp_compare " op ", " ... ");"
.BI "struct scmp_arg_cmp SCMP_A3_32(enum scmp_compare " op ", " ... ");"
.BI "struct scmp_arg_cmp SCMP_A4_32(enum scmp_compare " op ", " ... ");"
.BI "struct scmp_arg_cmp SCMP_A5_32(enum scmp_compare " op ", " ... ");"
.sp
.BI "int seccomp_rule_add(scmp_filter_ctx " ctx ", uint32_t " action ","
.BI "                     int " syscall ", unsigned int " arg_cnt ", " ... ");"
.BI "int seccomp_rule_add_exact(scmp_filter_ctx " ctx ", uint32_t " action ","
.BI "                           int " syscall ", unsigned int " arg_cnt ", " ... ");"
.sp
.BI "int seccomp_rule_add_array(scmp_filter_ctx " ctx ","
.BI "                           uint32_t " action ", int " syscall ","
.BI "                           unsigned int " arg_cnt ","
.BI "                           const struct scmp_arg_cmp *"arg_array ");"
.BI "int seccomp_rule_add_exact_array(scmp_filter_ctx " ctx ","
.BI "                                 uint32_t " action ", int " syscall ","
.BI "                                 unsigned int " arg_cnt ","
.BI "                                 const struct scmp_arg_cmp *"arg_array ");"
.sp
Link with \fI\-lseccomp\fP.
.fi
.\" //////////////////////////////////////////////////////////////////////////
.SH DESCRIPTION
.\" //////////////////////////////////////////////////////////////////////////
.P
The
.BR seccomp_rule_add (),
.BR seccomp_rule_add_array (),
.BR seccomp_rule_add_exact (),
and
.BR seccomp_rule_add_exact_array ()
functions all add a new filter rule to the current seccomp filter.  The
.BR seccomp_rule_add ()
and
.BR seccomp_rule_add_array ()
functions will make a "best effort" to add the rule as specified, but may alter
the rule slightly due to architecture specifics (e.g. internal rewriting of
multiplexed syscalls, like socket and ipc functions on x86).  The
.BR seccomp_rule_add_exact ()
and
.BR seccomp_rule_add_exact_array ()
functions will attempt to add the rule exactly as specified so it may behave
differently on different architectures.  While it does not guarantee a exact
filter ruleset,
.BR seccomp_rule_add ()
and
.BR seccomp_rule_add_array ()
do guarantee the same behavior regardless of the architecture.
.P
The newly added filter rule does not take effect until the entire filter is
loaded into the kernel using
.BR seccomp_load (3).
When adding rules to a filter, it is important to consider the impact of
previously loaded filters; see the
.BR seccomp_load (3)
documentation for more information.
.P
All of the filter rules supplied by the calling application are combined into
a union, with additional logic to eliminate redundant syscall filters.  For
example, if a rule is added which allows a given syscall with a specific set of
argument values and later a rule is added which allows the same syscall
regardless the argument values then the first, more specific rule, is
effectively dropped from the filter by the second more generic rule.
.P
The
.BR SCMP_CMP (),
.BR SCMP_CMP64 (),
.BR SCMP_A{0-5} (),
and
.BR SCMP_A{0-5}_64 ()
macros generate a scmp_arg_cmp structure for use with the above functions. The
.BR SCMP_CMP ()
and
.BR SCMP_CMP64 ()
macros allows the caller to specify an arbitrary argument along with the
comparison operator, 64-bit mask, and 64-bit datum values where the
.BR SCMP_A{0-5} ()
and
.BR SCMP_A{0-5}_64 ()
macros are specific to a certain argument.
.P
The
.BR SCMP_CMP32 ()
and
.BR SCMP_A{0-5}_32 ()
macros are similar to the variants above, but they take 32-bit mask and 32-bit
datum values.
.P
It is recommended that whenever possible developers avoid using the
.BR SCMP_CMP ()
and
.BR SCMP_A{0-5} ()
macros and use the variants which are explicitly 32 or 64-bit.  This should
help eliminate problems caused by an unwanted sign extension of negative datum
values.
.P
If syscall argument comparisons are included in the filter rule, all of the
comparisons must be true for the rule to match.
.P
When adding syscall argument comparisons to the filter it is important to
remember that while it is possible to have multiple comparisons in a single
rule, you can only compare each argument once in a single rule.  In other words,
you can not have multiple comparisons of the 3rd syscall argument in a single
rule.
.P
In a filter containing multiple architectures, it is an error to add a filter
rule for a syscall that does not exist in all of the filter's architectures.
.P
While it is possible to specify the
.I syscall
value directly using the standard
.B __NR_syscall
values, in order to ensure proper operation across multiple architectures it
is highly recommended to use the
.BR SCMP_SYS ()
macro instead.  See the EXAMPLES section below.  It is also important to
remember that regardless of the architectures present in the filter, the
syscall numbers used in filter rules are interpreted in the context of the
native architecture.
.P
Starting with Linux v4.8, there may be a need to create a rule with a syscall
value of -1 to allow tracing programs to skip a syscall invocation; in order
to create a rule with a -1 syscall value it is necessary to first set the
.B SCMP_FLTATR_API_TSKIP
attribute.  See
.BR seccomp_attr_set (3)
for more information.
.P
The filter context
.I ctx
is the value returned by the call to
.BR seccomp_init (3).
.P
Valid
.I action
values are as follows:
.TP
.B SCMP_ACT_KILL
The thread will be killed by the kernel when it calls a syscall that matches
the filter rule.
.TP
.B SCMP_ACT_KILL_PROCESS
The process will be killed by the kernel when it calls a syscall that matches
the filter rule.
.TP
.B SCMP_ACT_TRAP
The thread will throw a SIGSYS signal when it calls a syscall that matches the
filter rule.
.TP
.B SCMP_ACT_ERRNO(uint16_t errno)
The thread will receive a return value of
.I errno
when it calls a syscall that matches the filter rule.
.TP
.B SCMP_ACT_TRACE(uint16_t msg_num)
If the thread is being traced and the tracing process specified the
.B PTRACE_O_TRACESECCOMP
option in the call to
.BR ptrace (2),
the tracing process will be notified, via
.B PTRACE_EVENT_SECCOMP
, and the value provided in
.I msg_num
can be retrieved using the
.B PTRACE_GETEVENTMSG
option.
.TP
.B SCMP_ACT_LOG
The seccomp filter will have no effect on the thread calling the syscall if it
matches the filter rule but the syscall will be logged.
.TP
.B SCMP_ACT_ALLOW
The seccomp filter will have no effect on the thread calling the syscall if it
matches the filter rule.
.TP
.B SCMP_ACT_NOTIFY
A monitoring process will be notified when a process running the seccomp
filter calls a syscall that matches the filter rule.  The process that invokes
the syscall waits in the kernel until the monitoring process has responded via
.B seccomp_notify_respond (3)
\&.

When a filter utilizing
.B SCMP_ACT_NOTIFY
is loaded into the kernel, the kernel generates a notification fd that must be
used to communicate between the monitoring process and the process(es) being
filtered.  See
.B seccomp_notif_fd (3)
for more information.

.P
Valid comparison
.I op
values are as follows:
.TP
.B SCMP_CMP_NE
Matches when the argument value is not equal to the datum value, example:
.sp
SCMP_CMP(
.I arg
, SCMP_CMP_NE ,
.I datum
)
.TP
.B SCMP_CMP_LT
Matches when the argument value is less than the datum value, example:
.sp
SCMP_CMP(
.I arg
, SCMP_CMP_LT ,
.I datum
)
.TP
.B SCMP_CMP_LE
Matches when the argument value is less than or equal to the datum value,
example:
.sp
SCMP_CMP(
.I arg
, SCMP_CMP_LE ,
.I datum
)
.TP
.B SCMP_CMP_EQ
Matches when the argument value is equal to the datum value, example:
.sp
SCMP_CMP(
.I arg
, SCMP_CMP_EQ ,
.I datum
)
.TP
.B SCMP_CMP_GE
Matches when the argument value is greater than or equal to the datum value,
example:
.sp
SCMP_CMP(
.I arg
, SCMP_CMP_GE ,
.I datum
)
.TP
.B SCMP_CMP_GT
Matches when the argument value is greater than the datum value, example:
.sp
SCMP_CMP(
.I arg
, SCMP_CMP_GT ,
.I datum
)
.TP
.B SCMP_CMP_MASKED_EQ
Matches when the masked argument value is equal to the masked datum value,
example:
.sp
SCMP_CMP(
.I arg
, SCMP_CMP_MASKED_EQ ,
.I mask
,
.I datum
)
.\" //////////////////////////////////////////////////////////////////////////
.SH RETURN VALUE
.\" //////////////////////////////////////////////////////////////////////////
The
.BR SCMP_SYS ()
macro returns a value suitable for use as the
.I syscall
value in the
.BR seccomp_rule_add* ()
functions.  In a similar manner, the
.BR SCMP_CMP ()
and
.BR SCMP_A* ()
macros return values suitable for use as argument comparisons in the
.BR seccomp_rule_add ()
and
.BR seccomp_rule_add_exact ()
functions.
.P
The
.BR seccomp_rule_add (),
.BR seccomp_rule_add_array (),
.BR seccomp_rule_add_exact (),
and
.BR seccomp_rule_add_exact_array ()
functions return zero on success or one of the following error codes on
failure:
.TP
.B -EDOM
Architecture specific failure.
.TP
.B -EEXIST
The rule already exists.
.TP
.B -EACCCES
The rule conflicts with the filter (for example, the rule
.I action
equals the default action of the filter).
.TP
.B -EFAULT
Internal libseccomp failure.
.TP
.B -EINVAL
Invalid input, either the context or architecture token is invalid.
.TP
.B -ENOMEM
The library was unable to allocate enough memory.
.TP
.B -EOPNOTSUPP
The library doesn't support the particular operation.
.\" //////////////////////////////////////////////////////////////////////////
.SH EXAMPLES
.\" //////////////////////////////////////////////////////////////////////////
.nf
#include <fcntl.h>
#include <seccomp.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stddef.h>

#define BUF_SIZE	256

int main(int argc, char *argv[])
{
	int rc = \-1;
	scmp_filter_ctx ctx;
	struct scmp_arg_cmp arg_cmp[] = { SCMP_A0(SCMP_CMP_EQ, 2) };
	int fd;
	unsigned char buf[BUF_SIZE];

	ctx = seccomp_init(SCMP_ACT_KILL);
	if (ctx == NULL)
		goto out;

	/* ... */

	fd = open("file.txt", 0);

	/* ... */

	rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0);
	if (rc < 0)
		goto out;

	rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0);
	if (rc < 0)
		goto out;

	rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0);
	if (rc < 0)
		goto out;

	rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 3,
			      SCMP_A0(SCMP_CMP_EQ, fd),
			      SCMP_A1(SCMP_CMP_EQ, (scmp_datum_t)buf),
			      SCMP_A2(SCMP_CMP_LE, BUF_SIZE));
	if (rc < 0)
		goto out;

	rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1,
			      SCMP_CMP(0, SCMP_CMP_EQ, fd));
	if (rc < 0)
		goto out;

	rc = seccomp_rule_add_array(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1,
			            arg_cmp);
	if (rc < 0)
		goto out;

	rc = seccomp_load(ctx);
	if (rc < 0)
		goto out;

	/* ... */

out:
	seccomp_release(ctx);
	return \-rc;
}
.fi
.\" //////////////////////////////////////////////////////////////////////////
.SH NOTES
.\" //////////////////////////////////////////////////////////////////////////
.P
While the seccomp filter can be generated independent of the kernel, kernel
support is required to load and enforce the seccomp filter generated by
libseccomp.
.P
The libseccomp project site, with more information and the source code
repository, can be found at https://github.com/seccomp/libseccomp.  This tool,
as well as the libseccomp library, is currently under development, please
report any bugs at the project site or directly to the author.
.\" //////////////////////////////////////////////////////////////////////////
.SH BUGS
.\" //////////////////////////////////////////////////////////////////////////
.P
The runtime behavior of seccomp filters is dependent upon the kernel
version, the processor architecture, and other libraries including libc.
This could affect the return code of a seccomp filter.

.TP
.B *
PowerPC glibc will not return a negative number when the
.B getpid()
syscall is invoked.  If a seccomp filter has been created where
.B getpid()
will return a negative number from the kernel, then PowerPC glibc will
return the absolute value of the errno.  In this case, it is very difficult
for an application to distinguish between the errno and a valid pid.

.\" //////////////////////////////////////////////////////////////////////////
.SH AUTHOR
.\" //////////////////////////////////////////////////////////////////////////
Paul Moore <paul@paul-moore.com>
.\" //////////////////////////////////////////////////////////////////////////
.SH SEE ALSO
.\" //////////////////////////////////////////////////////////////////////////
.BR seccomp_syscall_resolve_name_rewrite (3),
.BR seccomp_syscall_priority (3),
.BR seccomp_load (3),
.BR seccomp_attr_set (3)