diff --git a/helper/seccomp/api.go b/helper/seccomp/api.go index 2799fc9..697b09f 100644 --- a/helper/seccomp/api.go +++ b/helper/seccomp/api.go @@ -11,6 +11,9 @@ import ( // New returns an inactive Encoder instance. func New(opts SyscallOpts) *Encoder { return &Encoder{newExporter(opts)} } +// Load loads a filter into the kernel. +func Load(opts SyscallOpts) error { return buildFilter(-1, opts) } + /* An Encoder writes a BPF program to an output stream. diff --git a/helper/seccomp/export.go b/helper/seccomp/export.go index 9efee3b..9568423 100644 --- a/helper/seccomp/export.go +++ b/helper/seccomp/export.go @@ -28,7 +28,7 @@ func (e *exporter) prepare() error { ec := make(chan error, 1) go func(fd uintptr) { - ec <- exportFilter(fd, e.opts) + ec <- buildFilter(int(fd), e.opts) close(ec) _ = e.closeWrite() runtime.KeepAlive(e.w) diff --git a/helper/seccomp/seccomp-export.c b/helper/seccomp/seccomp-build.c similarity index 96% rename from helper/seccomp/seccomp-export.c rename to helper/seccomp/seccomp-build.c index 5a3a56b..827d3b8 100644 --- a/helper/seccomp/seccomp-export.c +++ b/helper/seccomp/seccomp-build.c @@ -2,7 +2,7 @@ #define _GNU_SOURCE // CLONE_NEWUSER #endif -#include "seccomp-export.h" +#include "seccomp-build.h" #include #include #include @@ -48,7 +48,7 @@ struct f_syscall_act { } \ } while (0) -int32_t f_export_bpf(int fd, uint32_t arch, uint32_t multiarch, f_syscall_opts opts) { +int32_t f_build_filter(int fd, uint32_t arch, uint32_t multiarch, f_syscall_opts opts) { int32_t res = 0; // refer to resErr for meaning int allow_multiarch = opts & F_MULTIARCH; int allowed_personality = PER_LINUX; @@ -285,11 +285,20 @@ int32_t f_export_bpf(int fd, uint32_t arch, uint32_t multiarch, f_syscall_opts o // Blocklist the rest seccomp_rule_add_exact(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_GE, last_allowed_family + 1)); - ret = seccomp_export_bpf(ctx, fd); - if (ret != 0) { - res = 6; - errno = -ret; - goto out; + if (fd < 0) { + ret = seccomp_load(ctx); + if (ret != 0) { + res = 7; + errno = -ret; + goto out; + } + } else { + ret = seccomp_export_bpf(ctx, fd); + if (ret != 0) { + res = 6; + errno = -ret; + goto out; + } } out: diff --git a/helper/seccomp/seccomp-export.h b/helper/seccomp/seccomp-build.h similarity index 86% rename from helper/seccomp/seccomp-export.h rename to helper/seccomp/seccomp-build.h index df158d9..0ae201d 100644 --- a/helper/seccomp/seccomp-export.h +++ b/helper/seccomp/seccomp-build.h @@ -20,4 +20,4 @@ typedef enum { } f_syscall_opts; extern void F_println(char *v); -int32_t f_export_bpf(int fd, uint32_t arch, uint32_t multiarch, f_syscall_opts opts); \ No newline at end of file +int32_t f_build_filter(int fd, uint32_t arch, uint32_t multiarch, f_syscall_opts opts); \ No newline at end of file diff --git a/helper/seccomp/seccomp.go b/helper/seccomp/seccomp.go index a8cf8bb..fc19247 100644 --- a/helper/seccomp/seccomp.go +++ b/helper/seccomp/seccomp.go @@ -3,7 +3,7 @@ package seccomp /* #cgo linux pkg-config: --static libseccomp -#include "seccomp-export.h" +#include "seccomp-build.h" */ import "C" import ( @@ -22,6 +22,7 @@ var resErr = [...]error{ 4: errors.New("internal libseccomp failure"), 5: errors.New("seccomp_rule_add failed"), 6: errors.New("seccomp_export_bpf failed"), + 7: errors.New("seccomp_load failed"), } type SyscallOpts = C.f_syscall_opts @@ -46,7 +47,7 @@ const ( FlagBluetooth SyscallOpts = C.F_BLUETOOTH ) -func exportFilter(fd uintptr, opts SyscallOpts) error { +func buildFilter(fd int, opts SyscallOpts) error { var ( arch C.uint32_t = 0 multiarch C.uint32_t = 0 @@ -70,7 +71,7 @@ func exportFilter(fd uintptr, opts SyscallOpts) error { opts |= flagVerbose } - res, err := C.f_export_bpf(C.int(fd), arch, multiarch, opts) + res, err := C.f_build_filter(C.int(fd), arch, multiarch, opts) if re := resErr[res]; re != nil { if err == nil { return re