aboutsummaryrefslogtreecommitdiffhomepage
path: root/bwrap
diff options
context:
space:
mode:
authorOphestra Umiker <cat@ophivana.moe>2024-10-07 14:40:35 +0900
committerOphestra Umiker <cat@ophivana.moe>2024-10-07 14:40:35 +0900
commit6a2802cf309fb9758756c56ef05c9354d9cb9003 (patch)
treed1efa27407aa3a2e1337fa4ffafa3df9fd677ec4 /bwrap
parent0fb9e401912f89d25ff96b0dd36aabf43b4fab8f (diff)
helper: move bwrap into helper
Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
Diffstat (limited to 'bwrap')
-rw-r--r--bwrap/config.bool.go64
-rw-r--r--bwrap/config.go265
-rw-r--r--bwrap/config.int.go22
-rw-r--r--bwrap/config.interface.go34
-rw-r--r--bwrap/config.pair.go54
-rw-r--r--bwrap/config.string.go35
-rw-r--r--bwrap/config_test.go88
7 files changed, 0 insertions, 562 deletions
diff --git a/bwrap/config.bool.go b/bwrap/config.bool.go
deleted file mode 100644
index 81e6ab7b..00000000
--- a/bwrap/config.bool.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package bwrap
-
-const (
- UnshareAll = iota
- UnshareUser
- UnshareIPC
- UnsharePID
- UnshareNet
- UnshareUTS
- UnshareCGroup
- ShareNet
-
- UserNS
- Clearenv
-
- NewSession
- DieWithParent
- AsInit
-
- boolC
-)
-
-var boolArgs = func() (b [boolC][]string) {
- b[UnshareAll] = []string{"--unshare-all"}
- b[UnshareUser] = []string{"--unshare-user"}
- b[UnshareIPC] = []string{"--unshare-ipc"}
- b[UnsharePID] = []string{"--unshare-pid"}
- b[UnshareNet] = []string{"--unshare-net"}
- b[UnshareUTS] = []string{"--unshare-uts"}
- b[UnshareCGroup] = []string{"--unshare-cgroup"}
- b[ShareNet] = []string{"--share-net"}
-
- b[UserNS] = []string{"--disable-userns", "--assert-userns-disabled"}
- b[Clearenv] = []string{"--clearenv"}
-
- b[NewSession] = []string{"--new-session"}
- b[DieWithParent] = []string{"--die-with-parent"}
- b[AsInit] = []string{"--as-pid-1"}
-
- return
-}()
-
-func (c *Config) boolArgs() (b [boolC]bool) {
- if c.Unshare == nil {
- b[UnshareAll] = true
- b[ShareNet] = c.Net
- } else {
- b[UnshareUser] = c.Unshare.User
- b[UnshareIPC] = c.Unshare.IPC
- b[UnsharePID] = c.Unshare.PID
- b[UnshareNet] = c.Unshare.Net
- b[UnshareUTS] = c.Unshare.UTS
- b[UnshareCGroup] = c.Unshare.CGroup
- }
-
- b[UserNS] = !c.UserNS
- b[Clearenv] = c.Clearenv
-
- b[NewSession] = c.NewSession
- b[DieWithParent] = c.DieWithParent
- b[AsInit] = c.AsInit
-
- return
-}
diff --git a/bwrap/config.go b/bwrap/config.go
deleted file mode 100644
index c20a33b0..00000000
--- a/bwrap/config.go
+++ /dev/null
@@ -1,265 +0,0 @@
-package bwrap
-
-import (
- "os"
- "strconv"
-)
-
-func (c *Config) Args() (args []string) {
- b := c.boolArgs()
- n := c.intArgs()
- s := c.stringArgs()
- p := c.pairArgs()
- g := c.interfaceArgs()
-
- argc := 0
- for i, arg := range b {
- if arg {
- argc += len(boolArgs[i])
- }
- }
- for _, arg := range n {
- if arg != nil {
- argc += 2
- }
- }
- for _, arg := range s {
- argc += len(arg) * 2
- }
- for _, arg := range p {
- argc += len(arg) * 3
- }
-
- args = make([]string, 0, argc)
- for i, arg := range b {
- if arg {
- args = append(args, boolArgs[i]...)
- }
- }
- for i, arg := range n {
- if arg != nil {
- args = append(args, intArgs[i], strconv.Itoa(*arg))
- }
- }
- for i, arg := range s {
- for _, v := range arg {
- args = append(args, stringArgs[i], v)
- }
- }
- for i, arg := range p {
- for _, v := range arg {
- args = append(args, pairArgs[i], v[0], v[1])
- }
- }
- for i, arg := range g {
- for _, v := range arg {
- args = append(args, v.Value(interfaceArgs[i])...)
- }
- }
-
- return
-}
-
-type Config struct {
- // unshare every namespace we support by default if nil
- // (--unshare-all)
- Unshare *UnshareConfig `json:"unshare,omitempty"`
- // retain the network namespace (can only combine with nil Unshare)
- // (--share-net)
- Net bool `json:"net"`
-
- // disable further use of user namespaces inside sandbox and fail unless
- // further use of user namespace inside sandbox is disabled if false
- // (--disable-userns) (--assert-userns-disabled)
- UserNS bool `json:"userns"`
-
- // custom uid in the sandbox, requires new user namespace
- // (--uid UID)
- UID *int `json:"uid,omitempty"`
- // custom gid in the sandbox, requires new user namespace
- // (--gid GID)
- GID *int `json:"gid,omitempty"`
- // custom hostname in the sandbox, requires new uts namespace
- // (--hostname NAME)
- Hostname string `json:"hostname,omitempty"`
-
- // change directory
- // (--chdir DIR)
- Chdir string `json:"chdir,omitempty"`
- // unset all environment variables
- // (--clearenv)
- Clearenv bool `json:"clearenv"`
- // set environment variable
- // (--setenv VAR VALUE)
- SetEnv map[string]string `json:"setenv,omitempty"`
- // unset environment variables
- // (--unsetenv VAR)
- UnsetEnv []string `json:"unsetenv,omitempty"`
-
- // take a lock on file while sandbox is running
- // (--lock-file DEST)
- LockFile []string `json:"lock_file,omitempty"`
-
- // bind mount host path on sandbox
- // (--bind SRC DEST)
- Bind [][2]string `json:"bind,omitempty"`
- // equal to Bind but ignores non-existent host path
- // (--bind-try SRC DEST)
- BindTry [][2]string `json:"bind_try,omitempty"`
-
- // bind mount host path on sandbox, allowing device access
- // (--dev-bind SRC DEST)
- DevBind [][2]string `json:"dev_bind,omitempty"`
- // equal to DevBind but ignores non-existent host path
- // (--dev-bind-try SRC DEST)
- DevBindTry [][2]string `json:"dev_bind_try,omitempty"`
-
- // bind mount host path readonly on sandbox
- // (--ro-bind SRC DEST)
- ROBind [][2]string `json:"ro_bind,omitempty"`
- // equal to ROBind but ignores non-existent host path
- // (--ro-bind-try SRC DEST)
- ROBindTry [][2]string `json:"ro_bind_try,omitempty"`
-
- // remount path as readonly; does not recursively remount
- // (--remount-ro DEST)
- RemountRO []string `json:"remount_ro,omitempty"`
-
- // mount new procfs in sandbox
- // (--proc DEST)
- Procfs []PermConfig[string] `json:"proc,omitempty"`
- // mount new dev in sandbox
- // (--dev DEST)
- DevTmpfs []PermConfig[string] `json:"dev,omitempty"`
- // mount new tmpfs in sandbox
- // (--tmpfs DEST)
- Tmpfs []PermConfig[TmpfsConfig] `json:"tmpfs,omitempty"`
- // mount new mqueue in sandbox
- // (--mqueue DEST)
- Mqueue []PermConfig[string] `json:"mqueue,omitempty"`
- // create dir in sandbox
- // (--dir DEST)
- Dir []PermConfig[string] `json:"dir,omitempty"`
- // create symlink within sandbox
- // (--symlink SRC DEST)
- Symlink []PermConfig[[2]string] `json:"symlink,omitempty"`
-
- // change permissions (must already exist)
- // (--chmod OCTAL PATH)
- Chmod map[string]os.FileMode `json:"chmod,omitempty"`
-
- // create a new terminal session
- // (--new-session)
- NewSession bool `json:"new_session"`
- // kills with SIGKILL child process (COMMAND) when bwrap or bwrap's parent dies.
- // (--die-with-parent)
- DieWithParent bool `json:"die_with_parent"`
- // do not install a reaper process with PID=1
- // (--as-pid-1)
- AsInit bool `json:"as_init"`
-
- /* unmapped options include:
- --unshare-user-try Create new user namespace if possible else continue by skipping it
- --unshare-cgroup-try Create new cgroup namespace if possible else continue by skipping it
- --userns FD Use this user namespace (cannot combine with --unshare-user)
- --userns2 FD After setup switch to this user namespace, only useful with --userns
- --pidns FD Use this pid namespace (as parent namespace if using --unshare-pid)
- --sync-fd FD Keep this fd open while sandbox is running
- --exec-label LABEL Exec label for the sandbox
- --file-label LABEL File label for temporary sandbox content
- --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
- --info-fd FD Write information about the running container to FD
- --json-status-fd FD Write container status to FD as multiple JSON documents
- --cap-add CAP Add cap CAP when running as privileged user
- --cap-drop CAP Drop cap CAP when running as privileged user
-
- among which --args is used internally for passing arguments */
-}
-
-type UnshareConfig struct {
- // (--unshare-user)
- // create new user namespace
- User bool `json:"user"`
- // (--unshare-ipc)
- // create new ipc namespace
- IPC bool `json:"ipc"`
- // (--unshare-pid)
- // create new pid namespace
- PID bool `json:"pid"`
- // (--unshare-net)
- // create new network namespace
- Net bool `json:"net"`
- // (--unshare-uts)
- // create new uts namespace
- UTS bool `json:"uts"`
- // (--unshare-cgroup)
- // create new cgroup namespace
- CGroup bool `json:"cgroup"`
-}
-
-type TmpfsConfig struct {
- // set size of tmpfs
- // (--size BYTES)
- Size int `json:"size,omitempty"`
- // mount point of new tmpfs
- // (--tmpfs DEST)
- Dir string `json:"dir"`
-}
-
-type argOf interface {
- Value(arg string) (args []string)
-}
-
-func copyToArgOfSlice[T [2]string | string | TmpfsConfig](src []PermConfig[T]) (dst []argOf) {
- dst = make([]argOf, len(src))
- for i, arg := range src {
- dst[i] = arg
- }
- return
-}
-
-type PermConfig[T [2]string | string | TmpfsConfig] struct {
- // set permissions of next argument
- // (--perms OCTAL)
- Mode *os.FileMode `json:"mode,omitempty"`
- // path to get the new permission
- // (--bind-data, --file, etc.)
- Path T
-}
-
-func (p PermConfig[T]) Value(arg string) (args []string) {
- // max possible size
- if p.Mode != nil {
- args = make([]string, 0, 6)
- args = append(args, "--perms", strconv.Itoa(int(*p.Mode)))
- } else {
- args = make([]string, 0, 4)
- }
-
- switch v := any(p.Path).(type) {
- case string:
- args = append(args, arg, v)
- return
- case [2]string:
- args = append(args, arg, v[0], v[1])
- return
- case TmpfsConfig:
- if arg != "--tmpfs" {
- panic("unreachable")
- }
-
- if v.Size > 0 {
- args = append(args, "--size", strconv.Itoa(v.Size))
- }
- args = append(args, arg, v.Dir)
- return
- default:
- panic("unreachable")
- }
-}
diff --git a/bwrap/config.int.go b/bwrap/config.int.go
deleted file mode 100644
index 27c88c36..00000000
--- a/bwrap/config.int.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package bwrap
-
-const (
- UID = iota
- GID
-
- intC
-)
-
-var intArgs = func() (n [intC]string) {
- n[UID] = "--uid"
- n[GID] = "--gid"
-
- return
-}()
-
-func (c *Config) intArgs() (n [intC]*int) {
- n[UID] = c.UID
- n[GID] = c.GID
-
- return
-}
diff --git a/bwrap/config.interface.go b/bwrap/config.interface.go
deleted file mode 100644
index eb559c1d..00000000
--- a/bwrap/config.interface.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package bwrap
-
-const (
- Procfs = iota
- DevTmpfs
- Tmpfs
- Mqueue
- Dir
- Symlink
-
- interfaceC
-)
-
-var interfaceArgs = func() (g [interfaceC]string) {
- g[Procfs] = "--proc"
- g[DevTmpfs] = "--dev"
- g[Tmpfs] = "--tmpfs"
- g[Mqueue] = "--mqueue"
- g[Dir] = "--dir"
- g[Symlink] = "--symlink"
-
- return
-}()
-
-func (c *Config) interfaceArgs() (g [interfaceC][]argOf) {
- g[Procfs] = copyToArgOfSlice(c.Procfs)
- g[DevTmpfs] = copyToArgOfSlice(c.DevTmpfs)
- g[Tmpfs] = copyToArgOfSlice(c.Tmpfs)
- g[Mqueue] = copyToArgOfSlice(c.Mqueue)
- g[Dir] = copyToArgOfSlice(c.Dir)
- g[Symlink] = copyToArgOfSlice(c.Symlink)
-
- return
-}
diff --git a/bwrap/config.pair.go b/bwrap/config.pair.go
deleted file mode 100644
index b0b1001b..00000000
--- a/bwrap/config.pair.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package bwrap
-
-import "strconv"
-
-const (
- SetEnv = iota
-
- Bind
- BindTry
- DevBind
- DevBindTry
- ROBind
- ROBindTry
-
- Chmod
-
- pairC
-)
-
-var pairArgs = func() (n [pairC]string) {
- n[SetEnv] = "--setenv"
-
- n[Bind] = "--bind"
- n[BindTry] = "--bind-try"
- n[DevBind] = "--dev-bind"
- n[DevBindTry] = "--dev-bind-try"
- n[ROBind] = "--ro-bind"
- n[ROBindTry] = "--ro-bind-try"
-
- n[Chmod] = "--chmod"
-
- return
-}()
-
-func (c *Config) pairArgs() (n [pairC][][2]string) {
- n[SetEnv] = make([][2]string, 0, len(c.SetEnv))
- for k, v := range c.SetEnv {
- n[SetEnv] = append(n[SetEnv], [2]string{k, v})
- }
-
- n[Bind] = c.Bind
- n[BindTry] = c.BindTry
- n[DevBind] = c.DevBind
- n[DevBindTry] = c.DevBindTry
- n[ROBind] = c.ROBind
- n[ROBindTry] = c.ROBindTry
-
- n[Chmod] = make([][2]string, 0, len(c.Chmod))
- for path, octal := range c.Chmod {
- n[Chmod] = append(n[Chmod], [2]string{strconv.Itoa(int(octal)), path})
- }
-
- return
-}
diff --git a/bwrap/config.string.go b/bwrap/config.string.go
deleted file mode 100644
index c5c7a41e..00000000
--- a/bwrap/config.string.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package bwrap
-
-const (
- Hostname = iota
- Chdir
- UnsetEnv
- LockFile
- RemountRO
-
- stringC
-)
-
-var stringArgs = func() (n [stringC]string) {
- n[Hostname] = "--hostname"
- n[Chdir] = "--chdir"
- n[UnsetEnv] = "--unsetenv"
- n[LockFile] = "--lock-file"
- n[RemountRO] = "--remount-ro"
-
- return
-}()
-
-func (c *Config) stringArgs() (n [stringC][]string) {
- if c.Hostname != "" {
- n[Hostname] = []string{c.Hostname}
- }
- if c.Chdir != "" {
- n[Chdir] = []string{c.Chdir}
- }
- n[UnsetEnv] = c.UnsetEnv
- n[LockFile] = c.LockFile
- n[RemountRO] = c.RemountRO
-
- return
-}
diff --git a/bwrap/config_test.go b/bwrap/config_test.go
deleted file mode 100644
index d43c671d..00000000
--- a/bwrap/config_test.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package bwrap
-
-import (
- "slices"
- "testing"
-)
-
-func TestConfig_Args(t *testing.T) {
- testCases := []struct {
- name string
- conf *Config
- want []string
- }{
- {
- name: "xdg-dbus-proxy constraint sample",
- conf: &Config{
- Unshare: nil,
- UserNS: false,
- Clearenv: true,
- Symlink: []PermConfig[[2]string]{
- {Path: [2]string{"usr/bin", "/bin"}},
- {Path: [2]string{"var/home", "/home"}},
- {Path: [2]string{"usr/lib", "/lib"}},
- {Path: [2]string{"usr/lib64", "/lib64"}},
- {Path: [2]string{"run/media", "/media"}},
- {Path: [2]string{"var/mnt", "/mnt"}},
- {Path: [2]string{"var/opt", "/opt"}},
- {Path: [2]string{"sysroot/ostree", "/ostree"}},
- {Path: [2]string{"var/roothome", "/root"}},
- {Path: [2]string{"usr/sbin", "/sbin"}},
- {Path: [2]string{"var/srv", "/srv"}},
- },
- Bind: [][2]string{
- {"/run", "/run"},
- {"/tmp", "/tmp"},
- {"/var", "/var"},
- {"/run/user/1971/.dbus-proxy/", "/run/user/1971/.dbus-proxy/"},
- },
- ROBind: [][2]string{
- {"/boot", "/boot"},
- {"/dev", "/dev"},
- {"/proc", "/proc"},
- {"/sys", "/sys"},
- {"/sysroot", "/sysroot"},
- {"/usr", "/usr"},
- {"/etc", "/etc"},
- },
- DieWithParent: true,
- },
- want: []string{
- "--unshare-all",
- "--disable-userns",
- "--assert-userns-disabled",
- "--clearenv",
- "--die-with-parent",
- "--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",
- "--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"},
- },
- }
-
- 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)
- }
- })
- }
-}