]> git.proxmox.com Git - mirror_libseccomp.git/blame - src/python/seccomp.pyx
arch: add a ppc syscall table
[mirror_libseccomp.git] / src / python / seccomp.pyx
CommitLineData
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
24The libseccomp library provides and easy to use, platform independent,
25interface to the Linux Kernel's syscall filtering mechanism: seccomp. The
26libseccomp API is designed to abstract away the underlying BPF based
27syscall filter language and present a more conventional function-call
28based filtering interface that should be familiar to, and easily adopted
29by application developers.
30
31Filter 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
40Argument 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
51Example:
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
73from libc.stdint cimport uint32_t
74import errno
75
76cimport libseccomp
77
78KILL = libseccomp.SCMP_ACT_KILL
79TRAP = libseccomp.SCMP_ACT_TRAP
80ALLOW = libseccomp.SCMP_ACT_ALLOW
81def 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)
87def 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
94NE = libseccomp.SCMP_CMP_NE
95LT = libseccomp.SCMP_CMP_LT
96LE = libseccomp.SCMP_CMP_LE
97EQ = libseccomp.SCMP_CMP_EQ
98GE = libseccomp.SCMP_CMP_GE
99GT = libseccomp.SCMP_CMP_GT
100MASKED_EQ = libseccomp.SCMP_CMP_MASKED_EQ
101
aeac2736
PM
102def 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
110def 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
f05fc7cb 123 if isinstance(syscall, basestring):
7eb16b2b 124 return libseccomp.seccomp_syscall_resolve_name_rewrite(arch, syscall)
f05fc7cb 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
134cdef 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
ab63dc7f 143 AARCH64 - 64-bit ARM
5a703f60
PM
144 MIPS - MIPS O32 ABI
145 MIPS64 - MIPS 64-bit ABI
146 MIPS64N32 - MIPS N32 ABI
147 MIPSEL - MIPS little endian O32 ABI
148 MIPSEL64 - MIPS little endian 64-bit ABI
149 MIPSEL64N32 - MIPS little endian N32 ABI
daed219e 150 PPC64 - 64-bit PowerPC
62c6598e 151 """
aeac2736 152
f05fc7cb
PM
153 cdef int _token
154
62c6598e
PM
155 NATIVE = libseccomp.SCMP_ARCH_NATIVE
156 X86 = libseccomp.SCMP_ARCH_X86
157 X86_64 = libseccomp.SCMP_ARCH_X86_64
e9b5a6eb 158 X32 = libseccomp.SCMP_ARCH_X32
db440d1e 159 ARM = libseccomp.SCMP_ARCH_ARM
ab63dc7f 160 AARCH64 = libseccomp.SCMP_ARCH_AARCH64
2b9c637c 161 MIPS = libseccomp.SCMP_ARCH_MIPS
5a703f60
PM
162 MIPS64 = libseccomp.SCMP_ARCH_MIPS64
163 MIPS64N32 = libseccomp.SCMP_ARCH_MIPS64N32
2b9c637c 164 MIPSEL = libseccomp.SCMP_ARCH_MIPSEL
5a703f60
PM
165 MIPSEL64 = libseccomp.SCMP_ARCH_MIPSEL64
166 MIPSEL64N32 = libseccomp.SCMP_ARCH_MIPSEL64N32
daed219e
PM
167 PPC64 = libseccomp.SCMP_ARCH_PPC64
168 PPC64 = libseccomp.SCMP_ARCH_PPC64LE
62c6598e 169
f05fc7cb
PM
170 def __cinit__(self, arch=libseccomp.SCMP_ARCH_NATIVE):
171 """ Initialize the architecture object.
172
173 Arguments:
174 arch - the architecture name or token value
175
176 Description:
177 Create an architecture object using the given name or token value.
178 """
179 if isinstance(arch, int):
180 if arch == libseccomp.SCMP_ARCH_NATIVE:
181 self._token = libseccomp.seccomp_arch_native()
182 elif arch == libseccomp.SCMP_ARCH_X86:
183 self._token = libseccomp.SCMP_ARCH_X86
184 elif arch == libseccomp.SCMP_ARCH_X86_64:
185 self._token = libseccomp.SCMP_ARCH_X86_64
186 elif arch == libseccomp.SCMP_ARCH_X32:
187 self._token = libseccomp.SCMP_ARCH_X32
188 elif arch == libseccomp.SCMP_ARCH_ARM:
189 self._token = libseccomp.SCMP_ARCH_ARM
ab63dc7f
MJ
190 elif arch == libseccomp.SCMP_ARCH_AARCH64:
191 self._token = libseccomp.SCMP_ARCH_AARCH64
f05fc7cb
PM
192 elif arch == libseccomp.SCMP_ARCH_MIPS:
193 self._token = libseccomp.SCMP_ARCH_MIPS
5a703f60
PM
194 elif arch == libseccomp.SCMP_ARCH_MIPS64:
195 self._token = libseccomp.SCMP_ARCH_MIPS64
196 elif arch == libseccomp.SCMP_ARCH_MIPS64N32:
197 self._token = libseccomp.SCMP_ARCH_MIPS64N32
f05fc7cb
PM
198 elif arch == libseccomp.SCMP_ARCH_MIPSEL:
199 self._token = libseccomp.SCMP_ARCH_MIPSEL
5a703f60
PM
200 elif arch == libseccomp.SCMP_ARCH_MIPSEL64:
201 self._token = libseccomp.SCMP_ARCH_MIPSEL64
202 elif arch == libseccomp.SCMP_ARCH_MIPSEL64N32:
203 self._token = libseccomp.SCMP_ARCH_MIPSEL64N32
daed219e
PM
204 elif arch == libseccomp.SCMP_ARCH_PPC64:
205 self._token = libseccomp.SCMP_ARCH_PPC64
206 elif arch == libseccomp.SCMP_ARCH_PPC64LE:
207 self._token = libseccomp.SCMP_ARCH_PPC64LE
f05fc7cb
PM
208 else:
209 self._token = 0;
210 elif isinstance(arch, basestring):
211 self._token = libseccomp.seccomp_arch_resolve_name(arch)
212 else:
213 raise TypeError("Architecture must be an int or str type")
214 if self._token == 0:
215 raise ValueError("Invalid architecture")
216
217 def __int__(self):
218 """ Convert the architecture object to a token value.
219
220 Description:
221 Convert the architecture object to an integer representing the
222 architecture's token value.
223 """
224 return self._token
225
62c6598e
PM
226cdef class Attr:
227 """ Python object representing the SyscallFilter attributes.
228
229 Data values:
230 ACT_DEFAULT - the filter's default action
231 ACT_BADARCH - the filter's bad architecture action
232 CTL_NNP - the filter's "no new privileges" flag
233 """
234 ACT_DEFAULT = libseccomp.SCMP_FLTATR_ACT_DEFAULT
235 ACT_BADARCH = libseccomp.SCMP_FLTATR_ACT_BADARCH
236 CTL_NNP = libseccomp.SCMP_FLTATR_CTL_NNP
237
238cdef class Arg:
239 """ Python object representing a SyscallFilter syscall argument.
240 """
241 cdef libseccomp.scmp_arg_cmp _arg
242
243 def __cinit__(self, arg, op, datum_a, datum_b = 0):
244 """ Initialize the argument comparison.
245
246 Arguments:
46a0ab2f 247 arg - the argument number, starting at 0
62c6598e
PM
248 op - the argument comparison operator, e.g. {NE,LT,LE,...}
249 datum_a - argument value
250 datum_b - argument value, only valid when op == MASKED_EQ
251
252 Description:
253 Create an argument comparison object for use with SyscallFilter.
254 """
255 self._arg.arg = arg
256 self._arg.op = op
8e1b4634
AL
257 self._arg.datum_a = datum_a
258 self._arg.datum_b = datum_b
62c6598e 259
dd673b51 260 cdef libseccomp.scmp_arg_cmp to_c(self):
62c6598e
PM
261 """ Convert the object into a C structure.
262
263 Description:
264 Helper function which should only be used internally by
265 SyscallFilter objects and exists for the sole purpose of making it
266 easier to deal with the varadic functions of the libseccomp API,
267 e.g. seccomp_rule_add().
268 """
269 return self._arg
270
271cdef class SyscallFilter:
272 """ Python object representing a seccomp syscall filter. """
273 cdef int _defaction
274 cdef libseccomp.scmp_filter_ctx _ctx
275
276 def __cinit__(self, int defaction):
4021195b
AL
277 self._ctx = libseccomp.seccomp_init(defaction)
278 if self._ctx == NULL:
279 raise RuntimeError("Library error")
280 _defaction = defaction
281
282 def __init__(self, defaction):
62c6598e
PM
283 """ Initialize the filter state
284
285 Arguments:
286 defaction - the default filter action
287
288 Description:
289 Initializes the seccomp filter state to the defaults.
290 """
62c6598e
PM
291
292 def __dealloc__(self):
293 """ Destroys the filter state and releases any resources.
294
295 Description:
296 Destroys the seccomp filter state and releases any resources
297 associated with the filter state. This function does not affect
298 any seccomp filters already loaded into the kernel.
299 """
300 if self._ctx != NULL:
301 libseccomp.seccomp_release(self._ctx)
302
303 def reset(self, int defaction = -1):
304 """ Reset the filter state.
305
306 Arguments:
307 defaction - the default filter action
308
309 Description:
310 Resets the seccomp filter state to an initial default state, if a
311 default filter action is not specified in the reset call the
312 original action will be reused. This function does not affect any
313 seccomp filters alread loaded into the kernel.
314 """
315 if defaction == -1:
316 defaction = self._defaction
317 rc = libseccomp.seccomp_reset(self._ctx, defaction)
318 if rc == -errno.EINVAL:
319 raise ValueError("Invalid action")
320 if rc != 0:
321 raise RuntimeError(str.format("Library error (errno = {0})", rc))
322 _defaction = defaction
323
324 def merge(self, SyscallFilter filter):
325 """ Merge two existing SyscallFilter objects.
326
327 Arguments:
328 filter - a valid SyscallFilter object
329
330 Description:
331 Merges a valid SyscallFilter object with the current SyscallFilter
332 object; the passed filter object will be reset on success. In
333 order to successfully merge two seccomp filters they must have the
334 same attribute values and not share any of the same architectures.
335 """
336 rc = libseccomp.seccomp_merge(self._ctx, filter._ctx)
337 if rc != 0:
338 raise RuntimeError(str.format("Library error (errno = {0})", rc))
339 filter._ctx = NULL
340 filter = SyscallFilter(filter._defaction)
341
342 def exist_arch(self, arch):
343 """ Check if the seccomp filter contains a given architecture.
344
345 Arguments:
346 arch - the architecture value, e.g. Arch.*
347
348 Description:
349 Test to see if a given architecture is included in the filter.
350 Return True is the architecture exists, False if it does not
351 exist.
352 """
353 rc = libseccomp.seccomp_arch_exist(self._ctx, arch)
354 if rc == 0:
355 return True
356 elif rc == -errno.EEXIST:
357 return False
358 elif rc == -errno.EINVAL:
359 raise ValueError("Invalid architecture")
360 else:
361 raise RuntimeError(str.format("Library error (errno = {0})", rc))
362
363 def add_arch(self, arch):
364 """ Add an architecture to the filter.
365
366 Arguments:
367 arch - the architecture value, e.g. Arch.*
368
369 Description:
370 Add the given architecture to the filter. Any new rules added
371 after this method returns successfully will be added to this new
372 architecture, but any existing rules will not be added to the new
373 architecture.
374 """
375 rc = libseccomp.seccomp_arch_add(self._ctx, arch)
376 if rc == -errno.EINVAL:
377 raise ValueError("Invalid architecture")
378 elif rc != 0:
379 raise RuntimeError(str.format("Library error (errno = {0})", rc))
380
381 def remove_arch(self, arch):
382 """ Remove an architecture from the filter.
383
384 Arguments:
385 arch - the architecture value, e.g. Arch.*
386
387 Description:
388 Remove the given architecture from the filter. The filter must
389 always contain at least one architecture, so if only one
390 architecture exists in the filter this method will fail.
391 """
392 rc = libseccomp.seccomp_arch_remove(self._ctx, arch)
393 if rc == -errno.EINVAL:
394 raise ValueError("Invalid architecture")
395 elif rc != 0:
396 raise RuntimeError(str.format("Library error (errno = {0})", rc))
397
398 def load(self):
399 """ Load the filter into the Linux Kernel.
400
401 Description:
402 Load the current filter into the Linux Kernel. As soon as the
403 method returns the filter will be active and enforcing.
404 """
405 rc = libseccomp.seccomp_load(self._ctx)
406 if rc != 0:
407 raise RuntimeError(str.format("Library error (errno = {0})", rc))
408
409 def get_attr(self, attr):
410 """ Get an attribute value from the filter.
411
412 Arguments:
413 attr - the attribute, e.g. Attr.*
414
415 Description:
416 Lookup the given attribute in the filter and return the
417 attribute's value to the caller.
418 """
419 value = 0
420 rc = libseccomp.seccomp_attr_get(self._ctx,
421 attr, <uint32_t *>&value)
422 if rc == -errno.EINVAL:
423 raise ValueError("Invalid attribute")
424 elif rc != 0:
425 raise RuntimeError(str.format("Library error (errno = {0})", rc))
426 return value
427
428 def set_attr(self, attr, int value):
429 """ Set a filter attribute.
430
431 Arguments:
432 attr - the attribute, e.g. Attr.*
433 value - the attribute value
434
435 Description:
436 Lookup the given attribute in the filter and assign it the given
437 value.
438 """
439 rc = libseccomp.seccomp_attr_set(self._ctx, attr, value)
440 if rc == -errno.EINVAL:
441 raise ValueError("Invalid attribute")
442 elif rc != 0:
443 raise RuntimeError(str.format("Library error (errno = {0})", rc))
444
445 def syscall_priority(self, syscall, int priority):
446 """ Set the filter priority of a syscall.
447
448 Arguments:
449 syscall - the syscall name or number
450 priority - the priority of the syscall
451
452 Description:
453 Set the filter priority of the given syscall. A syscall with a
454 higher priority will have less overhead in the generated filter
455 code which is loaded into the system. Priority values can range
456 from 0 to 255 inclusive.
457 """
458 if priority < 0 or priority > 255:
6220c8c0 459 raise ValueError("Syscall priority must be between 0 and 255")
62c6598e
PM
460 if isinstance(syscall, str):
461 syscall_str = syscall.encode()
462 syscall_num = libseccomp.seccomp_syscall_resolve_name(syscall_str)
463 elif isinstance(syscall, int):
464 syscall_num = syscall
465 else:
6220c8c0 466 raise TypeError("Syscall must either be an int or str type")
62c6598e
PM
467 rc = libseccomp.seccomp_syscall_priority(self._ctx,
468 syscall_num, priority)
469 if rc != 0:
470 raise RuntimeError(str.format("Library error (errno = {0})", rc))
471
472 def add_rule(self, int action, syscall, *args):
473 """ Add a new rule to filter.
474
475 Arguments:
476 action - the rule action: KILL, TRAP, ERRNO(), TRACE(), or ALLOW
477 syscall - the syscall name or number
478 args - variable number of Arg objects
479
480 Description:
481 Add a new rule to the filter, matching on the given syscall and an
482 optional list of argument comparisons. If the rule is triggered
483 the given action will be taken by the kernel. In order for the
484 rule to trigger, the syscall as well as each argument comparison
485 must be true.
486
487 In the case where the specific rule is not valid on a specific
488 architecture, e.g. socket() on 32-bit x86, this method rewrites
489 the rule to the best possible match. If you don't want this fule
490 rewriting to take place use add_rule_exactly().
491 """
492 cdef libseccomp.scmp_arg_cmp c_arg[6]
493 if isinstance(syscall, str):
494 syscall_str = syscall.encode()
495 syscall_num = libseccomp.seccomp_syscall_resolve_name(syscall_str)
496 elif isinstance(syscall, int):
497 syscall_num = syscall
498 else:
6220c8c0 499 raise TypeError("Syscall must either be an int or str type")
62c6598e
PM
500 """ NOTE: the code below exists solely to deal with the varadic
501 nature of seccomp_rule_add() function and the inability of Cython
502 to handle this automatically """
2f65c7f4
PM
503 if len(args) > 6:
504 raise RuntimeError("Maximum number of arguments exceeded")
dd673b51 505 cdef Arg arg
62c6598e
PM
506 for i, arg in enumerate(args):
507 c_arg[i] = arg.to_c()
508 if len(args) == 0:
509 rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num, 0)
510 elif len(args) == 1:
511 rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num,
512 len(args),
513 c_arg[0])
514 elif len(args) == 2:
515 rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num,
516 len(args),
517 c_arg[0],
518 c_arg[1])
519 elif len(args) == 3:
520 rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num,
521 len(args),
522 c_arg[0],
523 c_arg[1],
524 c_arg[2])
525 elif len(args) == 4:
526 rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num,
527 len(args),
528 c_arg[0],
529 c_arg[1],
530 c_arg[2],
531 c_arg[3])
532 elif len(args) == 5:
533 rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num,
534 len(args),
535 c_arg[0],
536 c_arg[1],
537 c_arg[2],
538 c_arg[3],
539 c_arg[4])
540 elif len(args) == 6:
541 rc = libseccomp.seccomp_rule_add(self._ctx, action, syscall_num,
542 len(args),
543 c_arg[0],
544 c_arg[1],
545 c_arg[2],
546 c_arg[3],
547 c_arg[4],
548 c_arg[5])
549 else:
550 raise RuntimeError("Maximum number of arguments exceeded")
551 if rc != 0:
552 raise RuntimeError(str.format("Library error (errno = {0})", rc))
553
554 def add_rule_exactly(self, int action, syscall, *args):
555 """ Add a new rule to filter.
556
557 Arguments:
558 action - the rule action: KILL, TRAP, ERRNO(), TRACE(), or ALLOW
559 syscall - the syscall name or number
560 args - variable number of Arg objects
561
562 Description:
563 Add a new rule to the filter, matching on the given syscall and an
564 optional list of argument comparisons. If the rule is triggered
565 the given action will be taken by the kernel. In order for the
566 rule to trigger, the syscall as well as each argument comparison
567 must be true.
568
569 This method attempts to add the filter rule exactly as specified
570 which can cause problems on certain architectures, e.g. socket()
571 on 32-bit x86. For a architecture independent version of this
572 method use add_rule().
573 """
574 cdef libseccomp.scmp_arg_cmp c_arg[6]
575 if isinstance(syscall, str):
576 syscall_str = syscall.encode()
577 syscall_num = libseccomp.seccomp_syscall_resolve_name(syscall_str)
578 elif isinstance(syscall, int):
579 syscall_num = syscall
580 else:
6220c8c0 581 raise TypeError("Syscall must either be an int or str type")
62c6598e
PM
582 """ NOTE: the code below exists solely to deal with the varadic
583 nature of seccomp_rule_add_exact() function and the inability of
584 Cython to handle this automatically """
2f65c7f4
PM
585 if len(args) > 6:
586 raise RuntimeError("Maximum number of arguments exceeded")
dd673b51 587 cdef Arg arg
62c6598e
PM
588 for i, arg in enumerate(args):
589 c_arg[i] = arg.to_c()
590 if len(args) == 0:
591 rc = libseccomp.seccomp_rule_add_exact(self._ctx, action,
592 syscall_num, 0)
593 elif len(args) == 1:
594 rc = libseccomp.seccomp_rule_add_exact(self._ctx, action,
595 syscall_num, len(args),
596 c_arg[0])
597 elif len(args) == 2:
598 rc = libseccomp.seccomp_rule_add_exact(self._ctx, action,
599 syscall_num, len(args),
600 c_arg[0],
601 c_arg[1])
602 elif len(args) == 3:
603 rc = libseccomp.seccomp_rule_add_exact(self._ctx, action,
604 syscall_num, len(args),
605 c_arg[0],
606 c_arg[1],
607 c_arg[2])
608 elif len(args) == 4:
609 rc = libseccomp.seccomp_rule_add_exact(self._ctx, action,
610 syscall_num, len(args),
611 c_arg[0],
612 c_arg[1],
613 c_arg[2],
614 c_arg[3])
615 elif len(args) == 5:
616 rc = libseccomp.seccomp_rule_add_exact(self._ctx, action,
617 syscall_num, len(args),
618 c_arg[0],
619 c_arg[1],
620 c_arg[2],
621 c_arg[3],
622 c_arg[4])
623 elif len(args) == 6:
624 rc = libseccomp.seccomp_rule_add_exact(self._ctx, action,
625 syscall_num, len(args),
626 c_arg[0],
627 c_arg[1],
628 c_arg[2],
629 c_arg[3],
630 c_arg[4],
631 c_arg[5])
632 else:
633 raise RuntimeError("Maximum number of arguments exceeded")
634 if rc != 0:
635 raise RuntimeError(str.format("Library error (errno = {0})", rc))
636
637 def export_pfc(self, file):
638 """ Export the filter in PFC format.
639
640 Arguments:
641 file - the output file
642
643 Description:
644 Output the filter in Pseudo Filter Code (PFC) to the given file.
645 The output is functionally equivalent to the BPF based filter
646 which is loaded into the Linux Kernel.
647 """
648 rc = libseccomp.seccomp_export_pfc(self._ctx, file.fileno())
649 if rc != 0:
650 raise RuntimeError(str.format("Library error (errno = {0})", rc))
651
652 def export_bpf(self, file):
653 """ Export the filter in BPF format.
654
655 Arguments:
656 file - the output file
657
658 Output the filter in Berkley Packet Filter (BPF) to the given
659 file. The output is identical to what is loaded into the
660 Linux Kernel.
661 """
662 rc = libseccomp.seccomp_export_bpf(self._ctx, file.fileno())
663 if rc != 0:
664 raise RuntimeError(str.format("Library error (errno = {0})", rc))
665
666# kate: syntax python;
667# kate: indent-mode python; space-indent on; indent-width 4; mixedindent off;