Compare commits
4 Commits
a0062d8275
...
f955b15b84
Author | SHA1 | Date | |
---|---|---|---|
f955b15b84 | |||
0340c67995 | |||
72b0160aad | |||
ea8d1c07df |
@ -1,6 +1,8 @@
|
|||||||
package bwrap
|
package bwrap
|
||||||
|
|
||||||
import "os"
|
import (
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Bind binds mount src on host to dest in sandbox.
|
Bind binds mount src on host to dest in sandbox.
|
||||||
@ -61,6 +63,29 @@ func (c *Config) Bind(src, dest string, opts ...bool) *Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write copy from FD to destination DEST
|
||||||
|
// (--file FD DEST)
|
||||||
|
func (c *Config) Write(dest string, payload []byte) *Config {
|
||||||
|
c.Filesystem = append(c.Filesystem, &DataConfig{Dest: dest, Data: payload, Type: DataWrite})
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
CopyBind copy from FD to file which is readonly bind-mounted on DEST
|
||||||
|
(--ro-bind-data FD DEST)
|
||||||
|
|
||||||
|
CopyBind(dest, payload, true) copy from FD to file which is bind-mounted on DEST
|
||||||
|
(--bind-data FD DEST)
|
||||||
|
*/
|
||||||
|
func (c *Config) CopyBind(dest string, payload []byte, opts ...bool) *Config {
|
||||||
|
t := DataROBind
|
||||||
|
if len(opts) > 0 && opts[0] {
|
||||||
|
t = DataBind
|
||||||
|
}
|
||||||
|
c.Filesystem = append(c.Filesystem, &DataConfig{Dest: dest, Data: payload, Type: t})
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
// Dir create dir in sandbox
|
// Dir create dir in sandbox
|
||||||
// (--dir DEST)
|
// (--dir DEST)
|
||||||
func (c *Config) Dir(dest string) *Config {
|
func (c *Config) Dir(dest string) *Config {
|
||||||
|
@ -71,9 +71,6 @@ type Config struct {
|
|||||||
--ro-bind-fd FD DEST Bind open directory or path fd read-only on DEST
|
--ro-bind-fd FD DEST Bind open directory or path fd read-only on DEST
|
||||||
--exec-label LABEL Exec label for the sandbox
|
--exec-label LABEL Exec label for the sandbox
|
||||||
--file-label LABEL File label for temporary sandbox content
|
--file-label LABEL File label for temporary sandbox content
|
||||||
--file FD DEST Copy from FD to destination DEST
|
|
||||||
--bind-data FD DEST Copy from FD to file which is bind-mounted on DEST
|
|
||||||
--ro-bind-data FD DEST Copy from FD to file which is readonly bind-mounted on DEST
|
|
||||||
--add-seccomp-fd FD Load and use seccomp rules from FD (repeatable)
|
--add-seccomp-fd FD Load and use seccomp rules from FD (repeatable)
|
||||||
--block-fd FD Block on FD until some data to read is available
|
--block-fd FD Block on FD until some data to read is available
|
||||||
--userns-block-fd FD Block on FD until the user namespace is ready
|
--userns-block-fd FD Block on FD until the user namespace is ready
|
||||||
|
@ -21,15 +21,14 @@ func TestConfig_Args(t *testing.T) {
|
|||||||
want []string
|
want []string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "bind",
|
"bind", (new(bwrap.Config)).
|
||||||
conf: (new(bwrap.Config)).
|
|
||||||
Bind("/etc", "/.fortify/etc").
|
Bind("/etc", "/.fortify/etc").
|
||||||
Bind("/etc", "/.fortify/etc", true).
|
Bind("/etc", "/.fortify/etc", true).
|
||||||
Bind("/run", "/.fortify/run", false, true).
|
Bind("/run", "/.fortify/run", false, true).
|
||||||
Bind("/sys/devices", "/.fortify/sys/devices", true, true).
|
Bind("/sys/devices", "/.fortify/sys/devices", true, true).
|
||||||
Bind("/dev/dri", "/.fortify/dev/dri", false, true, true).
|
Bind("/dev/dri", "/.fortify/dev/dri", false, true, true).
|
||||||
Bind("/dev/dri", "/.fortify/dev/dri", true, true, true),
|
Bind("/dev/dri", "/.fortify/dev/dri", true, true, true),
|
||||||
want: []string{
|
[]string{
|
||||||
"--unshare-all", "--unshare-user",
|
"--unshare-all", "--unshare-user",
|
||||||
"--disable-userns", "--assert-userns-disabled",
|
"--disable-userns", "--assert-userns-disabled",
|
||||||
// Bind("/etc", "/.fortify/etc")
|
// Bind("/etc", "/.fortify/etc")
|
||||||
@ -47,14 +46,13 @@ func TestConfig_Args(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "dir remount-ro proc dev mqueue",
|
"dir remount-ro proc dev mqueue", (new(bwrap.Config)).
|
||||||
conf: (new(bwrap.Config)).
|
|
||||||
Dir("/.fortify").
|
Dir("/.fortify").
|
||||||
RemountRO("/home").
|
RemountRO("/home").
|
||||||
Procfs("/proc").
|
Procfs("/proc").
|
||||||
DevTmpfs("/dev").
|
DevTmpfs("/dev").
|
||||||
Mqueue("/dev/mqueue"),
|
Mqueue("/dev/mqueue"),
|
||||||
want: []string{
|
[]string{
|
||||||
"--unshare-all", "--unshare-user",
|
"--unshare-all", "--unshare-user",
|
||||||
"--disable-userns", "--assert-userns-disabled",
|
"--disable-userns", "--assert-userns-disabled",
|
||||||
// Dir("/.fortify")
|
// Dir("/.fortify")
|
||||||
@ -70,11 +68,10 @@ func TestConfig_Args(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "tmpfs",
|
"tmpfs", (new(bwrap.Config)).
|
||||||
conf: (new(bwrap.Config)).
|
|
||||||
Tmpfs("/run/user", 8192).
|
Tmpfs("/run/user", 8192).
|
||||||
Tmpfs("/run/dbus", 8192, 0755),
|
Tmpfs("/run/dbus", 8192, 0755),
|
||||||
want: []string{
|
[]string{
|
||||||
"--unshare-all", "--unshare-user",
|
"--unshare-all", "--unshare-user",
|
||||||
"--disable-userns", "--assert-userns-disabled",
|
"--disable-userns", "--assert-userns-disabled",
|
||||||
// Tmpfs("/run/user", 8192)
|
// Tmpfs("/run/user", 8192)
|
||||||
@ -84,11 +81,10 @@ func TestConfig_Args(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "symlink",
|
"symlink", (new(bwrap.Config)).
|
||||||
conf: (new(bwrap.Config)).
|
|
||||||
Symlink("/.fortify/sbin/init", "/sbin/init").
|
Symlink("/.fortify/sbin/init", "/sbin/init").
|
||||||
Symlink("/.fortify/sbin/init", "/sbin/init", 0755),
|
Symlink("/.fortify/sbin/init", "/sbin/init", 0755),
|
||||||
want: []string{
|
[]string{
|
||||||
"--unshare-all", "--unshare-user",
|
"--unshare-all", "--unshare-user",
|
||||||
"--disable-userns", "--assert-userns-disabled",
|
"--disable-userns", "--assert-userns-disabled",
|
||||||
// Symlink("/.fortify/sbin/init", "/sbin/init")
|
// Symlink("/.fortify/sbin/init", "/sbin/init")
|
||||||
@ -98,12 +94,11 @@ func TestConfig_Args(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "overlayfs",
|
"overlayfs", (new(bwrap.Config)).
|
||||||
conf: (new(bwrap.Config)).
|
|
||||||
Overlay("/etc", "/etc").
|
Overlay("/etc", "/etc").
|
||||||
Join("/.fortify/bin", "/bin", "/usr/bin", "/usr/local/bin").
|
Join("/.fortify/bin", "/bin", "/usr/bin", "/usr/local/bin").
|
||||||
Persist("/nix", "/data/data/org.chromium.Chromium/overlay/rwsrc", "/data/data/org.chromium.Chromium/workdir", "/data/app/org.chromium.Chromium/nix"),
|
Persist("/nix", "/data/data/org.chromium.Chromium/overlay/rwsrc", "/data/data/org.chromium.Chromium/workdir", "/data/app/org.chromium.Chromium/nix"),
|
||||||
want: []string{
|
[]string{
|
||||||
"--unshare-all", "--unshare-user",
|
"--unshare-all", "--unshare-user",
|
||||||
"--disable-userns", "--assert-userns-disabled",
|
"--disable-userns", "--assert-userns-disabled",
|
||||||
// Overlay("/etc", "/etc")
|
// Overlay("/etc", "/etc")
|
||||||
@ -117,8 +112,23 @@ func TestConfig_Args(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "unshare",
|
"copy", (new(bwrap.Config)).
|
||||||
conf: &bwrap.Config{Unshare: &bwrap.UnshareConfig{
|
Write("/.fortify/version", make([]byte, 8)).
|
||||||
|
CopyBind("/etc/group", make([]byte, 8)).
|
||||||
|
CopyBind("/etc/passwd", make([]byte, 8), true),
|
||||||
|
[]string{
|
||||||
|
"--unshare-all", "--unshare-user",
|
||||||
|
"--disable-userns", "--assert-userns-disabled",
|
||||||
|
// Write("/.fortify/version", make([]byte, 8))
|
||||||
|
"--file", "3", "/.fortify/version",
|
||||||
|
// CopyBind("/etc/group", make([]byte, 8))
|
||||||
|
"--ro-bind-data", "4", "/etc/group",
|
||||||
|
// CopyBind("/etc/passwd", make([]byte, 8), true)
|
||||||
|
"--bind-data", "5", "/etc/passwd",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"unshare", &bwrap.Config{Unshare: &bwrap.UnshareConfig{
|
||||||
User: false,
|
User: false,
|
||||||
IPC: false,
|
IPC: false,
|
||||||
PID: false,
|
PID: false,
|
||||||
@ -126,14 +136,13 @@ func TestConfig_Args(t *testing.T) {
|
|||||||
UTS: false,
|
UTS: false,
|
||||||
CGroup: false,
|
CGroup: false,
|
||||||
}},
|
}},
|
||||||
want: []string{"--disable-userns", "--assert-userns-disabled"},
|
[]string{"--disable-userns", "--assert-userns-disabled"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "uid gid sync",
|
"uid gid sync", (new(bwrap.Config)).
|
||||||
conf: (new(bwrap.Config)).
|
|
||||||
SetUID(1971).
|
SetUID(1971).
|
||||||
SetGID(100),
|
SetGID(100),
|
||||||
want: []string{
|
[]string{
|
||||||
"--unshare-all", "--unshare-user",
|
"--unshare-all", "--unshare-user",
|
||||||
"--disable-userns", "--assert-userns-disabled",
|
"--disable-userns", "--assert-userns-disabled",
|
||||||
// SetUID(1971)
|
// SetUID(1971)
|
||||||
@ -143,8 +152,7 @@ func TestConfig_Args(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "hostname chdir setenv unsetenv lockfile chmod syscall",
|
"hostname chdir setenv unsetenv lockfile chmod syscall", &bwrap.Config{
|
||||||
conf: &bwrap.Config{
|
|
||||||
Hostname: "fortify",
|
Hostname: "fortify",
|
||||||
Chdir: "/.fortify",
|
Chdir: "/.fortify",
|
||||||
SetEnv: map[string]string{"FORTIFY_INIT": "/.fortify/sbin/init"},
|
SetEnv: map[string]string{"FORTIFY_INIT": "/.fortify/sbin/init"},
|
||||||
@ -153,7 +161,7 @@ func TestConfig_Args(t *testing.T) {
|
|||||||
Syscall: new(bwrap.SyscallPolicy),
|
Syscall: new(bwrap.SyscallPolicy),
|
||||||
Chmod: map[string]os.FileMode{"/.fortify/sbin/init": 0755},
|
Chmod: map[string]os.FileMode{"/.fortify/sbin/init": 0755},
|
||||||
},
|
},
|
||||||
want: []string{
|
[]string{
|
||||||
"--unshare-all", "--unshare-user",
|
"--unshare-all", "--unshare-user",
|
||||||
"--disable-userns", "--assert-userns-disabled",
|
"--disable-userns", "--assert-userns-disabled",
|
||||||
// Hostname: "fortify"
|
// Hostname: "fortify"
|
||||||
@ -175,8 +183,7 @@ func TestConfig_Args(t *testing.T) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
name: "xdg-dbus-proxy constraint sample",
|
"xdg-dbus-proxy constraint sample", (&bwrap.Config{Clearenv: true, DieWithParent: true}).
|
||||||
conf: (&bwrap.Config{Clearenv: true, DieWithParent: true}).
|
|
||||||
Symlink("usr/bin", "/bin").
|
Symlink("usr/bin", "/bin").
|
||||||
Symlink("var/home", "/home").
|
Symlink("var/home", "/home").
|
||||||
Symlink("usr/lib", "/lib").
|
Symlink("usr/lib", "/lib").
|
||||||
@ -199,7 +206,7 @@ func TestConfig_Args(t *testing.T) {
|
|||||||
Bind("/sysroot", "/sysroot").
|
Bind("/sysroot", "/sysroot").
|
||||||
Bind("/usr", "/usr").
|
Bind("/usr", "/usr").
|
||||||
Bind("/etc", "/etc"),
|
Bind("/etc", "/etc"),
|
||||||
want: []string{
|
[]string{
|
||||||
"--unshare-all", "--unshare-user",
|
"--unshare-all", "--unshare-user",
|
||||||
"--disable-userns", "--assert-userns-disabled",
|
"--disable-userns", "--assert-userns-disabled",
|
||||||
"--clearenv", "--die-with-parent",
|
"--clearenv", "--die-with-parent",
|
||||||
|
@ -2,14 +2,19 @@ package bwrap
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"git.gensokyo.uk/security/fortify/helper/proc"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
gob.Register(new(PermConfig[SymlinkConfig]))
|
gob.Register(new(PermConfig[SymlinkConfig]))
|
||||||
gob.Register(new(PermConfig[*TmpfsConfig]))
|
gob.Register(new(PermConfig[*TmpfsConfig]))
|
||||||
gob.Register(new(OverlayConfig))
|
gob.Register(new(OverlayConfig))
|
||||||
|
gob.Register(new(DataConfig))
|
||||||
}
|
}
|
||||||
|
|
||||||
type PositionalArg int
|
type PositionalArg int
|
||||||
@ -44,6 +49,10 @@ const (
|
|||||||
|
|
||||||
SyncFd
|
SyncFd
|
||||||
Seccomp
|
Seccomp
|
||||||
|
|
||||||
|
File
|
||||||
|
BindData
|
||||||
|
ROBindData
|
||||||
)
|
)
|
||||||
|
|
||||||
var positionalArgs = [...]string{
|
var positionalArgs = [...]string{
|
||||||
@ -74,6 +83,10 @@ var positionalArgs = [...]string{
|
|||||||
|
|
||||||
SyncFd: "--sync-fd",
|
SyncFd: "--sync-fd",
|
||||||
Seccomp: "--seccomp",
|
Seccomp: "--seccomp",
|
||||||
|
|
||||||
|
File: "--file",
|
||||||
|
BindData: "--bind-data",
|
||||||
|
ROBindData: "--ro-bind-data",
|
||||||
}
|
}
|
||||||
|
|
||||||
type PermConfig[T FSBuilder] struct {
|
type PermConfig[T FSBuilder] struct {
|
||||||
@ -202,12 +215,59 @@ func (s SymlinkConfig) Append(args *[]string) { *args = append(*args, Symlink.St
|
|||||||
|
|
||||||
type ChmodConfig map[string]os.FileMode
|
type ChmodConfig map[string]os.FileMode
|
||||||
|
|
||||||
func (c ChmodConfig) Len() int {
|
func (c ChmodConfig) Len() int { return len(c) }
|
||||||
return len(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c ChmodConfig) Append(args *[]string) {
|
func (c ChmodConfig) Append(args *[]string) {
|
||||||
for path, mode := range c {
|
for path, mode := range c {
|
||||||
*args = append(*args, Chmod.String(), strconv.FormatInt(int64(mode), 8), path)
|
*args = append(*args, Chmod.String(), strconv.FormatInt(int64(mode), 8), path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
DataWrite = iota
|
||||||
|
DataBind
|
||||||
|
DataROBind
|
||||||
|
)
|
||||||
|
|
||||||
|
type DataConfig struct {
|
||||||
|
Dest string `json:"dest"`
|
||||||
|
Data []byte `json:"data,omitempty"`
|
||||||
|
Type int `json:"type"`
|
||||||
|
proc.File
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DataConfig) Path() string { return d.Dest }
|
||||||
|
func (d *DataConfig) Len() int {
|
||||||
|
if d == nil || d.Data == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return 3
|
||||||
|
}
|
||||||
|
func (d *DataConfig) Init(fd uintptr, v **os.File) uintptr {
|
||||||
|
if d.File != nil {
|
||||||
|
panic("file initialised twice")
|
||||||
|
}
|
||||||
|
d.File = proc.NewWriterTo(d)
|
||||||
|
return d.File.Init(fd, v)
|
||||||
|
}
|
||||||
|
func (d *DataConfig) WriteTo(w io.Writer) (int64, error) {
|
||||||
|
n, err := w.Write(d.Data)
|
||||||
|
return int64(n), err
|
||||||
|
}
|
||||||
|
func (d *DataConfig) Append(args *[]string) {
|
||||||
|
if d == nil || d.Data == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var a PositionalArg
|
||||||
|
switch d.Type {
|
||||||
|
case DataWrite:
|
||||||
|
a = File
|
||||||
|
case DataBind:
|
||||||
|
a = BindData
|
||||||
|
case DataROBind:
|
||||||
|
a = ROBindData
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("invalid type %d", a))
|
||||||
|
}
|
||||||
|
|
||||||
|
*args = append(*args, a.String(), strconv.Itoa(int(d.Fd())), d.Dest)
|
||||||
|
}
|
||||||
|
@ -62,8 +62,6 @@ var testCasesNixos = []sealTestCase{
|
|||||||
Ensure("/run/user/1971/fortify", 0700).UpdatePermType(system.User, "/run/user/1971/fortify", acl.Execute).
|
Ensure("/run/user/1971/fortify", 0700).UpdatePermType(system.User, "/run/user/1971/fortify", acl.Execute).
|
||||||
Ensure("/run/user/1971", 0700).UpdatePermType(system.User, "/run/user/1971", acl.Execute). // this is ordered as is because the previous Ensure only calls mkdir if XDG_RUNTIME_DIR is unset
|
Ensure("/run/user/1971", 0700).UpdatePermType(system.User, "/run/user/1971", acl.Execute). // this is ordered as is because the previous Ensure only calls mkdir if XDG_RUNTIME_DIR is unset
|
||||||
Ephemeral(system.Process, "/run/user/1971/fortify/8e2c76b066dabe574cf073bdb46eb5c1", 0700).UpdatePermType(system.Process, "/run/user/1971/fortify/8e2c76b066dabe574cf073bdb46eb5c1", acl.Execute).
|
Ephemeral(system.Process, "/run/user/1971/fortify/8e2c76b066dabe574cf073bdb46eb5c1", 0700).UpdatePermType(system.Process, "/run/user/1971/fortify/8e2c76b066dabe574cf073bdb46eb5c1", acl.Execute).
|
||||||
WriteType(system.Process, "/tmp/fortify.1971/8e2c76b066dabe574cf073bdb46eb5c1/passwd", "u0_a1:x:1971:1971:Fortify:/var/lib/persist/module/fortify/0/1:/run/current-system/sw/bin/zsh\n").
|
|
||||||
WriteType(system.Process, "/tmp/fortify.1971/8e2c76b066dabe574cf073bdb46eb5c1/group", "fortify:x:1971:\n").
|
|
||||||
Link("/run/user/1971/wayland-0", "/run/user/1971/fortify/8e2c76b066dabe574cf073bdb46eb5c1/wayland").
|
Link("/run/user/1971/wayland-0", "/run/user/1971/fortify/8e2c76b066dabe574cf073bdb46eb5c1/wayland").
|
||||||
UpdatePermType(system.EWayland, "/run/user/1971/wayland-0", acl.Read, acl.Write, acl.Execute).
|
UpdatePermType(system.EWayland, "/run/user/1971/wayland-0", acl.Read, acl.Write, acl.Execute).
|
||||||
Link("/run/user/1971/pulse/native", "/run/user/1971/fortify/8e2c76b066dabe574cf073bdb46eb5c1/pulse").
|
Link("/run/user/1971/pulse/native", "/run/user/1971/fortify/8e2c76b066dabe574cf073bdb46eb5c1/pulse").
|
||||||
@ -212,13 +210,15 @@ var testCasesNixos = []sealTestCase{
|
|||||||
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).
|
||||||
Bind("/tmp/fortify.1971/8e2c76b066dabe574cf073bdb46eb5c1/passwd", "/etc/passwd").
|
CopyBind("/etc/passwd", []byte("u0_a1:x:1971:1971:Fortify:/var/lib/persist/module/fortify/0/1:/run/current-system/sw/bin/zsh\n")).
|
||||||
Bind("/tmp/fortify.1971/8e2c76b066dabe574cf073bdb46eb5c1/group", "/etc/group").
|
CopyBind("/etc/group", []byte("fortify:x:1971:\n")).
|
||||||
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", fst.Tmp+"/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).
|
||||||
|
Bind("/run/wrappers/bin/fortify", "/.fortify/sbin/fortify").
|
||||||
|
Symlink("fortify", "/.fortify/sbin/init"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -32,9 +32,7 @@ var testCasesPd = []sealTestCase{
|
|||||||
Ensure("/tmp/fortify.1971/tmpdir/0", 01700).UpdatePermType(system.User, "/tmp/fortify.1971/tmpdir/0", acl.Read, acl.Write, acl.Execute).
|
Ensure("/tmp/fortify.1971/tmpdir/0", 01700).UpdatePermType(system.User, "/tmp/fortify.1971/tmpdir/0", acl.Read, acl.Write, acl.Execute).
|
||||||
Ensure("/run/user/1971/fortify", 0700).UpdatePermType(system.User, "/run/user/1971/fortify", acl.Execute).
|
Ensure("/run/user/1971/fortify", 0700).UpdatePermType(system.User, "/run/user/1971/fortify", acl.Execute).
|
||||||
Ensure("/run/user/1971", 0700).UpdatePermType(system.User, "/run/user/1971", acl.Execute). // this is ordered as is because the previous Ensure only calls mkdir if XDG_RUNTIME_DIR is unset
|
Ensure("/run/user/1971", 0700).UpdatePermType(system.User, "/run/user/1971", acl.Execute). // this is ordered as is because the previous Ensure only calls mkdir if XDG_RUNTIME_DIR is unset
|
||||||
Ephemeral(system.Process, "/run/user/1971/fortify/4a450b6596d7bc15bd01780eb9a607ac", 0700).UpdatePermType(system.Process, "/run/user/1971/fortify/4a450b6596d7bc15bd01780eb9a607ac", acl.Execute).
|
Ephemeral(system.Process, "/run/user/1971/fortify/4a450b6596d7bc15bd01780eb9a607ac", 0700).UpdatePermType(system.Process, "/run/user/1971/fortify/4a450b6596d7bc15bd01780eb9a607ac", acl.Execute),
|
||||||
WriteType(system.Process, "/tmp/fortify.1971/4a450b6596d7bc15bd01780eb9a607ac/passwd", "chronos:x:65534:65534:Fortify:/home/chronos:/run/current-system/sw/bin/zsh\n").
|
|
||||||
WriteType(system.Process, "/tmp/fortify.1971/4a450b6596d7bc15bd01780eb9a607ac/group", "fortify:x:65534:\n"),
|
|
||||||
(&bwrap.Config{
|
(&bwrap.Config{
|
||||||
Net: true,
|
Net: true,
|
||||||
UserNS: true,
|
UserNS: true,
|
||||||
@ -154,9 +152,11 @@ var testCasesPd = []sealTestCase{
|
|||||||
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).
|
||||||
Bind("/tmp/fortify.1971/4a450b6596d7bc15bd01780eb9a607ac/passwd", "/etc/passwd").
|
CopyBind("/etc/passwd", []byte("chronos:x:65534:65534:Fortify:/home/chronos:/run/current-system/sw/bin/zsh\n")).
|
||||||
Bind("/tmp/fortify.1971/4a450b6596d7bc15bd01780eb9a607ac/group", "/etc/group").
|
CopyBind("/etc/group", []byte("fortify:x:65534:\n")).
|
||||||
Tmpfs("/var/run/nscd", 8192),
|
Tmpfs("/var/run/nscd", 8192).
|
||||||
|
Bind("/run/wrappers/bin/fortify", "/.fortify/sbin/fortify").
|
||||||
|
Symlink("fortify", "/.fortify/sbin/init"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"nixos permissive defaults chromium", new(stubNixOS),
|
"nixos permissive defaults chromium", new(stubNixOS),
|
||||||
@ -216,8 +216,6 @@ var testCasesPd = []sealTestCase{
|
|||||||
Ensure("/run/user/1971/fortify", 0700).UpdatePermType(system.User, "/run/user/1971/fortify", acl.Execute).
|
Ensure("/run/user/1971/fortify", 0700).UpdatePermType(system.User, "/run/user/1971/fortify", acl.Execute).
|
||||||
Ensure("/run/user/1971", 0700).UpdatePermType(system.User, "/run/user/1971", acl.Execute). // this is ordered as is because the previous Ensure only calls mkdir if XDG_RUNTIME_DIR is unset
|
Ensure("/run/user/1971", 0700).UpdatePermType(system.User, "/run/user/1971", acl.Execute). // this is ordered as is because the previous Ensure only calls mkdir if XDG_RUNTIME_DIR is unset
|
||||||
Ephemeral(system.Process, "/run/user/1971/fortify/ebf083d1b175911782d413369b64ce7c", 0700).UpdatePermType(system.Process, "/run/user/1971/fortify/ebf083d1b175911782d413369b64ce7c", acl.Execute).
|
Ephemeral(system.Process, "/run/user/1971/fortify/ebf083d1b175911782d413369b64ce7c", 0700).UpdatePermType(system.Process, "/run/user/1971/fortify/ebf083d1b175911782d413369b64ce7c", acl.Execute).
|
||||||
WriteType(system.Process, "/tmp/fortify.1971/ebf083d1b175911782d413369b64ce7c/passwd", "chronos:x:65534:65534:Fortify:/home/chronos:/run/current-system/sw/bin/zsh\n").
|
|
||||||
WriteType(system.Process, "/tmp/fortify.1971/ebf083d1b175911782d413369b64ce7c/group", "fortify:x:65534:\n").
|
|
||||||
Ensure("/tmp/fortify.1971/wayland", 0711).
|
Ensure("/tmp/fortify.1971/wayland", 0711).
|
||||||
Wayland("/tmp/fortify.1971/wayland/ebf083d1b175911782d413369b64ce7c", "/run/user/1971/wayland-0", "org.chromium.Chromium", "ebf083d1b175911782d413369b64ce7c").
|
Wayland("/tmp/fortify.1971/wayland/ebf083d1b175911782d413369b64ce7c", "/run/user/1971/wayland-0", "org.chromium.Chromium", "ebf083d1b175911782d413369b64ce7c").
|
||||||
Link("/run/user/1971/pulse/native", "/run/user/1971/fortify/ebf083d1b175911782d413369b64ce7c/pulse").
|
Link("/run/user/1971/pulse/native", "/run/user/1971/fortify/ebf083d1b175911782d413369b64ce7c/pulse").
|
||||||
@ -380,13 +378,15 @@ var testCasesPd = []sealTestCase{
|
|||||||
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).
|
||||||
Bind("/tmp/fortify.1971/ebf083d1b175911782d413369b64ce7c/passwd", "/etc/passwd").
|
CopyBind("/etc/passwd", []byte("chronos:x:65534:65534:Fortify:/home/chronos:/run/current-system/sw/bin/zsh\n")).
|
||||||
Bind("/tmp/fortify.1971/ebf083d1b175911782d413369b64ce7c/group", "/etc/group").
|
CopyBind("/etc/group", []byte("fortify:x:65534:\n")).
|
||||||
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", fst.Tmp+"/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).
|
||||||
|
Bind("/run/wrappers/bin/fortify", "/.fortify/sbin/fortify").
|
||||||
|
Symlink("fortify", "/.fortify/sbin/init"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,12 @@ type stubNixOS struct {
|
|||||||
usernameErr map[string]error
|
usernameErr map[string]error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stubNixOS) Geteuid() int {
|
func (s *stubNixOS) Geteuid() int { return 1971 }
|
||||||
return 1971
|
func (s *stubNixOS) TempDir() string { return "/tmp" }
|
||||||
}
|
func (s *stubNixOS) MustExecutable() string { return "/run/wrappers/bin/fortify" }
|
||||||
|
func (s *stubNixOS) Exit(code int) { panic("called exit on stub with code " + strconv.Itoa(code)) }
|
||||||
|
func (s *stubNixOS) EvalSymlinks(path string) (string, error) { return path, nil }
|
||||||
|
func (s *stubNixOS) Uid(aid int) (int, error) { return 1000000 + 0*10000 + aid, nil }
|
||||||
|
|
||||||
func (s *stubNixOS) LookupEnv(key string) (string, bool) {
|
func (s *stubNixOS) LookupEnv(key string) (string, bool) {
|
||||||
switch key {
|
switch key {
|
||||||
@ -39,10 +42,6 @@ func (s *stubNixOS) LookupEnv(key string) (string, bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stubNixOS) TempDir() string {
|
|
||||||
return "/tmp"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stubNixOS) LookPath(file string) (string, error) {
|
func (s *stubNixOS) LookPath(file string) (string, error) {
|
||||||
if s.lookPathErr != nil {
|
if s.lookPathErr != nil {
|
||||||
if err, ok := s.lookPathErr[file]; ok {
|
if err, ok := s.lookPathErr[file]; ok {
|
||||||
@ -60,10 +59,6 @@ func (s *stubNixOS) LookPath(file string) (string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stubNixOS) Executable() (string, error) {
|
|
||||||
return "/home/ophestra/.nix-profile/bin/fortify", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stubNixOS) LookupGroup(name string) (*user.Group, error) {
|
func (s *stubNixOS) LookupGroup(name string) (*user.Group, error) {
|
||||||
switch name {
|
switch name {
|
||||||
case "video":
|
case "video":
|
||||||
@ -127,14 +122,6 @@ func (s *stubNixOS) Open(name string) (fs.File, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stubNixOS) EvalSymlinks(path string) (string, error) {
|
|
||||||
return path, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stubNixOS) Exit(code int) {
|
|
||||||
panic("called exit on stub with code " + strconv.Itoa(code))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stubNixOS) Paths() linux.Paths {
|
func (s *stubNixOS) Paths() linux.Paths {
|
||||||
return linux.Paths{
|
return linux.Paths{
|
||||||
SharePath: "/tmp/fortify.1971",
|
SharePath: "/tmp/fortify.1971",
|
||||||
@ -142,11 +129,3 @@ func (s *stubNixOS) Paths() linux.Paths {
|
|||||||
RunDirPath: "/run/user/1971/fortify",
|
RunDirPath: "/run/user/1971/fortify",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stubNixOS) Uid(aid int) (int, error) {
|
|
||||||
return 1000000 + 0*10000 + aid, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stubNixOS) SdBooted() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
@ -113,34 +113,25 @@ func (seal *appSeal) setupShares(bus [2]*dbus.Config, os linux.System) error {
|
|||||||
sh = s
|
sh = s
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate /etc/passwd
|
// bind home directory
|
||||||
passwdPath := path.Join(seal.share, "passwd")
|
|
||||||
username := "chronos"
|
|
||||||
if seal.sys.user.username != "" {
|
|
||||||
username = seal.sys.user.username
|
|
||||||
}
|
|
||||||
homeDir := "/var/empty"
|
homeDir := "/var/empty"
|
||||||
if seal.sys.user.home != "" {
|
if seal.sys.user.home != "" {
|
||||||
homeDir = seal.sys.user.home
|
homeDir = seal.sys.user.home
|
||||||
}
|
}
|
||||||
|
username := "chronos"
|
||||||
// bind home directory
|
if seal.sys.user.username != "" {
|
||||||
|
username = seal.sys.user.username
|
||||||
|
}
|
||||||
seal.sys.bwrap.Bind(seal.sys.user.data, homeDir, false, true)
|
seal.sys.bwrap.Bind(seal.sys.user.data, homeDir, false, true)
|
||||||
seal.sys.bwrap.Chdir = homeDir
|
seal.sys.bwrap.Chdir = homeDir
|
||||||
|
|
||||||
seal.sys.bwrap.SetEnv["USER"] = username
|
|
||||||
seal.sys.bwrap.SetEnv["HOME"] = homeDir
|
seal.sys.bwrap.SetEnv["HOME"] = homeDir
|
||||||
|
seal.sys.bwrap.SetEnv["USER"] = username
|
||||||
|
|
||||||
passwd := username + ":x:" + seal.sys.mappedIDString + ":" + seal.sys.mappedIDString + ":Fortify:" + homeDir + ":" + sh + "\n"
|
// generate /etc/passwd and /etc/group
|
||||||
seal.sys.Write(passwdPath, passwd)
|
seal.sys.bwrap.CopyBind("/etc/passwd",
|
||||||
|
[]byte(username+":x:"+seal.sys.mappedIDString+":"+seal.sys.mappedIDString+":Fortify:"+homeDir+":"+sh+"\n"))
|
||||||
// write /etc/group
|
seal.sys.bwrap.CopyBind("/etc/group",
|
||||||
groupPath := path.Join(seal.share, "group")
|
[]byte("fortify:x:"+seal.sys.mappedIDString+":\n"))
|
||||||
seal.sys.Write(groupPath, "fortify:x:"+seal.sys.mappedIDString+":\n")
|
|
||||||
|
|
||||||
// bind /etc/passwd and /etc/group
|
|
||||||
seal.sys.bwrap.Bind(passwdPath, "/etc/passwd")
|
|
||||||
seal.sys.bwrap.Bind(groupPath, "/etc/group")
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Display servers
|
Display servers
|
||||||
@ -293,6 +284,10 @@ func (seal *appSeal) setupShares(bus [2]*dbus.Config, os linux.System) error {
|
|||||||
seal.sys.bwrap.Tmpfs(dest, 8*1024)
|
seal.sys.bwrap.Tmpfs(dest, 8*1024)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mount fortify in sandbox for init
|
||||||
|
seal.sys.bwrap.Bind(os.MustExecutable(), path.Join(fst.Tmp, "sbin/fortify"))
|
||||||
|
seal.sys.bwrap.Symlink("fortify", path.Join(fst.Tmp, "sbin/init"))
|
||||||
|
|
||||||
// append extra perms
|
// append extra perms
|
||||||
for _, p := range seal.extraPerms {
|
for _, p := range seal.extraPerms {
|
||||||
if p == nil {
|
if p == nil {
|
||||||
|
@ -19,8 +19,8 @@ type System interface {
|
|||||||
TempDir() string
|
TempDir() string
|
||||||
// LookPath provides [exec.LookPath].
|
// LookPath provides [exec.LookPath].
|
||||||
LookPath(file string) (string, error)
|
LookPath(file string) (string, error)
|
||||||
// Executable provides [os.Executable].
|
// MustExecutable provides [proc.MustExecutable].
|
||||||
Executable() (string, error)
|
MustExecutable() string
|
||||||
// LookupGroup provides [user.LookupGroup].
|
// LookupGroup provides [user.LookupGroup].
|
||||||
LookupGroup(name string) (*user.Group, error)
|
LookupGroup(name string) (*user.Group, error)
|
||||||
// ReadDir provides [os.ReadDir].
|
// ReadDir provides [os.ReadDir].
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"git.gensokyo.uk/security/fortify/helper/proc"
|
||||||
"git.gensokyo.uk/security/fortify/internal"
|
"git.gensokyo.uk/security/fortify/internal"
|
||||||
"git.gensokyo.uk/security/fortify/internal/fmsg"
|
"git.gensokyo.uk/security/fortify/internal/fmsg"
|
||||||
)
|
)
|
||||||
@ -32,7 +33,7 @@ func (s *Std) Geteuid() int { return os.Geteuid(
|
|||||||
func (s *Std) LookupEnv(key string) (string, bool) { return os.LookupEnv(key) }
|
func (s *Std) LookupEnv(key string) (string, bool) { return os.LookupEnv(key) }
|
||||||
func (s *Std) TempDir() string { return os.TempDir() }
|
func (s *Std) TempDir() string { return os.TempDir() }
|
||||||
func (s *Std) LookPath(file string) (string, error) { return exec.LookPath(file) }
|
func (s *Std) LookPath(file string) (string, error) { return exec.LookPath(file) }
|
||||||
func (s *Std) Executable() (string, error) { return os.Executable() }
|
func (s *Std) MustExecutable() string { return proc.MustExecutable() }
|
||||||
func (s *Std) LookupGroup(name string) (*user.Group, error) { return user.LookupGroup(name) }
|
func (s *Std) LookupGroup(name string) (*user.Group, error) { return user.LookupGroup(name) }
|
||||||
func (s *Std) ReadDir(name string) ([]os.DirEntry, error) { return os.ReadDir(name) }
|
func (s *Std) ReadDir(name string) ([]os.DirEntry, error) { return os.ReadDir(name) }
|
||||||
func (s *Std) Stat(name string) (fs.FileInfo, error) { return os.Stat(name) }
|
func (s *Std) Stat(name string) (fs.FileInfo, error) { return os.Stat(name) }
|
||||||
|
@ -121,21 +121,12 @@ func Main() {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind fortify inside sandbox
|
|
||||||
var (
|
|
||||||
innerSbin = path.Join(fst.Tmp, "sbin")
|
|
||||||
innerFortify = path.Join(innerSbin, "fortify")
|
|
||||||
innerInit = path.Join(innerSbin, "init")
|
|
||||||
)
|
|
||||||
conf.Bind(proc.MustExecutable(), innerFortify)
|
|
||||||
conf.Symlink("fortify", innerInit)
|
|
||||||
|
|
||||||
helper.BubblewrapName = payload.Exec[0] // resolved bwrap path by parent
|
helper.BubblewrapName = payload.Exec[0] // resolved bwrap path by parent
|
||||||
if fmsg.Verbose() {
|
if fmsg.Verbose() {
|
||||||
seccomp.CPrintln = fmsg.Println
|
seccomp.CPrintln = fmsg.Println
|
||||||
}
|
}
|
||||||
if b, err := helper.NewBwrap(
|
if b, err := helper.NewBwrap(
|
||||||
conf, innerInit,
|
conf, path.Join(fst.Tmp, "sbin/init"),
|
||||||
nil, func(int, int) []string { return make([]string, 0) },
|
nil, func(int, int) []string { return make([]string, 0) },
|
||||||
extraFiles,
|
extraFiles,
|
||||||
syncFd,
|
syncFd,
|
||||||
|
@ -42,26 +42,9 @@ func (sys *I) LinkFileType(et Enablement, oldname, newname string) *I {
|
|||||||
return sys
|
return sys
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write registers an Op that writes dst with the contents of src.
|
|
||||||
func (sys *I) Write(dst, src string) *I {
|
|
||||||
return sys.WriteType(Process, dst, src)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteType registers a file writing Op labelled with type et.
|
|
||||||
func (sys *I) WriteType(et Enablement, dst, src string) *I {
|
|
||||||
sys.lock.Lock()
|
|
||||||
sys.ops = append(sys.ops, &Tmpfile{et, tmpfileWrite, dst, src})
|
|
||||||
sys.lock.Unlock()
|
|
||||||
|
|
||||||
sys.UpdatePermType(et, dst, acl.Read)
|
|
||||||
|
|
||||||
return sys
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
tmpfileCopy uint8 = iota
|
tmpfileCopy uint8 = iota
|
||||||
tmpfileLink
|
tmpfileLink
|
||||||
tmpfileWrite
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Tmpfile struct {
|
type Tmpfile struct {
|
||||||
@ -84,10 +67,6 @@ func (t *Tmpfile) apply(_ *I) error {
|
|||||||
fmsg.VPrintln("linking tmpfile", t)
|
fmsg.VPrintln("linking tmpfile", t)
|
||||||
return fmsg.WrapErrorSuffix(os.Link(t.src, t.dst),
|
return fmsg.WrapErrorSuffix(os.Link(t.src, t.dst),
|
||||||
fmt.Sprintf("cannot link tmpfile %q:", t.dst))
|
fmt.Sprintf("cannot link tmpfile %q:", t.dst))
|
||||||
case tmpfileWrite:
|
|
||||||
fmsg.VPrintln("writing", t)
|
|
||||||
return fmsg.WrapErrorSuffix(os.WriteFile(t.dst, []byte(t.src), 0600),
|
|
||||||
fmt.Sprintf("cannot write tmpfile %q:", t.dst))
|
|
||||||
default:
|
default:
|
||||||
panic("invalid tmpfile method " + strconv.Itoa(int(t.method)))
|
panic("invalid tmpfile method " + strconv.Itoa(int(t.method)))
|
||||||
}
|
}
|
||||||
@ -109,12 +88,7 @@ func (t *Tmpfile) Is(o Op) bool {
|
|||||||
return ok && t0 != nil && *t == *t0
|
return ok && t0 != nil && *t == *t0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tmpfile) Path() string {
|
func (t *Tmpfile) Path() string { return t.src }
|
||||||
if t.method == tmpfileWrite {
|
|
||||||
return fmt.Sprintf("(%d bytes of data)", len(t.src))
|
|
||||||
}
|
|
||||||
return t.src
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Tmpfile) String() string {
|
func (t *Tmpfile) String() string {
|
||||||
switch t.method {
|
switch t.method {
|
||||||
@ -122,8 +96,6 @@ func (t *Tmpfile) String() string {
|
|||||||
return fmt.Sprintf("%q from %q", t.dst, t.src)
|
return fmt.Sprintf("%q from %q", t.dst, t.src)
|
||||||
case tmpfileLink:
|
case tmpfileLink:
|
||||||
return fmt.Sprintf("%q from %q", t.dst, t.src)
|
return fmt.Sprintf("%q from %q", t.dst, t.src)
|
||||||
case tmpfileWrite:
|
|
||||||
return fmt.Sprintf("%d bytes of data to %q", len(t.src), t.dst)
|
|
||||||
default:
|
default:
|
||||||
panic("invalid tmpfile method " + strconv.Itoa(int(t.method)))
|
panic("invalid tmpfile method " + strconv.Itoa(int(t.method)))
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package system
|
package system
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/fortify/acl"
|
"git.gensokyo.uk/security/fortify/acl"
|
||||||
@ -83,47 +82,6 @@ func TestLinkFileType(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWrite(t *testing.T) {
|
|
||||||
testCases := []struct {
|
|
||||||
dst, src string
|
|
||||||
}{
|
|
||||||
{"/etc/passwd", "chronos:x:65534:65534:Fortify:/home/chronos:/run/current-system/sw/bin/zsh\n"},
|
|
||||||
{"/etc/group", "fortify:x:65534:\n"},
|
|
||||||
}
|
|
||||||
for _, tc := range testCases {
|
|
||||||
t.Run("write "+strconv.Itoa(len(tc.src))+" bytes to "+tc.dst, func(t *testing.T) {
|
|
||||||
sys := New(150)
|
|
||||||
sys.Write(tc.dst, tc.src)
|
|
||||||
(&tcOp{Process, "(" + strconv.Itoa(len(tc.src)) + " bytes of data)"}).test(t, sys.ops, []Op{
|
|
||||||
&Tmpfile{Process, tmpfileWrite, tc.dst, tc.src},
|
|
||||||
&ACL{Process, tc.dst, []acl.Perm{acl.Read}},
|
|
||||||
}, "Write")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWriteType(t *testing.T) {
|
|
||||||
testCases := []struct {
|
|
||||||
et Enablement
|
|
||||||
dst, src string
|
|
||||||
}{
|
|
||||||
{Process, "/etc/passwd", "chronos:x:65534:65534:Fortify:/home/chronos:/run/current-system/sw/bin/zsh\n"},
|
|
||||||
{Process, "/etc/group", "fortify:x:65534:\n"},
|
|
||||||
{User, "/etc/passwd", "chronos:x:65534:65534:Fortify:/home/chronos:/run/current-system/sw/bin/zsh\n"},
|
|
||||||
{User, "/etc/group", "fortify:x:65534:\n"},
|
|
||||||
}
|
|
||||||
for _, tc := range testCases {
|
|
||||||
t.Run("write "+strconv.Itoa(len(tc.src))+" bytes to "+tc.dst+" with type "+TypeString(tc.et), func(t *testing.T) {
|
|
||||||
sys := New(150)
|
|
||||||
sys.WriteType(tc.et, tc.dst, tc.src)
|
|
||||||
(&tcOp{tc.et, "(" + strconv.Itoa(len(tc.src)) + " bytes of data)"}).test(t, sys.ops, []Op{
|
|
||||||
&Tmpfile{tc.et, tmpfileWrite, tc.dst, tc.src},
|
|
||||||
&ACL{tc.et, tc.dst, []acl.Perm{acl.Read}},
|
|
||||||
}, "WriteType")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTmpfile_String(t *testing.T) {
|
func TestTmpfile_String(t *testing.T) {
|
||||||
t.Run("invalid method panic", func(t *testing.T) {
|
t.Run("invalid method panic", func(t *testing.T) {
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -147,10 +105,6 @@ func TestTmpfile_String(t *testing.T) {
|
|||||||
`"/run/user/1971/fortify/4b6bdc9182fb2f1d3a965c5fa8b9b66e/wayland" from "/run/user/1971/wayland-0"`},
|
`"/run/user/1971/fortify/4b6bdc9182fb2f1d3a965c5fa8b9b66e/wayland" from "/run/user/1971/wayland-0"`},
|
||||||
{tmpfileLink, "/run/user/1971/fortify/4b6bdc9182fb2f1d3a965c5fa8b9b66e/pulse", "/run/user/1971/pulse/native",
|
{tmpfileLink, "/run/user/1971/fortify/4b6bdc9182fb2f1d3a965c5fa8b9b66e/pulse", "/run/user/1971/pulse/native",
|
||||||
`"/run/user/1971/fortify/4b6bdc9182fb2f1d3a965c5fa8b9b66e/pulse" from "/run/user/1971/pulse/native"`},
|
`"/run/user/1971/fortify/4b6bdc9182fb2f1d3a965c5fa8b9b66e/pulse" from "/run/user/1971/pulse/native"`},
|
||||||
{tmpfileWrite, "/tmp/fortify.1971/4b6bdc9182fb2f1d3a965c5fa8b9b66e/passwd", "chronos:x:65534:65534:Fortify:/home/chronos:/run/current-system/sw/bin/zsh\n",
|
|
||||||
`75 bytes of data to "/tmp/fortify.1971/4b6bdc9182fb2f1d3a965c5fa8b9b66e/passwd"`},
|
|
||||||
{tmpfileWrite, "/tmp/fortify.1971/4b6bdc9182fb2f1d3a965c5fa8b9b66e/group", "fortify:x:65534:\n",
|
|
||||||
`17 bytes of data to "/tmp/fortify.1971/4b6bdc9182fb2f1d3a965c5fa8b9b66e/group"`},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
|
Loading…
Reference in New Issue
Block a user