1seccomp_rule_add(3) libseccomp Documentation seccomp_rule_add(3)
2
3
4
6 seccomp_rule_add, seccomp_rule_add_exact - Add a seccomp filter rule
7
9 #include <seccomp.h>
10
11 typedef void * scmp_filter_ctx;
12
13 int SCMP_SYS(syscall_name);
14
15 struct scmp_arg_cmp SCMP_CMP(unsigned int arg,
16 enum scmp_compare op, ...);
17 struct scmp_arg_cmp SCMP_A0(enum scmp_compare op, ...);
18 struct scmp_arg_cmp SCMP_A1(enum scmp_compare op, ...);
19 struct scmp_arg_cmp SCMP_A2(enum scmp_compare op, ...);
20 struct scmp_arg_cmp SCMP_A3(enum scmp_compare op, ...);
21 struct scmp_arg_cmp SCMP_A4(enum scmp_compare op, ...);
22 struct scmp_arg_cmp SCMP_A5(enum scmp_compare op, ...);
23
24 struct scmp_arg_cmp SCMP_CMP64(unsigned int arg,
25 enum scmp_compare op, ...);
26 struct scmp_arg_cmp SCMP_A0_64(enum scmp_compare op, ...);
27 struct scmp_arg_cmp SCMP_A1_64(enum scmp_compare op, ...);
28 struct scmp_arg_cmp SCMP_A2_64(enum scmp_compare op, ...);
29 struct scmp_arg_cmp SCMP_A3_64(enum scmp_compare op, ...);
30 struct scmp_arg_cmp SCMP_A4_64(enum scmp_compare op, ...);
31 struct scmp_arg_cmp SCMP_A5_64(enum scmp_compare op, ...);
32
33 struct scmp_arg_cmp SCMP_CMP32(unsigned int arg,
34 enum scmp_compare op, ...);
35 struct scmp_arg_cmp SCMP_A0_32(enum scmp_compare op, ...);
36 struct scmp_arg_cmp SCMP_A1_32(enum scmp_compare op, ...);
37 struct scmp_arg_cmp SCMP_A2_32(enum scmp_compare op, ...);
38 struct scmp_arg_cmp SCMP_A3_32(enum scmp_compare op, ...);
39 struct scmp_arg_cmp SCMP_A4_32(enum scmp_compare op, ...);
40 struct scmp_arg_cmp SCMP_A5_32(enum scmp_compare op, ...);
41
42 int seccomp_rule_add(scmp_filter_ctx ctx, uint32_t action,
43 int syscall, unsigned int arg_cnt, ...);
44 int seccomp_rule_add_exact(scmp_filter_ctx ctx, uint32_t action,
45 int syscall, unsigned int arg_cnt, ...);
46
47 int seccomp_rule_add_array(scmp_filter_ctx ctx,
48 uint32_t action, int syscall,
49 unsigned int arg_cnt,
50 const struct scmp_arg_cmp *arg_array);
51 int seccomp_rule_add_exact_array(scmp_filter_ctx ctx,
52 uint32_t action, int syscall,
53 unsigned int arg_cnt,
54 const struct scmp_arg_cmp *arg_array);
55
56 Link with -lseccomp.
57
59 The seccomp_rule_add(), seccomp_rule_add_array(), seccomp_rule_add_ex‐
60 act(), and seccomp_rule_add_exact_array() functions all add a new fil‐
61 ter rule to the current seccomp filter. The seccomp_rule_add() and
62 seccomp_rule_add_array() functions will make a "best effort" to add the
63 rule as specified, but may alter the rule slightly due to architecture
64 specifics (e.g. internal rewriting of multiplexed syscalls, like socket
65 and ipc functions on x86). The seccomp_rule_add_exact() and sec‐
66 comp_rule_add_exact_array() functions will attempt to add the rule ex‐
67 actly as specified so it may behave differently on different architec‐
68 tures. While it does not guarantee a exact filter ruleset, sec‐
69 comp_rule_add() and seccomp_rule_add_array() do guarantee the same be‐
70 havior regardless of the architecture.
71
72 The newly added filter rule does not take effect until the entire fil‐
73 ter is loaded into the kernel using seccomp_load(3). When adding rules
74 to a filter, it is important to consider the impact of previously
75 loaded filters; see the seccomp_load(3) documentation for more informa‐
76 tion.
77
78 All of the filter rules supplied by the calling application are com‐
79 bined into a union, with additional logic to eliminate redundant
80 syscall filters. For example, if a rule is added which allows a given
81 syscall with a specific set of argument values and later a rule is
82 added which allows the same syscall regardless the argument values then
83 the first, more specific rule, is effectively dropped from the filter
84 by the second more generic rule.
85
86 The SCMP_CMP(), SCMP_CMP64(), SCMP_A{0-5}(), and SCMP_A{0-5}_64()
87 macros generate a scmp_arg_cmp structure for use with the above func‐
88 tions. The SCMP_CMP() and SCMP_CMP64() macros allows the caller to
89 specify an arbitrary argument along with the comparison operator,
90 64-bit mask, and 64-bit datum values where the SCMP_A{0-5}() and
91 SCMP_A{0-5}_64() macros are specific to a certain argument.
92
93 The SCMP_CMP32() and SCMP_A{0-5}_32() macros are similar to the vari‐
94 ants above, but they take 32-bit mask and 32-bit datum values.
95
96 It is recommended that whenever possible developers avoid using the
97 SCMP_CMP() and SCMP_A{0-5}() macros and use the variants which are ex‐
98 plicitly 32 or 64-bit. This should help eliminate problems caused by
99 an unwanted sign extension of negative datum values.
100
101 If syscall argument comparisons are included in the filter rule, all of
102 the comparisons must be true for the rule to match.
103
104 When adding syscall argument comparisons to the filter it is important
105 to remember that while it is possible to have multiple comparisons in a
106 single rule, you can only compare each argument once in a single rule.
107 In other words, you can not have multiple comparisons of the 3rd
108 syscall argument in a single rule.
109
110 In a filter containing multiple architectures, it is an error to add a
111 filter rule for a syscall that does not exist in all of the filter's
112 architectures.
113
114 While it is possible to specify the syscall value directly using the
115 standard __NR_syscall values, in order to ensure proper operation
116 across multiple architectures it is highly recommended to use the
117 SCMP_SYS() macro instead. See the EXAMPLES section below. It is also
118 important to remember that regardless of the architectures present in
119 the filter, the syscall numbers used in filter rules are interpreted in
120 the context of the native architecture.
121
122 Starting with Linux v4.8, there may be a need to create a rule with a
123 syscall value of -1 to allow tracing programs to skip a syscall invoca‐
124 tion; in order to create a rule with a -1 syscall value it is necessary
125 to first set the SCMP_FLTATR_API_TSKIP attribute. See sec‐
126 comp_attr_set(3) for more information.
127
128 The filter context ctx is the value returned by the call to sec‐
129 comp_init(3).
130
131 Valid action values are as follows:
132
133 SCMP_ACT_KILL
134 The thread will be killed by the kernel when it calls a syscall
135 that matches the filter rule.
136
137 SCMP_ACT_KILL_PROCESS
138 The process will be killed by the kernel when it calls a syscall
139 that matches the filter rule.
140
141 SCMP_ACT_TRAP
142 The thread will throw a SIGSYS signal when it calls a syscall
143 that matches the filter rule.
144
145 SCMP_ACT_ERRNO(uint16_t errno)
146 The thread will receive a return value of errno when it calls a
147 syscall that matches the filter rule.
148
149 SCMP_ACT_TRACE(uint16_t msg_num)
150 If the thread is being traced and the tracing process specified
151 the PTRACE_O_TRACESECCOMP option in the call to ptrace(2), the
152 tracing process will be notified, via PTRACE_EVENT_SECCOMP , and
153 the value provided in msg_num can be retrieved using the
154 PTRACE_GETEVENTMSG option.
155
156 SCMP_ACT_LOG
157 The seccomp filter will have no effect on the thread calling the
158 syscall if it matches the filter rule but the syscall will be
159 logged.
160
161 SCMP_ACT_ALLOW
162 The seccomp filter will have no effect on the thread calling the
163 syscall if it matches the filter rule.
164
165 SCMP_ACT_NOTIFY
166 A monitoring process will be notified when a process running the
167 seccomp filter calls a syscall that matches the filter rule.
168 The process that invokes the syscall waits in the kernel until
169 the monitoring process has responded via seccomp_notify_respond
170 [1m(3) .
171
172 When a filter utilizing SCMP_ACT_NOTIFY is loaded into the ker‐
173 nel, the kernel generates a notification fd that must be used to
174 communicate between the monitoring process and the process(es)
175 being filtered. See seccomp_notif_fd (3) for more information.
176
177
178 Valid comparison op values are as follows:
179
180 SCMP_CMP_NE
181 Matches when the argument value is not equal to the datum value,
182 example:
183
184 SCMP_CMP( arg , SCMP_CMP_NE , datum )
185
186 SCMP_CMP_LT
187 Matches when the argument value is less than the datum value,
188 example:
189
190 SCMP_CMP( arg , SCMP_CMP_LT , datum )
191
192 SCMP_CMP_LE
193 Matches when the argument value is less than or equal to the da‐
194 tum value, example:
195
196 SCMP_CMP( arg , SCMP_CMP_LE , datum )
197
198 SCMP_CMP_EQ
199 Matches when the argument value is equal to the datum value, ex‐
200 ample:
201
202 SCMP_CMP( arg , SCMP_CMP_EQ , datum )
203
204 SCMP_CMP_GE
205 Matches when the argument value is greater than or equal to the
206 datum value, example:
207
208 SCMP_CMP( arg , SCMP_CMP_GE , datum )
209
210 SCMP_CMP_GT
211 Matches when the argument value is greater than the datum value,
212 example:
213
214 SCMP_CMP( arg , SCMP_CMP_GT , datum )
215
216 SCMP_CMP_MASKED_EQ
217 Matches when the masked argument value is equal to the masked
218 datum value, example:
219
220 SCMP_CMP( arg , SCMP_CMP_MASKED_EQ , mask , datum )
221
223 The SCMP_SYS() macro returns a value suitable for use as the syscall
224 value in the seccomp_rule_add*() functions. In a similar manner, the
225 SCMP_CMP() and SCMP_A*() macros return values suitable for use as argu‐
226 ment comparisons in the seccomp_rule_add() and seccomp_rule_add_exact()
227 functions.
228
229 The seccomp_rule_add(), seccomp_rule_add_array(), seccomp_rule_add_ex‐
230 act(), and seccomp_rule_add_exact_array() functions return zero on suc‐
231 cess or one of the following error codes on failure:
232
233 -EDOM Architecture specific failure.
234
235 -EEXIST
236 The rule already exists.
237
238 -EACCCES
239 The rule conflicts with the filter (for example, the rule action
240 equals the default action of the filter).
241
242 -EFAULT
243 Internal libseccomp failure.
244
245 -EINVAL
246 Invalid input, either the context or architecture token is in‐
247 valid.
248
249 -ENOMEM
250 The library was unable to allocate enough memory.
251
252 -EOPNOTSUPP
253 The library doesn't support the particular operation.
254
256 #include <fcntl.h>
257 #include <seccomp.h>
258 #include <sys/stat.h>
259 #include <sys/types.h>
260 #include <stddef.h>
261
262 #define BUF_SIZE 256
263
264 int main(int argc, char *argv[])
265 {
266 int rc = -1;
267 scmp_filter_ctx ctx;
268 struct scmp_arg_cmp arg_cmp[] = { SCMP_A0(SCMP_CMP_EQ, 2) };
269 int fd;
270 unsigned char buf[BUF_SIZE];
271
272 ctx = seccomp_init(SCMP_ACT_KILL);
273 if (ctx == NULL)
274 goto out;
275
276 /* ... */
277
278 fd = open("file.txt", 0);
279
280 /* ... */
281
282 rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0);
283 if (rc < 0)
284 goto out;
285
286 rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0);
287 if (rc < 0)
288 goto out;
289
290 rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0);
291 if (rc < 0)
292 goto out;
293
294 rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 3,
295 SCMP_A0(SCMP_CMP_EQ, fd),
296 SCMP_A1(SCMP_CMP_EQ, (scmp_datum_t)buf),
297 SCMP_A2(SCMP_CMP_LE, BUF_SIZE));
298 if (rc < 0)
299 goto out;
300
301 rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1,
302 SCMP_CMP(0, SCMP_CMP_EQ, fd));
303 if (rc < 0)
304 goto out;
305
306 rc = seccomp_rule_add_array(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1,
307 arg_cmp);
308 if (rc < 0)
309 goto out;
310
311 rc = seccomp_load(ctx);
312 if (rc < 0)
313 goto out;
314
315 /* ... */
316
317 out:
318 seccomp_release(ctx);
319 return -rc;
320 }
321
323 While the seccomp filter can be generated independent of the kernel,
324 kernel support is required to load and enforce the seccomp filter gen‐
325 erated by libseccomp.
326
327 The libseccomp project site, with more information and the source code
328 repository, can be found at https://github.com/seccomp/libseccomp.
329 This tool, as well as the libseccomp library, is currently under devel‐
330 opment, please report any bugs at the project site or directly to the
331 author.
332
334 The runtime behavior of seccomp filters is dependent upon the kernel
335 version, the processor architecture, and other libraries including
336 libc. This could affect the return code of a seccomp filter.
337
338
339 * PowerPC glibc will not return a negative number when the get‐
340 pid() syscall is invoked. If a seccomp filter has been created
341 where getpid() will return a negative number from the kernel,
342 then PowerPC glibc will return the absolute value of the errno.
343 In this case, it is very difficult for an application to distin‐
344 guish between the errno and a valid pid.
345
346
348 Paul Moore <paul@paul-moore.com>
349
351 seccomp_syscall_resolve_name_rewrite(3), seccomp_syscall_priority(3),
352 seccomp_load(3), seccomp_attr_set(3)
353
354
355
356paul@paul-moore.com 30 May 2020 seccomp_rule_add(3)