]>
Commit | Line | Data |
---|---|---|
62c6598e PM |
1 | # |
2 | # Seccomp Library Python Bindings | |
3 | # | |
6220c8c0 | 4 | # Copyright (c) 2012,2013 Red Hat <pmoore@redhat.com> |
62c6598e PM |
5 | # Author: Paul Moore <pmoore@redhat.com> |
6 | # | |
7 | ||
8 | # | |
9 | # This library is free software; you can redistribute it and/or modify it | |
10 | # under the terms of version 2.1 of the GNU Lesser General Public License as | |
11 | # published by the Free Software Foundation. | |
12 | # | |
13 | # This library is distributed in the hope that it will be useful, but WITHOUT | |
14 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
16 | # for more details. | |
17 | # | |
18 | # You should have received a copy of the GNU Lesser General Public License | |
19 | # along with this library; if not, see <http://www.gnu.org/licenses>. | |
20 | # | |
21 | ||
22 | """ Python bindings for the libseccomp library | |
23 | ||
24 | The libseccomp library provides and easy to use, platform independent, | |
25 | interface to the Linux Kernel's syscall filtering mechanism: seccomp. The | |
26 | libseccomp API is designed to abstract away the underlying BPF based | |
27 | syscall filter language and present a more conventional function-call | |
28 | based filtering interface that should be familiar to, and easily adopted | |
29 | by application developers. | |
30 | ||
31 | Filter action values: | |
32 | KILL - kill the process | |
33 | ALLOW - allow the syscall to execute | |
34 | TRAP - a SIGSYS signal will be thrown | |
35 | ERRNO(x) - syscall will return (x) | |
36 | TRACE(x) - if the process is being traced, (x) will be returned to the | |
37 | tracing process via PTRACE_EVENT_SECCOMP and the | |
38 | PTRACE_GETEVENTMSG option | |
39 | ||
70c89434 PM |
40 | Argument comparison values (see the Arg class): |
41 | ||
42 | NE - arg != datum_a | |
43 | LT - arg < datum_a | |
44 | LE - arg <= datum_a | |
45 | EQ - arg == datum_a | |
46 | GT - arg > datum_a | |
47 | GE - arg >= datum_a | |
8af9ba44 | 48 | MASKED_EQ - (arg & datum_b) == datum_a |
62c6598e PM |
49 | |
50 | ||
51 | Example: | |
52 | ||
53 | import sys | |
54 | from seccomp import * | |
55 | ||
56 | # create a filter object with a default KILL action | |
57 | f = SyscallFilter(defaction=KILL) | |
58 | ||
59 | # add syscall filter rules to allow certain syscalls | |
60 | f.add_rule(ALLOW, "open") | |
61 | f.add_rule(ALLOW, "close") | |
62 | f.add_rule(ALLOW, "read", Arg(0, EQ, sys.stdin)) | |
63 | f.add_rule(ALLOW, "write", Arg(0, EQ, sys.stdout)) | |
64 | f.add_rule(ALLOW, "write", Arg(0, EQ, sys.stderr)) | |
65 | f.add_rule(ALLOW, "rt_sigreturn") | |
66 | ||
67 | # load the filter into the kernel | |
68 | f.load() | |
69 | """ | |
70 | __author__ = 'Paul Moore <paul@paul-moore.com>' | |
6220c8c0 | 71 | __date__ = "7 January 2013" |
62c6598e PM |
72 | |
73 | from libc.stdint cimport uint32_t | |
74 | import errno | |
75 | ||
76 | cimport libseccomp | |
77 | ||
78 | KILL = libseccomp.SCMP_ACT_KILL | |
79 | TRAP = libseccomp.SCMP_ACT_TRAP | |
80 | ALLOW = libseccomp.SCMP_ACT_ALLOW | |
81 | def ERRNO(int errno): | |
28a57d88 AL |
82 | """The action ERRNO(x) means that the syscall will return (x). |
83 | To conform to Linux syscall calling conventions, the syscall return | |
84 | value should almost always be a negative number. | |
85 | """ | |
62c6598e PM |
86 | return libseccomp.SCMP_ACT_ERRNO(errno) |
87 | def TRACE(int value): | |
28a57d88 AL |
88 | """The action TRACE(x) means that, if the process is being traced, (x) |
89 | will be returned to the tracing process via PTRACE_EVENT_SECCOMP | |
90 | and the PTRACE_GETEVENTMSG option. | |
91 | """ | |
62c6598e PM |
92 | return libseccomp.SCMP_ACT_TRACE(value) |
93 | ||
94 | NE = libseccomp.SCMP_CMP_NE | |
95 | LT = libseccomp.SCMP_CMP_LT | |
96 | LE = libseccomp.SCMP_CMP_LE | |
97 | EQ = libseccomp.SCMP_CMP_EQ | |
98 | GE = libseccomp.SCMP_CMP_GE | |
99 | GT = libseccomp.SCMP_CMP_GT | |
100 | MASKED_EQ = libseccomp.SCMP_CMP_MASKED_EQ | |
101 | ||
aeac2736 PM |
102 | def system_arch(): |
103 | """ Return the system architecture value. | |
104 | ||
105 | Description: | |
106 | Returns the native system architecture value. | |
107 | """ | |
108 | return libseccomp.seccomp_arch_native() | |
109 | ||
6220c8c0 PM |
110 | def resolve_syscall(arch, syscall): |
111 | """ Resolve the syscall. | |
112 | ||
113 | Arguments: | |
114 | arch - the architecture value, e.g. Arch.* | |
115 | syscall - the syscall name or number | |
116 | ||
117 | Description: | |
118 | Resolve an architecture's syscall name to the correct number or the | |
119 | syscall number to the correct name. | |
120 | """ | |
f7c11d67 AL |
121 | cdef char *ret_str |
122 | ||
6220c8c0 PM |
123 | if (isinstance(syscall, basestring)): |
124 | return libseccomp.seccomp_syscall_resolve_name_arch(arch, syscall) | |
125 | elif (isinstance(syscall, int)): | |
f7c11d67 AL |
126 | ret_str = libseccomp.seccomp_syscall_resolve_num_arch(arch, syscall) |
127 | if ret_str is NULL: | |
128 | raise ValueError('Unknown syscall %d on arch %d' % (syscall, arch)) | |
129 | else: | |
130 | return ret_str | |
6220c8c0 PM |
131 | else: |
132 | raise TypeError("Syscall must either be an int or str type") | |
133 | ||
62c6598e PM |
134 | cdef class Arch: |
135 | """ Python object representing the SyscallFilter architecture values. | |
136 | ||
137 | Data values: | |
138 | NATIVE - the native architecture | |
139 | X86 - 32-bit x86 | |
140 | X86_64 - 64-bit x86 | |
e9b5a6eb | 141 | X32 - 64-bit x86 using the x32 ABI |
db440d1e | 142 | ARM - ARM |
62c6598e | 143 | """ |
aeac2736 | 144 | |
62c6598e PM |
145 | NATIVE = libseccomp.SCMP_ARCH_NATIVE |
146 | X86 = libseccomp.SCMP_ARCH_X86 | |
147 | X86_64 = libseccomp.SCMP_ARCH_X86_64 | |
e9b5a6eb | 148 | X32 = libseccomp.SCMP_ARCH_X32 |
db440d1e | 149 | ARM = libseccomp.SCMP_ARCH_ARM |
62c6598e PM |
150 | |
151 | cdef class Attr: | |
152 | """ Python object representing the SyscallFilter attributes. | |
153 | ||
154 | Data values: | |
155 | ACT_DEFAULT - the filter's default action | |
156 | ACT_BADARCH - the filter's bad architecture action | |
157 | CTL_NNP - the filter's "no new privileges" flag | |
158 | """ | |
159 | ACT_DEFAULT = libseccomp.SCMP_FLTATR_ACT_DEFAULT | |
160 | ACT_BADARCH = libseccomp.SCMP_FLTATR_ACT_BADARCH | |
161 | CTL_NNP = libseccomp.SCMP_FLTATR_CTL_NNP | |
162 | ||
163 | cdef class Arg: | |
164 | """ Python object representing a SyscallFilter syscall argument. | |
165 | """ | |
166 | cdef libseccomp.scmp_arg_cmp _arg | |
167 | ||
168 | def __cinit__(self, arg, op, datum_a, datum_b = 0): | |
169 | """ Initialize the argument comparison. | |
170 | ||
171 | Arguments: | |
46a0ab2f | 172 | arg - the argument number, starting at 0 |
62c6598e PM |
173 | op - the argument comparison operator, e.g. {NE,LT,LE,...} |
174 | datum_a - argument value | |
175 | datum_b - argument value, only valid when op == MASKED_EQ | |
176 | ||
177 | Description: | |
178 | Create an argument comparison object for use with SyscallFilter. | |
179 | """ | |
180 | self._arg.arg = arg | |
181 | self._arg.op = op | |
8e1b4634 AL |
182 | self._arg.datum_a = datum_a |
183 | self._arg.datum_b = datum_b | |
62c6598e | 184 | |
dd673b51 | 185 | cdef libseccomp.scmp_arg_cmp to_c(self): |
62c6598e PM |
186 | """ Convert the object into a C structure. |
187 | ||
188 | Description: | |
189 | Helper function which should only be used internally by | |
190 | SyscallFilter objects and exists for the sole purpose of making it | |
191 | easier to deal with the varadic functions of the libseccomp API, | |
192 | e.g. seccomp_rule_add(). | |
193 | """ | |
194 | return self._arg | |
195 | ||
196 | cdef class SyscallFilter: | |
197 | """ Python object representing a seccomp syscall filter. """ | |
198 | cdef int _defaction | |
199 | cdef libseccomp.scmp_filter_ctx _ctx | |
200 | ||
201 | def __cinit__(self, int defaction): | |
4021195b AL |
202 | self._ctx = libseccomp.seccomp_init(defaction) |
203 | if self._ctx == NULL: | |
204 | raise RuntimeError("Library error") | |
205 | _defaction = defaction | |
206 | ||
207 | def __init__(self, defaction): | |
62c6598e PM |
208 | """ Initialize the filter state |
209 | ||
210 | Arguments: | |
211 | defaction - the default filter action | |
212 | ||
213 | Description: | |
214 | Initializes the seccomp filter state to the defaults. | |
215 | """ | |
62c6598e PM |
216 | |
217 | def __dealloc__(self): | |
218 | """ Destroys the filter state and releases any resources. | |
219 | ||
220 | Description: | |
221 | Destroys the seccomp filter state and releases any resources | |
222 | associated with the filter state. This function does not affect | |
223 | any seccomp filters already loaded into the kernel. | |
224 | """ | |
225 | if self._ctx != NULL: | |
226 | libseccomp.seccomp_release(self._ctx) | |
227 | ||
228 | def reset(self, int defaction = -1): | |
229 | """ Reset the filter state. | |
230 | ||
231 | Arguments: | |
232 | defaction - the default filter action | |
233 | ||
234 | Description: | |
235 | Resets the seccomp filter state to an initial default state, if a | |
236 | default filter action is not specified in the reset call the | |
237 | original action will be reused. This function does not affect any | |
238 | seccomp filters alread loaded into the kernel. | |
239 | """ | |
240 | if defaction == -1: | |
241 | defaction = self._defaction | |
242 | rc = libseccomp.seccomp_reset(self._ctx, defaction) | |
243 | if rc == -errno.EINVAL: | |
244 | raise ValueError("Invalid action") | |
245 | if rc != 0: | |
246 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
247 | _defaction = defaction | |
248 | ||
249 | def merge(self, SyscallFilter filter): | |
250 | """ Merge two existing SyscallFilter objects. | |
251 | ||
252 | Arguments: | |
253 | filter - a valid SyscallFilter object | |
254 | ||
255 | Description: | |
256 | Merges a valid SyscallFilter object with the current SyscallFilter | |
257 | object; the passed filter object will be reset on success. In | |
258 | order to successfully merge two seccomp filters they must have the | |
259 | same attribute values and not share any of the same architectures. | |
260 | """ | |
261 | rc = libseccomp.seccomp_merge(self._ctx, filter._ctx) | |
262 | if rc != 0: | |
263 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
264 | filter._ctx = NULL | |
265 | filter = SyscallFilter(filter._defaction) | |
266 | ||
267 | def exist_arch(self, arch): | |
268 | """ Check if the seccomp filter contains a given architecture. | |
269 | ||
270 | Arguments: | |
271 | arch - the architecture value, e.g. Arch.* | |
272 | ||
273 | Description: | |
274 | Test to see if a given architecture is included in the filter. | |
275 | Return True is the architecture exists, False if it does not | |
276 | exist. | |
277 | """ | |
278 | rc = libseccomp.seccomp_arch_exist(self._ctx, arch) | |
279 | if rc == 0: | |
280 | return True | |
281 | elif rc == -errno.EEXIST: | |
282 | return False | |
283 | elif rc == -errno.EINVAL: | |
284 | raise ValueError("Invalid architecture") | |
285 | else: | |
286 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
287 | ||
288 | def add_arch(self, arch): | |
289 | """ Add an architecture to the filter. | |
290 | ||
291 | Arguments: | |
292 | arch - the architecture value, e.g. Arch.* | |
293 | ||
294 | Description: | |
295 | Add the given architecture to the filter. Any new rules added | |
296 | after this method returns successfully will be added to this new | |
297 | architecture, but any existing rules will not be added to the new | |
298 | architecture. | |
299 | """ | |
300 | rc = libseccomp.seccomp_arch_add(self._ctx, arch) | |
301 | if rc == -errno.EINVAL: | |
302 | raise ValueError("Invalid architecture") | |
303 | elif rc != 0: | |
304 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
305 | ||
306 | def remove_arch(self, arch): | |
307 | """ Remove an architecture from the filter. | |
308 | ||
309 | Arguments: | |
310 | arch - the architecture value, e.g. Arch.* | |
311 | ||
312 | Description: | |
313 | Remove the given architecture from the filter. The filter must | |
314 | always contain at least one architecture, so if only one | |
315 | architecture exists in the filter this method will fail. | |
316 | """ | |
317 | rc = libseccomp.seccomp_arch_remove(self._ctx, arch) | |
318 | if rc == -errno.EINVAL: | |
319 | raise ValueError("Invalid architecture") | |
320 | elif rc != 0: | |
321 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
322 | ||
323 | def load(self): | |
324 | """ Load the filter into the Linux Kernel. | |
325 | ||
326 | Description: | |
327 | Load the current filter into the Linux Kernel. As soon as the | |
328 | method returns the filter will be active and enforcing. | |
329 | """ | |
330 | rc = libseccomp.seccomp_load(self._ctx) | |
331 | if rc != 0: | |
332 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
333 | ||
334 | def get_attr(self, attr): | |
335 | """ Get an attribute value from the filter. | |
336 | ||
337 | Arguments: | |
338 | attr - the attribute, e.g. Attr.* | |
339 | ||
340 | Description: | |
341 | Lookup the given attribute in the filter and return the | |
342 | attribute's value to the caller. | |
343 | """ | |
344 | value = 0 | |
345 | rc = libseccomp.seccomp_attr_get(self._ctx, | |
346 | attr, <uint32_t *>&value) | |
347 | if rc == -errno.EINVAL: | |
348 | raise ValueError("Invalid attribute") | |
349 | elif rc != 0: | |
350 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
351 | return value | |
352 | ||
353 | def set_attr(self, attr, int value): | |
354 | """ Set a filter attribute. | |
355 | ||
356 | Arguments: | |
357 | attr - the attribute, e.g. Attr.* | |
358 | value - the attribute value | |
359 | ||
360 | Description: | |
361 | Lookup the given attribute in the filter and assign it the given | |
362 | value. | |
363 | """ | |
364 | rc = libseccomp.seccomp_attr_set(self._ctx, attr, value) | |
365 | if rc == -errno.EINVAL: | |
366 | raise ValueError("Invalid attribute") | |
367 | elif rc != 0: | |
368 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
369 | ||
370 | def syscall_priority(self, syscall, int priority): | |
371 | """ Set the filter priority of a syscall. | |
372 | ||
373 | Arguments: | |
374 | syscall - the syscall name or number | |
375 | priority - the priority of the syscall | |
376 | ||
377 | Description: | |
378 | Set the filter priority of the given syscall. A syscall with a | |
379 | higher priority will have less overhead in the generated filter | |
380 | code which is loaded into the system. Priority values can range | |
381 | from 0 to 255 inclusive. | |
382 | """ | |
383 | if priority < 0 or priority > 255: | |
6220c8c0 | 384 | raise ValueError("Syscall priority must be between 0 and 255") |
62c6598e PM |
385 | if isinstance(syscall, str): |
386 | syscall_str = syscall.encode() | |
387 | syscall_num = libseccomp.seccomp_syscall_resolve_name(syscall_str) | |
388 | elif isinstance(syscall, int): | |
389 | syscall_num = syscall | |
390 | else: | |
6220c8c0 | 391 | raise TypeError("Syscall must either be an int or str type") |
62c6598e PM |
392 | rc = libseccomp.seccomp_syscall_priority(self._ctx, |
393 | syscall_num, priority) | |
394 | if rc != 0: | |
395 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
396 | ||
397 | def add_rule(self, int action, syscall, *args): | |
398 | """ Add a new rule to filter. | |
399 | ||
400 | Arguments: | |
401 | action - the rule action: KILL, TRAP, ERRNO(), TRACE(), or ALLOW | |
402 | syscall - the syscall name or number | |
403 | args - variable number of Arg objects | |
404 | ||
405 | Description: | |
406 | Add a new rule to the filter, matching on the given syscall and an | |
407 | optional list of argument comparisons. If the rule is triggered | |
408 | the given action will be taken by the kernel. In order for the | |
409 | rule to trigger, the syscall as well as each argument comparison | |
410 | must be true. | |
411 | ||
412 | In the case where the specific rule is not valid on a specific | |
413 | architecture, e.g. socket() on 32-bit x86, this method rewrites | |
414 | the rule to the best possible match. If you don't want this fule | |
415 | rewriting to take place use add_rule_exactly(). | |
416 | """ | |
417 | cdef libseccomp.scmp_arg_cmp c_arg[6] | |
418 | if isinstance(syscall, str): | |
419 | syscall_str = syscall.encode() | |
420 | syscall_num = libseccomp.seccomp_syscall_resolve_name(syscall_str) | |
421 | elif isinstance(syscall, int): | |
422 | syscall_num = syscall | |
423 | else: | |
6220c8c0 | 424 | raise TypeError("Syscall must either be an int or str type") |
62c6598e PM |
425 | """ NOTE: the code below exists solely to deal with the varadic |
426 | nature of seccomp_rule_add() function and the inability of Cython | |
427 | to handle this automatically """ | |
dd673b51 | 428 | cdef Arg arg |
62c6598e PM |
429 | for i, arg in enumerate(args): |
430 | c_arg[i] = arg.to_c() | |
431 | if len(args) == 0: | |
432 | rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, 0) | |
433 | elif len(args) == 1: | |
434 | rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, | |
435 | len(args), | |
436 | c_arg[0]) | |
437 | elif len(args) == 2: | |
438 | rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, | |
439 | len(args), | |
440 | c_arg[0], | |
441 | c_arg[1]) | |
442 | elif len(args) == 3: | |
443 | rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, | |
444 | len(args), | |
445 | c_arg[0], | |
446 | c_arg[1], | |
447 | c_arg[2]) | |
448 | elif len(args) == 4: | |
449 | rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, | |
450 | len(args), | |
451 | c_arg[0], | |
452 | c_arg[1], | |
453 | c_arg[2], | |
454 | c_arg[3]) | |
455 | elif len(args) == 5: | |
456 | rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, | |
457 | len(args), | |
458 | c_arg[0], | |
459 | c_arg[1], | |
460 | c_arg[2], | |
461 | c_arg[3], | |
462 | c_arg[4]) | |
463 | elif len(args) == 6: | |
464 | rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, | |
465 | len(args), | |
466 | c_arg[0], | |
467 | c_arg[1], | |
468 | c_arg[2], | |
469 | c_arg[3], | |
470 | c_arg[4], | |
471 | c_arg[5]) | |
472 | else: | |
473 | raise RuntimeError("Maximum number of arguments exceeded") | |
474 | if rc != 0: | |
475 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
476 | ||
477 | def add_rule_exactly(self, int action, syscall, *args): | |
478 | """ Add a new rule to filter. | |
479 | ||
480 | Arguments: | |
481 | action - the rule action: KILL, TRAP, ERRNO(), TRACE(), or ALLOW | |
482 | syscall - the syscall name or number | |
483 | args - variable number of Arg objects | |
484 | ||
485 | Description: | |
486 | Add a new rule to the filter, matching on the given syscall and an | |
487 | optional list of argument comparisons. If the rule is triggered | |
488 | the given action will be taken by the kernel. In order for the | |
489 | rule to trigger, the syscall as well as each argument comparison | |
490 | must be true. | |
491 | ||
492 | This method attempts to add the filter rule exactly as specified | |
493 | which can cause problems on certain architectures, e.g. socket() | |
494 | on 32-bit x86. For a architecture independent version of this | |
495 | method use add_rule(). | |
496 | """ | |
497 | cdef libseccomp.scmp_arg_cmp c_arg[6] | |
498 | if isinstance(syscall, str): | |
499 | syscall_str = syscall.encode() | |
500 | syscall_num = libseccomp.seccomp_syscall_resolve_name(syscall_str) | |
501 | elif isinstance(syscall, int): | |
502 | syscall_num = syscall | |
503 | else: | |
6220c8c0 | 504 | raise TypeError("Syscall must either be an int or str type") |
62c6598e PM |
505 | """ NOTE: the code below exists solely to deal with the varadic |
506 | nature of seccomp_rule_add_exact() function and the inability of | |
507 | Cython to handle this automatically """ | |
dd673b51 | 508 | cdef Arg arg |
62c6598e PM |
509 | for i, arg in enumerate(args): |
510 | c_arg[i] = arg.to_c() | |
511 | if len(args) == 0: | |
512 | rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, | |
513 | syscall_num, 0) | |
514 | elif len(args) == 1: | |
515 | rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, | |
516 | syscall_num, len(args), | |
517 | c_arg[0]) | |
518 | elif len(args) == 2: | |
519 | rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, | |
520 | syscall_num, len(args), | |
521 | c_arg[0], | |
522 | c_arg[1]) | |
523 | elif len(args) == 3: | |
524 | rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, | |
525 | syscall_num, len(args), | |
526 | c_arg[0], | |
527 | c_arg[1], | |
528 | c_arg[2]) | |
529 | elif len(args) == 4: | |
530 | rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, | |
531 | syscall_num, len(args), | |
532 | c_arg[0], | |
533 | c_arg[1], | |
534 | c_arg[2], | |
535 | c_arg[3]) | |
536 | elif len(args) == 5: | |
537 | rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, | |
538 | syscall_num, len(args), | |
539 | c_arg[0], | |
540 | c_arg[1], | |
541 | c_arg[2], | |
542 | c_arg[3], | |
543 | c_arg[4]) | |
544 | elif len(args) == 6: | |
545 | rc = libseccomp.seccomp_rule_add_exact(self._ctx, action, | |
546 | syscall_num, len(args), | |
547 | c_arg[0], | |
548 | c_arg[1], | |
549 | c_arg[2], | |
550 | c_arg[3], | |
551 | c_arg[4], | |
552 | c_arg[5]) | |
553 | else: | |
554 | raise RuntimeError("Maximum number of arguments exceeded") | |
555 | if rc != 0: | |
556 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
557 | ||
558 | def export_pfc(self, file): | |
559 | """ Export the filter in PFC format. | |
560 | ||
561 | Arguments: | |
562 | file - the output file | |
563 | ||
564 | Description: | |
565 | Output the filter in Pseudo Filter Code (PFC) to the given file. | |
566 | The output is functionally equivalent to the BPF based filter | |
567 | which is loaded into the Linux Kernel. | |
568 | """ | |
569 | rc = libseccomp.seccomp_export_pfc(self._ctx, file.fileno()) | |
570 | if rc != 0: | |
571 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
572 | ||
573 | def export_bpf(self, file): | |
574 | """ Export the filter in BPF format. | |
575 | ||
576 | Arguments: | |
577 | file - the output file | |
578 | ||
579 | Output the filter in Berkley Packet Filter (BPF) to the given | |
580 | file. The output is identical to what is loaded into the | |
581 | Linux Kernel. | |
582 | """ | |
583 | rc = libseccomp.seccomp_export_bpf(self._ctx, file.fileno()) | |
584 | if rc != 0: | |
585 | raise RuntimeError(str.format("Library error (errno = {0})", rc)) | |
586 | ||
587 | # kate: syntax python; | |
588 | # kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; |