From 9a239fa1a5ad2ff248ca7a9d39342f66926c9fef Mon Sep 17 00:00:00 2001 From: Ophestra Date: Wed, 22 Jan 2025 01:51:10 +0900 Subject: [PATCH] helper/bwrap: integrate seccomp into helper interface This makes API usage much cleaner, and encapsulates all bwrap arguments in argsWt. Signed-off-by: Ophestra --- dbus/proxy.go | 2 +- dbus/run.go | 2 +- fst/config.go | 10 -- fst/sandbox.go | 7 + helper/bwrap.go | 41 +++--- helper/bwrap/arg.go | 63 ++++++++- helper/bwrap/config.go | 5 +- .../export.c => helper/bwrap/seccomp-export.c | 2 +- .../export.h => helper/bwrap/seccomp-export.h | 0 helper/bwrap/seccomp-resolve.go | 95 ++++++++++++++ .../priv/shim => helper/bwrap}/seccomp.go | 12 +- helper/bwrap/sequential.go | 6 + helper/bwrap_test.go | 12 +- internal/app/app_pd_test.go | 2 + internal/app/seal.go | 13 +- internal/app/start.go | 9 +- internal/proc/priv/shim/main.go | 120 +----------------- internal/proc/priv/shim/payload.go | 3 - internal/system/dbus.go | 2 +- ldd/exec.go | 3 +- main.go | 2 +- 21 files changed, 224 insertions(+), 187 deletions(-) rename internal/proc/priv/shim/export.c => helper/bwrap/seccomp-export.c (99%) rename internal/proc/priv/shim/export.h => helper/bwrap/seccomp-export.h (100%) create mode 100644 helper/bwrap/seccomp-resolve.go rename {internal/proc/priv/shim => helper/bwrap}/seccomp.go (92%) diff --git a/dbus/proxy.go b/dbus/proxy.go index 9f78648..59b887d 100644 --- a/dbus/proxy.go +++ b/dbus/proxy.go @@ -66,7 +66,7 @@ func (p *Proxy) String() string { return "(unsealed dbus proxy)" } -func (p *Proxy) Bwrap() []string { +func (p *Proxy) BwrapStatic() []string { return p.bwrap.Args() } diff --git a/dbus/run.go b/dbus/run.go index addf522..0a554bf 100644 --- a/dbus/run.go +++ b/dbus/run.go @@ -110,7 +110,7 @@ func (p *Proxy) Start(ready chan error, output io.Writer, sandbox bool) error { bc.Bind(k, k) } - h = helper.MustNewBwrap(bc, toolPath, p.seal, argF, nil) + h = helper.MustNewBwrap(bc, toolPath, p.seal, argF, nil, nil) cmd = h.Unwrap() p.bwrap = bc } diff --git a/fst/config.go b/fst/config.go index ed0ac4c..72cb202 100644 --- a/fst/config.go +++ b/fst/config.go @@ -31,8 +31,6 @@ type ConfinementConfig struct { Outer string `json:"home"` // bwrap sandbox confinement configuration Sandbox *SandboxConfig `json:"sandbox"` - // seccomp syscall filter configuration - Syscall *SyscallConfig `json:"syscall"` // extra acl entries to append ExtraPerms []*ExtraPermConfig `json:"extra_perms,omitempty"` @@ -47,14 +45,6 @@ type ConfinementConfig struct { Enablements system.Enablements `json:"enablements"` } -type SyscallConfig struct { - DenyDevel bool `json:"deny_devel"` - Multiarch bool `json:"multiarch"` - Linux32 bool `json:"linux32"` - Can bool `json:"can"` - Bluetooth bool `json:"bluetooth"` -} - type ExtraPermConfig struct { Ensure bool `json:"ensure,omitempty"` Path string `json:"path"` diff --git a/fst/sandbox.go b/fst/sandbox.go index 8def908..0c3918a 100644 --- a/fst/sandbox.go +++ b/fst/sandbox.go @@ -22,6 +22,8 @@ type SandboxConfig struct { Net bool `json:"net,omitempty"` // share all devices Dev bool `json:"dev,omitempty"` + // seccomp syscall filter policy + Syscall *bwrap.SyscallPolicy `json:"syscall"` // do not run in new session NoNewSession bool `json:"no_new_session,omitempty"` // map target user uid to privileged user uid in the user namespace @@ -50,6 +52,10 @@ func (s *SandboxConfig) Bwrap(os linux.System) (*bwrap.Config, error) { return nil, errors.New("nil sandbox config") } + if s.Syscall == nil { + fmsg.VPrintln("syscall filter not configured, PROCEED WITH CAUTION") + } + var uid int if !s.MapRealUID { uid = 65534 @@ -69,6 +75,7 @@ func (s *SandboxConfig) Bwrap(os linux.System) (*bwrap.Config, error) { so this capacity should eliminate copies for most setups */ Filesystem: make([]bwrap.FSBuilder, 0, 256), + Syscall: s.Syscall, NewSession: !s.NoNewSession, DieWithParent: true, AsInit: true, diff --git a/helper/bwrap.go b/helper/bwrap.go index ad07731..851f244 100644 --- a/helper/bwrap.go +++ b/helper/bwrap.go @@ -9,25 +9,17 @@ import ( "sync" "git.gensokyo.uk/security/fortify/helper/bwrap" - "git.gensokyo.uk/security/fortify/internal/proc" ) // BubblewrapName is the file name or path to bubblewrap. var BubblewrapName = "bwrap" -type BwrapExtraFile struct { - Name string - File *os.File -} - type bubblewrap struct { // bwrap child file name name string // bwrap pipes control *pipes - // extra files with fd passed as argument - extra []BwrapExtraFile // returns an array of arguments passed directly // to the child process spawned by bwrap argF func(argsFD, statFD int) []string @@ -54,14 +46,6 @@ func (b *bubblewrap) StartNotify(ready chan error) error { return errors.New("exec: already started") } - // pass extra fd to bwrap - for _, e := range b.extra { - if e.File == nil { - continue - } - b.Cmd.Args = append(b.Cmd.Args, e.Name, strconv.Itoa(int(proc.ExtraFile(b.Cmd, e.File)))) - } - // prepare bwrap pipe and args if argsFD, _, err := b.control.prepareCmd(b.Cmd); err != nil { return err @@ -130,9 +114,10 @@ func (b *bubblewrap) Unwrap() *exec.Cmd { func MustNewBwrap( conf *bwrap.Config, name string, wt io.WriterTo, argF func(argsFD, statFD int) []string, - extra []BwrapExtraFile, + extraFiles []*os.File, + syncFd *os.File, ) Helper { - b, err := NewBwrap(conf, name, wt, argF, extra) + b, err := NewBwrap(conf, name, wt, argF, extraFiles, syncFd) if err != nil { panic(err.Error()) } else { @@ -146,23 +131,27 @@ func MustNewBwrap( func NewBwrap( conf *bwrap.Config, name string, wt io.WriterTo, argF func(argsFD, statFD int) []string, - extra []BwrapExtraFile, + extraFiles []*os.File, + syncFd *os.File, ) (Helper, error) { b := new(bubblewrap) - if args, err := NewCheckedArgs(conf.Args()); err != nil { - return nil, err - } else { - b.control = &pipes{args: args} - } - - b.extra = extra b.argF = argF b.name = name if wt != nil { b.controlPt = &pipes{args: wt} } + b.Cmd = execCommand(BubblewrapName) + b.control = new(pipes) + args := conf.Args() + if fdArgs, err := conf.FDArgs(syncFd, &extraFiles); err != nil { + return nil, err + } else if b.control.args, err = NewCheckedArgs(append(args, fdArgs...)); err != nil { + return nil, err + } else { + b.Cmd.ExtraFiles = extraFiles + } return b, nil } diff --git a/helper/bwrap/arg.go b/helper/bwrap/arg.go index efdab82..d419ba5 100644 --- a/helper/bwrap/arg.go +++ b/helper/bwrap/arg.go @@ -1,6 +1,13 @@ package bwrap -import "encoding/gob" +import ( + "encoding/gob" + "os" + "slices" + "strconv" + + "git.gensokyo.uk/security/fortify/internal/proc" +) type Builder interface { Len() int @@ -12,6 +19,11 @@ type FSBuilder interface { Builder } +type FDBuilder interface { + Len() int + Append(args *[]string, extraFiles *[]*os.File) error +} + func init() { gob.Register(new(pairF)) gob.Register(new(stringF)) @@ -45,6 +57,33 @@ func (s stringF) Append(args *[]string) { *args = append(*args, s[0], s[1]) } +type fileF struct { + name string + file *os.File +} + +func (f *fileF) Len() int { + if f.file == nil { + return 0 + } + return 2 +} + +func (f *fileF) Append(args *[]string, extraFiles *[]*os.File) error { + if f.file == nil { + return nil + } + extraFile(args, extraFiles, f.name, f.file) + return nil +} + +func extraFile(args *[]string, extraFiles *[]*os.File, name string, f *os.File) { + if f == nil { + return + } + *args = append(*args, name, strconv.Itoa(int(proc.ExtraFileSlice(extraFiles, f)))) +} + // Args returns a slice of bwrap args corresponding to c. func (c *Config) Args() (args []string) { builders := []Builder{ @@ -75,3 +114,25 @@ func (c *Config) Args() (args []string) { return } + +func (c *Config) FDArgs(syncFd *os.File, extraFiles *[]*os.File) (args []string, err error) { + builders := []FDBuilder{ + &seccompBuilder{c}, + &fileF{positionalArgs[SyncFd], syncFd}, + } + + argc := 0 + for _, b := range builders { + argc += b.Len() + } + + args = make([]string, 0, argc) + *extraFiles = slices.Grow(*extraFiles, len(builders)) + + for _, b := range builders { + if err = b.Append(&args, extraFiles); err != nil { + break + } + } + return +} diff --git a/helper/bwrap/config.go b/helper/bwrap/config.go index 8def27a..b9fa0c1 100644 --- a/helper/bwrap/config.go +++ b/helper/bwrap/config.go @@ -47,6 +47,10 @@ type Config struct { // (--chmod OCTAL PATH) Chmod ChmodConfig `json:"chmod,omitempty"` + // load and use seccomp rules from FD (not repeatable) + // (--seccomp FD) + Syscall *SyscallPolicy + // create a new terminal session // (--new-session) NewSession bool `json:"new_session"` @@ -70,7 +74,6 @@ type Config struct { --file FD DEST Copy from FD to destination DEST --bind-data FD DEST Copy from FD to file which is bind-mounted on DEST --ro-bind-data FD DEST Copy from FD to file which is readonly bind-mounted on DEST - --seccomp FD Load and use seccomp rules from FD (not repeatable) --add-seccomp-fd FD Load and use seccomp rules from FD (repeatable) --block-fd FD Block on FD until some data to read is available --userns-block-fd FD Block on FD until the user namespace is ready diff --git a/internal/proc/priv/shim/export.c b/helper/bwrap/seccomp-export.c similarity index 99% rename from internal/proc/priv/shim/export.c rename to helper/bwrap/seccomp-export.c index 404dd13..40e3bea 100644 --- a/internal/proc/priv/shim/export.c +++ b/helper/bwrap/seccomp-export.c @@ -2,7 +2,7 @@ #define _GNU_SOURCE // CLONE_NEWUSER #endif -#include "export.h" +#include "seccomp-export.h" #include #include #include diff --git a/internal/proc/priv/shim/export.h b/helper/bwrap/seccomp-export.h similarity index 100% rename from internal/proc/priv/shim/export.h rename to helper/bwrap/seccomp-export.h diff --git a/helper/bwrap/seccomp-resolve.go b/helper/bwrap/seccomp-resolve.go new file mode 100644 index 0000000..995a371 --- /dev/null +++ b/helper/bwrap/seccomp-resolve.go @@ -0,0 +1,95 @@ +package bwrap + +import ( + "fmt" + "io" + "os" + + "git.gensokyo.uk/security/fortify/internal/fmsg" +) + +type SyscallPolicy struct { + DenyDevel bool `json:"deny_devel"` + Multiarch bool `json:"multiarch"` + Linux32 bool `json:"linux32"` + Can bool `json:"can"` + 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 syscallOpts + optd []string + optCond = [...]struct { + v bool + o syscallOpts + d string + }{ + {!c.UserNS, flagDenyNS, "denyns"}, + {c.NewSession, flagDenyTTY, "denytty"}, + {c.Syscall.DenyDevel, flagDenyDevel, "denydevel"}, + {c.Syscall.Multiarch, flagMultiarch, "multiarch"}, + {c.Syscall.Linux32, flagLinux32, "linux32"}, + {c.Syscall.Can, flagCan, "can"}, + {c.Syscall.Bluetooth, flagBluetooth, "bluetooth"}, + } + ) + if 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 CPrintln != nil { + CPrintln(fmt.Sprintf("seccomp flags: %s", optd)) + } + + // export seccomp filter to tmpfile + if f, err := tmpfile(); err != nil { + return nil, err + } else { + return f, exportAndSeek(f, opts) + } +} + +func exportAndSeek(f *os.File, opts syscallOpts) error { + if err := exportFilter(f.Fd(), opts); err != nil { + return err + } + _, err := f.Seek(0, io.SeekStart) + return err +} diff --git a/internal/proc/priv/shim/seccomp.go b/helper/bwrap/seccomp.go similarity index 92% rename from internal/proc/priv/shim/seccomp.go rename to helper/bwrap/seccomp.go index bf45874..abc2738 100644 --- a/internal/proc/priv/shim/seccomp.go +++ b/helper/bwrap/seccomp.go @@ -1,9 +1,9 @@ -package shim +package bwrap /* #cgo linux pkg-config: --static libseccomp -#include "export.h" +#include "seccomp-export.h" */ import "C" import ( @@ -11,10 +11,10 @@ import ( "fmt" "os" "runtime" - - "git.gensokyo.uk/security/fortify/internal/fmsg" ) +var CPrintln func(v ...any) + var resErr = [...]error{ 0: nil, 1: errors.New("seccomp_init failed"), @@ -77,5 +77,7 @@ func exportFilter(fd uintptr, opts syscallOpts) error { //export F_println func F_println(v *C.char) { - fmsg.VPrintln(C.GoString(v)) + if CPrintln != nil { + CPrintln(C.GoString(v)) + } } diff --git a/helper/bwrap/sequential.go b/helper/bwrap/sequential.go index 42a4b2b..1776c23 100644 --- a/helper/bwrap/sequential.go +++ b/helper/bwrap/sequential.go @@ -43,6 +43,9 @@ const ( Overlay TmpOverlay ROOverlay + + SyncFd + Seccomp ) var positionalArgs = [...]string{ @@ -70,6 +73,9 @@ var positionalArgs = [...]string{ Overlay: "--overlay", TmpOverlay: "--tmp-overlay", ROOverlay: "--ro-overlay", + + SyncFd: "--sync-fd", + Seccomp: "--seccomp", } type PermConfig[T FSBuilder] struct { diff --git a/helper/bwrap_test.go b/helper/bwrap_test.go index 9a565a4..0860d57 100644 --- a/helper/bwrap_test.go +++ b/helper/bwrap_test.go @@ -34,7 +34,7 @@ func TestBwrap(t *testing.T) { h := helper.MustNewBwrap( sc, "fortify", argsWt, argF, - nil, + nil, nil, ) if err := h.Start(); !errors.Is(err, os.ErrNotExist) { @@ -47,7 +47,7 @@ func TestBwrap(t *testing.T) { if got := helper.MustNewBwrap( sc, "fortify", argsWt, argF, - nil, + nil, nil, ); got == nil { t.Errorf("MustNewBwrap(%#v, %#v, %#v) got nil", sc, argsWt, "fortify") @@ -67,7 +67,7 @@ func TestBwrap(t *testing.T) { helper.MustNewBwrap( &bwrap.Config{Hostname: "\x00"}, "fortify", nil, argF, - nil, + nil, nil, ) }) @@ -84,7 +84,7 @@ func TestBwrap(t *testing.T) { helper.MustNewBwrap( sc, "fortify", nil, argF, - nil, + nil, nil, ).StartNotify(make(chan error)))) }) @@ -94,7 +94,7 @@ func TestBwrap(t *testing.T) { h := helper.MustNewBwrap( sc, "crash-test-dummy", nil, argFChecked, - nil, + nil, nil, ) cmd := h.Unwrap() @@ -127,6 +127,6 @@ func TestBwrap(t *testing.T) { }) t.Run("implementation compliance", func(t *testing.T) { - testHelper(t, func() helper.Helper { return helper.MustNewBwrap(sc, "crash-test-dummy", argsWt, argF, nil) }) + testHelper(t, func() helper.Helper { return helper.MustNewBwrap(sc, "crash-test-dummy", argsWt, argF, nil, nil) }) }) } diff --git a/internal/app/app_pd_test.go b/internal/app/app_pd_test.go index 968a11a..98ddf31 100644 --- a/internal/app/app_pd_test.go +++ b/internal/app/app_pd_test.go @@ -39,6 +39,7 @@ var testCasesPd = []sealTestCase{ Net: true, UserNS: true, Clearenv: true, + Syscall: new(bwrap.SyscallPolicy), Chdir: "/home/chronos", SetEnv: map[string]string{ "HOME": "/home/chronos", @@ -258,6 +259,7 @@ var testCasesPd = []sealTestCase{ UserNS: true, Chdir: "/home/chronos", Clearenv: true, + Syscall: new(bwrap.SyscallPolicy), SetEnv: map[string]string{ "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/65534/bus", "DBUS_SYSTEM_BUS_ADDRESS": "unix:path=/run/dbus/system_bus_socket", diff --git a/internal/app/seal.go b/internal/app/seal.go index bd0522a..228be5c 100644 --- a/internal/app/seal.go +++ b/internal/app/seal.go @@ -14,6 +14,7 @@ import ( "git.gensokyo.uk/security/fortify/acl" "git.gensokyo.uk/security/fortify/dbus" "git.gensokyo.uk/security/fortify/fst" + "git.gensokyo.uk/security/fortify/helper/bwrap" "git.gensokyo.uk/security/fortify/internal/fmsg" "git.gensokyo.uk/security/fortify/internal/linux" "git.gensokyo.uk/security/fortify/internal/state" @@ -52,8 +53,6 @@ type appSeal struct { et system.Enablements // initial config gob encoding buffer ct io.WriterTo - // pass-through seccomp config from config - scmp *fst.SyscallConfig // wayland socket direct access directWayland bool // extra UpdatePerm ops @@ -196,6 +195,7 @@ func (a *app) Seal(config *fst.Config) error { conf := &fst.SandboxConfig{ UserNS: true, Net: true, + Syscall: new(bwrap.SyscallPolicy), NoNewSession: true, AutoEtc: true, } @@ -233,12 +233,6 @@ func (a *app) Seal(config *fst.Config) error { conf.Filesystem = append(conf.Filesystem, &fst.FilesystemConfig{Src: "/dev/kvm", Device: true}) config.Confinement.Sandbox = conf - - // ensure syscall filter - if config.Confinement.Syscall == nil { - config.Confinement.Syscall = new(fst.SyscallConfig) - config.Confinement.Syscall.Multiarch = true - } } seal.directWayland = config.Confinement.Sandbox.DirectWayland if b, err := config.Confinement.Sandbox.Bwrap(a.os); err != nil { @@ -259,9 +253,8 @@ func (a *app) Seal(config *fst.Config) error { // initialise system interface with full uid seal.sys.I = system.New(seal.sys.user.uid) - // pass through enablements and seccomp + // pass through enablements seal.et = config.Confinement.Enablements - seal.scmp = config.Confinement.Syscall // this method calls all share methods in sequence if err := seal.setupShares([2]*dbus.Config{config.Confinement.SessionBus, config.Confinement.SystemBus}, a.os); err != nil { diff --git a/internal/app/start.go b/internal/app/start.go index 87bb6fd..d0a0116 100644 --- a/internal/app/start.go +++ b/internal/app/start.go @@ -76,11 +76,10 @@ func (a *app) Run(ctx context.Context, rs *RunState) error { // send payload if err = a.shim.Serve(shimSetupCtx, &shim.Payload{ - Argv: a.seal.command, - Exec: shimExec, - Bwrap: a.seal.sys.bwrap, - Home: a.seal.sys.user.data, - Syscall: a.seal.scmp, + Argv: a.seal.command, + Exec: shimExec, + Bwrap: a.seal.sys.bwrap, + Home: a.seal.sys.user.data, Verbose: fmsg.Verbose(), }); err != nil { diff --git a/internal/proc/priv/shim/main.go b/internal/proc/priv/shim/main.go index a92a3cf..85c5baf 100644 --- a/internal/proc/priv/shim/main.go +++ b/internal/proc/priv/shim/main.go @@ -2,8 +2,6 @@ package shim import ( "errors" - "flag" - "io" "os" "path" "strconv" @@ -20,7 +18,7 @@ import ( // everything beyond this point runs as unconstrained target user // proceed with caution! -func Main(args []string) { +func Main() { // sharing stdout with fortify // USE WITH CAUTION fmsg.SetPrefix("shim") @@ -31,46 +29,6 @@ func Main(args []string) { panic("unreachable") } - set := flag.NewFlagSet("shim", flag.ExitOnError) - - // debug: export seccomp filter - debugExportSeccomp := set.String("export-seccomp", "", "export the seccomp filter to file") - debugExportSeccompFlags := [...]struct { - o syscallOpts - v *bool - }{ - {flagDenyNS, set.Bool("deny-ns", false, "deny namespace-related syscalls")}, - {flagDenyTTY, set.Bool("deny-tty", false, "deny faking input ioctls")}, - {flagDenyDevel, set.Bool("deny-devel", false, "deny development syscalls")}, - {flagMultiarch, set.Bool("multiarch", false, "allow multiarch")}, - {flagLinux32, set.Bool("linux32", false, "allow PER_LINUX32")}, - {flagCan, set.Bool("can", false, "allow AF_CAN")}, - {flagBluetooth, set.Bool("bluetooth", false, "AF_BLUETOOTH")}, - } - - // Ignore errors; set is set for ExitOnError. - _ = set.Parse(args[1:]) - - // debug: export seccomp filter - if *debugExportSeccomp != "" { - var opts syscallOpts - for _, opt := range debugExportSeccompFlags { - if *opt.v { - opts |= opt.o - } - } - - if f, err := os.Create(*debugExportSeccomp); err != nil { - fmsg.Fatalf("cannot create %q: %v", *debugExportSeccomp, err) - } else { - mustExportFilter(f, opts) - if err = f.Close(); err != nil { - fmsg.Fatalf("cannot close %q: %v", *debugExportSeccomp, err) - } - } - fmsg.Exit(0) - } - // receive setup payload var ( payload Payload @@ -169,23 +127,19 @@ func Main(args []string) { conf.Symlink("fortify", innerInit) helper.BubblewrapName = payload.Exec[0] // resolved bwrap path by parent + if fmsg.Verbose() { + bwrap.CPrintln = fmsg.Println + } if b, err := helper.NewBwrap( conf, innerInit, nil, func(int, int) []string { return make([]string, 0) }, - []helper.BwrapExtraFile{ - // keep this fd open while sandbox is running - // (--sync-fd FD) - {"--sync-fd", syncFd}, - // load and use seccomp rules from FD (not repeatable) - // (--seccomp FD) - {"--seccomp", mustResolveSeccomp(payload.Bwrap, payload.Syscall)}, - }, + extraFiles, + syncFd, ); err != nil { fmsg.Fatalf("malformed sandbox config: %v", err) } else { cmd := b.Unwrap() cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr - cmd.ExtraFiles = extraFiles // run and pass through exit code if err = b.Start(); err != nil { @@ -200,65 +154,3 @@ func Main(args []string) { } } } - -func mustResolveSeccomp(bwrap *bwrap.Config, syscall *fst.SyscallConfig) (seccompFd *os.File) { - if syscall == nil { - fmsg.VPrintln("syscall filter not configured, PROCEED WITH CAUTION") - return - } - - // resolve seccomp filter opts - var ( - opts syscallOpts - optd []string - optCond = [...]struct { - v bool - o syscallOpts - d string - }{ - {!bwrap.UserNS, flagDenyNS, "denyns"}, - {bwrap.NewSession, flagDenyTTY, "denytty"}, - {syscall.DenyDevel, flagDenyDevel, "denydevel"}, - {syscall.Multiarch, flagMultiarch, "multiarch"}, - {syscall.Linux32, flagLinux32, "linux32"}, - {syscall.Can, flagCan, "can"}, - {syscall.Bluetooth, flagBluetooth, "bluetooth"}, - } - ) - if fmsg.Verbose() { - optd = make([]string, 1, len(optCond)+1) - optd[0] = "fortify" - } - for _, opt := range optCond { - if opt.v { - opts |= opt.o - if fmsg.Verbose() { - optd = append(optd, opt.d) - } - } - } - if fmsg.Verbose() { - fmsg.VPrintf("seccomp flags: %s", optd) - } - - // export seccomp filter to tmpfile - if f, err := tmpfile(); err != nil { - fmsg.Fatalf("cannot create tmpfile: %v", err) - panic("unreachable") - } else { - mustExportFilter(f, opts) - seccompFd = f - return - } -} - -func mustExportFilter(f *os.File, opts syscallOpts) { - if err := exportFilter(f.Fd(), opts); err != nil { - fmsg.Fatalf("cannot export seccomp filter: %v", err) - panic("unreachable") - } - if _, err := f.Seek(0, io.SeekStart); err != nil { - fmsg.Fatalf("cannot lseek seccomp file: %v", err) - panic("unreachable") - } -} diff --git a/internal/proc/priv/shim/payload.go b/internal/proc/priv/shim/payload.go index 2d6854f..e659e3f 100644 --- a/internal/proc/priv/shim/payload.go +++ b/internal/proc/priv/shim/payload.go @@ -1,7 +1,6 @@ package shim import ( - "git.gensokyo.uk/security/fortify/fst" "git.gensokyo.uk/security/fortify/helper/bwrap" ) @@ -18,8 +17,6 @@ type Payload struct { Home string // sync fd Sync *uintptr - // seccomp opts pass through - Syscall *fst.SyscallConfig // verbosity pass through Verbose bool diff --git a/internal/system/dbus.go b/internal/system/dbus.go index 3bed540..b74d5d3 100644 --- a/internal/system/dbus.go +++ b/internal/system/dbus.go @@ -99,7 +99,7 @@ func (d *DBus) apply(_ *I) error { } fmsg.VPrintln("starting message bus proxy:", d.proxy) if fmsg.Verbose() { // save the extra bwrap arg build when verbose logging is off - fmsg.VPrintln("message bus proxy bwrap args:", d.proxy.Bwrap()) + fmsg.VPrintln("message bus proxy bwrap args:", d.proxy.BwrapStatic()) } // background wait for proxy instance and notify completion diff --git a/ldd/exec.go b/ldd/exec.go index eec31e4..23c4e89 100644 --- a/ldd/exec.go +++ b/ldd/exec.go @@ -23,7 +23,8 @@ func Exec(p string) ([]*Entry, error) { NewSession: true, DieWithParent: true, }).Bind("/", "/").DevTmpfs("/dev"), "ldd", - nil, func(_, _ int) []string { return []string{p} }, nil, + nil, func(_, _ int) []string { return []string{p} }, + nil, nil, ); err != nil { return nil, err } else { diff --git a/main.go b/main.go index 8909e5b..e6e856b 100644 --- a/main.go +++ b/main.go @@ -291,7 +291,7 @@ func main() { // internal commands case "shim": - shim.Main(args) + shim.Main() fmsg.Exit(0) case "init": init0.Main()