aboutsummaryrefslogtreecommitdiffhomepage
path: root/helper/bwrap.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-02-13 23:15:34 +0900
committerOphestra <cat@gensokyo.uk>2025-02-13 23:34:15 +0900
commitfe7d208cf76fa6f24bb9d12ba29b5ed61d837ce3 (patch)
treecac02af50a13b2078739a8f5a74d219f3b60833d /helper/bwrap.go
parent60c287375048b21eab2bd82f1e7d43e36dcfb3a2 (diff)
helper: use generic extra files interface
This replaces the pipes object and integrates context into helper process lifecycle. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'helper/bwrap.go')
-rw-r--r--helper/bwrap.go112
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