Compare commits

..

No commits in common. "5c73acb56f81d820fdacc4ceff4f00f869318dbc" and "195b717e01ede09cc6fc608ecf72855b49316687" have entirely different histories.

15 changed files with 403 additions and 716 deletions

View File

@ -1,8 +1,7 @@
#compdef fortify #compdef fortify
_fortify_app() { _fortify_app() {
__fortify_files _path_files -g "*.(json|ftfy)"
return $?
} }
_fortify_run() { _fortify_run() {
@ -22,41 +21,12 @@ _fortify_run() {
'--dbus-log[Force logging in the D-Bus proxy]' '--dbus-log[Force logging in the D-Bus proxy]'
} }
_fortify_ps() {
_arguments \
'--short[Print instance id]'
}
_fortify_show() {
_alternative \
'instances:domains:__fortify_instances' \
'files:files:__fortify_files'
}
__fortify_files() {
_files -g "*.(json|ftfy)"
return $?
}
__fortify_instances() {
local -a out
shift -p
out=( ${(f)"$(_call_program commands fortify ps --short 2>&1)"} )
if (( $#out == 0 )); then
_message "No active instances"
else
_describe "active instances" out
fi
return $?
}
(( $+functions[_fortify_commands] )) || _fortify_commands() (( $+functions[_fortify_commands] )) || _fortify_commands()
{ {
local -a _fortify_cmds local -a _fortify_cmds
_fortify_cmds=( _fortify_cmds=(
"app:Launch app defined by the specified config file" "app:Launch app defined by the specified config file"
"run:Configure and start a permissive default sandbox" "run:Configure and start a permissive default sandbox"
"show:Show the contents of an app configuration"
"ps:List active apps and their state" "ps:List active apps and their state"
"version:Show fortify version" "version:Show fortify version"
"license:Show full license text" "license:Show full license text"
@ -64,7 +34,7 @@ __fortify_instances() {
"help:Show help message" "help:Show help message"
) )
if (( CURRENT == 1 )); then if (( CURRENT == 1 )); then
_describe -t commands 'action' _fortify_cmds || compadd "$@" _describe -t commands 'fortify command' _fortify_cmds || compadd "$@"
else else
local curcontext="$curcontext" local curcontext="$curcontext"
cmd="${${_fortify_cmds[(r)$words[1]:*]%%:*}}" cmd="${${_fortify_cmds[(r)$words[1]:*]%%:*}}"
@ -78,5 +48,4 @@ __fortify_instances() {
_arguments -C \ _arguments -C \
'-v[Verbose output]' \ '-v[Verbose output]' \
'--json[Format output in JSON when applicable]' \
'*::fortify command:_fortify_commands' '*::fortify command:_fortify_commands'

View File

@ -9,7 +9,7 @@ import (
"git.gensokyo.uk/security/fortify/internal/system" "git.gensokyo.uk/security/fortify/internal/system"
) )
const Tmp = "/.fortify" const fTmp = "/fortify"
// Config is used to seal an *App // Config is used to seal an *App
type Config struct { type Config struct {
@ -119,7 +119,7 @@ func (s *SandboxConfig) Bwrap(os linux.System) (*bwrap.Config, error) {
}). }).
SetUID(uid).SetGID(uid). SetUID(uid).SetGID(uid).
Procfs("/proc"). Procfs("/proc").
Tmpfs(Tmp, 4*1024) Tmpfs(fTmp, 4*1024)
if !s.Dev { if !s.Dev {
conf.DevTmpfs("/dev").Mqueue("/dev/mqueue") conf.DevTmpfs("/dev").Mqueue("/dev/mqueue")
@ -148,7 +148,7 @@ func (s *SandboxConfig) Bwrap(os linux.System) (*bwrap.Config, error) {
} }
if s.AutoEtc { if s.AutoEtc {
conf.Bind("/etc", Tmp+"/etc") conf.Bind("/etc", fTmp+"/etc")
// link host /etc contents to prevent passwd/group from being overwritten // link host /etc contents to prevent passwd/group from being overwritten
if d, err := os.ReadDir("/etc"); err != nil { if d, err := os.ReadDir("/etc"); err != nil {
@ -163,7 +163,7 @@ func (s *SandboxConfig) Bwrap(os linux.System) (*bwrap.Config, error) {
case "mtab": case "mtab":
conf.Symlink("/proc/mounts", "/etc/"+name) conf.Symlink("/proc/mounts", "/etc/"+name)
default: default:
conf.Symlink(Tmp+"/etc/"+name, "/etc/"+name) conf.Symlink(fTmp+"/etc/"+name, "/etc/"+name)
} }
} }
} }

View File

@ -100,7 +100,7 @@ var testCasesNixos = []sealTestCase{
"DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1971/bus", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1971/bus",
"DBUS_SYSTEM_BUS_ADDRESS": "unix:path=/run/dbus/system_bus_socket", "DBUS_SYSTEM_BUS_ADDRESS": "unix:path=/run/dbus/system_bus_socket",
"HOME": "/var/lib/persist/module/fortify/0/1", "HOME": "/var/lib/persist/module/fortify/0/1",
"PULSE_COOKIE": fst.Tmp + "/pulse-cookie", "PULSE_COOKIE": "/tmp/fortify.1971/8e2c76b066dabe574cf073bdb46eb5c1/pulse-cookie",
"PULSE_SERVER": "unix:/run/user/1971/pulse/native", "PULSE_SERVER": "unix:/run/user/1971/pulse/native",
"SHELL": "/run/current-system/sw/bin/zsh", "SHELL": "/run/current-system/sw/bin/zsh",
"TERM": "xterm-256color", "TERM": "xterm-256color",
@ -116,7 +116,7 @@ var testCasesNixos = []sealTestCase{
AsInit: true, AsInit: true,
}).SetUID(1971).SetGID(1971). }).SetUID(1971).SetGID(1971).
Procfs("/proc"). Procfs("/proc").
Tmpfs(fst.Tmp, 4096). Tmpfs("/fortify", 4096).
DevTmpfs("/dev").Mqueue("/dev/mqueue"). DevTmpfs("/dev").Mqueue("/dev/mqueue").
Bind("/bin", "/bin"). Bind("/bin", "/bin").
Bind("/usr/bin", "/usr/bin"). Bind("/usr/bin", "/usr/bin").
@ -129,86 +129,87 @@ var testCasesNixos = []sealTestCase{
Bind("/sys/devices", "/sys/devices", true). Bind("/sys/devices", "/sys/devices", true).
Bind("/run/opengl-driver", "/run/opengl-driver"). Bind("/run/opengl-driver", "/run/opengl-driver").
Bind("/dev/dri", "/dev/dri", true, true, true). Bind("/dev/dri", "/dev/dri", true, true, true).
Bind("/etc", fst.Tmp+"/etc"). Bind("/etc", "/fortify/etc").
Symlink(fst.Tmp+"/etc/alsa", "/etc/alsa"). Symlink("/fortify/etc/alsa", "/etc/alsa").
Symlink(fst.Tmp+"/etc/bashrc", "/etc/bashrc"). Symlink("/fortify/etc/bashrc", "/etc/bashrc").
Symlink(fst.Tmp+"/etc/binfmt.d", "/etc/binfmt.d"). Symlink("/fortify/etc/binfmt.d", "/etc/binfmt.d").
Symlink(fst.Tmp+"/etc/dbus-1", "/etc/dbus-1"). Symlink("/fortify/etc/dbus-1", "/etc/dbus-1").
Symlink(fst.Tmp+"/etc/default", "/etc/default"). Symlink("/fortify/etc/default", "/etc/default").
Symlink(fst.Tmp+"/etc/ethertypes", "/etc/ethertypes"). Symlink("/fortify/etc/ethertypes", "/etc/ethertypes").
Symlink(fst.Tmp+"/etc/fonts", "/etc/fonts"). Symlink("/fortify/etc/fonts", "/etc/fonts").
Symlink(fst.Tmp+"/etc/fstab", "/etc/fstab"). Symlink("/fortify/etc/fstab", "/etc/fstab").
Symlink(fst.Tmp+"/etc/fuse.conf", "/etc/fuse.conf"). Symlink("/fortify/etc/fuse.conf", "/etc/fuse.conf").
Symlink(fst.Tmp+"/etc/host.conf", "/etc/host.conf"). Symlink("/fortify/etc/host.conf", "/etc/host.conf").
Symlink(fst.Tmp+"/etc/hostid", "/etc/hostid"). Symlink("/fortify/etc/hostid", "/etc/hostid").
Symlink(fst.Tmp+"/etc/hostname", "/etc/hostname"). Symlink("/fortify/etc/hostname", "/etc/hostname").
Symlink(fst.Tmp+"/etc/hostname.CHECKSUM", "/etc/hostname.CHECKSUM"). Symlink("/fortify/etc/hostname.CHECKSUM", "/etc/hostname.CHECKSUM").
Symlink(fst.Tmp+"/etc/hosts", "/etc/hosts"). Symlink("/fortify/etc/hosts", "/etc/hosts").
Symlink(fst.Tmp+"/etc/inputrc", "/etc/inputrc"). Symlink("/fortify/etc/inputrc", "/etc/inputrc").
Symlink(fst.Tmp+"/etc/ipsec.d", "/etc/ipsec.d"). Symlink("/fortify/etc/ipsec.d", "/etc/ipsec.d").
Symlink(fst.Tmp+"/etc/issue", "/etc/issue"). Symlink("/fortify/etc/issue", "/etc/issue").
Symlink(fst.Tmp+"/etc/kbd", "/etc/kbd"). Symlink("/fortify/etc/kbd", "/etc/kbd").
Symlink(fst.Tmp+"/etc/libblockdev", "/etc/libblockdev"). Symlink("/fortify/etc/libblockdev", "/etc/libblockdev").
Symlink(fst.Tmp+"/etc/locale.conf", "/etc/locale.conf"). Symlink("/fortify/etc/locale.conf", "/etc/locale.conf").
Symlink(fst.Tmp+"/etc/localtime", "/etc/localtime"). Symlink("/fortify/etc/localtime", "/etc/localtime").
Symlink(fst.Tmp+"/etc/login.defs", "/etc/login.defs"). Symlink("/fortify/etc/login.defs", "/etc/login.defs").
Symlink(fst.Tmp+"/etc/lsb-release", "/etc/lsb-release"). Symlink("/fortify/etc/lsb-release", "/etc/lsb-release").
Symlink(fst.Tmp+"/etc/lvm", "/etc/lvm"). Symlink("/fortify/etc/lvm", "/etc/lvm").
Symlink(fst.Tmp+"/etc/machine-id", "/etc/machine-id"). Symlink("/fortify/etc/machine-id", "/etc/machine-id").
Symlink(fst.Tmp+"/etc/man_db.conf", "/etc/man_db.conf"). Symlink("/fortify/etc/man_db.conf", "/etc/man_db.conf").
Symlink(fst.Tmp+"/etc/modprobe.d", "/etc/modprobe.d"). Symlink("/fortify/etc/modprobe.d", "/etc/modprobe.d").
Symlink(fst.Tmp+"/etc/modules-load.d", "/etc/modules-load.d"). Symlink("/fortify/etc/modules-load.d", "/etc/modules-load.d").
Symlink("/proc/mounts", "/etc/mtab"). Symlink("/proc/mounts", "/etc/mtab").
Symlink(fst.Tmp+"/etc/nanorc", "/etc/nanorc"). Symlink("/fortify/etc/nanorc", "/etc/nanorc").
Symlink(fst.Tmp+"/etc/netgroup", "/etc/netgroup"). Symlink("/fortify/etc/netgroup", "/etc/netgroup").
Symlink(fst.Tmp+"/etc/NetworkManager", "/etc/NetworkManager"). Symlink("/fortify/etc/NetworkManager", "/etc/NetworkManager").
Symlink(fst.Tmp+"/etc/nix", "/etc/nix"). Symlink("/fortify/etc/nix", "/etc/nix").
Symlink(fst.Tmp+"/etc/nixos", "/etc/nixos"). Symlink("/fortify/etc/nixos", "/etc/nixos").
Symlink(fst.Tmp+"/etc/NIXOS", "/etc/NIXOS"). Symlink("/fortify/etc/NIXOS", "/etc/NIXOS").
Symlink(fst.Tmp+"/etc/nscd.conf", "/etc/nscd.conf"). Symlink("/fortify/etc/nscd.conf", "/etc/nscd.conf").
Symlink(fst.Tmp+"/etc/nsswitch.conf", "/etc/nsswitch.conf"). Symlink("/fortify/etc/nsswitch.conf", "/etc/nsswitch.conf").
Symlink(fst.Tmp+"/etc/opensnitchd", "/etc/opensnitchd"). Symlink("/fortify/etc/opensnitchd", "/etc/opensnitchd").
Symlink(fst.Tmp+"/etc/os-release", "/etc/os-release"). Symlink("/fortify/etc/os-release", "/etc/os-release").
Symlink(fst.Tmp+"/etc/pam", "/etc/pam"). Symlink("/fortify/etc/pam", "/etc/pam").
Symlink(fst.Tmp+"/etc/pam.d", "/etc/pam.d"). Symlink("/fortify/etc/pam.d", "/etc/pam.d").
Symlink(fst.Tmp+"/etc/pipewire", "/etc/pipewire"). Symlink("/fortify/etc/pipewire", "/etc/pipewire").
Symlink(fst.Tmp+"/etc/pki", "/etc/pki"). Symlink("/fortify/etc/pki", "/etc/pki").
Symlink(fst.Tmp+"/etc/polkit-1", "/etc/polkit-1"). Symlink("/fortify/etc/polkit-1", "/etc/polkit-1").
Symlink(fst.Tmp+"/etc/profile", "/etc/profile"). Symlink("/fortify/etc/profile", "/etc/profile").
Symlink(fst.Tmp+"/etc/protocols", "/etc/protocols"). Symlink("/fortify/etc/protocols", "/etc/protocols").
Symlink(fst.Tmp+"/etc/qemu", "/etc/qemu"). Symlink("/fortify/etc/qemu", "/etc/qemu").
Symlink(fst.Tmp+"/etc/resolv.conf", "/etc/resolv.conf"). Symlink("/fortify/etc/resolv.conf", "/etc/resolv.conf").
Symlink(fst.Tmp+"/etc/resolvconf.conf", "/etc/resolvconf.conf"). Symlink("/fortify/etc/resolvconf.conf", "/etc/resolvconf.conf").
Symlink(fst.Tmp+"/etc/rpc", "/etc/rpc"). Symlink("/fortify/etc/rpc", "/etc/rpc").
Symlink(fst.Tmp+"/etc/samba", "/etc/samba"). Symlink("/fortify/etc/samba", "/etc/samba").
Symlink(fst.Tmp+"/etc/sddm.conf", "/etc/sddm.conf"). Symlink("/fortify/etc/sddm.conf", "/etc/sddm.conf").
Symlink(fst.Tmp+"/etc/secureboot", "/etc/secureboot"). Symlink("/fortify/etc/secureboot", "/etc/secureboot").
Symlink(fst.Tmp+"/etc/services", "/etc/services"). Symlink("/fortify/etc/services", "/etc/services").
Symlink(fst.Tmp+"/etc/set-environment", "/etc/set-environment"). Symlink("/fortify/etc/set-environment", "/etc/set-environment").
Symlink(fst.Tmp+"/etc/shadow", "/etc/shadow"). Symlink("/fortify/etc/shadow", "/etc/shadow").
Symlink(fst.Tmp+"/etc/shells", "/etc/shells"). Symlink("/fortify/etc/shells", "/etc/shells").
Symlink(fst.Tmp+"/etc/ssh", "/etc/ssh"). Symlink("/fortify/etc/ssh", "/etc/ssh").
Symlink(fst.Tmp+"/etc/ssl", "/etc/ssl"). Symlink("/fortify/etc/ssl", "/etc/ssl").
Symlink(fst.Tmp+"/etc/static", "/etc/static"). Symlink("/fortify/etc/static", "/etc/static").
Symlink(fst.Tmp+"/etc/subgid", "/etc/subgid"). Symlink("/fortify/etc/subgid", "/etc/subgid").
Symlink(fst.Tmp+"/etc/subuid", "/etc/subuid"). Symlink("/fortify/etc/subuid", "/etc/subuid").
Symlink(fst.Tmp+"/etc/sudoers", "/etc/sudoers"). Symlink("/fortify/etc/sudoers", "/etc/sudoers").
Symlink(fst.Tmp+"/etc/sysctl.d", "/etc/sysctl.d"). Symlink("/fortify/etc/sysctl.d", "/etc/sysctl.d").
Symlink(fst.Tmp+"/etc/systemd", "/etc/systemd"). Symlink("/fortify/etc/systemd", "/etc/systemd").
Symlink(fst.Tmp+"/etc/terminfo", "/etc/terminfo"). Symlink("/fortify/etc/terminfo", "/etc/terminfo").
Symlink(fst.Tmp+"/etc/tmpfiles.d", "/etc/tmpfiles.d"). Symlink("/fortify/etc/tmpfiles.d", "/etc/tmpfiles.d").
Symlink(fst.Tmp+"/etc/udev", "/etc/udev"). Symlink("/fortify/etc/udev", "/etc/udev").
Symlink(fst.Tmp+"/etc/udisks2", "/etc/udisks2"). Symlink("/fortify/etc/udisks2", "/etc/udisks2").
Symlink(fst.Tmp+"/etc/UPower", "/etc/UPower"). Symlink("/fortify/etc/UPower", "/etc/UPower").
Symlink(fst.Tmp+"/etc/vconsole.conf", "/etc/vconsole.conf"). Symlink("/fortify/etc/vconsole.conf", "/etc/vconsole.conf").
Symlink(fst.Tmp+"/etc/X11", "/etc/X11"). Symlink("/fortify/etc/X11", "/etc/X11").
Symlink(fst.Tmp+"/etc/zfs", "/etc/zfs"). Symlink("/fortify/etc/zfs", "/etc/zfs").
Symlink(fst.Tmp+"/etc/zinputrc", "/etc/zinputrc"). Symlink("/fortify/etc/zinputrc", "/etc/zinputrc").
Symlink(fst.Tmp+"/etc/zoneinfo", "/etc/zoneinfo"). Symlink("/fortify/etc/zoneinfo", "/etc/zoneinfo").
Symlink(fst.Tmp+"/etc/zprofile", "/etc/zprofile"). Symlink("/fortify/etc/zprofile", "/etc/zprofile").
Symlink(fst.Tmp+"/etc/zshenv", "/etc/zshenv"). Symlink("/fortify/etc/zshenv", "/etc/zshenv").
Symlink(fst.Tmp+"/etc/zshrc", "/etc/zshrc"). Symlink("/fortify/etc/zshrc", "/etc/zshrc").
Bind("/tmp/fortify.1971/tmpdir/1", "/tmp", false, true). Bind("/tmp/fortify.1971/tmpdir/1", "/tmp", false, true).
Tmpfs("/tmp/fortify.1971", 1048576).
Tmpfs("/run/user", 1048576). Tmpfs("/run/user", 1048576).
Tmpfs("/run/user/1971", 8388608). Tmpfs("/run/user/1971", 8388608).
Bind("/var/lib/persist/module/fortify/0/1", "/var/lib/persist/module/fortify/0/1", false, true). Bind("/var/lib/persist/module/fortify/0/1", "/var/lib/persist/module/fortify/0/1", false, true).
@ -216,7 +217,7 @@ var testCasesNixos = []sealTestCase{
Bind("/tmp/fortify.1971/8e2c76b066dabe574cf073bdb46eb5c1/group", "/etc/group"). Bind("/tmp/fortify.1971/8e2c76b066dabe574cf073bdb46eb5c1/group", "/etc/group").
Bind("/run/user/1971/fortify/8e2c76b066dabe574cf073bdb46eb5c1/wayland", "/run/user/1971/wayland-0"). Bind("/run/user/1971/fortify/8e2c76b066dabe574cf073bdb46eb5c1/wayland", "/run/user/1971/wayland-0").
Bind("/run/user/1971/fortify/8e2c76b066dabe574cf073bdb46eb5c1/pulse", "/run/user/1971/pulse/native"). Bind("/run/user/1971/fortify/8e2c76b066dabe574cf073bdb46eb5c1/pulse", "/run/user/1971/pulse/native").
Bind("/tmp/fortify.1971/8e2c76b066dabe574cf073bdb46eb5c1/pulse-cookie", fst.Tmp+"/pulse-cookie"). Bind("/tmp/fortify.1971/8e2c76b066dabe574cf073bdb46eb5c1/pulse-cookie", "/tmp/fortify.1971/8e2c76b066dabe574cf073bdb46eb5c1/pulse-cookie").
Bind("/tmp/fortify.1971/8e2c76b066dabe574cf073bdb46eb5c1/bus", "/run/user/1971/bus"). Bind("/tmp/fortify.1971/8e2c76b066dabe574cf073bdb46eb5c1/bus", "/run/user/1971/bus").
Bind("/tmp/fortify.1971/8e2c76b066dabe574cf073bdb46eb5c1/system_bus_socket", "/run/dbus/system_bus_socket"). Bind("/tmp/fortify.1971/8e2c76b066dabe574cf073bdb46eb5c1/system_bus_socket", "/run/dbus/system_bus_socket").
Tmpfs("/var/run/nscd", 8192), Tmpfs("/var/run/nscd", 8192),

View File

@ -53,7 +53,7 @@ var testCasesPd = []sealTestCase{
AsInit: true, AsInit: true,
}).SetUID(65534).SetGID(65534). }).SetUID(65534).SetGID(65534).
Procfs("/proc"). Procfs("/proc").
Tmpfs(fst.Tmp, 4096). Tmpfs("/fortify", 4096).
DevTmpfs("/dev").Mqueue("/dev/mqueue"). DevTmpfs("/dev").Mqueue("/dev/mqueue").
Bind("/bin", "/bin", false, true). Bind("/bin", "/bin", false, true).
Bind("/boot", "/boot", false, true). Bind("/boot", "/boot", false, true).
@ -100,86 +100,87 @@ var testCasesPd = []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", fst.Tmp+"/etc"). Bind("/etc", "/fortify/etc").
Symlink(fst.Tmp+"/etc/alsa", "/etc/alsa"). Symlink("/fortify/etc/alsa", "/etc/alsa").
Symlink(fst.Tmp+"/etc/bashrc", "/etc/bashrc"). Symlink("/fortify/etc/bashrc", "/etc/bashrc").
Symlink(fst.Tmp+"/etc/binfmt.d", "/etc/binfmt.d"). Symlink("/fortify/etc/binfmt.d", "/etc/binfmt.d").
Symlink(fst.Tmp+"/etc/dbus-1", "/etc/dbus-1"). Symlink("/fortify/etc/dbus-1", "/etc/dbus-1").
Symlink(fst.Tmp+"/etc/default", "/etc/default"). Symlink("/fortify/etc/default", "/etc/default").
Symlink(fst.Tmp+"/etc/ethertypes", "/etc/ethertypes"). Symlink("/fortify/etc/ethertypes", "/etc/ethertypes").
Symlink(fst.Tmp+"/etc/fonts", "/etc/fonts"). Symlink("/fortify/etc/fonts", "/etc/fonts").
Symlink(fst.Tmp+"/etc/fstab", "/etc/fstab"). Symlink("/fortify/etc/fstab", "/etc/fstab").
Symlink(fst.Tmp+"/etc/fuse.conf", "/etc/fuse.conf"). Symlink("/fortify/etc/fuse.conf", "/etc/fuse.conf").
Symlink(fst.Tmp+"/etc/host.conf", "/etc/host.conf"). Symlink("/fortify/etc/host.conf", "/etc/host.conf").
Symlink(fst.Tmp+"/etc/hostid", "/etc/hostid"). Symlink("/fortify/etc/hostid", "/etc/hostid").
Symlink(fst.Tmp+"/etc/hostname", "/etc/hostname"). Symlink("/fortify/etc/hostname", "/etc/hostname").
Symlink(fst.Tmp+"/etc/hostname.CHECKSUM", "/etc/hostname.CHECKSUM"). Symlink("/fortify/etc/hostname.CHECKSUM", "/etc/hostname.CHECKSUM").
Symlink(fst.Tmp+"/etc/hosts", "/etc/hosts"). Symlink("/fortify/etc/hosts", "/etc/hosts").
Symlink(fst.Tmp+"/etc/inputrc", "/etc/inputrc"). Symlink("/fortify/etc/inputrc", "/etc/inputrc").
Symlink(fst.Tmp+"/etc/ipsec.d", "/etc/ipsec.d"). Symlink("/fortify/etc/ipsec.d", "/etc/ipsec.d").
Symlink(fst.Tmp+"/etc/issue", "/etc/issue"). Symlink("/fortify/etc/issue", "/etc/issue").
Symlink(fst.Tmp+"/etc/kbd", "/etc/kbd"). Symlink("/fortify/etc/kbd", "/etc/kbd").
Symlink(fst.Tmp+"/etc/libblockdev", "/etc/libblockdev"). Symlink("/fortify/etc/libblockdev", "/etc/libblockdev").
Symlink(fst.Tmp+"/etc/locale.conf", "/etc/locale.conf"). Symlink("/fortify/etc/locale.conf", "/etc/locale.conf").
Symlink(fst.Tmp+"/etc/localtime", "/etc/localtime"). Symlink("/fortify/etc/localtime", "/etc/localtime").
Symlink(fst.Tmp+"/etc/login.defs", "/etc/login.defs"). Symlink("/fortify/etc/login.defs", "/etc/login.defs").
Symlink(fst.Tmp+"/etc/lsb-release", "/etc/lsb-release"). Symlink("/fortify/etc/lsb-release", "/etc/lsb-release").
Symlink(fst.Tmp+"/etc/lvm", "/etc/lvm"). Symlink("/fortify/etc/lvm", "/etc/lvm").
Symlink(fst.Tmp+"/etc/machine-id", "/etc/machine-id"). Symlink("/fortify/etc/machine-id", "/etc/machine-id").
Symlink(fst.Tmp+"/etc/man_db.conf", "/etc/man_db.conf"). Symlink("/fortify/etc/man_db.conf", "/etc/man_db.conf").
Symlink(fst.Tmp+"/etc/modprobe.d", "/etc/modprobe.d"). Symlink("/fortify/etc/modprobe.d", "/etc/modprobe.d").
Symlink(fst.Tmp+"/etc/modules-load.d", "/etc/modules-load.d"). Symlink("/fortify/etc/modules-load.d", "/etc/modules-load.d").
Symlink("/proc/mounts", "/etc/mtab"). Symlink("/proc/mounts", "/etc/mtab").
Symlink(fst.Tmp+"/etc/nanorc", "/etc/nanorc"). Symlink("/fortify/etc/nanorc", "/etc/nanorc").
Symlink(fst.Tmp+"/etc/netgroup", "/etc/netgroup"). Symlink("/fortify/etc/netgroup", "/etc/netgroup").
Symlink(fst.Tmp+"/etc/NetworkManager", "/etc/NetworkManager"). Symlink("/fortify/etc/NetworkManager", "/etc/NetworkManager").
Symlink(fst.Tmp+"/etc/nix", "/etc/nix"). Symlink("/fortify/etc/nix", "/etc/nix").
Symlink(fst.Tmp+"/etc/nixos", "/etc/nixos"). Symlink("/fortify/etc/nixos", "/etc/nixos").
Symlink(fst.Tmp+"/etc/NIXOS", "/etc/NIXOS"). Symlink("/fortify/etc/NIXOS", "/etc/NIXOS").
Symlink(fst.Tmp+"/etc/nscd.conf", "/etc/nscd.conf"). Symlink("/fortify/etc/nscd.conf", "/etc/nscd.conf").
Symlink(fst.Tmp+"/etc/nsswitch.conf", "/etc/nsswitch.conf"). Symlink("/fortify/etc/nsswitch.conf", "/etc/nsswitch.conf").
Symlink(fst.Tmp+"/etc/opensnitchd", "/etc/opensnitchd"). Symlink("/fortify/etc/opensnitchd", "/etc/opensnitchd").
Symlink(fst.Tmp+"/etc/os-release", "/etc/os-release"). Symlink("/fortify/etc/os-release", "/etc/os-release").
Symlink(fst.Tmp+"/etc/pam", "/etc/pam"). Symlink("/fortify/etc/pam", "/etc/pam").
Symlink(fst.Tmp+"/etc/pam.d", "/etc/pam.d"). Symlink("/fortify/etc/pam.d", "/etc/pam.d").
Symlink(fst.Tmp+"/etc/pipewire", "/etc/pipewire"). Symlink("/fortify/etc/pipewire", "/etc/pipewire").
Symlink(fst.Tmp+"/etc/pki", "/etc/pki"). Symlink("/fortify/etc/pki", "/etc/pki").
Symlink(fst.Tmp+"/etc/polkit-1", "/etc/polkit-1"). Symlink("/fortify/etc/polkit-1", "/etc/polkit-1").
Symlink(fst.Tmp+"/etc/profile", "/etc/profile"). Symlink("/fortify/etc/profile", "/etc/profile").
Symlink(fst.Tmp+"/etc/protocols", "/etc/protocols"). Symlink("/fortify/etc/protocols", "/etc/protocols").
Symlink(fst.Tmp+"/etc/qemu", "/etc/qemu"). Symlink("/fortify/etc/qemu", "/etc/qemu").
Symlink(fst.Tmp+"/etc/resolv.conf", "/etc/resolv.conf"). Symlink("/fortify/etc/resolv.conf", "/etc/resolv.conf").
Symlink(fst.Tmp+"/etc/resolvconf.conf", "/etc/resolvconf.conf"). Symlink("/fortify/etc/resolvconf.conf", "/etc/resolvconf.conf").
Symlink(fst.Tmp+"/etc/rpc", "/etc/rpc"). Symlink("/fortify/etc/rpc", "/etc/rpc").
Symlink(fst.Tmp+"/etc/samba", "/etc/samba"). Symlink("/fortify/etc/samba", "/etc/samba").
Symlink(fst.Tmp+"/etc/sddm.conf", "/etc/sddm.conf"). Symlink("/fortify/etc/sddm.conf", "/etc/sddm.conf").
Symlink(fst.Tmp+"/etc/secureboot", "/etc/secureboot"). Symlink("/fortify/etc/secureboot", "/etc/secureboot").
Symlink(fst.Tmp+"/etc/services", "/etc/services"). Symlink("/fortify/etc/services", "/etc/services").
Symlink(fst.Tmp+"/etc/set-environment", "/etc/set-environment"). Symlink("/fortify/etc/set-environment", "/etc/set-environment").
Symlink(fst.Tmp+"/etc/shadow", "/etc/shadow"). Symlink("/fortify/etc/shadow", "/etc/shadow").
Symlink(fst.Tmp+"/etc/shells", "/etc/shells"). Symlink("/fortify/etc/shells", "/etc/shells").
Symlink(fst.Tmp+"/etc/ssh", "/etc/ssh"). Symlink("/fortify/etc/ssh", "/etc/ssh").
Symlink(fst.Tmp+"/etc/ssl", "/etc/ssl"). Symlink("/fortify/etc/ssl", "/etc/ssl").
Symlink(fst.Tmp+"/etc/static", "/etc/static"). Symlink("/fortify/etc/static", "/etc/static").
Symlink(fst.Tmp+"/etc/subgid", "/etc/subgid"). Symlink("/fortify/etc/subgid", "/etc/subgid").
Symlink(fst.Tmp+"/etc/subuid", "/etc/subuid"). Symlink("/fortify/etc/subuid", "/etc/subuid").
Symlink(fst.Tmp+"/etc/sudoers", "/etc/sudoers"). Symlink("/fortify/etc/sudoers", "/etc/sudoers").
Symlink(fst.Tmp+"/etc/sysctl.d", "/etc/sysctl.d"). Symlink("/fortify/etc/sysctl.d", "/etc/sysctl.d").
Symlink(fst.Tmp+"/etc/systemd", "/etc/systemd"). Symlink("/fortify/etc/systemd", "/etc/systemd").
Symlink(fst.Tmp+"/etc/terminfo", "/etc/terminfo"). Symlink("/fortify/etc/terminfo", "/etc/terminfo").
Symlink(fst.Tmp+"/etc/tmpfiles.d", "/etc/tmpfiles.d"). Symlink("/fortify/etc/tmpfiles.d", "/etc/tmpfiles.d").
Symlink(fst.Tmp+"/etc/udev", "/etc/udev"). Symlink("/fortify/etc/udev", "/etc/udev").
Symlink(fst.Tmp+"/etc/udisks2", "/etc/udisks2"). Symlink("/fortify/etc/udisks2", "/etc/udisks2").
Symlink(fst.Tmp+"/etc/UPower", "/etc/UPower"). Symlink("/fortify/etc/UPower", "/etc/UPower").
Symlink(fst.Tmp+"/etc/vconsole.conf", "/etc/vconsole.conf"). Symlink("/fortify/etc/vconsole.conf", "/etc/vconsole.conf").
Symlink(fst.Tmp+"/etc/X11", "/etc/X11"). Symlink("/fortify/etc/X11", "/etc/X11").
Symlink(fst.Tmp+"/etc/zfs", "/etc/zfs"). Symlink("/fortify/etc/zfs", "/etc/zfs").
Symlink(fst.Tmp+"/etc/zinputrc", "/etc/zinputrc"). Symlink("/fortify/etc/zinputrc", "/etc/zinputrc").
Symlink(fst.Tmp+"/etc/zoneinfo", "/etc/zoneinfo"). Symlink("/fortify/etc/zoneinfo", "/etc/zoneinfo").
Symlink(fst.Tmp+"/etc/zprofile", "/etc/zprofile"). Symlink("/fortify/etc/zprofile", "/etc/zprofile").
Symlink(fst.Tmp+"/etc/zshenv", "/etc/zshenv"). Symlink("/fortify/etc/zshenv", "/etc/zshenv").
Symlink(fst.Tmp+"/etc/zshrc", "/etc/zshrc"). Symlink("/fortify/etc/zshrc", "/etc/zshrc").
Bind("/tmp/fortify.1971/tmpdir/0", "/tmp", false, true). Bind("/tmp/fortify.1971/tmpdir/0", "/tmp", false, true).
Tmpfs("/tmp/fortify.1971", 1048576).
Tmpfs("/run/user", 1048576). Tmpfs("/run/user", 1048576).
Tmpfs("/run/user/65534", 8388608). Tmpfs("/run/user/65534", 8388608).
Bind("/home/chronos", "/home/chronos", false, true). Bind("/home/chronos", "/home/chronos", false, true).
@ -292,7 +293,7 @@ var testCasesPd = []sealTestCase{
"DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/65534/bus", "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/65534/bus",
"DBUS_SYSTEM_BUS_ADDRESS": "unix:path=/run/dbus/system_bus_socket", "DBUS_SYSTEM_BUS_ADDRESS": "unix:path=/run/dbus/system_bus_socket",
"HOME": "/home/chronos", "HOME": "/home/chronos",
"PULSE_COOKIE": fst.Tmp + "/pulse-cookie", "PULSE_COOKIE": "/tmp/fortify.1971/ebf083d1b175911782d413369b64ce7c/pulse-cookie",
"PULSE_SERVER": "unix:/run/user/65534/pulse/native", "PULSE_SERVER": "unix:/run/user/65534/pulse/native",
"SHELL": "/run/current-system/sw/bin/zsh", "SHELL": "/run/current-system/sw/bin/zsh",
"TERM": "xterm-256color", "TERM": "xterm-256color",
@ -307,7 +308,7 @@ var testCasesPd = []sealTestCase{
AsInit: true, AsInit: true,
}).SetUID(65534).SetGID(65534). }).SetUID(65534).SetGID(65534).
Procfs("/proc"). Procfs("/proc").
Tmpfs(fst.Tmp, 4096). Tmpfs("/fortify", 4096).
DevTmpfs("/dev").Mqueue("/dev/mqueue"). DevTmpfs("/dev").Mqueue("/dev/mqueue").
Bind("/bin", "/bin", false, true). Bind("/bin", "/bin", false, true).
Bind("/boot", "/boot", false, true). Bind("/boot", "/boot", false, true).
@ -355,86 +356,87 @@ var testCasesPd = []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", fst.Tmp+"/etc"). Bind("/etc", "/fortify/etc").
Symlink(fst.Tmp+"/etc/alsa", "/etc/alsa"). Symlink("/fortify/etc/alsa", "/etc/alsa").
Symlink(fst.Tmp+"/etc/bashrc", "/etc/bashrc"). Symlink("/fortify/etc/bashrc", "/etc/bashrc").
Symlink(fst.Tmp+"/etc/binfmt.d", "/etc/binfmt.d"). Symlink("/fortify/etc/binfmt.d", "/etc/binfmt.d").
Symlink(fst.Tmp+"/etc/dbus-1", "/etc/dbus-1"). Symlink("/fortify/etc/dbus-1", "/etc/dbus-1").
Symlink(fst.Tmp+"/etc/default", "/etc/default"). Symlink("/fortify/etc/default", "/etc/default").
Symlink(fst.Tmp+"/etc/ethertypes", "/etc/ethertypes"). Symlink("/fortify/etc/ethertypes", "/etc/ethertypes").
Symlink(fst.Tmp+"/etc/fonts", "/etc/fonts"). Symlink("/fortify/etc/fonts", "/etc/fonts").
Symlink(fst.Tmp+"/etc/fstab", "/etc/fstab"). Symlink("/fortify/etc/fstab", "/etc/fstab").
Symlink(fst.Tmp+"/etc/fuse.conf", "/etc/fuse.conf"). Symlink("/fortify/etc/fuse.conf", "/etc/fuse.conf").
Symlink(fst.Tmp+"/etc/host.conf", "/etc/host.conf"). Symlink("/fortify/etc/host.conf", "/etc/host.conf").
Symlink(fst.Tmp+"/etc/hostid", "/etc/hostid"). Symlink("/fortify/etc/hostid", "/etc/hostid").
Symlink(fst.Tmp+"/etc/hostname", "/etc/hostname"). Symlink("/fortify/etc/hostname", "/etc/hostname").
Symlink(fst.Tmp+"/etc/hostname.CHECKSUM", "/etc/hostname.CHECKSUM"). Symlink("/fortify/etc/hostname.CHECKSUM", "/etc/hostname.CHECKSUM").
Symlink(fst.Tmp+"/etc/hosts", "/etc/hosts"). Symlink("/fortify/etc/hosts", "/etc/hosts").
Symlink(fst.Tmp+"/etc/inputrc", "/etc/inputrc"). Symlink("/fortify/etc/inputrc", "/etc/inputrc").
Symlink(fst.Tmp+"/etc/ipsec.d", "/etc/ipsec.d"). Symlink("/fortify/etc/ipsec.d", "/etc/ipsec.d").
Symlink(fst.Tmp+"/etc/issue", "/etc/issue"). Symlink("/fortify/etc/issue", "/etc/issue").
Symlink(fst.Tmp+"/etc/kbd", "/etc/kbd"). Symlink("/fortify/etc/kbd", "/etc/kbd").
Symlink(fst.Tmp+"/etc/libblockdev", "/etc/libblockdev"). Symlink("/fortify/etc/libblockdev", "/etc/libblockdev").
Symlink(fst.Tmp+"/etc/locale.conf", "/etc/locale.conf"). Symlink("/fortify/etc/locale.conf", "/etc/locale.conf").
Symlink(fst.Tmp+"/etc/localtime", "/etc/localtime"). Symlink("/fortify/etc/localtime", "/etc/localtime").
Symlink(fst.Tmp+"/etc/login.defs", "/etc/login.defs"). Symlink("/fortify/etc/login.defs", "/etc/login.defs").
Symlink(fst.Tmp+"/etc/lsb-release", "/etc/lsb-release"). Symlink("/fortify/etc/lsb-release", "/etc/lsb-release").
Symlink(fst.Tmp+"/etc/lvm", "/etc/lvm"). Symlink("/fortify/etc/lvm", "/etc/lvm").
Symlink(fst.Tmp+"/etc/machine-id", "/etc/machine-id"). Symlink("/fortify/etc/machine-id", "/etc/machine-id").
Symlink(fst.Tmp+"/etc/man_db.conf", "/etc/man_db.conf"). Symlink("/fortify/etc/man_db.conf", "/etc/man_db.conf").
Symlink(fst.Tmp+"/etc/modprobe.d", "/etc/modprobe.d"). Symlink("/fortify/etc/modprobe.d", "/etc/modprobe.d").
Symlink(fst.Tmp+"/etc/modules-load.d", "/etc/modules-load.d"). Symlink("/fortify/etc/modules-load.d", "/etc/modules-load.d").
Symlink("/proc/mounts", "/etc/mtab"). Symlink("/proc/mounts", "/etc/mtab").
Symlink(fst.Tmp+"/etc/nanorc", "/etc/nanorc"). Symlink("/fortify/etc/nanorc", "/etc/nanorc").
Symlink(fst.Tmp+"/etc/netgroup", "/etc/netgroup"). Symlink("/fortify/etc/netgroup", "/etc/netgroup").
Symlink(fst.Tmp+"/etc/NetworkManager", "/etc/NetworkManager"). Symlink("/fortify/etc/NetworkManager", "/etc/NetworkManager").
Symlink(fst.Tmp+"/etc/nix", "/etc/nix"). Symlink("/fortify/etc/nix", "/etc/nix").
Symlink(fst.Tmp+"/etc/nixos", "/etc/nixos"). Symlink("/fortify/etc/nixos", "/etc/nixos").
Symlink(fst.Tmp+"/etc/NIXOS", "/etc/NIXOS"). Symlink("/fortify/etc/NIXOS", "/etc/NIXOS").
Symlink(fst.Tmp+"/etc/nscd.conf", "/etc/nscd.conf"). Symlink("/fortify/etc/nscd.conf", "/etc/nscd.conf").
Symlink(fst.Tmp+"/etc/nsswitch.conf", "/etc/nsswitch.conf"). Symlink("/fortify/etc/nsswitch.conf", "/etc/nsswitch.conf").
Symlink(fst.Tmp+"/etc/opensnitchd", "/etc/opensnitchd"). Symlink("/fortify/etc/opensnitchd", "/etc/opensnitchd").
Symlink(fst.Tmp+"/etc/os-release", "/etc/os-release"). Symlink("/fortify/etc/os-release", "/etc/os-release").
Symlink(fst.Tmp+"/etc/pam", "/etc/pam"). Symlink("/fortify/etc/pam", "/etc/pam").
Symlink(fst.Tmp+"/etc/pam.d", "/etc/pam.d"). Symlink("/fortify/etc/pam.d", "/etc/pam.d").
Symlink(fst.Tmp+"/etc/pipewire", "/etc/pipewire"). Symlink("/fortify/etc/pipewire", "/etc/pipewire").
Symlink(fst.Tmp+"/etc/pki", "/etc/pki"). Symlink("/fortify/etc/pki", "/etc/pki").
Symlink(fst.Tmp+"/etc/polkit-1", "/etc/polkit-1"). Symlink("/fortify/etc/polkit-1", "/etc/polkit-1").
Symlink(fst.Tmp+"/etc/profile", "/etc/profile"). Symlink("/fortify/etc/profile", "/etc/profile").
Symlink(fst.Tmp+"/etc/protocols", "/etc/protocols"). Symlink("/fortify/etc/protocols", "/etc/protocols").
Symlink(fst.Tmp+"/etc/qemu", "/etc/qemu"). Symlink("/fortify/etc/qemu", "/etc/qemu").
Symlink(fst.Tmp+"/etc/resolv.conf", "/etc/resolv.conf"). Symlink("/fortify/etc/resolv.conf", "/etc/resolv.conf").
Symlink(fst.Tmp+"/etc/resolvconf.conf", "/etc/resolvconf.conf"). Symlink("/fortify/etc/resolvconf.conf", "/etc/resolvconf.conf").
Symlink(fst.Tmp+"/etc/rpc", "/etc/rpc"). Symlink("/fortify/etc/rpc", "/etc/rpc").
Symlink(fst.Tmp+"/etc/samba", "/etc/samba"). Symlink("/fortify/etc/samba", "/etc/samba").
Symlink(fst.Tmp+"/etc/sddm.conf", "/etc/sddm.conf"). Symlink("/fortify/etc/sddm.conf", "/etc/sddm.conf").
Symlink(fst.Tmp+"/etc/secureboot", "/etc/secureboot"). Symlink("/fortify/etc/secureboot", "/etc/secureboot").
Symlink(fst.Tmp+"/etc/services", "/etc/services"). Symlink("/fortify/etc/services", "/etc/services").
Symlink(fst.Tmp+"/etc/set-environment", "/etc/set-environment"). Symlink("/fortify/etc/set-environment", "/etc/set-environment").
Symlink(fst.Tmp+"/etc/shadow", "/etc/shadow"). Symlink("/fortify/etc/shadow", "/etc/shadow").
Symlink(fst.Tmp+"/etc/shells", "/etc/shells"). Symlink("/fortify/etc/shells", "/etc/shells").
Symlink(fst.Tmp+"/etc/ssh", "/etc/ssh"). Symlink("/fortify/etc/ssh", "/etc/ssh").
Symlink(fst.Tmp+"/etc/ssl", "/etc/ssl"). Symlink("/fortify/etc/ssl", "/etc/ssl").
Symlink(fst.Tmp+"/etc/static", "/etc/static"). Symlink("/fortify/etc/static", "/etc/static").
Symlink(fst.Tmp+"/etc/subgid", "/etc/subgid"). Symlink("/fortify/etc/subgid", "/etc/subgid").
Symlink(fst.Tmp+"/etc/subuid", "/etc/subuid"). Symlink("/fortify/etc/subuid", "/etc/subuid").
Symlink(fst.Tmp+"/etc/sudoers", "/etc/sudoers"). Symlink("/fortify/etc/sudoers", "/etc/sudoers").
Symlink(fst.Tmp+"/etc/sysctl.d", "/etc/sysctl.d"). Symlink("/fortify/etc/sysctl.d", "/etc/sysctl.d").
Symlink(fst.Tmp+"/etc/systemd", "/etc/systemd"). Symlink("/fortify/etc/systemd", "/etc/systemd").
Symlink(fst.Tmp+"/etc/terminfo", "/etc/terminfo"). Symlink("/fortify/etc/terminfo", "/etc/terminfo").
Symlink(fst.Tmp+"/etc/tmpfiles.d", "/etc/tmpfiles.d"). Symlink("/fortify/etc/tmpfiles.d", "/etc/tmpfiles.d").
Symlink(fst.Tmp+"/etc/udev", "/etc/udev"). Symlink("/fortify/etc/udev", "/etc/udev").
Symlink(fst.Tmp+"/etc/udisks2", "/etc/udisks2"). Symlink("/fortify/etc/udisks2", "/etc/udisks2").
Symlink(fst.Tmp+"/etc/UPower", "/etc/UPower"). Symlink("/fortify/etc/UPower", "/etc/UPower").
Symlink(fst.Tmp+"/etc/vconsole.conf", "/etc/vconsole.conf"). Symlink("/fortify/etc/vconsole.conf", "/etc/vconsole.conf").
Symlink(fst.Tmp+"/etc/X11", "/etc/X11"). Symlink("/fortify/etc/X11", "/etc/X11").
Symlink(fst.Tmp+"/etc/zfs", "/etc/zfs"). Symlink("/fortify/etc/zfs", "/etc/zfs").
Symlink(fst.Tmp+"/etc/zinputrc", "/etc/zinputrc"). Symlink("/fortify/etc/zinputrc", "/etc/zinputrc").
Symlink(fst.Tmp+"/etc/zoneinfo", "/etc/zoneinfo"). Symlink("/fortify/etc/zoneinfo", "/etc/zoneinfo").
Symlink(fst.Tmp+"/etc/zprofile", "/etc/zprofile"). Symlink("/fortify/etc/zprofile", "/etc/zprofile").
Symlink(fst.Tmp+"/etc/zshenv", "/etc/zshenv"). Symlink("/fortify/etc/zshenv", "/etc/zshenv").
Symlink(fst.Tmp+"/etc/zshrc", "/etc/zshrc"). Symlink("/fortify/etc/zshrc", "/etc/zshrc").
Bind("/tmp/fortify.1971/tmpdir/9", "/tmp", false, true). Bind("/tmp/fortify.1971/tmpdir/9", "/tmp", false, true).
Tmpfs("/tmp/fortify.1971", 1048576).
Tmpfs("/run/user", 1048576). Tmpfs("/run/user", 1048576).
Tmpfs("/run/user/65534", 8388608). Tmpfs("/run/user/65534", 8388608).
Bind("/home/chronos", "/home/chronos", false, true). Bind("/home/chronos", "/home/chronos", false, true).
@ -442,7 +444,7 @@ var testCasesPd = []sealTestCase{
Bind("/tmp/fortify.1971/ebf083d1b175911782d413369b64ce7c/group", "/etc/group"). Bind("/tmp/fortify.1971/ebf083d1b175911782d413369b64ce7c/group", "/etc/group").
Bind("/tmp/fortify.1971/wayland/ebf083d1b175911782d413369b64ce7c", "/run/user/65534/wayland-0"). Bind("/tmp/fortify.1971/wayland/ebf083d1b175911782d413369b64ce7c", "/run/user/65534/wayland-0").
Bind("/run/user/1971/fortify/ebf083d1b175911782d413369b64ce7c/pulse", "/run/user/65534/pulse/native"). Bind("/run/user/1971/fortify/ebf083d1b175911782d413369b64ce7c/pulse", "/run/user/65534/pulse/native").
Bind("/tmp/fortify.1971/ebf083d1b175911782d413369b64ce7c/pulse-cookie", fst.Tmp+"/pulse-cookie"). Bind("/tmp/fortify.1971/ebf083d1b175911782d413369b64ce7c/pulse-cookie", "/tmp/fortify.1971/ebf083d1b175911782d413369b64ce7c/pulse-cookie").
Bind("/tmp/fortify.1971/ebf083d1b175911782d413369b64ce7c/bus", "/run/user/65534/bus"). Bind("/tmp/fortify.1971/ebf083d1b175911782d413369b64ce7c/bus", "/run/user/65534/bus").
Bind("/tmp/fortify.1971/ebf083d1b175911782d413369b64ce7c/system_bus_socket", "/run/dbus/system_bus_socket"). Bind("/tmp/fortify.1971/ebf083d1b175911782d413369b64ce7c/system_bus_socket", "/run/dbus/system_bus_socket").
Tmpfs("/var/run/nscd", 8192), Tmpfs("/var/run/nscd", 8192),

View File

@ -6,7 +6,6 @@ import (
"io/fs" "io/fs"
"path" "path"
"git.gensokyo.uk/security/fortify/fst"
"git.gensokyo.uk/security/fortify/internal/fmsg" "git.gensokyo.uk/security/fortify/internal/fmsg"
"git.gensokyo.uk/security/fortify/internal/linux" "git.gensokyo.uk/security/fortify/internal/linux"
"git.gensokyo.uk/security/fortify/internal/system" "git.gensokyo.uk/security/fortify/internal/system"
@ -67,13 +66,12 @@ func (seal *appSeal) sharePulse(os linux.System) error {
// publish current user's pulse cookie for target user // publish current user's pulse cookie for target user
if src, err := discoverPulseCookie(os); err != nil { if src, err := discoverPulseCookie(os); err != nil {
fmsg.VPrintln(err.(*fmsg.BaseError).Message()) return err
} else { } else {
dst := path.Join(seal.share, "pulse-cookie") dst := path.Join(seal.share, "pulse-cookie")
innerDst := fst.Tmp + "/pulse-cookie" seal.sys.bwrap.SetEnv[pulseCookie] = dst
seal.sys.bwrap.SetEnv[pulseCookie] = innerDst
seal.sys.CopyFile(dst, src) seal.sys.CopyFile(dst, src)
seal.sys.bwrap.Bind(dst, innerDst) seal.sys.bwrap.Bind(dst, dst)
} }
return nil return nil

View File

@ -33,6 +33,9 @@ func (seal *appSeal) shareSystem() {
seal.sys.Ensure(targetTmpdir, 01700) seal.sys.Ensure(targetTmpdir, 01700)
seal.sys.UpdatePermType(system.User, targetTmpdir, acl.Read, acl.Write, acl.Execute) seal.sys.UpdatePermType(system.User, targetTmpdir, acl.Read, acl.Write, acl.Execute)
seal.sys.bwrap.Bind(targetTmpdir, "/tmp", false, true) seal.sys.bwrap.Bind(targetTmpdir, "/tmp", false, true)
// mount tmpfs on inner shared directory (e.g. `/tmp/fortify.%d`)
seal.sys.bwrap.Tmpfs(seal.SharePath, 1*1024*1024)
} }
func (seal *appSeal) sharePasswd(os linux.System) { func (seal *appSeal) sharePasswd(os linux.System) {

118
internal/state/print.go Normal file
View File

@ -0,0 +1,118 @@
package state
import (
"fmt"
"os"
"strings"
"text/tabwriter"
"time"
"git.gensokyo.uk/security/fortify/internal/fmsg"
"git.gensokyo.uk/security/fortify/internal/system"
)
// MustPrintLauncherStateSimpleGlobal prints active launcher states of all simple stores
// in an implementation-specific way.
func MustPrintLauncherStateSimpleGlobal(w **tabwriter.Writer, runDir string) {
now := time.Now().UTC()
s := NewMulti(runDir)
// read runtime directory to get all UIDs
if aids, err := s.List(); err != nil {
fmsg.Fatal("cannot list store:", err)
} else {
for _, aid := range aids {
// print states belonging to this store
s.(*multiStore).mustPrintLauncherState(aid, w, now)
}
}
// mustPrintLauncherState causes store activity so store needs to be closed
if err := s.Close(); err != nil {
fmsg.Printf("cannot close store: %v", err)
}
}
func (s *multiStore) mustPrintLauncherState(aid int, w **tabwriter.Writer, now time.Time) {
var innerErr error
if ok, err := s.Do(aid, func(c Cursor) {
innerErr = func() error {
// read launcher states
states, err := c.Load()
if err != nil {
return err
}
// initialise tabwriter if nil
if *w == nil {
*w = tabwriter.NewWriter(os.Stdout, 0, 1, 4, ' ', 0)
// write header when initialising
if !fmsg.Verbose() {
_, _ = fmt.Fprintln(*w, "\tPID\tApp\tUptime\tEnablements\tCommand")
} else {
// argv is emitted in body when verbose
_, _ = fmt.Fprintln(*w, "\tPID\tApp\tArgv")
}
}
// print each state
for _, state := range states {
// skip nil states
if state == nil {
_, _ = fmt.Fprintln(*w, "\tnil state entry")
continue
}
// build enablements and command string
var (
ets *strings.Builder
cs = "(No command information)"
)
// check if enablements are provided
if state.Config != nil {
ets = new(strings.Builder)
// append enablement strings in order
for i := system.Enablement(0); i < system.Enablement(system.ELen); i++ {
if state.Config.Confinement.Enablements.Has(i) {
ets.WriteString(", " + i.String())
}
}
cs = fmt.Sprintf("%q", state.Config.Command)
}
if ets != nil {
// prevent an empty string
if ets.Len() == 0 {
ets.WriteString("(No enablements)")
}
} else {
ets = new(strings.Builder)
ets.WriteString("(No confinement information)")
}
if !fmsg.Verbose() {
_, _ = fmt.Fprintf(*w, "\t%d\t%d\t%s\t%s\t%s\n",
state.PID, aid, now.Sub(state.Time).Round(time.Second).String(), strings.TrimPrefix(ets.String(), ", "), cs)
} else {
// emit argv instead when verbose
_, _ = fmt.Fprintf(*w, "\t%d\t%d\t%s\n",
state.PID, aid, state.ID)
}
}
return nil
}()
}); err != nil {
fmsg.Printf("cannot perform action on app %d: %v", aid, err)
if !ok {
fmsg.Fatal("store faulted before printing")
}
}
if innerErr != nil {
fmsg.Fatalf("cannot print launcher state of app %d: %s", aid, innerErr)
}
}

View File

@ -94,14 +94,6 @@ func testStore(t *testing.T, s state.Store) {
} }
}) })
t.Run("join store", func(t *testing.T) {
if entries, err := state.Join(s); err != nil {
t.Fatalf("Join: error = %v", err)
} else if len(entries) != 3 {
t.Fatalf("Join(s) = %#v", entries)
}
})
t.Run("clear aid 1", func(t *testing.T) { t.Run("clear aid 1", func(t *testing.T) {
do(1, func(c state.Cursor) { do(1, func(c state.Cursor) {
if err := c.Destroy(tc[insertEntryOtherApp].ID); err != nil { if err := c.Destroy(tc[insertEntryOtherApp].ID); err != nil {

View File

@ -1,49 +0,0 @@
package state
import (
"errors"
"maps"
)
var (
ErrDuplicate = errors.New("store contains duplicates")
)
// Join returns joined state entries of all active aids.
func Join(s Store) (Entries, error) {
var (
aids []int
entries = make(Entries)
el int
res Entries
loadErr error
)
if ln, err := s.List(); err != nil {
return nil, err
} else {
aids = ln
}
for _, aid := range aids {
if _, err := s.Do(aid, func(c Cursor) {
res, loadErr = c.Load()
}); err != nil {
return nil, err
}
if loadErr != nil {
return nil, loadErr
}
// save expected length
el = len(entries) + len(res)
maps.Copy(entries, res)
if len(entries) != el {
return nil, ErrDuplicate
}
}
return entries, nil
}

View File

@ -1,9 +1,5 @@
package system package system
import (
"strings"
)
type ( type (
// Enablement represents an optional system resource // Enablement represents an optional system resource
Enablement uint8 Enablement uint8
@ -51,18 +47,3 @@ func (es *Enablements) Set(e Enablement) {
*es |= e.Mask() *es |= e.Mask()
} }
func (es *Enablements) String() string {
buf := new(strings.Builder)
for i := Enablement(0); i < Enablement(ELen); i++ {
if es.Has(i) {
buf.WriteString(", " + i.String())
}
}
if buf.Len() == 0 {
buf.WriteString("(No enablements)")
}
return strings.TrimPrefix(buf.String(), ", ")
}

85
main.go
View File

@ -23,7 +23,6 @@ import (
var ( var (
flagVerbose bool flagVerbose bool
flagJSON bool
//go:embed LICENSE //go:embed LICENSE
license string license string
@ -31,7 +30,6 @@ var (
func init() { func init() {
flag.BoolVar(&flagVerbose, "v", false, "Verbose output") flag.BoolVar(&flagVerbose, "v", false, "Verbose output")
flag.BoolVar(&flagJSON, "json", false, "Format output in JSON when applicable")
} }
var os = new(linux.Std) var os = new(linux.Std)
@ -63,14 +61,13 @@ func main() {
flag.CommandLine.Usage = func() { flag.CommandLine.Usage = func() {
fmt.Println() fmt.Println()
fmt.Println("Usage:\tfortify [-v] [--json] COMMAND [OPTIONS]") fmt.Println("Usage:\tfortify [-v] COMMAND [OPTIONS]")
fmt.Println() fmt.Println()
fmt.Println("Commands:") fmt.Println("Commands:")
w := tabwriter.NewWriter(os.Stdout(), 0, 1, 4, ' ', 0) w := tabwriter.NewWriter(os.Stdout(), 0, 1, 4, ' ', 0)
commands := [][2]string{ commands := [][2]string{
{"app", "Launch app defined by the specified config file"}, {"app", "Launch app defined by the specified config file"},
{"run", "Configure and start a permissive default sandbox"}, {"run", "Configure and start a permissive default sandbox"},
{"show", "Show the contents of an app configuration"},
{"ps", "List active apps and their state"}, {"ps", "List active apps and their state"},
{"version", "Show fortify version"}, {"version", "Show fortify version"},
{"license", "Show full license text"}, {"license", "Show full license text"},
@ -106,83 +103,27 @@ func main() {
fmt.Println(license) fmt.Println(license)
fmsg.Exit(0) fmsg.Exit(0)
case "template": // print full template configuration case "template": // print full template configuration
printJSON(fst.Template()) if s, err := json.MarshalIndent(fst.Template(), "", " "); err != nil {
fmsg.Fatalf("cannot generate template: %v", err)
panic("unreachable")
} else {
fmt.Println(string(s))
}
fmsg.Exit(0) fmsg.Exit(0)
case "help": // print help message case "help": // print help message
flag.CommandLine.Usage() flag.CommandLine.Usage()
fmsg.Exit(0) fmsg.Exit(0)
case "ps": // print all state info case "ps": // print all state info
set := flag.NewFlagSet("ps", flag.ExitOnError) var w *tabwriter.Writer
var short bool state.MustPrintLauncherStateSimpleGlobal(&w, os.Paths().RunDirPath)
set.BoolVar(&short, "short", false, "Print instance id") if w != nil {
if err := w.Flush(); err != nil {
// Ignore errors; set is set for ExitOnError. fmsg.Println("cannot format output:", err)
_ = set.Parse(args[1:])
printPs(short)
fmsg.Exit(0)
case "show": // pretty-print app info
if len(args) != 2 {
fmsg.Fatal("show requires 1 argument")
} }
likePrefix := false
if len(args[1]) <= 32 {
likePrefix = true
for _, c := range args[1] {
if c >= '0' && c <= '9' {
continue
}
if c >= 'a' && c <= 'f' {
continue
}
likePrefix = false
break
}
}
var (
config *fst.Config
instance *state.State
)
// try to match from state store
if likePrefix && len(args[1]) >= 8 {
fmsg.VPrintln("argument looks like prefix")
s := state.NewMulti(os.Paths().RunDirPath)
if entries, err := state.Join(s); err != nil {
fmsg.Printf("cannot join store: %v", err)
// drop to fetch from file
} else { } else {
for id := range entries { fmt.Println("No information available")
v := id.String()
if strings.HasPrefix(v, args[1]) {
// match, use config from this state entry
instance = entries[id]
config = instance.Config
break
} }
fmsg.VPrintf("instance %s skipped", v)
}
}
}
if config == nil {
fmsg.VPrintf("reading from file")
config = new(fst.Config)
if f, err := os.Open(args[1]); err != nil {
fmsg.Fatalf("cannot access config file %q: %s", args[1], err)
panic("unreachable")
} else if err = json.NewDecoder(f).Decode(&config); err != nil {
fmsg.Fatalf("cannot parse config file %q: %s", args[1], err)
panic("unreachable")
}
}
printShow(instance, config)
fmsg.Exit(0) fmsg.Exit(0)
case "app": // launch app from configuration file case "app": // launch app from configuration file
if len(args) < 2 { if len(args) < 2 {

View File

@ -36,7 +36,7 @@ package
*Default:* *Default:*
` <derivation fortify-0.2.6> ` ` <derivation fortify-0.2.5> `

View File

@ -14,13 +14,9 @@
buildGoModule rec { buildGoModule rec {
pname = "fortify"; pname = "fortify";
version = "0.2.6"; version = "0.2.5";
src = builtins.path { src = ./.;
name = "fortify-src";
path = lib.cleanSource ./.;
filter = path: type: !(type != "directory" && lib.hasSuffix ".nix" path);
};
vendorHash = null; vendorHash = null;
ldflags = ldflags =

225
print.go
View File

@ -1,225 +0,0 @@
package main
import (
"encoding/json"
"fmt"
direct "os"
"strconv"
"strings"
"text/tabwriter"
"time"
"git.gensokyo.uk/security/fortify/dbus"
"git.gensokyo.uk/security/fortify/fst"
"git.gensokyo.uk/security/fortify/internal/fmsg"
"git.gensokyo.uk/security/fortify/internal/state"
)
func printShow(instance *state.State, config *fst.Config) {
if flagJSON {
v := any(config)
if instance != nil {
v = instance
}
printJSON(v)
return
}
now := time.Now().UTC()
w := tabwriter.NewWriter(direct.Stdout, 0, 1, 4, ' ', 0)
if instance != nil {
fmt.Fprintf(w, "State\n")
fmt.Fprintf(w, " Instance:\t%s (%d)\n", instance.ID.String(), instance.PID)
fmt.Fprintf(w, " Uptime:\t%s\n", now.Sub(instance.Time).Round(time.Second).String())
fmt.Fprintf(w, "\n")
}
fmt.Fprintf(w, "App\n")
if config.ID != "" {
fmt.Fprintf(w, " ID:\t%d (%s)\n", config.Confinement.AppID, config.ID)
} else {
fmt.Fprintf(w, " ID:\t%d\n", config.Confinement.AppID)
}
fmt.Fprintf(w, " Enablements:\t%s\n", config.Confinement.Enablements.String())
if len(config.Confinement.Groups) > 0 {
fmt.Fprintf(w, " Groups:\t%q\n", config.Confinement.Groups)
}
fmt.Fprintf(w, " Directory:\t%s\n", config.Confinement.Outer)
if config.Confinement.Sandbox != nil {
sandbox := config.Confinement.Sandbox
if sandbox.Hostname != "" {
fmt.Fprintf(w, " Hostname:\t%q\n", sandbox.Hostname)
}
flags := make([]string, 0, 7)
writeFlag := func(name string, value bool) {
if value {
flags = append(flags, name)
}
}
writeFlag("userns", sandbox.UserNS)
writeFlag("net", sandbox.Net)
writeFlag("dev", sandbox.Dev)
writeFlag("tty", sandbox.NoNewSession)
writeFlag("mapuid", sandbox.MapRealUID)
writeFlag("directwl", sandbox.DirectWayland)
writeFlag("autoetc", sandbox.AutoEtc)
if len(flags) == 0 {
flags = append(flags, "none")
}
fmt.Fprintf(w, " Flags:\t%s\n", strings.Join(flags, " "))
fmt.Fprintf(w, " Overrides:\t%s\n", strings.Join(sandbox.Override, " "))
// Env map[string]string `json:"env"`
// Link [][2]string `json:"symlink"`
} else {
// this gets printed before everything else
fmt.Println("WARNING: current configuration uses permissive defaults!")
}
fmt.Fprintf(w, " Command:\t%s\n", strings.Join(config.Command, " "))
fmt.Fprintf(w, "\n")
if config.Confinement.Sandbox != nil && len(config.Confinement.Sandbox.Filesystem) > 0 {
fmt.Fprintf(w, "Filesystem:\n")
for _, f := range config.Confinement.Sandbox.Filesystem {
expr := new(strings.Builder)
if f.Device {
expr.WriteString(" d")
} else if f.Write {
expr.WriteString(" w")
} else {
expr.WriteString(" ")
}
if f.Must {
expr.WriteString("*")
} else {
expr.WriteString("+")
}
expr.WriteString(f.Src)
if f.Dst != "" {
expr.WriteString(":" + f.Dst)
}
fmt.Fprintf(w, "%s\n", expr.String())
}
fmt.Fprintf(w, "\n")
}
printDBus := func(c *dbus.Config) {
fmt.Fprintf(w, " Filter:\t%v\n", c.Filter)
if len(c.See) > 0 {
fmt.Fprintf(w, " See:\t%q\n", c.See)
}
if len(c.Talk) > 0 {
fmt.Fprintf(w, " Talk:\t%q\n", c.Talk)
}
if len(c.Own) > 0 {
fmt.Fprintf(w, " Own:\t%q\n", c.Own)
}
if len(c.Call) > 0 {
fmt.Fprintf(w, " Call:\t%q\n", c.Call)
}
if len(c.Broadcast) > 0 {
fmt.Fprintf(w, " Broadcast:\t%q\n", c.Broadcast)
}
}
if config.Confinement.SessionBus != nil {
fmt.Fprintf(w, "Session bus\n")
printDBus(config.Confinement.SessionBus)
fmt.Fprintf(w, "\n")
}
if config.Confinement.SystemBus != nil {
fmt.Fprintf(w, "System bus\n")
printDBus(config.Confinement.SystemBus)
fmt.Fprintf(w, "\n")
}
if err := w.Flush(); err != nil {
fmsg.Fatalf("cannot flush tabwriter: %v", err)
}
}
func printPs(short bool) {
now := time.Now().UTC()
var entries state.Entries
s := state.NewMulti(os.Paths().RunDirPath)
if e, err := state.Join(s); err != nil {
fmsg.Fatalf("cannot join store: %v", err)
} else {
entries = e
}
if err := s.Close(); err != nil {
fmsg.Printf("cannot close store: %v", err)
}
if short {
var v []string
if flagJSON {
v = make([]string, 0, len(entries))
}
for _, instance := range entries {
if !flagJSON {
fmt.Println(instance.ID.String())
} else {
v = append(v, instance.ID.String())
}
}
if flagJSON {
printJSON(v)
}
return
}
if flagJSON {
es := make(map[string]*state.State, len(entries))
for id, instance := range entries {
es[id.String()] = instance
}
printJSON(es)
return
}
// buffer output to reduce terminal activity
w := tabwriter.NewWriter(direct.Stdout, 0, 1, 4, ' ', 0)
fmt.Fprintln(w, "\tInstance\tPID\tApp\tUptime\tEnablements\tCommand")
for _, instance := range entries {
printInstance(w, instance, now)
}
if err := w.Flush(); err != nil {
fmsg.Fatalf("cannot flush tabwriter: %v", err)
}
}
func printInstance(w *tabwriter.Writer, instance *state.State, now time.Time) {
// gracefully skip nil states
if instance == nil {
fmsg.Println("got invalid state entry")
return
}
var (
es = "(No confinement information)"
cs = "(No command information)"
as = "(No configuration information)"
)
if instance.Config != nil {
es = instance.Config.Confinement.Enablements.String()
cs = fmt.Sprintf("%q", instance.Config.Command)
as = strconv.Itoa(instance.Config.Confinement.AppID)
}
fmt.Fprintf(w, "\t%s\t%d\t%s\t%s\t%s\t%s\n",
instance.ID.String()[:8], instance.PID, as, now.Sub(instance.Time).Round(time.Second).String(), strings.TrimPrefix(es, ", "), cs)
}
func printJSON(v any) {
encoder := json.NewEncoder(direct.Stdout)
encoder.SetIndent("", " ")
if err := encoder.Encode(v); err != nil {
fmsg.Fatalf("cannot serialise: %v", err)
panic("unreachable")
}
}

View File

@ -77,16 +77,6 @@ nixosTest {
programs.sway.enable = true; programs.sway.enable = true;
# For PulseAudio tests:
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
jack.enable = true;
};
virtualisation.qemu.options = [ virtualisation.qemu.options = [
# Need to switch to a different GPU driver than the default one (-vga std) so that Sway can launch: # Need to switch to a different GPU driver than the default one (-vga std) so that Sway can launch:
"-vga none -device virtio-gpu-pci" "-vga none -device virtio-gpu-pci"
@ -155,33 +145,17 @@ nixosTest {
retry(func) retry(func)
def collect_state_ui(name): def collect_state_ui(name):
swaymsg(f"exec fortify ps > '/tmp/{name}.ps'") swaymsg(f"exec fortify ps > '/tmp/{name}.ps'")
machine.copy_from_vm(f"/tmp/{name}.ps", "") machine.copy_from_vm(f"/tmp/{name}.ps", "")
swaymsg(f"exec fortify --json ps > '/tmp/{name}.json'")
machine.copy_from_vm(f"/tmp/{name}.json", "")
machine.screenshot(name) machine.screenshot(name)
def check_state(command, enablements):
instances = json.loads(machine.succeed("sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 fortify --json ps"))
if len(instances) != 1:
raise Exception(f"unexpected state length {len(instances)}")
instance = next(iter(instances.values()))
if instance['config']['command'] != command:
raise Exception(f"unexpected command {instance['config']['command']}")
if instance['config']['confinement']['enablements'] != enablements:
raise Exception(f"unexpected enablements {instance['config']['confinement']['enablements']}")
start_all() start_all()
machine.wait_for_unit("multi-user.target") machine.wait_for_unit("multi-user.target")
# Run fortify Go tests outside of nix build in the background: # Run fortify Go tests outside of nix build:
machine.succeed("rm -rf /tmp/src && cp -a '${self.packages.${system}.fortify.src}' /tmp/src") machine.succeed("rm -rf /tmp/src && cp -a '${self.packages.${system}.fortify.src}' /tmp/src")
machine.succeed("fortify-fhs -c '(cd /tmp/src && go generate ./... && go test ./... && touch /tmp/success-gotest)' &> /tmp/gotest &") print(machine.succeed("fortify-fhs -c '(cd /tmp/src && go generate ./... && go test ./...)'"))
# To check sway's version: # To check sway's version:
print(machine.succeed("sway --version")) print(machine.succeed("sway --version"))
@ -198,16 +172,17 @@ nixosTest {
machine.wait_for_file("/tmp/fortify.1000/tmpdir/0/success-bare") machine.wait_for_file("/tmp/fortify.1000/tmpdir/0/success-bare")
# Start fortify within Wayland session: # Start fortify within Wayland session:
swaymsg("exec fortify -v run --wayland --dbus touch /tmp/success-session") swaymsg("exec fortify -v run --wayland touch /tmp/success-session")
machine.wait_for_file("/tmp/fortify.1000/tmpdir/0/success-session") machine.wait_for_file("/tmp/fortify.1000/tmpdir/0/success-session")
# Start a terminal (foot) within fortify: # Start a terminal (foot) within fortify on workspace 3:
machine.send_key("alt-3")
machine.sleep(3)
swaymsg("exec fortify run --wayland foot") swaymsg("exec fortify run --wayland foot")
wait_for_window("u0_a0@machine") wait_for_window("u0_a0@machine")
machine.send_chars("clear; wayland-info && touch /tmp/success-client\n") machine.send_chars("wayland-info && touch /tmp/success-client\n")
machine.wait_for_file("/tmp/fortify.1000/tmpdir/0/success-client") machine.wait_for_file("/tmp/fortify.1000/tmpdir/0/success-client")
collect_state_ui("foot_wayland_permissive") collect_state_ui("foot_wayland_permissive")
check_state(["foot"], 1)
# Verify acl on XDG_RUNTIME_DIR: # Verify acl on XDG_RUNTIME_DIR:
print(machine.succeed("getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep 1000000")) print(machine.succeed("getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep 1000000"))
machine.send_chars("exit\n") machine.send_chars("exit\n")
@ -215,33 +190,23 @@ nixosTest {
# Verify acl cleanup on XDG_RUNTIME_DIR: # Verify acl cleanup on XDG_RUNTIME_DIR:
machine.wait_until_fails("getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep 1000000") machine.wait_until_fails("getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep 1000000")
# Start a terminal (foot) within fortify from a terminal: # Start a terminal (foot) within fortify from a terminal on workspace 4:
machine.send_key("alt-4")
machine.sleep(3)
swaymsg("exec foot fortify run --wayland foot") swaymsg("exec foot fortify run --wayland foot")
wait_for_window("u0_a0@machine") wait_for_window("u0_a0@machine")
machine.send_chars("clear; wayland-info && touch /tmp/success-client-term\n") machine.send_chars("wayland-info && touch /tmp/success-client-term\n")
machine.wait_for_file("/tmp/fortify.1000/tmpdir/0/success-client-term") machine.wait_for_file("/tmp/fortify.1000/tmpdir/0/success-client-term")
collect_state_ui("foot_wayland_permissive_term") collect_state_ui("foot_wayland_permissive_term")
check_state(["foot"], 1)
machine.send_chars("exit\n")
machine.wait_until_fails("pgrep foot")
# Test PulseAudio (fortify does not support PipeWire yet):
swaymsg("exec fortify run --wayland --pulse foot")
wait_for_window("u0_a0@machine")
machine.send_chars("clear; pactl info && touch /tmp/success-pulse\n")
machine.wait_for_file("/tmp/fortify.1000/tmpdir/0/success-pulse")
collect_state_ui("pulse_wayland")
check_state(["foot"], 9)
machine.send_chars("exit\n") machine.send_chars("exit\n")
machine.wait_until_fails("pgrep foot") machine.wait_until_fails("pgrep foot")
# Test XWayland (foot does not support X): # Test XWayland (foot does not support X):
swaymsg("exec fortify run -X alacritty") swaymsg("exec fortify run -X alacritty")
wait_for_window("u0_a0@machine") wait_for_window("u0_a0@machine")
machine.send_chars("clear; glinfo && touch /tmp/success-client-x11\n") machine.send_chars("glinfo && touch /tmp/success-client-x11\n")
machine.wait_for_file("/tmp/fortify.1000/tmpdir/0/success-client-x11") machine.wait_for_file("/tmp/fortify.1000/tmpdir/0/success-client-x11")
collect_state_ui("alacritty_x11_permissive") collect_state_ui("alacritty_x11_permissive")
check_state(["alacritty"], 2)
machine.send_chars("exit\n") machine.send_chars("exit\n")
machine.wait_until_fails("pgrep alacritty") machine.wait_until_fails("pgrep alacritty")
@ -252,10 +217,5 @@ nixosTest {
# Print fortify runDir contents: # Print fortify runDir contents:
print(machine.succeed("find /run/user/1000/fortify")) print(machine.succeed("find /run/user/1000/fortify"))
# Verify go test status:
machine.wait_for_file("/tmp/gotest")
print(machine.succeed("cat /tmp/gotest"))
machine.wait_for_file("/tmp/success-gotest")
''; '';
} }