256 lines
8.0 KiB
Go
256 lines
8.0 KiB
Go
package bwrap_test
|
|
|
|
import (
|
|
"os"
|
|
"slices"
|
|
"testing"
|
|
|
|
"git.gensokyo.uk/security/fortify/helper/bwrap"
|
|
)
|
|
|
|
func TestConfig_Args(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
conf *bwrap.Config
|
|
want []string
|
|
}{
|
|
{
|
|
name: "bind",
|
|
conf: (new(bwrap.Config)).
|
|
Bind("/etc", "/.fortify/etc").
|
|
Bind("/etc", "/.fortify/etc", true).
|
|
Bind("/run", "/.fortify/run", false, true).
|
|
Bind("/sys/devices", "/.fortify/sys/devices", true, true).
|
|
Bind("/dev/dri", "/.fortify/dev/dri", false, true, true).
|
|
Bind("/dev/dri", "/.fortify/dev/dri", true, true, true),
|
|
want: []string{
|
|
"--unshare-all", "--unshare-user",
|
|
"--disable-userns", "--assert-userns-disabled",
|
|
// Bind("/etc", "/.fortify/etc")
|
|
"--ro-bind", "/etc", "/.fortify/etc",
|
|
// Bind("/etc", "/.fortify/etc", true)
|
|
"--ro-bind-try", "/etc", "/.fortify/etc",
|
|
// Bind("/run", "/.fortify/run", false, true)
|
|
"--bind", "/run", "/.fortify/run",
|
|
// Bind("/sys/devices", "/.fortify/sys/devices", true, true)
|
|
"--bind-try", "/sys/devices", "/.fortify/sys/devices",
|
|
// Bind("/dev/dri", "/.fortify/dev/dri", false, true, true)
|
|
"--dev-bind", "/dev/dri", "/.fortify/dev/dri",
|
|
// Bind("/dev/dri", "/.fortify/dev/dri", true, true, true)
|
|
"--dev-bind-try", "/dev/dri", "/.fortify/dev/dri",
|
|
},
|
|
},
|
|
{
|
|
name: "dir remount-ro proc dev mqueue",
|
|
conf: (new(bwrap.Config)).
|
|
Dir("/.fortify").
|
|
RemountRO("/home").
|
|
Procfs("/proc").
|
|
DevTmpfs("/dev").
|
|
Mqueue("/dev/mqueue"),
|
|
want: []string{
|
|
"--unshare-all", "--unshare-user",
|
|
"--disable-userns", "--assert-userns-disabled",
|
|
// Dir("/.fortify")
|
|
"--dir", "/.fortify",
|
|
// RemountRO("/home")
|
|
"--remount-ro", "/home",
|
|
// Procfs("/proc")
|
|
"--proc", "/proc",
|
|
// DevTmpfs("/dev")
|
|
"--dev", "/dev",
|
|
// Mqueue("/dev/mqueue")
|
|
"--mqueue", "/dev/mqueue",
|
|
},
|
|
},
|
|
{
|
|
name: "tmpfs",
|
|
conf: (new(bwrap.Config)).
|
|
Tmpfs("/run/user", 8192).
|
|
Tmpfs("/run/dbus", 8192, 0755),
|
|
want: []string{
|
|
"--unshare-all", "--unshare-user",
|
|
"--disable-userns", "--assert-userns-disabled",
|
|
// Tmpfs("/run/user", 8192)
|
|
"--size", "8192", "--tmpfs", "/run/user",
|
|
// Tmpfs("/run/dbus", 8192, 0755)
|
|
"--perms", "755", "--size", "8192", "--tmpfs", "/run/dbus",
|
|
},
|
|
},
|
|
{
|
|
name: "symlink",
|
|
conf: (new(bwrap.Config)).
|
|
Symlink("/.fortify/sbin/init", "/sbin/init").
|
|
Symlink("/.fortify/sbin/init", "/sbin/init", 0755),
|
|
want: []string{
|
|
"--unshare-all", "--unshare-user",
|
|
"--disable-userns", "--assert-userns-disabled",
|
|
// Symlink("/.fortify/sbin/init", "/sbin/init")
|
|
"--symlink", "/.fortify/sbin/init", "/sbin/init",
|
|
// Symlink("/.fortify/sbin/init", "/sbin/init", 0755)
|
|
"--perms", "755", "--symlink", "/.fortify/sbin/init", "/sbin/init",
|
|
},
|
|
},
|
|
{
|
|
name: "overlayfs",
|
|
conf: (new(bwrap.Config)).
|
|
Overlay("/etc", "/etc").
|
|
Join("/.fortify/bin", "/bin", "/usr/bin", "/usr/local/bin").
|
|
Persist("/nix", "/data/data/org.chromium.Chromium/overlay/rwsrc", "/data/data/org.chromium.Chromium/workdir", "/data/app/org.chromium.Chromium/nix"),
|
|
want: []string{
|
|
"--unshare-all", "--unshare-user",
|
|
"--disable-userns", "--assert-userns-disabled",
|
|
// Overlay("/etc", "/etc")
|
|
"--overlay-src", "/etc", "--tmp-overlay", "/etc",
|
|
// Join("/.fortify/bin", "/bin", "/usr/bin", "/usr/local/bin")
|
|
"--overlay-src", "/bin", "--overlay-src", "/usr/bin",
|
|
"--overlay-src", "/usr/local/bin", "--ro-overlay", "/.fortify/bin",
|
|
// Persist("/nix", "/data/data/org.chromium.Chromium/overlay/rwsrc", "/data/data/org.chromium.Chromium/workdir", "/data/app/org.chromium.Chromium/nix")
|
|
"--overlay-src", "/data/app/org.chromium.Chromium/nix",
|
|
"--overlay", "/data/data/org.chromium.Chromium/overlay/rwsrc", "/data/data/org.chromium.Chromium/workdir", "/nix",
|
|
},
|
|
},
|
|
{
|
|
name: "unshare",
|
|
conf: &bwrap.Config{Unshare: &bwrap.UnshareConfig{
|
|
User: false,
|
|
IPC: false,
|
|
PID: false,
|
|
Net: false,
|
|
UTS: false,
|
|
CGroup: false,
|
|
}},
|
|
want: []string{"--disable-userns", "--assert-userns-disabled"},
|
|
},
|
|
{
|
|
name: "uid gid sync",
|
|
conf: (new(bwrap.Config)).
|
|
SetUID(1971).
|
|
SetGID(100).
|
|
SetSync(os.Stdin),
|
|
want: []string{
|
|
"--unshare-all", "--unshare-user",
|
|
"--disable-userns", "--assert-userns-disabled",
|
|
// SetUID(1971)
|
|
"--uid", "1971",
|
|
// SetGID(100)
|
|
"--gid", "100",
|
|
// SetSync(os.Stdin)
|
|
// this is set when the process is created
|
|
},
|
|
},
|
|
{
|
|
name: "hostname chdir setenv unsetenv lockfile chmod",
|
|
conf: &bwrap.Config{
|
|
Hostname: "fortify",
|
|
Chdir: "/.fortify",
|
|
SetEnv: map[string]string{"FORTIFY_INIT": "/.fortify/sbin/init"},
|
|
UnsetEnv: []string{"HOME", "HOST"},
|
|
LockFile: []string{"/.fortify/lock"},
|
|
Chmod: map[string]os.FileMode{"/.fortify/sbin/init": 0755},
|
|
},
|
|
want: []string{
|
|
"--unshare-all", "--unshare-user",
|
|
"--disable-userns", "--assert-userns-disabled",
|
|
// Hostname: "fortify"
|
|
"--hostname", "fortify",
|
|
// Chdir: "/.fortify"
|
|
"--chdir", "/.fortify",
|
|
// UnsetEnv: []string{"HOME", "HOST"}
|
|
"--unsetenv", "HOME",
|
|
"--unsetenv", "HOST",
|
|
// LockFile: []string{"/.fortify/lock"},
|
|
"--lock-file", "/.fortify/lock",
|
|
// SetEnv: map[string]string{"FORTIFY_INIT": "/.fortify/sbin/init"}
|
|
"--setenv", "FORTIFY_INIT", "/.fortify/sbin/init",
|
|
// Chmod: map[string]os.FileMode{"/.fortify/sbin/init": 0755}
|
|
"--chmod", "755", "/.fortify/sbin/init",
|
|
},
|
|
},
|
|
|
|
{
|
|
name: "xdg-dbus-proxy constraint sample",
|
|
conf: (&bwrap.Config{
|
|
Unshare: nil,
|
|
UserNS: false,
|
|
Clearenv: true,
|
|
DieWithParent: true,
|
|
}).
|
|
Symlink("usr/bin", "/bin").
|
|
Symlink("var/home", "/home").
|
|
Symlink("usr/lib", "/lib").
|
|
Symlink("usr/lib64", "/lib64").
|
|
Symlink("run/media", "/media").
|
|
Symlink("var/mnt", "/mnt").
|
|
Symlink("var/opt", "/opt").
|
|
Symlink("sysroot/ostree", "/ostree").
|
|
Symlink("var/roothome", "/root").
|
|
Symlink("usr/sbin", "/sbin").
|
|
Symlink("var/srv", "/srv").
|
|
Bind("/run", "/run", false, true).
|
|
Bind("/tmp", "/tmp", false, true).
|
|
Bind("/var", "/var", false, true).
|
|
Bind("/run/user/1971/.dbus-proxy/", "/run/user/1971/.dbus-proxy/", false, true).
|
|
Bind("/boot", "/boot").
|
|
Bind("/dev", "/dev").
|
|
Bind("/proc", "/proc").
|
|
Bind("/sys", "/sys").
|
|
Bind("/sysroot", "/sysroot").
|
|
Bind("/usr", "/usr").
|
|
Bind("/etc", "/etc"),
|
|
want: []string{
|
|
"--unshare-all", "--unshare-user",
|
|
"--disable-userns", "--assert-userns-disabled",
|
|
"--clearenv", "--die-with-parent",
|
|
"--symlink", "usr/bin", "/bin",
|
|
"--symlink", "var/home", "/home",
|
|
"--symlink", "usr/lib", "/lib",
|
|
"--symlink", "usr/lib64", "/lib64",
|
|
"--symlink", "run/media", "/media",
|
|
"--symlink", "var/mnt", "/mnt",
|
|
"--symlink", "var/opt", "/opt",
|
|
"--symlink", "sysroot/ostree", "/ostree",
|
|
"--symlink", "var/roothome", "/root",
|
|
"--symlink", "usr/sbin", "/sbin",
|
|
"--symlink", "var/srv", "/srv",
|
|
"--bind", "/run", "/run",
|
|
"--bind", "/tmp", "/tmp",
|
|
"--bind", "/var", "/var",
|
|
"--bind", "/run/user/1971/.dbus-proxy/", "/run/user/1971/.dbus-proxy/",
|
|
"--ro-bind", "/boot", "/boot",
|
|
"--ro-bind", "/dev", "/dev",
|
|
"--ro-bind", "/proc", "/proc",
|
|
"--ro-bind", "/sys", "/sys",
|
|
"--ro-bind", "/sysroot", "/sysroot",
|
|
"--ro-bind", "/usr", "/usr",
|
|
"--ro-bind", "/etc", "/etc",
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
if got := tc.conf.Args(); !slices.Equal(got, tc.want) {
|
|
t.Errorf("Args() = %#v, want %#v", got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
|
|
// test persist validation
|
|
t.Run("invalid persist", func(t *testing.T) {
|
|
defer func() {
|
|
wantPanic := "persist called without required paths"
|
|
if r := recover(); r != wantPanic {
|
|
t.Errorf("Persist() panic = %v; wantPanic %v", r, wantPanic)
|
|
}
|
|
}()
|
|
(new(bwrap.Config)).Persist("/run", "", "")
|
|
})
|
|
|
|
t.Run("sync file", func(t *testing.T) {
|
|
if s := (new(bwrap.Config)).SetSync(os.Stdout).Sync(); s != os.Stdout {
|
|
t.Errorf("Sync() = %v", s)
|
|
}
|
|
})
|
|
}
|