aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--cmd/fpkg/app.go90
-rw-r--r--cmd/fpkg/build.nix4
-rw-r--r--cmd/fpkg/main.go12
-rw-r--r--cmd/fpkg/paths.go2
-rw-r--r--cmd/fpkg/test/foot.nix2
-rw-r--r--cmd/fpkg/test/test.py4
-rw-r--r--cmd/fpkg/with.go108
-rw-r--r--fst/config.go49
-rw-r--r--fst/container.go (renamed from fst/sandbox.go)14
-rw-r--r--fst/template.go130
-rw-r--r--fst/template_test.go206
-rw-r--r--internal/app/instance/common/container.go4
-rw-r--r--internal/app/internal/setuid/app_nixos_test.go64
-rw-r--r--internal/app/internal/setuid/app_pd_test.go80
-rw-r--r--internal/app/internal/setuid/process.go2
-rw-r--r--internal/app/internal/setuid/seal.go72
-rw-r--r--main.go26
-rw-r--r--nixos.nix147
-rw-r--r--print.go68
-rw-r--r--print_test.go572
-rw-r--r--test/test.py4
21 files changed, 831 insertions, 829 deletions
diff --git a/cmd/fpkg/app.go b/cmd/fpkg/app.go
index facf2dc2..72468700 100644
--- a/cmd/fpkg/app.go
+++ b/cmd/fpkg/app.go
@@ -19,7 +19,7 @@ type appInfo struct {
// passed through to [fst.Config]
ID string `json:"id"`
// passed through to [fst.Config]
- AppID int `json:"app_id"`
+ Identity int `json:"identity"`
// passed through to [fst.Config]
Groups []string `json:"groups,omitempty"`
// passed through to [fst.Config]
@@ -64,57 +64,61 @@ type appInfo struct {
func (app *appInfo) toFst(pathSet *appPathSet, argv []string, flagDropShell bool) *fst.Config {
config := &fst.Config{
- ID: app.ID,
+ ID: app.ID,
+
Path: argv[0],
Args: argv,
- Confinement: fst.ConfinementConfig{
- AppID: app.AppID,
- Groups: app.Groups,
- Username: "fortify",
- Inner: path.Join("/data/data", app.ID),
- Outer: pathSet.homeDir,
- Shell: shellPath,
- Sandbox: &fst.SandboxConfig{
- Hostname: formatHostname(app.Name),
- Devel: app.Devel,
- Userns: app.Userns,
- Net: app.Net,
- Device: app.Device,
- Tty: app.Tty || flagDropShell,
- MapRealUID: app.MapRealUID,
- DirectWayland: app.DirectWayland,
- Filesystem: []*fst.FilesystemConfig{
- {Src: path.Join(pathSet.nixPath, "store"), Dst: "/nix/store", Must: true},
- {Src: pathSet.metaPath, Dst: path.Join(fst.Tmp, "app"), Must: true},
- {Src: "/etc/resolv.conf"},
- {Src: "/sys/block"},
- {Src: "/sys/bus"},
- {Src: "/sys/class"},
- {Src: "/sys/dev"},
- {Src: "/sys/devices"},
- },
- Link: [][2]string{
- {app.CurrentSystem, "/run/current-system"},
- {"/run/current-system/sw/bin", "/bin"},
- {"/run/current-system/sw/bin", "/usr/bin"},
- },
- Etc: path.Join(pathSet.cacheDir, "etc"),
- AutoEtc: true,
+
+ Enablements: app.Enablements,
+
+ SystemBus: app.SystemBus,
+ SessionBus: app.SessionBus,
+ DirectWayland: app.DirectWayland,
+
+ Username: "fortify",
+ Shell: shellPath,
+ Data: pathSet.homeDir,
+ Dir: path.Join("/data/data", app.ID),
+
+ Identity: app.Identity,
+ Groups: app.Groups,
+
+ Container: &fst.ContainerConfig{
+ Hostname: formatHostname(app.Name),
+ Devel: app.Devel,
+ Userns: app.Userns,
+ Net: app.Net,
+ Device: app.Device,
+ Tty: app.Tty || flagDropShell,
+ MapRealUID: app.MapRealUID,
+ Filesystem: []*fst.FilesystemConfig{
+ {Src: path.Join(pathSet.nixPath, "store"), Dst: "/nix/store", Must: true},
+ {Src: pathSet.metaPath, Dst: path.Join(fst.Tmp, "app"), Must: true},
+ {Src: "/etc/resolv.conf"},
+ {Src: "/sys/block"},
+ {Src: "/sys/bus"},
+ {Src: "/sys/class"},
+ {Src: "/sys/dev"},
+ {Src: "/sys/devices"},
},
- ExtraPerms: []*fst.ExtraPermConfig{
- {Path: dataHome, Execute: true},
- {Ensure: true, Path: pathSet.baseDir, Read: true, Write: true, Execute: true},
+ Link: [][2]string{
+ {app.CurrentSystem, "/run/current-system"},
+ {"/run/current-system/sw/bin", "/bin"},
+ {"/run/current-system/sw/bin", "/usr/bin"},
},
- SystemBus: app.SystemBus,
- SessionBus: app.SessionBus,
- Enablements: app.Enablements,
+ Etc: path.Join(pathSet.cacheDir, "etc"),
+ AutoEtc: true,
+ },
+ ExtraPerms: []*fst.ExtraPermConfig{
+ {Path: dataHome, Execute: true},
+ {Ensure: true, Path: pathSet.baseDir, Read: true, Write: true, Execute: true},
},
}
if app.Multiarch {
- config.Confinement.Sandbox.Seccomp |= seccomp.FilterMultiarch
+ config.Container.Seccomp |= seccomp.FilterMultiarch
}
if app.Bluetooth {
- config.Confinement.Sandbox.Seccomp |= seccomp.FilterBluetooth
+ config.Container.Seccomp |= seccomp.FilterBluetooth
}
return config
}
diff --git a/cmd/fpkg/build.nix b/cmd/fpkg/build.nix
index 17dfa93e..0a0a558f 100644
--- a/cmd/fpkg/build.nix
+++ b/cmd/fpkg/build.nix
@@ -31,7 +31,7 @@
'',
id ? name,
- app_id ? throw "app_id is required",
+ identity ? throw "identity is required",
groups ? [ ],
userns ? false,
net ? true,
@@ -147,7 +147,7 @@ let
name
version
id
- app_id
+ identity
launcher
groups
userns
diff --git a/cmd/fpkg/main.go b/cmd/fpkg/main.go
index e48cfb57..ac95bc1f 100644
--- a/cmd/fpkg/main.go
+++ b/cmd/fpkg/main.go
@@ -157,11 +157,11 @@ func main() {
return errSuccess
}
- // AppID determines uid
- if a.AppID != bundle.AppID {
+ // identity determines uid
+ if a.Identity != bundle.Identity {
cleanup()
- log.Printf("package %q app id %d differs from installed %d",
- pkgPath, bundle.AppID, a.AppID)
+ log.Printf("package %q identity %d differs from installed %d",
+ pkgPath, bundle.Identity, a.Identity)
return syscall.EBADE
}
@@ -292,7 +292,7 @@ func main() {
"--override-input nixpkgs path:/etc/nixpkgs " +
"path:" + a.NixGL + "#nixVulkanNvidia",
}, true, func(config *fst.Config) *fst.Config {
- config.Confinement.Sandbox.Filesystem = append(config.Confinement.Sandbox.Filesystem, []*fst.FilesystemConfig{
+ config.Container.Filesystem = append(config.Container.Filesystem, []*fst.FilesystemConfig{
{Src: "/etc/resolv.conf"},
{Src: "/sys/block"},
{Src: "/sys/bus"},
@@ -324,7 +324,7 @@ func main() {
*/
if a.GPU {
- config.Confinement.Sandbox.Filesystem = append(config.Confinement.Sandbox.Filesystem,
+ config.Container.Filesystem = append(config.Container.Filesystem,
&fst.FilesystemConfig{Src: path.Join(pathSet.nixPath, ".nixGL"), Dst: path.Join(fst.Tmp, "nixGL")})
appendGPUFilesystem(config)
}
diff --git a/cmd/fpkg/paths.go b/cmd/fpkg/paths.go
index 3d832d65..2eaeb425 100644
--- a/cmd/fpkg/paths.go
+++ b/cmd/fpkg/paths.go
@@ -72,7 +72,7 @@ func pathSetByApp(id string) *appPathSet {
}
func appendGPUFilesystem(config *fst.Config) {
- config.Confinement.Sandbox.Filesystem = append(config.Confinement.Sandbox.Filesystem, []*fst.FilesystemConfig{
+ config.Container.Filesystem = append(config.Container.Filesystem, []*fst.FilesystemConfig{
// flatpak commit 763a686d874dd668f0236f911de00b80766ffe79
{Src: "/dev/dri", Device: true},
// mali
diff --git a/cmd/fpkg/test/foot.nix b/cmd/fpkg/test/foot.nix
index 34469da0..76b677ac 100644
--- a/cmd/fpkg/test/foot.nix
+++ b/cmd/fpkg/test/foot.nix
@@ -10,7 +10,7 @@ buildPackage {
name = "foot";
inherit (foot) version;
- app_id = 2;
+ identity = 2;
id = "org.codeberg.dnkl.foot";
modules = [
diff --git a/cmd/fpkg/test/test.py b/cmd/fpkg/test/test.py
index 7d4e0d58..641062f2 100644
--- a/cmd/fpkg/test/test.py
+++ b/cmd/fpkg/test/test.py
@@ -65,8 +65,8 @@ def check_state(name, enablements):
if len(config['args']) != 1 or not (config['args'][0].startswith("/nix/store/")) or f"fortify-{name}-" not in (config['args'][0]):
raise Exception(f"unexpected args {instance['config']['args']}")
- if config['confinement']['enablements'] != enablements:
- raise Exception(f"unexpected enablements {instance['config']['confinement']['enablements']}")
+ if config['enablements'] != enablements:
+ raise Exception(f"unexpected enablements {instance['config']['enablements']}")
start_all()
diff --git a/cmd/fpkg/with.go b/cmd/fpkg/with.go
index 92c5ba9e..9de1a397 100644
--- a/cmd/fpkg/with.go
+++ b/cmd/fpkg/with.go
@@ -16,7 +16,8 @@ func withNixDaemon(
app *appInfo, pathSet *appPathSet, dropShell bool, beforeFail func(),
) {
mustRunAppDropShell(ctx, updateConfig(&fst.Config{
- ID: app.ID,
+ ID: app.ID,
+
Path: shellPath,
Args: []string{shellPath, "-lc", "rm -f /nix/var/nix/daemon-socket/socket && " +
// start nix-daemon
@@ -29,33 +30,34 @@ func withNixDaemon(
// terminate nix-daemon
" && pkill nix-daemon",
},
- Confinement: fst.ConfinementConfig{
- AppID: app.AppID,
- Username: "fortify",
- Inner: path.Join("/data/data", app.ID),
- Outer: pathSet.homeDir,
- Shell: shellPath,
- Sandbox: &fst.SandboxConfig{
- Hostname: formatHostname(app.Name) + "-" + action,
- Userns: true, // nix sandbox requires userns
- Net: net,
- Seccomp: seccomp.FilterMultiarch,
- Tty: dropShell,
- Filesystem: []*fst.FilesystemConfig{
- {Src: pathSet.nixPath, Dst: "/nix", Write: true, Must: true},
- },
- Link: [][2]string{
- {app.CurrentSystem, "/run/current-system"},
- {"/run/current-system/sw/bin", "/bin"},
- {"/run/current-system/sw/bin", "/usr/bin"},
- },
- Etc: path.Join(pathSet.cacheDir, "etc"),
- AutoEtc: true,
+
+ Username: "fortify",
+ Shell: shellPath,
+ Data: pathSet.homeDir,
+ Dir: path.Join("/data/data", app.ID),
+ ExtraPerms: []*fst.ExtraPermConfig{
+ {Path: dataHome, Execute: true},
+ {Ensure: true, Path: pathSet.baseDir, Read: true, Write: true, Execute: true},
+ },
+
+ Identity: app.Identity,
+
+ Container: &fst.ContainerConfig{
+ Hostname: formatHostname(app.Name) + "-" + action,
+ Userns: true, // nix sandbox requires userns
+ Net: net,
+ Seccomp: seccomp.FilterMultiarch,
+ Tty: dropShell,
+ Filesystem: []*fst.FilesystemConfig{
+ {Src: pathSet.nixPath, Dst: "/nix", Write: true, Must: true},
},
- ExtraPerms: []*fst.ExtraPermConfig{
- {Path: dataHome, Execute: true},
- {Ensure: true, Path: pathSet.baseDir, Read: true, Write: true, Execute: true},
+ Link: [][2]string{
+ {app.CurrentSystem, "/run/current-system"},
+ {"/run/current-system/sw/bin", "/bin"},
+ {"/run/current-system/sw/bin", "/usr/bin"},
},
+ Etc: path.Join(pathSet.cacheDir, "etc"),
+ AutoEtc: true,
},
}), dropShell, beforeFail)
}
@@ -65,36 +67,38 @@ func withCacheDir(
action string, command []string, workDir string,
app *appInfo, pathSet *appPathSet, dropShell bool, beforeFail func()) {
mustRunAppDropShell(ctx, &fst.Config{
- ID: app.ID,
+ ID: app.ID,
+
Path: shellPath,
Args: []string{shellPath, "-lc", strings.Join(command, " && ")},
- Confinement: fst.ConfinementConfig{
- AppID: app.AppID,
- Username: "nixos",
- Inner: path.Join("/data/data", app.ID, "cache"),
- Outer: pathSet.cacheDir, // this also ensures cacheDir via shim
- Shell: shellPath,
- Sandbox: &fst.SandboxConfig{
- Hostname: formatHostname(app.Name) + "-" + action,
- Seccomp: seccomp.FilterMultiarch,
- Tty: dropShell,
- Filesystem: []*fst.FilesystemConfig{
- {Src: path.Join(workDir, "nix"), Dst: "/nix", Must: true},
- {Src: workDir, Dst: path.Join(fst.Tmp, "bundle"), Must: true},
- },
- Link: [][2]string{
- {app.CurrentSystem, "/run/current-system"},
- {"/run/current-system/sw/bin", "/bin"},
- {"/run/current-system/sw/bin", "/usr/bin"},
- },
- Etc: path.Join(workDir, "etc"),
- AutoEtc: true,
+
+ Username: "nixos",
+ Shell: shellPath,
+ Data: pathSet.cacheDir, // this also ensures cacheDir via shim
+ Dir: path.Join("/data/data", app.ID, "cache"),
+ ExtraPerms: []*fst.ExtraPermConfig{
+ {Path: dataHome, Execute: true},
+ {Ensure: true, Path: pathSet.baseDir, Read: true, Write: true, Execute: true},
+ {Path: workDir, Execute: true},
+ },
+
+ Identity: app.Identity,
+
+ Container: &fst.ContainerConfig{
+ Hostname: formatHostname(app.Name) + "-" + action,
+ Seccomp: seccomp.FilterMultiarch,
+ Tty: dropShell,
+ Filesystem: []*fst.FilesystemConfig{
+ {Src: path.Join(workDir, "nix"), Dst: "/nix", Must: true},
+ {Src: workDir, Dst: path.Join(fst.Tmp, "bundle"), Must: true},
},
- ExtraPerms: []*fst.ExtraPermConfig{
- {Path: dataHome, Execute: true},
- {Ensure: true, Path: pathSet.baseDir, Read: true, Write: true, Execute: true},
- {Path: workDir, Execute: true},
+ Link: [][2]string{
+ {app.CurrentSystem, "/run/current-system"},
+ {"/run/current-system/sw/bin", "/bin"},
+ {"/run/current-system/sw/bin", "/usr/bin"},
},
+ Etc: path.Join(workDir, "etc"),
+ AutoEtc: true,
},
}, dropShell, beforeFail)
}
diff --git a/fst/config.go b/fst/config.go
index a56927f0..62c85701 100644
--- a/fst/config.go
+++ b/fst/config.go
@@ -8,7 +8,7 @@ import (
const Tmp = "/.fortify"
-// Config is used to seal an app
+// Config is used to seal an app implementation.
type Config struct {
// reverse-DNS style arbitrary identifier string from config;
// passed to wayland security-context-v1 as application ID
@@ -20,39 +20,40 @@ type Config struct {
// final args passed to container init
Args []string `json:"args"`
- Confinement ConfinementConfig `json:"confinement"`
-}
+ // system services to make available in the container
+ Enablements system.Enablement `json:"enablements"`
+
+ // session D-Bus proxy configuration;
+ // nil makes session bus proxy assume built-in defaults
+ SessionBus *dbus.Config `json:"session_bus,omitempty"`
+ // system D-Bus proxy configuration;
+ // nil disables system bus proxy
+ SystemBus *dbus.Config `json:"system_bus,omitempty"`
+ // direct access to wayland socket; when this gets set no attempt is made to attach security-context-v1
+ // and the bare socket is mounted to the sandbox
+ DirectWayland bool `json:"direct_wayland,omitempty"`
-// ConfinementConfig defines fortified child's confinement
-type ConfinementConfig struct {
- // numerical application id, determines uid in the init namespace
- AppID int `json:"app_id"`
- // list of supplementary groups to inherit
- Groups []string `json:"groups"`
// passwd username in container, defaults to passwd name of target uid or chronos
Username string `json:"username,omitempty"`
- // home directory in container, empty for outer
- Inner string `json:"home_inner"`
- // home directory in init namespace
- Outer string `json:"home"`
// absolute path to shell, empty for host shell
Shell string `json:"shell,omitempty"`
- // abstract sandbox configuration
- Sandbox *SandboxConfig `json:"sandbox"`
- // extra acl ops, runs after everything else
+ // absolute path to home directory in the init mount namespace
+ Data string `json:"data"`
+ // directory to enter and use as home in the container mount namespace, empty for Data
+ Dir string `json:"dir"`
+ // extra acl ops, dispatches before container init
ExtraPerms []*ExtraPermConfig `json:"extra_perms,omitempty"`
- // reference to a system D-Bus proxy configuration,
- // nil value disables system bus proxy
- SystemBus *dbus.Config `json:"system_bus,omitempty"`
- // reference to a session D-Bus proxy configuration,
- // nil value makes session bus proxy assume built-in defaults
- SessionBus *dbus.Config `json:"session_bus,omitempty"`
+ // numerical application id, used for init user namespace credentials
+ Identity int `json:"identity"`
+ // list of supplementary groups inherited by container processes
+ Groups []string `json:"groups"`
- // system resources to expose to the container
- Enablements system.Enablement `json:"enablements"`
+ // abstract container configuration baseline
+ Container *ContainerConfig `json:"container"`
}
+// ExtraPermConfig describes an acl update op.
type ExtraPermConfig struct {
Ensure bool `json:"ensure,omitempty"`
Path string `json:"path"`
diff --git a/fst/sandbox.go b/fst/container.go
index c4936a2e..1190caa3 100644
--- a/fst/sandbox.go
+++ b/fst/container.go
@@ -4,9 +4,9 @@ import (
"git.gensokyo.uk/security/fortify/sandbox/seccomp"
)
-// SandboxConfig describes resources made available to the sandbox.
type (
- SandboxConfig struct {
+ // ContainerConfig describes the container configuration baseline to which the app implementation adds upon.
+ ContainerConfig struct {
// container hostname
Hostname string `json:"hostname,omitempty"`
@@ -18,7 +18,7 @@ type (
Userns bool `json:"userns,omitempty"`
// share host net namespace
Net bool `json:"net,omitempty"`
- // expose main process tty
+ // allow dangerous terminal I/O
Tty bool `json:"tty,omitempty"`
// allow multiarch
Multiarch bool `json:"multiarch,omitempty"`
@@ -28,17 +28,13 @@ type (
// map target user uid to privileged user uid in the user namespace
MapRealUID bool `json:"map_real_uid"`
- // expose all devices
+ // pass through all devices
Device bool `json:"device,omitempty"`
// container host filesystem bind mounts
Filesystem []*FilesystemConfig `json:"filesystem"`
// create symlinks inside container filesystem
Link [][2]string `json:"symlink"`
- // direct access to wayland socket; when this gets set no attempt is made to attach security-context-v1
- // and the bare socket is mounted to the sandbox
- DirectWayland bool `json:"direct_wayland,omitempty"`
-
// read-only /etc directory
Etc string `json:"etc,omitempty"`
// automatically set up /etc symlinks
@@ -47,7 +43,7 @@ type (
Cover []string `json:"cover"`
}
- // FilesystemConfig is a representation of [sandbox.BindMount].
+ // FilesystemConfig is an abstract representation of a bind mount.
FilesystemConfig struct {
// mount point in container, same as src if empty
Dst string `json:"dst,omitempty"`
diff --git a/fst/template.go b/fst/template.go
index 0777c9d2..0ca928a1 100644
--- a/fst/template.go
+++ b/fst/template.go
@@ -9,7 +9,8 @@ import (
// Template returns a fully populated instance of Config.
func Template() *Config {
return &Config{
- ID: "org.chromium.Chromium",
+ ID: "org.chromium.Chromium",
+
Path: "/run/current-system/sw/bin/chromium",
Args: []string{
"chromium",
@@ -18,70 +19,73 @@ func Template() *Config {
"--enable-features=UseOzonePlatform",
"--ozone-platform=wayland",
},
- Confinement: ConfinementConfig{
- AppID: 9,
- Groups: []string{"video"},
- Username: "chronos",
- Outer: "/var/lib/persist/home/org.chromium.Chromium",
- Inner: "/var/lib/fortify",
- Shell: "/run/current-system/sw/bin/zsh",
- Sandbox: &SandboxConfig{
- Hostname: "localhost",
- Devel: true,
- Userns: true,
- Net: true,
- Device: true,
- Seccomp: seccomp.FilterMultiarch,
- Tty: true,
- Multiarch: true,
- MapRealUID: true,
- DirectWayland: false,
- // example API credentials pulled from Google Chrome
- // DO NOT USE THESE IN A REAL BROWSER
- Env: map[string]string{
- "GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY",
- "GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com",
- "GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT",
- },
- Filesystem: []*FilesystemConfig{
- {Src: "/nix/store"},
- {Src: "/run/current-system"},
- {Src: "/run/opengl-driver"},
- {Src: "/var/db/nix-channels"},
- {Src: "/var/lib/fortify/u0/org.chromium.Chromium",
- Dst: "/data/data/org.chromium.Chromium", Write: true, Must: true},
- {Src: "/dev/dri", Device: true},
- },
- Link: [][2]string{{"/run/user/65534", "/run/user/150"}},
- Etc: "/etc",
- AutoEtc: true,
- Cover: []string{"/var/run/nscd"},
- },
- ExtraPerms: []*ExtraPermConfig{
- {Path: "/var/lib/fortify/u0", Ensure: true, Execute: true},
- {Path: "/var/lib/fortify/u0/org.chromium.Chromium", Read: true, Write: true, Execute: true},
- },
- SystemBus: &dbus.Config{
- See: nil,
- Talk: []string{"org.bluez", "org.freedesktop.Avahi", "org.freedesktop.UPower"},
- Own: nil,
- Call: nil,
- Broadcast: nil,
- Log: false,
- Filter: true,
+
+ Enablements: system.EWayland | system.EDBus | system.EPulse,
+
+ SessionBus: &dbus.Config{
+ See: nil,
+ Talk: []string{"org.freedesktop.Notifications", "org.freedesktop.FileManager1", "org.freedesktop.ScreenSaver",
+ "org.freedesktop.secrets", "org.kde.kwalletd5", "org.kde.kwalletd6", "org.gnome.SessionManager"},
+ Own: []string{"org.chromium.Chromium.*", "org.mpris.MediaPlayer2.org.chromium.Chromium.*",
+ "org.mpris.MediaPlayer2.chromium.*"},
+ Call: map[string]string{"org.freedesktop.portal.*": "*"},
+ Broadcast: map[string]string{"org.freedesktop.portal.*": "@/org/freedesktop/portal/*"},
+ Log: false,
+ Filter: true,
+ },
+ SystemBus: &dbus.Config{
+ See: nil,
+ Talk: []string{"org.bluez", "org.freedesktop.Avahi", "org.freedesktop.UPower"},
+ Own: nil,
+ Call: nil,
+ Broadcast: nil,
+ Log: false,
+ Filter: true,
+ },
+ DirectWayland: false,
+
+ Username: "chronos",
+ Shell: "/run/current-system/sw/bin/zsh",
+ Data: "/var/lib/fortify/u0/org.chromium.Chromium",
+ Dir: "/data/data/org.chromium.Chromium",
+ ExtraPerms: []*ExtraPermConfig{
+ {Path: "/var/lib/fortify/u0", Ensure: true, Execute: true},
+ {Path: "/var/lib/fortify/u0/org.chromium.Chromium", Read: true, Write: true, Execute: true},
+ },
+
+ Identity: 9,
+ Groups: []string{"video", "dialout", "plugdev"},
+
+ Container: &ContainerConfig{
+ Hostname: "localhost",
+ Devel: true,
+ Userns: true,
+ Net: true,
+ Device: true,
+ Seccomp: seccomp.FilterMultiarch,
+ Tty: true,
+ Multiarch: true,
+ MapRealUID: true,
+ // example API credentials pulled from Google Chrome
+ // DO NOT USE THESE IN A REAL BROWSER
+ Env: map[string]string{
+ "GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY",
+ "GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com",
+ "GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT",
},
- SessionBus: &dbus.Config{
- See: nil,
- Talk: []string{"org.freedesktop.Notifications", "org.freedesktop.FileManager1", "org.freedesktop.ScreenSaver",
- "org.freedesktop.secrets", "org.kde.kwalletd5", "org.kde.kwalletd6", "org.gnome.SessionManager"},
- Own: []string{"org.chromium.Chromium.*", "org.mpris.MediaPlayer2.org.chromium.Chromium.*",
- "org.mpris.MediaPlayer2.chromium.*"},
- Call: map[string]string{"org.freedesktop.portal.*": "*"},
- Broadcast: map[string]string{"org.freedesktop.portal.*": "@/org/freedesktop/portal/*"},
- Log: false,
- Filter: true,
+ Filesystem: []*FilesystemConfig{
+ {Src: "/nix/store"},
+ {Src: "/run/current-system"},
+ {Src: "/run/opengl-driver"},
+ {Src: "/var/db/nix-channels"},
+ {Src: "/var/lib/fortify/u0/org.chromium.Chromium",
+ Dst: "/data/data/org.chromium.Chromium", Write: true, Must: true},
+ {Src: "/dev/dri", Device: true},
},
- Enablements: system.EWayland | system.EDBus | system.EPulse,
+ Link: [][2]string{{"/run/user/65534", "/run/user/150"}},
+ Etc: "/etc",
+ AutoEtc: true,
+ Cover: []string{"/var/run/nscd"},
},
}
}
diff --git a/fst/template_test.go b/fst/template_test.go
index 0ec2dae2..c7fd7804 100644
--- a/fst/template_test.go
+++ b/fst/template_test.go
@@ -18,116 +18,116 @@ func TestTemplate(t *testing.T) {
"--enable-features=UseOzonePlatform",
"--ozone-platform=wayland"
],
- "confinement": {
- "app_id": 9,
- "groups": [
- "video"
+ "enablements": 13,
+ "session_bus": {
+ "see": null,
+ "talk": [
+ "org.freedesktop.Notifications",
+ "org.freedesktop.FileManager1",
+ "org.freedesktop.ScreenSaver",
+ "org.freedesktop.secrets",
+ "org.kde.kwalletd5",
+ "org.kde.kwalletd6",
+ "org.gnome.SessionManager"
],
- "username": "chronos",
- "home_inner": "/var/lib/fortify",
- "home": "/var/lib/persist/home/org.chromium.Chromium",
- "shell": "/run/current-system/sw/bin/zsh",
- "sandbox": {
- "hostname": "localhost",
- "seccomp": 32,
- "devel": true,
- "userns": true,
- "net": true,
- "tty": true,
- "multiarch": true,
- "env": {
- "GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY",
- "GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com",
- "GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT"
- },
- "map_real_uid": true,
- "device": true,
- "filesystem": [
- {
- "src": "/nix/store"
- },
- {
- "src": "/run/current-system"
- },
- {
- "src": "/run/opengl-driver"
- },
- {
- "src": "/var/db/nix-channels"
- },
- {
- "dst": "/data/data/org.chromium.Chromium",
- "src": "/var/lib/fortify/u0/org.chromium.Chromium",
- "write": true,
- "require": true
- },
- {
- "src": "/dev/dri",
- "dev": true
- }
- ],
- "symlink": [
- [
- "/run/user/65534",
- "/run/user/150"
- ]
- ],
- "etc": "/etc",
- "auto_etc": true,
- "cover": [
- "/var/run/nscd"
- ]
+ "own": [
+ "org.chromium.Chromium.*",
+ "org.mpris.MediaPlayer2.org.chromium.Chromium.*",
+ "org.mpris.MediaPlayer2.chromium.*"
+ ],
+ "call": {
+ "org.freedesktop.portal.*": "*"
+ },
+ "broadcast": {
+ "org.freedesktop.portal.*": "@/org/freedesktop/portal/*"
+ },
+ "filter": true
+ },
+ "system_bus": {
+ "see": null,
+ "talk": [
+ "org.bluez",
+ "org.freedesktop.Avahi",
+ "org.freedesktop.UPower"
+ ],
+ "own": null,
+ "call": null,
+ "broadcast": null,
+ "filter": true
+ },
+ "username": "chronos",
+ "shell": "/run/current-system/sw/bin/zsh",
+ "data": "/var/lib/fortify/u0/org.chromium.Chromium",
+ "dir": "/data/data/org.chromium.Chromium",
+ "extra_perms": [
+ {
+ "ensure": true,
+ "path": "/var/lib/fortify/u0",
+ "x": true
},
- "extra_perms": [
+ {
+ "path": "/var/lib/fortify/u0/org.chromium.Chromium",
+ "r": true,
+ "w": true,
+ "x": true
+ }
+ ],
+ "identity": 9,
+ "groups": [
+ "video",
+ "dialout",
+ "plugdev"
+ ],
+ "container": {
+ "hostname": "localhost",
+ "seccomp": 32,
+ "devel": true,
+ "userns": true,
+ "net": true,
+ "tty": true,
+ "multiarch": true,
+ "env": {
+ "GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY",
+ "GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com",
+ "GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT"
+ },
+ "map_real_uid": true,
+ "device": true,
+ "filesystem": [
{
- "ensure": true,
- "path": "/var/lib/fortify/u0",
- "x": true
+ "src": "/nix/store"
},
{
- "path": "/var/lib/fortify/u0/org.chromium.Chromium",
- "r": true,
- "w": true,
- "x": true
- }
- ],
- "system_bus": {
- "see": null,
- "talk": [
- "org.bluez",
- "org.freedesktop.Avahi",
- "org.freedesktop.UPower"
- ],
- "own": null,
- "call": null,
- "broadcast": null,
- "filter": true
- },
- "session_bus": {
- "see": null,
- "talk": [
- "org.freedesktop.Notifications",
- "org.freedesktop.FileManager1",
- "org.freedesktop.ScreenSaver",
- "org.freedesktop.secrets",
- "org.kde.kwalletd5",
- "org.kde.kwalletd6",
- "org.gnome.SessionManager"
- ],
- "own": [
- "org.chromium.Chromium.*",
- "org.mpris.MediaPlayer2.org.chromium.Chromium.*",
- "org.mpris.MediaPlayer2.chromium.*"
- ],
- "call": {
- "org.freedesktop.portal.*": "*"
+ "src": "/run/current-system"
},
- "broadcast": {
- "org.freedesktop.portal.*": "@/org/freedesktop/portal/*"
+ {
+ "src": "/run/opengl-driver"
},
- "filter": true
- },
- "enablements": 13
+ {
+ "src": "/var/db/nix-channels"
+ },
+ {
+ "dst": "/data/data/org.chromium.Chromium",
+ "src": "/var/lib/fortify/u0/org.chromium.Chromium",
+ "write": true,
+ "require": true
+ },
+ {
+ "src": "/dev/dri",
+ "dev": true
+ }
+ ],
+ "symlink": [
+ [
+ "/run/user/65534",
+ "/run/user/150"
+ ]
+ ],
+ "etc": "/etc",
+ "auto_etc": true,
+ "cover": [
+ "/var/run/nscd"
+ ]
}
}`
diff --git a/internal/app/instance/common/container.go b/internal/app/instance/common/container.go
index cc26c803..370997aa 100644
--- a/internal/app/instance/common/container.go
+++ b/internal/app/instance/common/container.go
@@ -16,9 +16,9 @@ import (
"git.gensokyo.uk/security/fortify/sandbox/seccomp"
)
-// NewContainer initialises [sandbox.Params] via [fst.SandboxConfig].
+// NewContainer initialises [sandbox.Params] via [fst.ContainerConfig].
// Note that remaining container setup must be queued by the caller.
-func NewContainer(s *fst.SandboxConfig, os sys.State, uid, gid *int) (*sandbox.Params, map[string]string, error) {
+func NewContainer(s *fst.ContainerConfig, os sys.State, uid, gid *int) (*sandbox.Params, map[string]string, error) {
if s == nil {
return nil, nil, syscall.EBADE
}
diff --git a/internal/app/internal/setuid/app_nixos_test.go b/internal/app/internal/setuid/app_nixos_test.go
index 0daaf690..0e649ad4 100644
--- a/internal/app/internal/setuid/app_nixos_test.go
+++ b/internal/app/internal/setuid/app_nixos_test.go
@@ -13,41 +13,43 @@ var testCasesNixos = []sealTestCase{
{
"nixos chromium direct wayland", new(stubNixOS),
&fst.Config{
- ID: "org.chromium.Chromium",
- Path: "/nix/store/yqivzpzzn7z5x0lq9hmbzygh45d8rhqd-chromium-start",
- Confinement: fst.ConfinementConfig{
- AppID: 1, Groups: []string{}, Username: "u0_a1",
- Outer: "/var/lib/persist/module/fortify/0/1",
- Sandbox: &fst.SandboxConfig{
- Userns: true, Net: true, MapRealUID: true, DirectWayland: true, Env: nil, AutoEtc: true,
- Filesystem: []*fst.FilesystemConfig{
- {Src: "/bin", Must: true}, {Src: "/usr/bin", Must: true},
- {Src: "/nix/store", Must: true}, {Src: "/run/current-system", Must: true},
- {Src: "/sys/block"}, {Src: "/sys/bus"}, {Src: "/sys/class"}, {Src: "/sys/dev"}, {Src: "/sys/devices"},
- {Src: "/run/opengl-driver", Must: true}, {Src: "/dev/dri", Device: true},
- },
- Cover: []string{"/var/run/nscd"},
+ ID: "org.chromium.Chromium",
+ Path: "/nix/store/yqivzpzzn7z5x0lq9hmbzygh45d8rhqd-chromium-start",
+ Enablements: system.EWayland | system.EDBus | system.EPulse,
+
+ Container: &fst.ContainerConfig{
+ Userns: true, Net: true, MapRealUID: true, Env: nil, AutoEtc: true,
+ Filesystem: []*fst.FilesystemConfig{
+ {Src: "/bin", Must: true}, {Src: "/usr/bin", Must: true},
+ {Src: "/nix/store", Must: true}, {Src: "/run/current-system", Must: true},
+ {Src: "/sys/block"}, {Src: "/sys/bus"}, {Src: "/sys/class"}, {Src: "/sys/dev"}, {Src: "/sys/devices"},
+ {Src: "/run/opengl-driver", Must: true}, {Src: "/dev/dri", Device: true},
},
- SystemBus: &dbus.Config{
- Talk: []string{"org.bluez", "org.freedesktop.Avahi", "org.freedesktop.UPower"},
- Filter: true,
+ Cover: []string{"/var/run/nscd"},
+ },
+ SystemBus: &dbus.Config{
+ Talk: []string{"org.bluez", "org.freedesktop.Avahi", "org.freedesktop.UPower"},
+ Filter: true,
+ },
+ SessionBus: &dbus.Config{
+ Talk: []string{
+ "org.freedesktop.FileManager1", "org.freedesktop.Notifications",
+ "org.freedesktop.ScreenSaver", "org.freedesktop.secrets",
+ "org.kde.kwalletd5", "org.kde.kwalletd6",
},
- SessionBus: &dbus.Config{
- Talk: []string{
- "org.freedesktop.FileManager1", "org.freedesktop.Notifications",
- "org.freedesktop.ScreenSaver", "org.freedesktop.secrets",
- "org.kde.kwalletd5", "org.kde.kwalletd6",
- },
- Own: []string{
- "org.chromium.Chromium.*",
- "org.mpris.MediaPlayer2.org.chromium.Chromium.*",
- "org.mpris.MediaPlayer2.chromium.*",
- },
- Call: map[string]string{}, Broadcast: map[string]string{},
- Filter: true,
+ Own: []string{
+ "org.chromium.Chromium.*",
+ "org.mpris.MediaPlayer2.org.chromium.Chromium.*",
+ "org.mpris.MediaPlayer2.chromium.*",
},
- Enablements: system.EWayland | system.EDBus | system.EPulse,
+ Call: map[string]string{}, Broadcast: map[string]string{},
+ Filter: true,
},
+ DirectWayland: true,
+
+ Username: "u0_a1",
+ Data: "/var/lib/persist/module/fortify/0/1",
+ Identity: 1, Groups: []string{},
},
app.ID{
0x8e, 0x2c, 0x76, 0xb0,
diff --git a/internal/app/internal/setuid/app_pd_test.go b/internal/app/internal/setuid/app_pd_test.go
index 2dc06253..b331684b 100644
--- a/internal/app/internal/setuid/app_pd_test.go
+++ b/internal/app/internal/setuid/app_pd_test.go
@@ -14,13 +14,7 @@ import (
var testCasesPd = []sealTestCase{
{
"nixos permissive defaults no enablements", new(stubNixOS),
- &fst.Config{
- Confinement: fst.ConfinementConfig{
- AppID: 0,
- Username: "chronos",
- Outer: "/home/chronos",
- },
- },
+ &fst.Config{Username: "chronos", Data: "/home/chronos"},
app.ID{
0x4a, 0x45, 0x0b, 0x65,
0x96, 0xd7, 0xbc, 0x15,
@@ -77,46 +71,44 @@ var testCasesPd = []sealTestCase{
{
"nixos permissive defaults chromium", new(stubNixOS),
&fst.Config{
- ID: "org.chromium.Chromium",
- Args: []string{"zsh", "-c", "exec chromium "},
- Confinement: fst.ConfinementConfig{
- AppID: 9,
- Groups: []string{"video"},
- Username: "chronos",
- Outer: "/home/chronos",
- SessionBus: &dbus.Config{
- Talk: []string{
- "org.freedesktop.Notifications",
- "org.freedesktop.FileManager1",
- "org.freedesktop.ScreenSaver",
- "org.freedesktop.secrets",
- "org.kde.kwalletd5",
- "org.kde.kwalletd6",
- "org.gnome.SessionManager",
- },
- Own: []string{
- "org.chromium.Chromium.*",
- "org.mpris.MediaPlayer2.org.chromium.Chromium.*",
- "org.mpris.MediaPlayer2.chromium.*",
- },
- Call: map[string]string{
- "org.freedesktop.portal.*": "*",
- },
- Broadcast: map[string]string{
- "org.freedesktop.portal.*": "@/org/freedesktop/portal/*",
- },
- Filter: true,
+ ID: "org.chromium.Chromium",
+ Args: []string{"zsh", "-c", "exec chromium "},
+ Identity: 9,
+ Groups: []string{"video"},
+ Username: "chronos",
+ Data: "/home/chronos",
+ SessionBus: &dbus.Config{
+ Talk: []string{
+ "org.freedesktop.Notifications",
+ "org.freedesktop.FileManager1",
+ "org.freedesktop.ScreenSaver",
+ "org.freedesktop.secrets",
+ "org.kde.kwalletd5",
+ "org.kde.kwalletd6",
+ "org.gnome.SessionManager",
},
- SystemBus: &dbus.Config{
- Talk: []string{
- "org.bluez",
- "org.freedesktop.Avahi",
- "org.freedesktop.UPower",
- },
- Filter: true,
+ Own: []string{
+ "org.chromium.Chromium.*",
+ "org.mpris.MediaPlayer2.org.chromium.Chromium.*",
+ "org.mpris.MediaPlayer2.chromium.*",
},
- Enablements: system.EWayland | system.EDBus | system.EPulse,
+ Call: map[string]string{
+ "org.freedesktop.portal.*": "*",
+ },
+ Broadcast: map[string]string{
+ "org.freedesktop.portal.*": "@/org/freedesktop/portal/*",
+ },
+ Filter: true,
+ },
+ SystemBus: &dbus.Config{
+ Talk: []string{
+ "org.bluez",
+ "org.freedesktop.Avahi",
+ "org.freedesktop.UPower",
+ },
+ Filter: true,
},
+ Enablements: system.EWayland | system.EDBus | system.EPulse,
},
app.ID{
0xeb, 0xf0, 0x83, 0xd1,
diff --git a/internal/app/internal/setuid/process.go b/internal/app/internal/setuid/process.go
index 271e64e7..d3114c7a 100644
--- a/internal/app/internal/setuid/process.go
+++ b/internal/app/internal/setuid/process.go
@@ -65,7 +65,7 @@ func (seal *outcome) Run(rs *RunState) error {
// accumulate enablements of remaining launchers
for i, s := range states {
if s.Config != nil {
- rt |= s.Config.Confinement.Enablements
+ rt |= s.Config.Enablements
} else {
log.Printf("state entry %d does not contain config", i)
}
diff --git a/internal/app/internal/setuid/seal.go b/internal/app/internal/setuid/seal.go
index 44a73b1a..edf7c87b 100644
--- a/internal/app/internal/setuid/seal.go
+++ b/internal/app/internal/setuid/seal.go
@@ -169,16 +169,16 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *fst.Co
}
// allowed aid range 0 to 9999, this is checked again in fsu
- if config.Confinement.AppID < 0 || config.Confinement.AppID > 9999 {
+ if config.Identity < 0 || config.Identity > 9999 {
return fmsg.WrapError(ErrUser,
- fmt.Sprintf("aid %d out of range", config.Confinement.AppID))
+ fmt.Sprintf("identity %d out of range", config.Identity))
}
seal.user = fsuUser{
- aid: newInt(config.Confinement.AppID),
- data: config.Confinement.Outer,
- home: config.Confinement.Inner,
- username: config.Confinement.Username,
+ aid: newInt(config.Identity),
+ data: config.Data,
+ home: config.Dir,
+ username: config.Username,
}
if seal.user.username == "" {
seal.user.username = "chronos"
@@ -199,8 +199,8 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *fst.Co
} else {
seal.user.uid = newInt(u)
}
- seal.user.supp = make([]string, len(config.Confinement.Groups))
- for i, name := range config.Confinement.Groups {
+ seal.user.supp = make([]string, len(config.Groups))
+ for i, name := range config.Groups {
if g, err := sys.LookupGroup(name); err != nil {
return fmsg.WrapError(err,
fmt.Sprintf("unknown group %q", name))
@@ -210,17 +210,17 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *fst.Co
}
// this also falls back to host path if encountering an invalid path
- if !path.IsAbs(config.Confinement.Shell) {
- config.Confinement.Shell = "/bin/sh"
+ if !path.IsAbs(config.Shell) {
+ config.Shell = "/bin/sh"
if s, ok := sys.LookupEnv(shell); ok && path.IsAbs(s) {
- config.Confinement.Shell = s
+ config.Shell = s
}
}
// do not use the value of shell before this point
// permissive defaults
- if config.Confinement.Sandbox == nil {
- fmsg.Verbose("sandbox configuration not supplied, PROCEED WITH CAUTION")
+ if config.Container == nil {
+ fmsg.Verbose("container configuration not supplied, PROCEED WITH CAUTION")
// fsu clears the environment so resolve paths early
if !path.IsAbs(config.Path) {
@@ -231,11 +231,11 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *fst.Co
config.Path = p
}
} else {
- config.Path = config.Confinement.Shell
+ config.Path = config.Shell
}
}
- conf := &fst.SandboxConfig{
+ conf := &fst.ContainerConfig{
Userns: true,
Net: true,
Tty: true,
@@ -268,20 +268,20 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *fst.Co
conf.Cover = append(conf.Cover, nscd)
}
// bind GPU stuff
- if config.Confinement.Enablements&(system.EX11|system.EWayland) != 0 {
+ if config.Enablements&(system.EX11|system.EWayland) != 0 {
conf.Filesystem = append(conf.Filesystem, &fst.FilesystemConfig{Src: "/dev/dri", Device: true})
}
// opportunistically bind kvm
conf.Filesystem = append(conf.Filesystem, &fst.FilesystemConfig{Src: "/dev/kvm", Device: true})
- config.Confinement.Sandbox = conf
+ config.Container = conf
}
var mapuid, mapgid *stringPair[int]
{
var uid, gid int
var err error
- seal.container, seal.env, err = common.NewContainer(config.Confinement.Sandbox, sys, &uid, &gid)
+ seal.container, seal.env, err = common.NewContainer(config.Container, sys, &uid, &gid)
if err != nil {
return fmsg.WrapErrorSuffix(err,
"cannot initialise container configuration:")
@@ -303,12 +303,12 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *fst.Co
}
}
- if !config.Confinement.Sandbox.AutoEtc {
- if config.Confinement.Sandbox.Etc != "" {
- seal.container.Bind(config.Confinement.Sandbox.Etc, "/etc", 0)
+ if !config.Container.AutoEtc {
+ if config.Container.Etc != "" {
+ seal.container.Bind(config.Container.Etc, "/etc", 0)
}
} else {
- etcPath := config.Confinement.Sandbox.Etc
+ etcPath := config.Container.Etc
if etcPath == "" {
etcPath = "/etc"
}
@@ -352,10 +352,10 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *fst.Co
seal.container.Dir = homeDir
seal.env["HOME"] = homeDir
seal.env["USER"] = username
- seal.env[shell] = config.Confinement.Shell
+ seal.env[shell] = config.Shell
seal.container.Place("/etc/passwd",
- []byte(username+":x:"+mapuid.String()+":"+mapgid.String()+":Fortify:"+homeDir+":"+config.Confinement.Shell+"\n"))
+ []byte(username+":x:"+mapuid.String()+":"+mapgid.String()+":Fortify:"+homeDir+":"+config.Shell+"\n"))
seal.container.Place("/etc/group",
[]byte("fortify:x:"+mapgid.String()+":\n"))
}
@@ -365,7 +365,7 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *fst.Co
seal.env[term] = t
}
- if config.Confinement.Enablements&system.EWayland != 0 {
+ if config.Enablements&system.EWayland != 0 {
// outer wayland socket (usually `/run/user/%d/wayland-%d`)
var socketPath string
if name, ok := sys.LookupEnv(wl.WaylandDisplay); !ok {
@@ -380,7 +380,7 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *fst.Co
innerPath := path.Join(innerRuntimeDir, wl.FallbackName)
seal.env[wl.WaylandDisplay] = wl.FallbackName
- if !config.Confinement.Sandbox.DirectWayland { // set up security-context-v1
+ if !config.DirectWayland { // set up security-context-v1
appID := config.ID
if appID == "" {
// use instance ID in case app id is not set
@@ -398,7 +398,7 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *fst.Co
}
}
- if config.Confinement.Enablements&system.EX11 != 0 {
+ if config.Enablements&system.EX11 != 0 {
if d, ok := sys.LookupEnv(display); !ok {
return fmsg.WrapError(ErrXDisplay,
"DISPLAY is not set")
@@ -409,7 +409,7 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *fst.Co
}
}
- if config.Confinement.Enablements&system.EPulse != 0 {
+ if config.Enablements&system.EPulse != 0 {
// PulseAudio runtime directory (usually `/run/user/%d/pulse`)
pulseRuntimeDir := path.Join(share.sc.RuntimePath, "pulse")
// PulseAudio socket (usually `/run/user/%d/pulse/native`)
@@ -458,10 +458,10 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *fst.Co
}
}
- if config.Confinement.Enablements&system.EDBus != 0 {
+ if config.Enablements&system.EDBus != 0 {
// ensure dbus session bus defaults
- if config.Confinement.SessionBus == nil {
- config.Confinement.SessionBus = dbus.NewConfig(config.ID, true, true)
+ if config.SessionBus == nil {
+ config.SessionBus = dbus.NewConfig(config.ID, true, true)
}
// downstream socket paths
@@ -470,7 +470,7 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *fst.Co
// configure dbus proxy
if f, err := seal.sys.ProxyDBus(
- config.Confinement.SessionBus, config.Confinement.SystemBus,
+ config.SessionBus, config.SystemBus,
sessionPath, systemPath,
); err != nil {
return err
@@ -483,7 +483,7 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *fst.Co
seal.env[dbusSessionBusAddress] = "unix:path=" + sessionInner
seal.container.Bind(sessionPath, sessionInner, 0)
seal.sys.UpdatePerm(sessionPath, acl.Read, acl.Write)
- if config.Confinement.SystemBus != nil {
+ if config.SystemBus != nil {
systemInner := "/run/dbus/system_bus_socket"
seal.env[dbusSystemBusAddress] = "unix:path=" + systemInner
seal.container.Bind(systemPath, systemInner, 0)
@@ -491,12 +491,12 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *fst.Co
}
}
- for _, dest := range config.Confinement.Sandbox.Cover {
+ for _, dest := range config.Container.Cover {
seal.container.Tmpfs(dest, 1<<13, 0755)
}
// append ExtraPerms last
- for _, p := range config.Confinement.ExtraPerms {
+ for _, p := range config.ExtraPerms {
if p == nil {
continue
}
@@ -530,7 +530,7 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *fst.Co
slices.Sort(seal.container.Env)
fmsg.Verbosef("created application seal for uid %s (%s) groups: %v, argv: %s",
- seal.user.uid, seal.user.username, config.Confinement.Groups, seal.container.Args)
+ seal.user.uid, seal.user.username, config.Groups, seal.container.Args)
return nil
}
diff --git a/main.go b/main.go
index 1fe2f7a7..4c13edcb 100644
--- a/main.go
+++ b/main.go
@@ -154,33 +154,33 @@ func buildCommand(out io.Writer) command.Command {
userName = passwd.Username
}
- config.Confinement.AppID = aid
- config.Confinement.Groups = groups
- config.Confinement.Outer = homeDir
- config.Confinement.Username = userName
+ config.Identity = aid
+ config.Groups = groups
+ config.Data = homeDir
+ config.Username = userName
if wayland {
- config.Confinement.Enablements |= system.EWayland
+ config.Enablements |= system.EWayland
}
if x11 {
- config.Confinement.Enablements |= system.EX11
+ config.Enablements |= system.EX11
}
if dBus {
- config.Confinement.Enablements |= system.EDBus
+ config.Enablements |= system.EDBus
}
if pulse {
- config.Confinement.Enablements |= system.EPulse
+ config.Enablements |= system.EPulse
}
// parse D-Bus config file from flags if applicable
if dBus {
if dbusConfigSession == "builtin" {
- config.Confinement.SessionBus = dbus.NewConfig(fid, true, mpris)
+ config.SessionBus = dbus.NewConfig(fid, true, mpris)
} else {
if conf, err := dbus.NewConfigFromFile(dbusConfigSession); err != nil {
log.Fatalf("cannot load session bus proxy config from %q: %s", dbusConfigSession, err)
} else {
- config.Confinement.SessionBus = conf
+ config.SessionBus = conf
}
}
@@ -189,14 +189,14 @@ func buildCommand(out io.Writer) command.Command {
if conf, err := dbus.NewConfigFromFile(dbusConfigSystem); err != nil {
log.Fatalf("cannot load system bus proxy config from %q: %s", dbusConfigSystem, err)
} else {
- config.Confinement.SystemBus = conf
+ config.SystemBus = conf
}
}
// override log from configuration
if dbusVerbose {
- config.Confinement.SessionBus.Log = true
- config.Confinement.SystemBus.Log = true
+ config.SessionBus.Log = true
+ config.SystemBus.Log = true
}
}
diff --git a/nixos.nix b/nixos.nix
index 030cb3aa..49d41f33 100644
--- a/nixos.nix
+++ b/nixos.nix
@@ -88,6 +88,7 @@ in
conf = {
inherit (app) id;
+
path =
if app.path == null then
pkgs.writeScript "${app.name}-start" ''
@@ -98,88 +99,90 @@ in
app.path;
args = if app.args == null then [ "${app.name}-start" ] else app.args;
- confinement = {
- app_id = aid;
- inherit (app) groups;
- username = getsubname fid aid;
- home = getsubhome fid aid;
- sandbox = {
- inherit (app)
- devel
- userns
- net
- device
- tty
- multiarch
- env
- ;
- map_real_uid = app.mapRealUid;
- direct_wayland = app.insecureWayland;
+ inherit enablements;
+
+ inherit (dbusConfig) session_bus system_bus;
+ direct_wayland = app.insecureWayland;
+
+ username = getsubname fid aid;
+ data = getsubhome fid aid;
+
+ identity = aid;
+ inherit (app) groups;
- filesystem =
- let
- bind = src: { inherit src; };
- mustBind = src: {
- inherit src;
- require = true;
- };
- devBind = src: {
- inherit src;
- dev = true;
- };
- in
+ container = {
+ inherit (app)
+ devel
+ userns
+ net
+ device
+ tty
+ multiarch
+ env
+ ;
+ map_real_uid = app.mapRealUid;
+
+ filesystem =
+ let
+ bind = src: { inherit src; };
+ mustBind = src: {
+ inherit src;
+ require = true;
+ };
+ devBind = src: {
+ inherit src;
+ dev = true;
+ };
+ in
+ [
+ (mustBind "/bin")
+ (mustBind "/usr/bin")
+ (mustBind "/nix/store")
+ (bind "/sys/block")
+ (bind "/sys/bus")
+ (bind "/sys/class")
+ (bind "/sys/dev")
+ (bind "/sys/devices")
+ ]
+ ++ optionals app.nix [
+ (mustBind "/nix/var")
+ (bind "/var/db/nix-channels")
+ ]
+ ++ optionals isGraphical [
+ (devBind "/dev/dri")
+ (devBind "/dev/nvidiactl")
+ (devBind "/dev/nvidia-modeset")
+ (devBind "/dev/nvidia-uvm")
+ (devBind "/dev/nvidia-uvm-tools")
+ (devBind "/dev/nvidia0")
+ ]
+ ++ app.extraPaths;
+ auto_etc = true;
+ cover = [ "/var/run/nscd" ];
+
+ symlink =
+ [
[
- (mustBind "/bin")
- (mustBind "/usr/bin")
- (mustBind "/nix/store")
- (bind "/sys/block")
- (bind "/sys/bus")
- (bind "/sys/class")
- (bind "/sys/dev")
- (bind "/sys/devices")
- ]
- ++ optionals app.nix [
- (mustBind "/nix/var")
- (bind "/var/db/nix-channels")
+ "*/run/current-system"
+ "/run/current-system"
]
- ++ optionals isGraphical [
- (devBind "/dev/dri")
- (devBind "/dev/nvidiactl")
- (devBind "/dev/nvidia-modeset")
- (devBind "/dev/nvidia-uvm")
- (devBind "/dev/nvidia-uvm-tools")
- (devBind "/dev/nvidia0")
- ]
- ++ app.extraPaths;
- auto_etc = true;
- cover = [ "/var/run/nscd" ];
-
- symlink =
+ ]
+ ++ optionals (isGraphical && config.hardware.graphics.enable) (
[
[
- "*/run/current-system"
- "/run/current-system"
+ config.systemd.tmpfiles.settings.graphics-driver."/run/opengl-driver"."L+".argument
+ "/run/opengl-driver"
]
]
- ++ optionals (isGraphical && config.hardware.graphics.enable) (
+ ++ optionals (app.multiarch && config.hardware.graphics.enable32Bit) [
[
- [
- config.systemd.tmpfiles.settings.graphics-driver."/run/opengl-driver"."L+".argument
- "/run/opengl-driver"
- ]
+ config.systemd.tmpfiles.settings.graphics-driver."/run/opengl-driver-32"."L+".argument
+ /run/opengl-driver-32
]
- ++ optionals (app.multiarch && config.hardware.graphics.enable32Bit) [
- [
- config.systemd.tmpfiles.settings.graphics-driver."/run/opengl-driver-32"."L+".argument
- /run/opengl-driver-32
- ]
- ]
- );
- };
-
- inherit enablements;
- inherit (dbusConfig) session_bus system_bus;
+ ]
+ );
};
+
};
in
pkgs.writeShellScriptBin app.name ''
diff --git a/print.go b/print.go
index e77f60b3..2f679ebe 100644
--- a/print.go
+++ b/print.go
@@ -56,7 +56,7 @@ func printShowInstance(
t := newPrinter(output)
defer t.MustFlush()
- if config.Confinement.Sandbox == nil {
+ if config.Container == nil {
mustPrint(output, "Warning: this configuration uses permissive defaults!\n\n")
}
@@ -69,21 +69,21 @@ func printShowInstance(
t.Printf("App\n")
if config.ID != "" {
- t.Printf(" ID:\t%d (%s)\n", config.Confinement.AppID, config.ID)
+ t.Printf(" ID:\t%d (%s)\n", config.Identity, config.ID)
} else {
- t.Printf(" ID:\t%d\n", config.Confinement.AppID)
+ t.Printf(" ID:\t%d\n", config.Identity)
}
- t.Printf(" Enablements:\t%s\n", config.Confinement.Enablements.String())
- if len(config.Confinement.Groups) > 0 {
- t.Printf(" Groups:\t%q\n", config.Confinement.Groups)
+ t.Printf(" Enablements:\t%s\n", config.Enablements.String())
+ if len(config.Groups) > 0 {
+ t.Printf(" Groups:\t%s\n", strings.Join(config.Groups, ", "))
}
- if config.Confinement.Outer != "" {
- t.Printf(" Directory:\t%s\n", config.Confinement.Outer)
+ if config.Data != "" {
+ t.Printf(" Data:\t%s\n", config.Data)
}
- if config.Confinement.Sandbox != nil {
- sandbox := config.Confinement.Sandbox
- if sandbox.Hostname != "" {
- t.Printf(" Hostname:\t%q\n", sandbox.Hostname)
+ if config.Container != nil {
+ container := config.Container
+ if container.Hostname != "" {
+ t.Printf(" Hostname:\t%s\n", container.Hostname)
}
flags := make([]string, 0, 7)
writeFlag := func(name string, value bool) {
@@ -91,33 +91,29 @@ func printShowInstance(
flags = append(flags, name)
}
}
- writeFlag("userns", sandbox.Userns)
- writeFlag("devel", sandbox.Devel)
- writeFlag("net", sandbox.Net)
- writeFlag("device", sandbox.Device)
- writeFlag("tty", sandbox.Tty)
- writeFlag("mapuid", sandbox.MapRealUID)
- writeFlag("directwl", sandbox.DirectWayland)
- writeFlag("autoetc", sandbox.AutoEtc)
+ writeFlag("userns", container.Userns)
+ writeFlag("devel", container.Devel)
+ writeFlag("net", container.Net)
+ writeFlag("device", container.Device)
+ writeFlag("tty", container.Tty)
+ writeFlag("mapuid", container.MapRealUID)
+ writeFlag("directwl", config.DirectWayland)
+ writeFlag("autoetc", container.AutoEtc)
if len(flags) == 0 {
flags = append(flags, "none")
}
t.Printf(" Flags:\t%s\n", strings.Join(flags, " "))
- etc := sandbox.Etc
+ etc := container.Etc
if etc == "" {
etc = "/etc"
}
t.Printf(" Etc:\t%s\n", etc)
- if len(sandbox.Cover) > 0 {
- t.Printf(" Cover:\t%s\n", strings.Join(sandbox.Cover, " "))
+ if len(container.Cover) > 0 {
+ t.Printf(" Cover:\t%s\n", strings.Join(container.Cover, " "))
}
- // Env map[string]string `json:"env"`
- // Link [][2]string `json:"symlink"`
- }
- if config.Confinement.Sandbox != nil {
t.Printf(" Path:\t%s\n", config.Path)
}
if len(config.Args) > 0 {
@@ -126,9 +122,9 @@ func printShowInstance(
t.Printf("\n")
if !short {
- if config.Confinement.Sandbox != nil && len(config.Confinement.Sandbox.Filesystem) > 0 {
+ if config.Container != nil && len(config.Container.Filesystem) > 0 {
t.Printf("Filesystem\n")
- for _, f := range config.Confinement.Sandbox.Filesystem {
+ for _, f := range config.Container.Filesystem {
if f == nil {
continue
}
@@ -156,9 +152,9 @@ func printShowInstance(
}
t.Printf("\n")
}
- if len(config.Confinement.ExtraPerms) > 0 {
+ if len(config.ExtraPerms) > 0 {
t.Printf("Extra ACL\n")
- for _, p := range config.Confinement.ExtraPerms {
+ for _, p := range config.ExtraPerms {
if p == nil {
continue
}
@@ -186,14 +182,14 @@ func printShowInstance(
t.Printf(" Broadcast:\t%q\n", c.Broadcast)
}
}
- if config.Confinement.SessionBus != nil {
+ if config.SessionBus != nil {
t.Printf("Session bus\n")
- printDBus(config.Confinement.SessionBus)
+ printDBus(config.SessionBus)
t.Printf("\n")
}
- if config.Confinement.SystemBus != nil {
+ if config.SystemBus != nil {
t.Printf("System bus\n")
- printDBus(config.Confinement.SystemBus)
+ printDBus(config.SystemBus)
t.Printf("\n")
}
}
@@ -265,7 +261,7 @@ func printPs(output io.Writer, now time.Time, s state.Store, short, flagJSON boo
as := "(No configuration information)"
if e.Config != nil {
- as = strconv.Itoa(e.Config.Confinement.AppID)
+ as = strconv.Itoa(e.Config.Identity)
id := e.Config.ID
if id == "" {
id = "uk.gensokyo.fortify." + e.s[:8]
diff --git a/print_test.go b/print_test.go
index 1073a079..4e50dfd1 100644
--- a/print_test.go
+++ b/print_test.go
@@ -39,9 +39,9 @@ func Test_printShowInstance(t *testing.T) {
{"config", nil, fst.Template(), false, false, `App
ID: 9 (org.chromium.Chromium)
Enablements: wayland, dbus, pulseaudio
- Groups: ["video"]
- Directory: /var/lib/persist/home/org.chromium.Chromium
- Hostname: "localhost"
+ Groups: video, dialout, plugdev
+ Data: /var/lib/fortify/u0/org.chromium.Chromium
+ Hostname: localhost
Flags: userns devel net device tty mapuid autoetc
Etc: /etc
Cover: /var/run/nscd
@@ -79,7 +79,7 @@ App
Enablements: (no enablements)
`},
- {"config flag none", nil, &fst.Config{Confinement: fst.ConfinementConfig{Sandbox: new(fst.SandboxConfig)}}, false, false, `App
+ {"config flag none", nil, &fst.Config{Container: new(fst.ContainerConfig)}, false, false, `App
ID: 0
Enablements: (no enablements)
Flags: none
@@ -87,7 +87,7 @@ App
Path:
`},
- {"config nil entries", nil, &fst.Config{Confinement: fst.ConfinementConfig{Sandbox: &fst.SandboxConfig{Filesystem: make([]*fst.FilesystemConfig, 1)}, ExtraPerms: make([]*fst.ExtraPermConfig, 1)}}, false, false, `App
+ {"config nil entries", nil, &fst.Config{Container: &fst.ContainerConfig{Filesystem: make([]*fst.FilesystemConfig, 1)}, ExtraPerms: make([]*fst.ExtraPermConfig, 1)}, false, false, `App
ID: 0
Enablements: (no enablements)
Flags: none
@@ -99,7 +99,7 @@ Filesystem
Extra ACL
`},
- {"config pd dbus see", nil, &fst.Config{Confinement: fst.ConfinementConfig{SessionBus: &dbus.Config{See: []string{"org.example.test"}}}}, false, false, `Warning: this configuration uses permissive defaults!
+ {"config pd dbus see", nil, &fst.Config{SessionBus: &dbus.Config{See: []string{"org.example.test"}}}, false, false, `Warning: this configuration uses permissive defaults!
App
ID: 0
@@ -118,9 +118,9 @@ Session bus
App
ID: 9 (org.chromium.Chromium)
Enablements: wayland, dbus, pulseaudio
- Groups: ["video"]
- Directory: /var/lib/persist/home/org.chromium.Chromium
- Hostname: "localhost"
+ Groups: video, dialout, plugdev
+ Data: /var/lib/fortify/u0/org.chromium.Chromium
+ Hostname: localhost
Flags: userns devel net device tty mapuid autoetc
Etc: /etc
Cover: /var/run/nscd
@@ -195,141 +195,67 @@ App
"--enable-features=UseOzonePlatform",
"--ozone-platform=wayland"
],
- "confinement": {
- "app_id": 9,
- "groups": [
- "video"
+ "enablements": 13,
+ "session_bus": {
+ "see": null,
+ "talk": [
+ "org.freedesktop.Notifications",
+ "org.freedesktop.FileManager1",
+ "org.freedesktop.ScreenSaver",
+ "org.freedesktop.secrets",
+ "org.kde.kwalletd5",
+ "org.kde.kwalletd6",
+ "org.gnome.SessionManager"
],
- "username": "chronos",
- "home_inner": "/var/lib/fortify",
- "home": "/var/lib/persist/home/org.chromium.Chromium",
- "shell": "/run/current-system/sw/bin/zsh",
- "sandbox": {
- "hostname": "localhost",
- "seccomp": 32,
- "devel": true,
- "userns": true,
- "net": true,
- "tty": true,
- "multiarch": true,
- "env": {
- "GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY",
- "GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com",
- "GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT"
- },
- "map_real_uid": true,
- "device": true,
- "filesystem": [
- {
- "src": "/nix/store"
- },
- {
- "src": "/run/current-system"
- },
- {
- "src": "/run/opengl-driver"
- },
- {
- "src": "/var/db/nix-channels"
- },
- {
- "dst": "/data/data/org.chromium.Chromium",
- "src": "/var/lib/fortify/u0/org.chromium.Chromium",
- "write": true,
- "require": true
- },
- {
- "src": "/dev/dri",
- "dev": true
- }
- ],
- "symlink": [
- [
- "/run/user/65534",
- "/run/user/150"
- ]
- ],
- "etc": "/etc",
- "auto_etc": true,
- "cover": [
- "/var/run/nscd"
- ]
- },
- "extra_perms": [
- {
- "ensure": true,
- "path": "/var/lib/fortify/u0",
- "x": true
- },
- {
- "path": "/var/lib/fortify/u0/org.chromium.Chromium",
- "r": true,
- "w": true,
- "x": true
- }
+ "own": [
+ "org.chromium.Chromium.*",
+ "org.mpris.MediaPlayer2.org.chromium.Chromium.*",
+ "org.mpris.MediaPlayer2.chromium.*"
],
- "system_bus": {
- "see": null,
- "talk": [
- "org.bluez",
- "org.freedesktop.Avahi",
- "org.freedesktop.UPower"
- ],
- "own": null,
- "call": null,
- "broadcast": null,
- "filter": true
+ "call": {
+ "org.freedesktop.portal.*": "*"
},
- "session_bus": {
- "see": null,
- "talk": [
- "org.freedesktop.Notifications",
- "org.freedesktop.FileManager1",
- "org.freedesktop.ScreenSaver",
- "org.freedesktop.secrets",
- "org.kde.kwalletd5",
- "org.kde.kwalletd6",
- "org.gnome.SessionManager"
- ],
- "own": [
- "org.chromium.Chromium.*",
- "org.mpris.MediaPlayer2.org.chromium.Chromium.*",
- "org.mpris.MediaPlayer2.chromium.*"
- ],
- "call": {
- "org.freedesktop.portal.*": "*"
- },
- "broadcast": {
- "org.freedesktop.portal.*": "@/org/freedesktop/portal/*"
- },
- "filter": true
+ "broadcast": {
+ "org.freedesktop.portal.*": "@/org/freedesktop/portal/*"
},
- "enablements": 13
- }
- },
- "time": "1970-01-01T00:00:00.000000009Z"
-}
-`},
- {"json config", nil, fst.Template(), false, true, `{
- "id": "org.chromium.Chromium",
- "path": "/run/current-system/sw/bin/chromium",
- "args": [
- "chromium",
- "--ignore-gpu-blocklist",
- "--disable-smooth-scrolling",
- "--enable-features=UseOzonePlatform",
- "--ozone-platform=wayland"
- ],
- "confinement": {
- "app_id": 9,
- "groups": [
- "video"
- ],
+ "filter": true
+ },
+ "system_bus": {
+ "see": null,
+ "talk": [
+ "org.bluez",
+ "org.freedesktop.Avahi",
+ "org.freedesktop.UPower"
+ ],
+ "own": null,
+ "call": null,
+ "broadcast": null,
+ "filter": true
+ },
"username": "chronos",
- "home_inner": "/var/lib/fortify",
- "home": "/var/lib/persist/home/org.chromium.Chromium",
"shell": "/run/current-system/sw/bin/zsh",
- "sandbox": {
+ "data": "/var/lib/fortify/u0/org.chromium.Chromium",
+ "dir": "/data/data/org.chromium.Chromium",
+ "extra_perms": [
+ {
+ "ensure": true,
+ "path": "/var/lib/fortify/u0",
+ "x": true
+ },
+ {
+ "path": "/var/lib/fortify/u0/org.chromium.Chromium",
+ "r": true,
+ "w": true,
+ "x": true
+ }
+ ],
+ "identity": 9,
+ "groups": [
+ "video",
+ "dialout",
+ "plugdev"
+ ],
+ "container": {
"hostname": "localhost",
"seccomp": 32,
"devel": true,
@@ -379,57 +305,131 @@ App
"cover": [
"/var/run/nscd"
]
+ }
+ },
+ "time": "1970-01-01T00:00:00.000000009Z"
+}
+`},
+ {"json config", nil, fst.Template(), false, true, `{
+ "id": "org.chromium.Chromium",
+ "path": "/run/current-system/sw/bin/chromium",
+ "args": [
+ "chromium",
+ "--ignore-gpu-blocklist",
+ "--disable-smooth-scrolling",
+ "--enable-features=UseOzonePlatform",
+ "--ozone-platform=wayland"
+ ],
+ "enablements": 13,
+ "session_bus": {
+ "see": null,
+ "talk": [
+ "org.freedesktop.Notifications",
+ "org.freedesktop.FileManager1",
+ "org.freedesktop.ScreenSaver",
+ "org.freedesktop.secrets",
+ "org.kde.kwalletd5",
+ "org.kde.kwalletd6",
+ "org.gnome.SessionManager"
+ ],
+ "own": [
+ "org.chromium.Chromium.*",
+ "org.mpris.MediaPlayer2.org.chromium.Chromium.*",
+ "org.mpris.MediaPlayer2.chromium.*"
+ ],
+ "call": {
+ "org.freedesktop.portal.*": "*"
},
- "extra_perms": [
+ "broadcast": {
+ "org.freedesktop.portal.*": "@/org/freedesktop/portal/*"
+ },
+ "filter": true
+ },
+ "system_bus": {
+ "see": null,
+ "talk": [
+ "org.bluez",
+ "org.freedesktop.Avahi",
+ "org.freedesktop.UPower"
+ ],
+ "own": null,
+ "call": null,
+ "broadcast": null,
+ "filter": true
+ },
+ "username": "chronos",
+ "shell": "/run/current-system/sw/bin/zsh",
+ "data": "/var/lib/fortify/u0/org.chromium.Chromium",
+ "dir": "/data/data/org.chromium.Chromium",
+ "extra_perms": [
+ {
+ "ensure": true,
+ "path": "/var/lib/fortify/u0",
+ "x": true
+ },
+ {
+ "path": "/var/lib/fortify/u0/org.chromium.Chromium",
+ "r": true,
+ "w": true,
+ "x": true
+ }
+ ],
+ "identity": 9,
+ "groups": [
+ "video",
+ "dialout",
+ "plugdev"
+ ],
+ "container": {
+ "hostname": "localhost",
+ "seccomp": 32,
+ "devel": true,
+ "userns": true,
+ "net": true,
+ "tty": true,
+ "multiarch": true,
+ "env": {
+ "GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY",
+ "GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com",
+ "GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT"
+ },
+ "map_real_uid": true,
+ "device": true,
+ "filesystem": [
{
- "ensure": true,
- "path": "/var/lib/fortify/u0",
- "x": true
+ "src": "/nix/store"
},
{
- "path": "/var/lib/fortify/u0/org.chromium.Chromium",
- "r": true,
- "w": true,
- "x": true
- }
- ],
- "system_bus": {
- "see": null,
- "talk": [
- "org.bluez",
- "org.freedesktop.Avahi",
- "org.freedesktop.UPower"
- ],
- "own": null,
- "call": null,
- "broadcast": null,
- "filter": true
- },
- "session_bus": {
- "see": null,
- "talk": [
- "org.freedesktop.Notifications",
- "org.freedesktop.FileManager1",
- "org.freedesktop.ScreenSaver",
- "org.freedesktop.secrets",
- "org.kde.kwalletd5",
- "org.kde.kwalletd6",
- "org.gnome.SessionManager"
- ],
- "own": [
- "org.chromium.Chromium.*",
- "org.mpris.MediaPlayer2.org.chromium.Chromium.*",
- "org.mpris.MediaPlayer2.chromium.*"
- ],
- "call": {
- "org.freedesktop.portal.*": "*"
+ "src": "/run/current-system"
},
- "broadcast": {
- "org.freedesktop.portal.*": "@/org/freedesktop/portal/*"
+ {
+ "src": "/run/opengl-driver"
},
- "filter": true
- },
- "enablements": 13
+ {
+ "src": "/var/db/nix-channels"
+ },
+ {
+ "dst": "/data/data/org.chromium.Chromium",
+ "src": "/var/lib/fortify/u0/org.chromium.Chromium",
+ "write": true,
+ "require": true
+ },
+ {
+ "src": "/dev/dri",
+ "dev": true
+ }
+ ],
+ "symlink": [
+ [
+ "/run/user/65534",
+ "/run/user/150"
+ ]
+ ],
+ "etc": "/etc",
+ "auto_etc": true,
+ "cover": [
+ "/var/run/nscd"
+ ]
}
}
`},
@@ -499,116 +499,116 @@ func Test_printPs(t *testing.T) {
"--enable-features=UseOzonePlatform",
"--ozone-platform=wayland"
],
- "confinement": {
- "app_id": 9,
- "groups": [
- "video"
+ "enablements": 13,
+ "session_bus": {
+ "see": null,
+ "talk": [
+ "org.freedesktop.Notifications",
+ "org.freedesktop.FileManager1",
+ "org.freedesktop.ScreenSaver",
+ "org.freedesktop.secrets",
+ "org.kde.kwalletd5",
+ "org.kde.kwalletd6",
+ "org.gnome.SessionManager"
],
- "username": "chronos",
- "home_inner": "/var/lib/fortify",
- "home": "/var/lib/persist/home/org.chromium.Chromium",
- "shell": "/run/current-system/sw/bin/zsh",
- "sandbox": {
- "hostname": "localhost",
- "seccomp": 32,
- "devel": true,
- "userns": true,
- "net": true,
- "tty": true,
- "multiarch": true,
- "env": {
- "GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY",
- "GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com",
- "GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT"
- },
- "map_real_uid": true,
- "device": true,
- "filesystem": [
- {
- "src": "/nix/store"
- },
- {
- "src": "/run/current-system"
- },
- {
- "src": "/run/opengl-driver"
- },
- {
- "src": "/var/db/nix-channels"
- },
- {
- "dst": "/data/data/org.chromium.Chromium",
- "src": "/var/lib/fortify/u0/org.chromium.Chromium",
- "write": true,
- "require": true
- },
- {
- "src": "/dev/dri",
- "dev": true
- }
- ],
- "symlink": [
- [
- "/run/user/65534",
- "/run/user/150"
- ]
- ],
- "etc": "/etc",
- "auto_etc": true,
- "cover": [
- "/var/run/nscd"
- ]
+ "own": [
+ "org.chromium.Chromium.*",
+ "org.mpris.MediaPlayer2.org.chromium.Chromium.*",
+ "org.mpris.MediaPlayer2.chromium.*"
+ ],
+ "call": {
+ "org.freedesktop.portal.*": "*"
+ },
+ "broadcast": {
+ "org.freedesktop.portal.*": "@/org/freedesktop/portal/*"
+ },
+ "filter": true
+ },
+ "system_bus": {
+ "see": null,
+ "talk": [
+ "org.bluez",
+ "org.freedesktop.Avahi",
+ "org.freedesktop.UPower"
+ ],
+ "own": null,
+ "call": null,
+ "broadcast": null,
+ "filter": true
+ },
+ "username": "chronos",
+ "shell": "/run/current-system/sw/bin/zsh",
+ "data": "/var/lib/fortify/u0/org.chromium.Chromium",
+ "dir": "/data/data/org.chromium.Chromium",
+ "extra_perms": [
+ {
+ "ensure": true,
+ "path": "/var/lib/fortify/u0",
+ "x": true
+ },
+ {
+ "path": "/var/lib/fortify/u0/org.chromium.Chromium",
+ "r": true,
+ "w": true,
+ "x": true
+ }
+ ],
+ "identity": 9,
+ "groups": [
+ "video",
+ "dialout",
+ "plugdev"
+ ],
+ "container": {
+ "hostname": "localhost",
+ "seccomp": 32,
+ "devel": true,
+ "userns": true,
+ "net": true,
+ "tty": true,
+ "multiarch": true,
+ "env": {
+ "GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY",
+ "GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com",
+ "GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT"
},
- "extra_perms": [
+ "map_real_uid": true,
+ "device": true,
+ "filesystem": [
+ {
+ "src": "/nix/store"
+ },
{
- "ensure": true,
- "path": "/var/lib/fortify/u0",
- "x": true
+ "src": "/run/current-system"
},
{
- "path": "/var/lib/fortify/u0/org.chromium.Chromium",
- "r": true,
- "w": true,
- "x": true
- }
- ],
- "system_bus": {
- "see": null,
- "talk": [
- "org.bluez",
- "org.freedesktop.Avahi",
- "org.freedesktop.UPower"
- ],
- "own": null,
- "call": null,
- "broadcast": null,
- "filter": true
- },
- "session_bus": {
- "see": null,
- "talk": [
- "org.freedesktop.Notifications",
- "org.freedesktop.FileManager1",
- "org.freedesktop.ScreenSaver",
- "org.freedesktop.secrets",
- "org.kde.kwalletd5",
- "org.kde.kwalletd6",
- "org.gnome.SessionManager"
- ],
- "own": [
- "org.chromium.Chromium.*",
- "org.mpris.MediaPlayer2.org.chromium.Chromium.*",
- "org.mpris.MediaPlayer2.chromium.*"
- ],
- "call": {
- "org.freedesktop.portal.*": "*"
+ "src": "/run/opengl-driver"
},
- "broadcast": {
- "org.freedesktop.portal.*": "@/org/freedesktop/portal/*"
+ {
+ "src": "/var/db/nix-channels"
},
- "filter": true
- },
- "enablements": 13
+ {
+ "dst": "/data/data/org.chromium.Chromium",
+ "src": "/var/lib/fortify/u0/org.chromium.Chromium",
+ "write": true,
+ "require": true
+ },
+ {
+ "src": "/dev/dri",
+ "dev": true
+ }
+ ],
+ "symlink": [
+ [
+ "/run/user/65534",
+ "/run/user/150"
+ ]
+ ],
+ "etc": "/etc",
+ "auto_etc": true,
+ "cover": [
+ "/var/run/nscd"
+ ]
}
},
"time": "1970-01-01T00:00:00.000000009Z"
diff --git a/test/test.py b/test/test.py
index b7e85c14..d72dafbd 100644
--- a/test/test.py
+++ b/test/test.py
@@ -69,8 +69,8 @@ def check_state(name, enablements):
if len(config['args']) != 1 or config['args'][0] != command:
raise Exception(f"unexpected args {config['args']}")
- if config['confinement']['enablements'] != enablements:
- raise Exception(f"unexpected enablements {instance['config']['confinement']['enablements']}")
+ if config['enablements'] != enablements:
+ raise Exception(f"unexpected enablements {instance['config']['enablements']}")
def fortify(command):