197 lines
5.7 KiB
Go
197 lines
5.7 KiB
Go
package bwrap
|
|
|
|
import (
|
|
"encoding/gob"
|
|
"os"
|
|
"strconv"
|
|
)
|
|
|
|
func init() {
|
|
gob.Register(new(PermConfig[SymlinkConfig]))
|
|
gob.Register(new(PermConfig[*TmpfsConfig]))
|
|
}
|
|
|
|
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"`
|
|
|
|
// ordered filesystem args
|
|
Filesystem []FSBuilder
|
|
|
|
// change permissions (must already exist)
|
|
// (--chmod OCTAL PATH)
|
|
Chmod ChmodConfig `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 PermConfig[T FSBuilder] struct {
|
|
// set permissions of next argument
|
|
// (--perms OCTAL)
|
|
Mode *os.FileMode `json:"mode,omitempty"`
|
|
// path to get the new permission
|
|
// (--bind-data, --file, etc.)
|
|
Inner T `json:"path"`
|
|
}
|
|
|
|
func (p *PermConfig[T]) Path() string {
|
|
return p.Inner.Path()
|
|
}
|
|
|
|
func (p *PermConfig[T]) Len() int {
|
|
if p.Mode != nil {
|
|
return p.Inner.Len() + 2
|
|
} else {
|
|
return p.Inner.Len()
|
|
}
|
|
}
|
|
|
|
func (p *PermConfig[T]) Append(args *[]string) {
|
|
if p.Mode != nil {
|
|
*args = append(*args, intArgs[Perms], strconv.FormatInt(int64(*p.Mode), 8))
|
|
}
|
|
p.Inner.Append(args)
|
|
}
|
|
|
|
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"`
|
|
}
|
|
|
|
func (t *TmpfsConfig) Path() string {
|
|
return t.Dir
|
|
}
|
|
|
|
func (t *TmpfsConfig) Len() int {
|
|
if t.Size > 0 {
|
|
return 4
|
|
} else {
|
|
return 2
|
|
}
|
|
}
|
|
|
|
func (t *TmpfsConfig) Append(args *[]string) {
|
|
if t.Size > 0 {
|
|
*args = append(*args, intArgs[Size], strconv.Itoa(t.Size))
|
|
}
|
|
*args = append(*args, awkwardArgs[Tmpfs], t.Dir)
|
|
}
|
|
|
|
type SymlinkConfig [2]string
|
|
|
|
func (s SymlinkConfig) Path() string {
|
|
return s[1]
|
|
}
|
|
|
|
func (s SymlinkConfig) Len() int {
|
|
return 3
|
|
}
|
|
|
|
func (s SymlinkConfig) Append(args *[]string) {
|
|
*args = append(*args, awkwardArgs[Symlink], s[0], s[1])
|
|
}
|
|
|
|
type ChmodConfig map[string]os.FileMode
|
|
|
|
func (c ChmodConfig) Len() int {
|
|
return len(c)
|
|
}
|
|
|
|
func (c ChmodConfig) Append(args *[]string) {
|
|
for path, mode := range c {
|
|
*args = append(*args, pairArgs[Chmod], strconv.FormatInt(int64(mode), 8), path)
|
|
}
|
|
}
|