diff options
Diffstat (limited to 'helper/bwrap.go')
| -rw-r--r-- | helper/bwrap.go | 112 |
1 files changed, 22 insertions, 90 deletions
diff --git a/helper/bwrap.go b/helper/bwrap.go index 851f2448..8044e6a8 100644 --- a/helper/bwrap.go +++ b/helper/bwrap.go @@ -1,111 +1,47 @@ package helper import ( + "context" "errors" "io" "os" - "os/exec" + "slices" "strconv" "sync" "git.gensokyo.uk/security/fortify/helper/bwrap" + "git.gensokyo.uk/security/fortify/helper/proc" ) // BubblewrapName is the file name or path to bubblewrap. var BubblewrapName = "bwrap" type bubblewrap struct { - // bwrap child file name - name string - - // bwrap pipes - control *pipes - // returns an array of arguments passed directly - // to the child process spawned by bwrap - argF func(argsFD, statFD int) []string + // final args fd of bwrap process + argsFd uintptr - // pipes received by the child - // nil if no pipes are required - controlPt *pipes + // name of the command to run in bwrap + name string lock sync.RWMutex - *exec.Cmd + *helperCmd } -func (b *bubblewrap) StartNotify(ready chan error) error { +func (b *bubblewrap) Start(ctx context.Context, stat bool) error { b.lock.Lock() defer b.lock.Unlock() - if ready != nil && b.controlPt == nil { - panic("attempted to start with status monitoring on a bwrap child initialised without pipes") - } - // Check for doubled Start calls before we defer failure cleanup. If the prior // call to Start succeeded, we don't want to spuriously close its pipes. - if b.Cmd.Process != nil { + if b.Cmd != nil && b.Cmd.Process != nil { return errors.New("exec: already started") } - // prepare bwrap pipe and args - if argsFD, _, err := b.control.prepareCmd(b.Cmd); err != nil { - return err - } else { - b.Cmd.Args = append(b.Cmd.Args, "--args", strconv.Itoa(argsFD), "--", b.name) - } - - // prepare child args and pipes if enabled - if b.controlPt != nil { - b.controlPt.ready = ready - if argsFD, statFD, err := b.controlPt.prepareCmd(b.Cmd); err != nil { - return err - } else { - b.Cmd.Args = append(b.Cmd.Args, b.argF(argsFD, statFD)...) - } - } else { - b.Cmd.Args = append(b.Cmd.Args, b.argF(-1, -1)...) - } - - if ready != nil { - b.Cmd.Env = append(b.Cmd.Env, FortifyHelper+"=1", FortifyStatus+"=1") - } else if b.controlPt != nil { - b.Cmd.Env = append(b.Cmd.Env, FortifyHelper+"=1", FortifyStatus+"=0") - } else { - b.Cmd.Env = append(b.Cmd.Env, FortifyHelper+"=1", FortifyStatus+"=-1") - } - - if err := b.Cmd.Start(); err != nil { - return err - } - - // write bwrap args first - if err := b.control.readyWriteArgs(); err != nil { - return err - } - - // write child args if enabled - if b.controlPt != nil { - if err := b.controlPt.readyWriteArgs(); err != nil { - return err - } - } - - return nil -} - -func (b *bubblewrap) Close() error { - if b.controlPt == nil { - panic("attempted to close bwrap child initialised without pipes") - } - - return b.controlPt.closeStatus() -} - -func (b *bubblewrap) Start() error { - return b.StartNotify(nil) -} - -func (b *bubblewrap) Unwrap() *exec.Cmd { - return b.Cmd + args := b.finalise(ctx, stat) + b.Cmd.Args = slices.Grow(b.Cmd.Args, 4+len(args)) + b.Cmd.Args = append(b.Cmd.Args, "--args", strconv.Itoa(int(b.argsFd)), "--", b.name) + b.Cmd.Args = append(b.Cmd.Args, args...) + return proc.Fulfill(ctx, b.Cmd, b.files, b.extraFiles) } // MustNewBwrap initialises a new Bwrap instance with wt as the null-terminated argument writer. @@ -130,27 +66,23 @@ func MustNewBwrap( // Function argF returns an array of arguments passed directly to the child process. func NewBwrap( conf *bwrap.Config, name string, - wt io.WriterTo, argF func(argsFD, statFD int) []string, + wt io.WriterTo, argF func(argsFd, statFd int) []string, extraFiles []*os.File, syncFd *os.File, ) (Helper, error) { b := new(bubblewrap) - b.argF = argF b.name = name - if wt != nil { - b.controlPt = &pipes{args: wt} - } + b.helperCmd = newHelperCmd(b, BubblewrapName, wt, argF, extraFiles) - 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 { + conf.FDArgs(syncFd, &args, b.extraFiles, &b.files) + if v, err := NewCheckedArgs(args); err != nil { return nil, err } else { - b.Cmd.ExtraFiles = extraFiles + f := proc.NewWriterTo(v) + b.argsFd = proc.InitFile(f, b.extraFiles) + b.files = append(b.files, f) } return b, nil |
