app: separate auto etc from permissive defaults
test / test (push) Successful in 23s
Details
test / test (push) Successful in 23s
Details
Populating /etc with symlinks is quite useful even outside the permissive defaults usage pattern. Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
This commit is contained in:
parent
d909b1190a
commit
fc25ac2523
|
@ -58,7 +58,6 @@ var testCasesNixos = []sealTestCase{
|
||||||
Tmpfs("/dev/fortify", 4096).
|
Tmpfs("/dev/fortify", 4096).
|
||||||
Bind("/bin", "/bin", false, true).
|
Bind("/bin", "/bin", false, true).
|
||||||
Bind("/boot", "/boot", false, true).
|
Bind("/boot", "/boot", false, true).
|
||||||
Bind("/etc", "/dev/fortify/etc").
|
|
||||||
Bind("/home", "/home", false, true).
|
Bind("/home", "/home", false, true).
|
||||||
Bind("/lib", "/lib", false, true).
|
Bind("/lib", "/lib", false, true).
|
||||||
Bind("/lib64", "/lib64", false, true).
|
Bind("/lib64", "/lib64", false, true).
|
||||||
|
@ -102,6 +101,7 @@ var testCasesNixos = []sealTestCase{
|
||||||
Bind("/run/wrappers", "/run/wrappers", false, true).
|
Bind("/run/wrappers", "/run/wrappers", false, true).
|
||||||
Bind("/run/zed.pid", "/run/zed.pid", false, true).
|
Bind("/run/zed.pid", "/run/zed.pid", false, true).
|
||||||
Bind("/run/zed.state", "/run/zed.state", false, true).
|
Bind("/run/zed.state", "/run/zed.state", false, true).
|
||||||
|
Bind("/etc", "/dev/fortify/etc").
|
||||||
Symlink("/dev/fortify/etc/alsa", "/etc/alsa").
|
Symlink("/dev/fortify/etc/alsa", "/etc/alsa").
|
||||||
Symlink("/dev/fortify/etc/bashrc", "/etc/bashrc").
|
Symlink("/dev/fortify/etc/bashrc", "/etc/bashrc").
|
||||||
Symlink("/dev/fortify/etc/binfmt.d", "/etc/binfmt.d").
|
Symlink("/dev/fortify/etc/binfmt.d", "/etc/binfmt.d").
|
||||||
|
@ -308,7 +308,6 @@ var testCasesNixos = []sealTestCase{
|
||||||
Tmpfs("/dev/fortify", 4096).
|
Tmpfs("/dev/fortify", 4096).
|
||||||
Bind("/bin", "/bin", false, true).
|
Bind("/bin", "/bin", false, true).
|
||||||
Bind("/boot", "/boot", false, true).
|
Bind("/boot", "/boot", false, true).
|
||||||
Bind("/etc", "/dev/fortify/etc").
|
|
||||||
Bind("/home", "/home", false, true).
|
Bind("/home", "/home", false, true).
|
||||||
Bind("/lib", "/lib", false, true).
|
Bind("/lib", "/lib", false, true).
|
||||||
Bind("/lib64", "/lib64", false, true).
|
Bind("/lib64", "/lib64", false, true).
|
||||||
|
@ -353,6 +352,7 @@ var testCasesNixos = []sealTestCase{
|
||||||
Bind("/run/zed.pid", "/run/zed.pid", false, true).
|
Bind("/run/zed.pid", "/run/zed.pid", false, true).
|
||||||
Bind("/run/zed.state", "/run/zed.state", false, true).
|
Bind("/run/zed.state", "/run/zed.state", false, true).
|
||||||
Bind("/dev/dri", "/dev/dri", true, true, true).
|
Bind("/dev/dri", "/dev/dri", true, true, true).
|
||||||
|
Bind("/etc", "/dev/fortify/etc").
|
||||||
Symlink("/dev/fortify/etc/alsa", "/etc/alsa").
|
Symlink("/dev/fortify/etc/alsa", "/etc/alsa").
|
||||||
Symlink("/dev/fortify/etc/bashrc", "/etc/bashrc").
|
Symlink("/dev/fortify/etc/bashrc", "/etc/bashrc").
|
||||||
Symlink("/dev/fortify/etc/binfmt.d", "/etc/binfmt.d").
|
Symlink("/dev/fortify/etc/binfmt.d", "/etc/binfmt.d").
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"errors"
|
||||||
|
|
||||||
"git.ophivana.moe/security/fortify/dbus"
|
"git.ophivana.moe/security/fortify/dbus"
|
||||||
"git.ophivana.moe/security/fortify/helper/bwrap"
|
"git.ophivana.moe/security/fortify/helper/bwrap"
|
||||||
|
"git.ophivana.moe/security/fortify/internal/linux"
|
||||||
"git.ophivana.moe/security/fortify/internal/system"
|
"git.ophivana.moe/security/fortify/internal/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -60,6 +61,8 @@ type SandboxConfig struct {
|
||||||
Filesystem []*FilesystemConfig `json:"filesystem"`
|
Filesystem []*FilesystemConfig `json:"filesystem"`
|
||||||
// symlinks created inside the sandbox
|
// symlinks created inside the sandbox
|
||||||
Link [][2]string `json:"symlink"`
|
Link [][2]string `json:"symlink"`
|
||||||
|
// automatically set up /etc symlinks
|
||||||
|
AutoEtc bool `json:"auto_etc"`
|
||||||
// paths to override by mounting tmpfs over them
|
// paths to override by mounting tmpfs over them
|
||||||
Override []string `json:"override"`
|
Override []string `json:"override"`
|
||||||
}
|
}
|
||||||
|
@ -79,13 +82,16 @@ type FilesystemConfig struct {
|
||||||
|
|
||||||
// Bwrap returns the address of the corresponding bwrap.Config to s.
|
// Bwrap returns the address of the corresponding bwrap.Config to s.
|
||||||
// Note that remaining tmpfs entries must be queued by the caller prior to launch.
|
// Note that remaining tmpfs entries must be queued by the caller prior to launch.
|
||||||
func (s *SandboxConfig) Bwrap(uid int) *bwrap.Config {
|
func (s *SandboxConfig) Bwrap(os linux.System) (*bwrap.Config, error) {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return nil
|
return nil, errors.New("nil sandbox config")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var uid int
|
||||||
if !s.UseRealUID {
|
if !s.UseRealUID {
|
||||||
uid = 65534
|
uid = 65534
|
||||||
|
} else {
|
||||||
|
uid = os.Geteuid()
|
||||||
}
|
}
|
||||||
|
|
||||||
conf := (&bwrap.Config{
|
conf := (&bwrap.Config{
|
||||||
|
@ -99,12 +105,16 @@ func (s *SandboxConfig) Bwrap(uid int) *bwrap.Config {
|
||||||
AsInit: true,
|
AsInit: true,
|
||||||
|
|
||||||
// initialise map
|
// initialise map
|
||||||
Chmod: make(map[string]os.FileMode),
|
Chmod: make(bwrap.ChmodConfig),
|
||||||
}).
|
}).
|
||||||
SetUID(uid).SetGID(uid).
|
SetUID(uid).SetGID(uid).
|
||||||
Procfs("/proc").DevTmpfs("/dev").Mqueue("/dev/mqueue").
|
Procfs("/proc").DevTmpfs("/dev").Mqueue("/dev/mqueue").
|
||||||
Tmpfs("/dev/fortify", 4*1024)
|
Tmpfs("/dev/fortify", 4*1024)
|
||||||
|
|
||||||
|
if !s.AutoEtc {
|
||||||
|
conf.Dir("/etc")
|
||||||
|
}
|
||||||
|
|
||||||
for _, c := range s.Filesystem {
|
for _, c := range s.Filesystem {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
continue
|
continue
|
||||||
|
@ -121,7 +131,29 @@ func (s *SandboxConfig) Bwrap(uid int) *bwrap.Config {
|
||||||
conf.Symlink(l[0], l[1])
|
conf.Symlink(l[0], l[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
return conf
|
if s.AutoEtc {
|
||||||
|
conf.Bind("/etc", "/dev/fortify/etc")
|
||||||
|
|
||||||
|
// link host /etc contents to prevent passwd/group from being overwritten
|
||||||
|
if d, err := os.ReadDir("/etc"); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
for _, ent := range d {
|
||||||
|
name := ent.Name()
|
||||||
|
switch name {
|
||||||
|
case "passwd":
|
||||||
|
case "group":
|
||||||
|
|
||||||
|
case "mtab":
|
||||||
|
conf.Symlink("/proc/mounts", "/etc/"+name)
|
||||||
|
default:
|
||||||
|
conf.Symlink("/dev/fortify/etc/"+name, "/etc/"+name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return conf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Template returns a fully populated instance of Config.
|
// Template returns a fully populated instance of Config.
|
||||||
|
@ -153,12 +185,15 @@ func Template() *Config {
|
||||||
"GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT",
|
"GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT",
|
||||||
},
|
},
|
||||||
Filesystem: []*FilesystemConfig{
|
Filesystem: []*FilesystemConfig{
|
||||||
{Src: "/nix"},
|
{Src: "/nix/store"},
|
||||||
{Src: "/storage/emulated/0", Write: true, Must: true},
|
{Src: "/run/current-system"},
|
||||||
{Src: "/data/user/0", Dst: "/data/data", Write: true, Must: true},
|
{Src: "/run/opengl-driver"},
|
||||||
{Src: "/var/tmp", Write: true},
|
{Src: "/var/db/nix-channels"},
|
||||||
|
{Src: "/home/chronos", Write: true, Must: true},
|
||||||
|
{Src: "/dev/dri", Device: true},
|
||||||
},
|
},
|
||||||
Link: [][2]string{{"/dev/fortify/etc", "/etc"}},
|
Link: [][2]string{{"/run/user/65534", "/run/user/150"}},
|
||||||
|
AutoEtc: true,
|
||||||
Override: []string{"/var/run/nscd"},
|
Override: []string{"/var/run/nscd"},
|
||||||
},
|
},
|
||||||
SystemBus: &dbus.Config{
|
SystemBus: &dbus.Config{
|
||||||
|
|
|
@ -159,6 +159,7 @@ func (a *app) Seal(config *Config) error {
|
||||||
UserNS: true,
|
UserNS: true,
|
||||||
Net: true,
|
Net: true,
|
||||||
NoNewSession: true,
|
NoNewSession: true,
|
||||||
|
AutoEtc: true,
|
||||||
}
|
}
|
||||||
// bind entries in /
|
// bind entries in /
|
||||||
if d, err := a.os.ReadDir("/"); err != nil {
|
if d, err := a.os.ReadDir("/"); err != nil {
|
||||||
|
@ -173,9 +174,8 @@ func (a *app) Seal(config *Config) error {
|
||||||
case "/run":
|
case "/run":
|
||||||
case "/tmp":
|
case "/tmp":
|
||||||
case "/mnt":
|
case "/mnt":
|
||||||
|
|
||||||
case "/etc":
|
case "/etc":
|
||||||
b = append(b, &FilesystemConfig{Src: p, Dst: "/dev/fortify/etc", Write: false, Must: true})
|
|
||||||
default:
|
default:
|
||||||
b = append(b, &FilesystemConfig{Src: p, Write: true, Must: true})
|
b = append(b, &FilesystemConfig{Src: p, Write: true, Must: true})
|
||||||
}
|
}
|
||||||
|
@ -208,35 +208,14 @@ func (a *app) Seal(config *Config) error {
|
||||||
if config.Confinement.Enablements.Has(system.EX11) || config.Confinement.Enablements.Has(system.EWayland) {
|
if config.Confinement.Enablements.Has(system.EX11) || config.Confinement.Enablements.Has(system.EWayland) {
|
||||||
conf.Filesystem = append(conf.Filesystem, &FilesystemConfig{Src: "/dev/dri", Device: true})
|
conf.Filesystem = append(conf.Filesystem, &FilesystemConfig{Src: "/dev/dri", Device: true})
|
||||||
}
|
}
|
||||||
// link host /etc to prevent passwd/group from being overwritten
|
|
||||||
if d, err := a.os.ReadDir("/etc"); err != nil {
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
b := make([][2]string, 0, len(d))
|
|
||||||
for _, ent := range d {
|
|
||||||
name := ent.Name()
|
|
||||||
switch name {
|
|
||||||
case "passwd":
|
|
||||||
case "group":
|
|
||||||
|
|
||||||
case "mtab":
|
|
||||||
b = append(b, [2]string{
|
|
||||||
"/proc/mounts",
|
|
||||||
"/etc/" + name,
|
|
||||||
})
|
|
||||||
default:
|
|
||||||
b = append(b, [2]string{
|
|
||||||
"/dev/fortify/etc/" + name,
|
|
||||||
"/etc/" + name,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
conf.Link = append(conf.Link, b...)
|
|
||||||
}
|
|
||||||
|
|
||||||
config.Confinement.Sandbox = conf
|
config.Confinement.Sandbox = conf
|
||||||
}
|
}
|
||||||
seal.sys.bwrap = config.Confinement.Sandbox.Bwrap(a.os.Geteuid())
|
if b, err := config.Confinement.Sandbox.Bwrap(a.os); err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
seal.sys.bwrap = b
|
||||||
|
}
|
||||||
seal.sys.override = config.Confinement.Sandbox.Override
|
seal.sys.override = config.Confinement.Sandbox.Override
|
||||||
if seal.sys.bwrap.SetEnv == nil {
|
if seal.sys.bwrap.SetEnv == nil {
|
||||||
seal.sys.bwrap.SetEnv = make(map[string]string)
|
seal.sys.bwrap.SetEnv = make(map[string]string)
|
||||||
|
|
Loading…
Reference in New Issue