app: filesystem struct that maps to all bwrap bind options

Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
This commit is contained in:
Ophestra Umiker 2024-10-12 22:33:04 +09:00
parent 283bcba05b
commit 805ef99f9b
Signed by: cat
SSH Key Fingerprint: SHA256:gQ67O0enBZ7UdZypgtspB2FDM1g3GVw8nX0XSdcFw8Q
3 changed files with 59 additions and 15 deletions

View File

@ -55,10 +55,21 @@ type SandboxConfig struct {
// final environment variables // final environment variables
Env map[string]string `json:"env"` Env map[string]string `json:"env"`
// paths made available within the sandbox // sandbox host filesystem access
Bind [][2]string `json:"bind"` Filesystem []*FilesystemConfig `json:"filesystem"`
// paths made available read-only within the sandbox }
ROBind [][2]string `json:"ro-bind"`
type FilesystemConfig struct {
// mount point in sandbox, same as src if empty
Dst string `json:"dst,omitempty"`
// host filesystem path to make available to sandbox
Src string `json:"src"`
// write access
Write bool `json:"write,omitempty"`
// device access
Device bool `json:"dev,omitempty"`
// exit if unable to share
Must bool `json:"require,omitempty"`
} }
func (s *SandboxConfig) Bwrap() *bwrap.Config { func (s *SandboxConfig) Bwrap() *bwrap.Config {
@ -72,8 +83,6 @@ func (s *SandboxConfig) Bwrap() *bwrap.Config {
Hostname: s.Hostname, Hostname: s.Hostname,
Clearenv: true, Clearenv: true,
SetEnv: s.Env, SetEnv: s.Env,
Bind: s.Bind,
ROBind: s.ROBind,
Procfs: []string{"/proc"}, Procfs: []string{"/proc"},
DevTmpfs: []string{"/dev"}, DevTmpfs: []string{"/dev"},
Mqueue: []string{"/dev/mqueue"}, Mqueue: []string{"/dev/mqueue"},
@ -87,6 +96,37 @@ func (s *SandboxConfig) Bwrap() *bwrap.Config {
conf.GID = &s.GID conf.GID = &s.GID
} }
for _, c := range s.Filesystem {
if c == nil {
continue
}
p := [2]string{c.Src, c.Dst}
if c.Dst == "" {
p[1] = c.Src
}
switch {
case c.Device:
if c.Must {
conf.DevBind = append(conf.DevBind, p)
} else {
conf.DevBindTry = append(conf.DevBindTry, p)
}
case c.Write:
if c.Must {
conf.Bind = append(conf.Bind, p)
} else {
conf.BindTry = append(conf.BindTry, p)
}
default:
if c.Must {
conf.ROBind = append(conf.ROBind, p)
} else {
conf.ROBindTry = append(conf.ROBindTry, p)
}
}
}
return conf return conf
} }
@ -119,8 +159,12 @@ func Template() *Config {
"GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com", "GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com",
"GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT", "GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT",
}, },
Bind: [][2]string{{"/sdcard", "/sdcard"}, {"/var/tmp", "/var/tmp"}}, Filesystem: []*FilesystemConfig{
ROBind: [][2]string{{"/nix", "/nix"}}, {Src: "/nix"},
{Src: "/storage/emulated/0", Write: true, Must: true},
{Src: "/data/user/0", Dst: "/data/data", Write: true, Must: true},
{Src: "/var/tmp", Write: true},
},
}, },
SystemBus: &dbus.Config{ SystemBus: &dbus.Config{
See: nil, See: nil,

View File

@ -127,7 +127,7 @@ func (a *app) Seal(config *Config) error {
if d, err := os.ReadDir("/"); err != nil { if d, err := os.ReadDir("/"); err != nil {
return err return err
} else { } else {
b := make([][2]string, 0, len(d)) b := make([]*FilesystemConfig, 0, len(d))
for _, ent := range d { for _, ent := range d {
name := ent.Name() name := ent.Name()
switch name { switch name {
@ -136,16 +136,16 @@ func (a *app) Seal(config *Config) error {
case "run": case "run":
default: default:
p := "/" + name p := "/" + name
b = append(b, [2]string{p, p}) b = append(b, &FilesystemConfig{Src: p, Write: true, Must: true})
} }
} }
conf.Bind = append(conf.Bind, b...) conf.Filesystem = append(conf.Filesystem, b...)
} }
// bind entries in /run // bind entries in /run
if d, err := os.ReadDir("/run"); err != nil { if d, err := os.ReadDir("/run"); err != nil {
return err return err
} else { } else {
b := make([][2]string, 0, len(d)) b := make([]*FilesystemConfig, 0, len(d))
for _, ent := range d { for _, ent := range d {
name := ent.Name() name := ent.Name()
switch name { switch name {
@ -153,10 +153,10 @@ func (a *app) Seal(config *Config) error {
case "dbus": case "dbus":
default: default:
p := "/run/" + name p := "/run/" + name
b = append(b, [2]string{p, p}) b = append(b, &FilesystemConfig{Src: p, Write: true, Must: true})
} }
} }
conf.Bind = append(conf.Bind, b...) conf.Filesystem = append(conf.Filesystem, b...)
} }
config.Confinement.Sandbox = conf config.Confinement.Sandbox = conf
} }

View File

@ -41,7 +41,7 @@ func (a *app) Start() error {
if s, err := exec.LookPath(n); err == nil { if s, err := exec.LookPath(n); err == nil {
e[i] = s e[i] = s
} else { } else {
return (*ProcessError)(wrapError(err, fmt.Sprintf("cannot find %q in PATH: %v", n, err))) return (*ProcessError)(wrapError(err, fmt.Sprintf("cannot find %q: %v", n, err)))
} }
} }
} }