From 7b96cd6ded2668b04c908737ff393b805d34cc5c Mon Sep 17 00:00:00 2001 From: Ophestra Date: Sat, 25 Jan 2025 13:19:38 +0900 Subject: helper/seccomp: do not call F_println if not verbose This (slightly) improves performance. Signed-off-by: Ophestra --- helper/bwrap/seccomp-resolve.go | 90 ----------------------------------------- helper/bwrap/seccomp.go | 90 +++++++++++++++++++++++++++++++++++++++++ helper/seccomp/seccomp-export.c | 2 +- helper/seccomp/seccomp-export.h | 17 ++++---- helper/seccomp/seccomp.go | 7 ++++ 5 files changed, 107 insertions(+), 99 deletions(-) delete mode 100644 helper/bwrap/seccomp-resolve.go create mode 100644 helper/bwrap/seccomp.go diff --git a/helper/bwrap/seccomp-resolve.go b/helper/bwrap/seccomp-resolve.go deleted file mode 100644 index 860d720b..00000000 --- a/helper/bwrap/seccomp-resolve.go +++ /dev/null @@ -1,90 +0,0 @@ -package bwrap - -import ( - "fmt" - "os" - - "git.gensokyo.uk/security/fortify/helper/seccomp" - "git.gensokyo.uk/security/fortify/internal/fmsg" -) - -type SyscallPolicy struct { - // disable fortify extensions - Compat bool `json:"compat"` - // deny development syscalls - DenyDevel bool `json:"deny_devel"` - // deny multiarch/emulation syscalls - Multiarch bool `json:"multiarch"` - // allow PER_LINUX32 - Linux32 bool `json:"linux32"` - // allow AF_CAN - Can bool `json:"can"` - // allow AF_BLUETOOTH - Bluetooth bool `json:"bluetooth"` -} - -type seccompBuilder struct { - config *Config -} - -func (s *seccompBuilder) Len() int { - if s == nil { - return 0 - } - return 2 -} - -func (s *seccompBuilder) Append(args *[]string, extraFiles *[]*os.File) error { - if s == nil { - return nil - } - if f, err := s.config.resolveSeccomp(); err != nil { - return err - } else { - extraFile(args, extraFiles, positionalArgs[Seccomp], f) - return nil - } -} - -func (c *Config) resolveSeccomp() (*os.File, error) { - if c.Syscall == nil { - return nil, nil - } - - // resolve seccomp filter opts - var ( - opts seccomp.SyscallOpts - optd []string - optCond = [...]struct { - v bool - o seccomp.SyscallOpts - d string - }{ - {!c.Syscall.Compat, seccomp.FlagExt, "fortify"}, - {!c.UserNS, seccomp.FlagDenyNS, "denyns"}, - {c.NewSession, seccomp.FlagDenyTTY, "denytty"}, - {c.Syscall.DenyDevel, seccomp.FlagDenyDevel, "denydevel"}, - {c.Syscall.Multiarch, seccomp.FlagMultiarch, "multiarch"}, - {c.Syscall.Linux32, seccomp.FlagLinux32, "linux32"}, - {c.Syscall.Can, seccomp.FlagCan, "can"}, - {c.Syscall.Bluetooth, seccomp.FlagBluetooth, "bluetooth"}, - } - ) - if seccomp.CPrintln != nil { - optd = make([]string, 1, len(optCond)+1) - optd[0] = "common" - } - for _, opt := range optCond { - if opt.v { - opts |= opt.o - if fmsg.Verbose() { - optd = append(optd, opt.d) - } - } - } - if seccomp.CPrintln != nil { - seccomp.CPrintln(fmt.Sprintf("seccomp flags: %s", optd)) - } - - return seccomp.Export(opts) -} diff --git a/helper/bwrap/seccomp.go b/helper/bwrap/seccomp.go new file mode 100644 index 00000000..860d720b --- /dev/null +++ b/helper/bwrap/seccomp.go @@ -0,0 +1,90 @@ +package bwrap + +import ( + "fmt" + "os" + + "git.gensokyo.uk/security/fortify/helper/seccomp" + "git.gensokyo.uk/security/fortify/internal/fmsg" +) + +type SyscallPolicy struct { + // disable fortify extensions + Compat bool `json:"compat"` + // deny development syscalls + DenyDevel bool `json:"deny_devel"` + // deny multiarch/emulation syscalls + Multiarch bool `json:"multiarch"` + // allow PER_LINUX32 + Linux32 bool `json:"linux32"` + // allow AF_CAN + Can bool `json:"can"` + // allow AF_BLUETOOTH + Bluetooth bool `json:"bluetooth"` +} + +type seccompBuilder struct { + config *Config +} + +func (s *seccompBuilder) Len() int { + if s == nil { + return 0 + } + return 2 +} + +func (s *seccompBuilder) Append(args *[]string, extraFiles *[]*os.File) error { + if s == nil { + return nil + } + if f, err := s.config.resolveSeccomp(); err != nil { + return err + } else { + extraFile(args, extraFiles, positionalArgs[Seccomp], f) + return nil + } +} + +func (c *Config) resolveSeccomp() (*os.File, error) { + if c.Syscall == nil { + return nil, nil + } + + // resolve seccomp filter opts + var ( + opts seccomp.SyscallOpts + optd []string + optCond = [...]struct { + v bool + o seccomp.SyscallOpts + d string + }{ + {!c.Syscall.Compat, seccomp.FlagExt, "fortify"}, + {!c.UserNS, seccomp.FlagDenyNS, "denyns"}, + {c.NewSession, seccomp.FlagDenyTTY, "denytty"}, + {c.Syscall.DenyDevel, seccomp.FlagDenyDevel, "denydevel"}, + {c.Syscall.Multiarch, seccomp.FlagMultiarch, "multiarch"}, + {c.Syscall.Linux32, seccomp.FlagLinux32, "linux32"}, + {c.Syscall.Can, seccomp.FlagCan, "can"}, + {c.Syscall.Bluetooth, seccomp.FlagBluetooth, "bluetooth"}, + } + ) + if seccomp.CPrintln != nil { + optd = make([]string, 1, len(optCond)+1) + optd[0] = "common" + } + for _, opt := range optCond { + if opt.v { + opts |= opt.o + if fmsg.Verbose() { + optd = append(optd, opt.d) + } + } + } + if seccomp.CPrintln != nil { + seccomp.CPrintln(fmt.Sprintf("seccomp flags: %s", optd)) + } + + return seccomp.Export(opts) +} diff --git a/helper/seccomp/seccomp-export.c b/helper/seccomp/seccomp-export.c index 78d27e0b..855c3bf0 100644 --- a/helper/seccomp/seccomp-export.c +++ b/helper/seccomp/seccomp-export.c @@ -28,7 +28,7 @@ struct f_syscall_act { #define LEN(arr) (sizeof(arr) / sizeof((arr)[0])) #define SECCOMP_RULESET_ADD(ruleset) do { \ - F_println("adding seccomp ruleset \"" #ruleset "\""); \ + if (opts & F_VERBOSE) F_println("adding seccomp ruleset \"" #ruleset "\""); \ for (int i = 0; i < LEN(ruleset); i++) { \ assert(ruleset[i].m_errno == EPERM || ruleset[i].m_errno == ENOSYS); \ \ diff --git a/helper/seccomp/seccomp-export.h b/helper/seccomp/seccomp-export.h index 90640d8f..3a28b127 100644 --- a/helper/seccomp/seccomp-export.h +++ b/helper/seccomp/seccomp-export.h @@ -8,14 +8,15 @@ #endif typedef enum { - F_EXT = 1 << 0, - F_DENY_NS = 1 << 1, - F_DENY_TTY = 1 << 2, - F_DENY_DEVEL = 1 << 3, - F_MULTIARCH = 1 << 4, - F_LINUX32 = 1 << 5, - F_CAN = 1 << 6, - F_BLUETOOTH = 1 << 7, + F_VERBOSE = 1 << 0, + F_EXT = 1 << 1, + F_DENY_NS = 1 << 2, + F_DENY_TTY = 1 << 3, + F_DENY_DEVEL = 1 << 4, + F_MULTIARCH = 1 << 5, + F_LINUX32 = 1 << 6, + F_CAN = 1 << 7, + F_BLUETOOTH = 1 << 8, } f_syscall_opts; extern void F_println(char *v); diff --git a/helper/seccomp/seccomp.go b/helper/seccomp/seccomp.go index b3294672..ed13118a 100644 --- a/helper/seccomp/seccomp.go +++ b/helper/seccomp/seccomp.go @@ -28,6 +28,7 @@ var resErr = [...]error{ type SyscallOpts = C.f_syscall_opts const ( + flagVerbose SyscallOpts = C.F_VERBOSE FlagExt SyscallOpts = C.F_EXT FlagDenyNS SyscallOpts = C.F_DENY_NS FlagDenyTTY SyscallOpts = C.F_DENY_TTY @@ -64,6 +65,12 @@ func exportFilter(fd uintptr, opts SyscallOpts) error { multiarch = C.SCMP_ARCH_ARM } + // this removes repeated transitions between C and Go execution + // when producing log output via F_println and CPrintln is nil + if CPrintln != nil { + opts |= flagVerbose + } + res, err := C.f_export_bpf(C.int(fd), arch, multiarch, opts) if re := resErr[res]; re != nil { if err == nil { -- cgit v1.3.1