summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2017-03-08 21:13:31 -0800
committerPaul Moore <paul@paul-moore.com>2021-10-08 14:36:40 -0400
commit3f0e47fe2717b73ccef68ca18f9f7297ee73ebb2 (patch)
treef6fabaa1a81f54371f4744b5075c8b66de7d0a7a /src
parent50da6c1c61c1237cc3af2240b294af66de505018 (diff)
downloadlibseccomp-3f0e47fe2717b73ccef68ca18f9f7297ee73ebb2.tar.gz
api: extend BPF export API to write to a memory buffer
The API to export to a fd is helpful, but for tools that want to generate & read the BPF program, outputting to a buffer would be much more helpful. Signed-off-by: Mike Frysinger <vapier@gentoo.org> Reviewed-by: Tom Hromatka <tom.hromatka@oracle.com> [PM: rename seccomp_export_bpf_buf() to seccomp_export_bpf_mem()] [PM: 'make check-syntax' fixes] Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'src')
-rw-r--r--src/api.c34
-rw-r--r--src/python/libseccomp.pxd2
-rw-r--r--src/python/seccomp.pyx25
3 files changed, 61 insertions, 0 deletions
diff --git a/src/api.c b/src/api.c
index 5cec088..423a1c5 100644
--- a/src/api.c
+++ b/src/api.c
@@ -83,6 +83,8 @@ static int _rc_filter(int err)
* requested operation */
case -EOPNOTSUPP:
/* NOTE: operation is not supported */
+ case -ERANGE:
+ /* NOTE: provided buffer is too small */
case -ESRCH:
/* NOTE: operation failed due to multi-threading */
return err;
@@ -731,3 +733,35 @@ API int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd)
return 0;
}
+
+/* NOTE - function header comment in include/seccomp.h */
+API int seccomp_export_bpf_mem(const scmp_filter_ctx ctx, void *buf,
+ size_t *len)
+{
+ int rc;
+ size_t buf_len;
+ struct db_filter_col *col;
+ struct bpf_program *program;
+
+ if (_ctx_valid(ctx) || !len)
+ return _rc_filter(-EINVAL);
+ col = (struct db_filter_col *)ctx;
+
+ rc = gen_bpf_generate(col, &program);
+ if (rc < 0)
+ return _rc_filter(rc);
+ buf_len = *len;
+ *len = BPF_PGM_SIZE(program);
+
+ rc = 0;
+ if (buf) {
+ /* If we have a big enough buffer, write the program. */
+ if (*len > buf_len)
+ rc = _rc_filter(-ERANGE);
+ else
+ memcpy(buf, program->blks, *len);
+ }
+ gen_bpf_release(program);
+
+ return rc;
+}
diff --git a/src/python/libseccomp.pxd b/src/python/libseccomp.pxd
index 0629bf1..6175c8a 100644
--- a/src/python/libseccomp.pxd
+++ b/src/python/libseccomp.pxd
@@ -167,6 +167,8 @@ cdef extern from "seccomp.h":
int seccomp_export_pfc(scmp_filter_ctx ctx, int fd)
int seccomp_export_bpf(scmp_filter_ctx ctx, int fd)
+ int seccomp_export_bpf_mem(const scmp_filter_ctx ctx, void *buf,
+ size_t *len)
# kate: syntax python;
# kate: indent-mode python; space-indent on; indent-width 4; mixedindent off;
diff --git a/src/python/seccomp.pyx b/src/python/seccomp.pyx
index 2eeabc1..73f6625 100644
--- a/src/python/seccomp.pyx
+++ b/src/python/seccomp.pyx
@@ -80,10 +80,12 @@ Example:
__author__ = 'Paul Moore <paul@paul-moore.com>'
__date__ = "3 February 2017"
+from cpython cimport array
from cpython.version cimport PY_MAJOR_VERSION
from libc.stdint cimport int8_t, int16_t, int32_t, int64_t
from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t
from libc.stdlib cimport free
+import array
import errno
cimport libseccomp
@@ -1044,5 +1046,28 @@ cdef class SyscallFilter:
if rc != 0:
raise RuntimeError(str.format("Library error (errno = {0})", rc))
+ def export_bpf_mem(self):
+ """ Export the filter in BPF format.
+
+ Description:
+ Return the filter in Berkeley Packet Filter (BPF) as bytes.
+ The output is identical to what is loaded into the Linux Kernel.
+ """
+ cdef size_t len = 0
+
+ # Figure out how big the program is.
+ rc = libseccomp.seccomp_export_bpf_mem(self._ctx, NULL, <size_t *>&len)
+ if rc != 0:
+ raise RuntimeError(str.format("Library error (errno = {0})", rc))
+
+ # Get the program.
+ cdef array.array data = array.array('b', bytes(len))
+ cdef char[:] program = data
+ rc = libseccomp.seccomp_export_bpf_mem(self._ctx, <void *>&program[0],
+ <size_t *>&len)
+ if rc != 0:
+ raise RuntimeError(str.format("Library error (errno = {0})", rc))
+ return program
+
# kate: syntax python;
# kate: indent-mode python; space-indent on; indent-width 4; mixedindent off;