helper/bwrap: merge Args and FDArgs
All checks were successful
Test / Create distribution (push) Successful in 1m13s
Test / Run NixOS test (push) Successful in 4m34s

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
Ophestra 2025-02-14 18:13:06 +09:00
parent 73146ea7fa
commit ace97952cc
Signed by: cat
SSH Key Fingerprint: SHA256:gQ67O0enBZ7UdZypgtspB2FDM1g3GVw8nX0XSdcFw8Q
4 changed files with 33 additions and 48 deletions

View File

@ -75,9 +75,7 @@ func NewBwrap(
b.name = name b.name = name
b.helperCmd = newHelperCmd(b, BubblewrapName, wt, argF, extraFiles) b.helperCmd = newHelperCmd(b, BubblewrapName, wt, argF, extraFiles)
args := conf.Args() if v, err := NewCheckedArgs(conf.Args(syncFd, b.extraFiles, &b.files)); err != nil {
conf.FDArgs(syncFd, &args, b.extraFiles, &b.files)
if v, err := NewCheckedArgs(args); err != nil {
return nil, err return nil, err
} else { } else {
f := proc.NewWriterTo(v) f := proc.NewWriterTo(v)

View File

@ -23,42 +23,22 @@ type FDBuilder interface {
} }
// Args returns a slice of bwrap args corresponding to c. // Args returns a slice of bwrap args corresponding to c.
func (c *Config) Args() (args []string) { func (c *Config) Args(syncFd *os.File, extraFiles *proc.ExtraFilesPre, files *[]proc.File) (args []string) {
builders := []Builder{ builders := []Builder{
c.boolArgs(), c.boolArgs(),
c.intArgs(), c.intArgs(),
c.stringArgs(), c.stringArgs(),
c.pairArgs(), c.pairArgs(),
}
// copy FSBuilder slice to builder slice
fb := make([]Builder, len(c.Filesystem)+1)
for i, f := range c.Filesystem {
fb[i] = f
}
fb[len(fb)-1] = c.Chmod
builders = append(builders, fb...)
// accumulate arg count
argc := 0
for _, b := range builders {
argc += b.Len()
}
args = make([]string, 0, argc)
for _, b := range builders {
b.Append(&args)
}
return
}
func (c *Config) FDArgs(syncFd *os.File, args *[]string, extraFiles *proc.ExtraFilesPre, files *[]proc.File) {
builders := []FDBuilder{
c.seccompArgs(), c.seccompArgs(),
newFile(positionalArgs[SyncFd], syncFd), newFile(positionalArgs[SyncFd], syncFd),
} }
builders = slices.Grow(builders, len(c.Filesystem)+1)
for _, f := range c.Filesystem {
builders = append(builders, f)
}
builders = append(builders, c.Chmod)
argc := 0 argc := 0
fc := 0 fc := 0
for _, b := range builders { for _, b := range builders {
@ -67,22 +47,26 @@ func (c *Config) FDArgs(syncFd *os.File, args *[]string, extraFiles *proc.ExtraF
continue continue
} }
argc += l argc += l
fc++
proc.InitFile(b, extraFiles) if f, ok := b.(FDBuilder); ok {
fc++
proc.InitFile(f, extraFiles)
}
} }
fc++ // allocate extra slot for stat fd fc++ // allocate extra slot for stat fd
*args = slices.Grow(*args, argc)
*files = slices.Grow(*files, fc)
args = make([]string, 0, argc)
*files = slices.Grow(*files, fc)
for _, b := range builders { for _, b := range builders {
if b.Len() < 1 { if b.Len() < 1 {
continue continue
} }
b.Append(&args)
b.Append(args) if f, ok := b.(FDBuilder); ok {
*files = append(*files, b) *files = append(*files, f)
}
} }
return return
} }

View File

@ -6,9 +6,15 @@ import (
"testing" "testing"
"git.gensokyo.uk/security/fortify/helper/bwrap" "git.gensokyo.uk/security/fortify/helper/bwrap"
"git.gensokyo.uk/security/fortify/helper/proc"
"git.gensokyo.uk/security/fortify/helper/seccomp"
"git.gensokyo.uk/security/fortify/internal/fmsg"
) )
func TestConfig_Args(t *testing.T) { func TestConfig_Args(t *testing.T) {
seccomp.CPrintln = fmsg.Println
t.Cleanup(func() { seccomp.CPrintln = nil })
testCases := []struct { testCases := []struct {
name string name string
conf *bwrap.Config conf *bwrap.Config
@ -137,13 +143,14 @@ func TestConfig_Args(t *testing.T) {
}, },
}, },
{ {
name: "hostname chdir setenv unsetenv lockfile chmod", name: "hostname chdir setenv unsetenv lockfile chmod syscall",
conf: &bwrap.Config{ conf: &bwrap.Config{
Hostname: "fortify", Hostname: "fortify",
Chdir: "/.fortify", Chdir: "/.fortify",
SetEnv: map[string]string{"FORTIFY_INIT": "/.fortify/sbin/init"}, SetEnv: map[string]string{"FORTIFY_INIT": "/.fortify/sbin/init"},
UnsetEnv: []string{"HOME", "HOST"}, UnsetEnv: []string{"HOME", "HOST"},
LockFile: []string{"/.fortify/lock"}, LockFile: []string{"/.fortify/lock"},
Syscall: new(bwrap.SyscallPolicy),
Chmod: map[string]os.FileMode{"/.fortify/sbin/init": 0755}, Chmod: map[string]os.FileMode{"/.fortify/sbin/init": 0755},
}, },
want: []string{ want: []string{
@ -160,6 +167,8 @@ func TestConfig_Args(t *testing.T) {
"--lock-file", "/.fortify/lock", "--lock-file", "/.fortify/lock",
// SetEnv: map[string]string{"FORTIFY_INIT": "/.fortify/sbin/init"} // SetEnv: map[string]string{"FORTIFY_INIT": "/.fortify/sbin/init"}
"--setenv", "FORTIFY_INIT", "/.fortify/sbin/init", "--setenv", "FORTIFY_INIT", "/.fortify/sbin/init",
// Syscall: new(bwrap.SyscallPolicy),
"--seccomp", "3",
// Chmod: map[string]os.FileMode{"/.fortify/sbin/init": 0755} // Chmod: map[string]os.FileMode{"/.fortify/sbin/init": 0755}
"--chmod", "755", "/.fortify/sbin/init", "--chmod", "755", "/.fortify/sbin/init",
}, },
@ -167,12 +176,7 @@ func TestConfig_Args(t *testing.T) {
{ {
name: "xdg-dbus-proxy constraint sample", name: "xdg-dbus-proxy constraint sample",
conf: (&bwrap.Config{ conf: (&bwrap.Config{Clearenv: true, DieWithParent: true}).
Unshare: nil,
UserNS: false,
Clearenv: true,
DieWithParent: true,
}).
Symlink("usr/bin", "/bin"). Symlink("usr/bin", "/bin").
Symlink("var/home", "/home"). Symlink("var/home", "/home").
Symlink("usr/lib", "/lib"). Symlink("usr/lib", "/lib").
@ -227,7 +231,7 @@ func TestConfig_Args(t *testing.T) {
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
if got := tc.conf.Args(); !slices.Equal(got, tc.want) { if got := tc.conf.Args(nil, new(proc.ExtraFilesPre), new([]proc.File)); !slices.Equal(got, tc.want) {
t.Errorf("Args() = %#v, want %#v", got, tc.want) t.Errorf("Args() = %#v, want %#v", got, tc.want)
} }
}) })

View File

@ -155,9 +155,8 @@ func bwrapStub() {
DieWithParent: true, DieWithParent: true,
AsInit: true, AsInit: true,
} }
args := sc.Args() if _, err := MustNewCheckedArgs(sc.Args(nil, new(proc.ExtraFilesPre), new([]proc.File))).
sc.FDArgs(nil, &args, new(proc.ExtraFilesPre), new([]proc.File)) WriteTo(want); err != nil {
if _, err := MustNewCheckedArgs(args).WriteTo(want); err != nil {
panic("cannot read want: " + err.Error()) panic("cannot read want: " + err.Error())
} }