system: enforce absolute paths
All checks were successful
Test / Create distribution (push) Successful in 1m17s
Test / Sandbox (push) Successful in 2m56s
Test / Hakurei (push) Successful in 3m54s
Test / Hpkg (push) Successful in 4m51s
Test / Sandbox (race detector) (push) Successful in 5m3s
Test / Hakurei (race detector) (push) Successful in 6m0s
Test / Flake checks (push) Successful in 1m38s
All checks were successful
Test / Create distribution (push) Successful in 1m17s
Test / Sandbox (push) Successful in 2m56s
Test / Hakurei (push) Successful in 3m54s
Test / Hpkg (push) Successful in 4m51s
Test / Sandbox (race detector) (push) Successful in 5m3s
Test / Hakurei (race detector) (push) Successful in 6m0s
Test / Flake checks (push) Successful in 1m38s
This is less error-prone, and is quite easy to integrate considering internal/app has already migrated to container.Absolute. Closes #11. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
e58181a930
commit
d16da6da8c
@ -1,7 +1,6 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
@ -37,12 +36,12 @@ func TestApp(t *testing.T) {
|
|||||||
0xbd, 0x01, 0x78, 0x0e,
|
0xbd, 0x01, 0x78, 0x0e,
|
||||||
0xb9, 0xa6, 0x07, 0xac,
|
0xb9, 0xa6, 0x07, 0xac,
|
||||||
},
|
},
|
||||||
system.New(context.TODO(), container.NewMsg(nil), 1000000).
|
system.New(t.Context(), container.NewMsg(nil), 1000000).
|
||||||
Ensure("/tmp/hakurei.0", 0711).
|
Ensure(m("/tmp/hakurei.0"), 0711).
|
||||||
Ensure("/tmp/hakurei.0/runtime", 0700).UpdatePermType(system.User, "/tmp/hakurei.0/runtime", acl.Execute).
|
Ensure(m("/tmp/hakurei.0/runtime"), 0700).UpdatePermType(system.User, m("/tmp/hakurei.0/runtime"), acl.Execute).
|
||||||
Ensure("/tmp/hakurei.0/runtime/0", 0700).UpdatePermType(system.User, "/tmp/hakurei.0/runtime/0", acl.Read, acl.Write, acl.Execute).
|
Ensure(m("/tmp/hakurei.0/runtime/0"), 0700).UpdatePermType(system.User, m("/tmp/hakurei.0/runtime/0"), acl.Read, acl.Write, acl.Execute).
|
||||||
Ensure("/tmp/hakurei.0/tmpdir", 0700).UpdatePermType(system.User, "/tmp/hakurei.0/tmpdir", acl.Execute).
|
Ensure(m("/tmp/hakurei.0/tmpdir"), 0700).UpdatePermType(system.User, m("/tmp/hakurei.0/tmpdir"), acl.Execute).
|
||||||
Ensure("/tmp/hakurei.0/tmpdir/0", 01700).UpdatePermType(system.User, "/tmp/hakurei.0/tmpdir/0", acl.Read, acl.Write, acl.Execute),
|
Ensure(m("/tmp/hakurei.0/tmpdir/0"), 01700).UpdatePermType(system.User, m("/tmp/hakurei.0/tmpdir/0"), acl.Read, acl.Write, acl.Execute),
|
||||||
&container.Params{
|
&container.Params{
|
||||||
Dir: m("/home/chronos"),
|
Dir: m("/home/chronos"),
|
||||||
Path: m("/run/current-system/sw/bin/zsh"),
|
Path: m("/run/current-system/sw/bin/zsh"),
|
||||||
@ -129,20 +128,20 @@ func TestApp(t *testing.T) {
|
|||||||
0x82, 0xd4, 0x13, 0x36,
|
0x82, 0xd4, 0x13, 0x36,
|
||||||
0x9b, 0x64, 0xce, 0x7c,
|
0x9b, 0x64, 0xce, 0x7c,
|
||||||
},
|
},
|
||||||
system.New(context.TODO(), container.NewMsg(nil), 1000009).
|
system.New(t.Context(), container.NewMsg(nil), 1000009).
|
||||||
Ensure("/tmp/hakurei.0", 0711).
|
Ensure(m("/tmp/hakurei.0"), 0711).
|
||||||
Ensure("/tmp/hakurei.0/runtime", 0700).UpdatePermType(system.User, "/tmp/hakurei.0/runtime", acl.Execute).
|
Ensure(m("/tmp/hakurei.0/runtime"), 0700).UpdatePermType(system.User, m("/tmp/hakurei.0/runtime"), acl.Execute).
|
||||||
Ensure("/tmp/hakurei.0/runtime/9", 0700).UpdatePermType(system.User, "/tmp/hakurei.0/runtime/9", acl.Read, acl.Write, acl.Execute).
|
Ensure(m("/tmp/hakurei.0/runtime/9"), 0700).UpdatePermType(system.User, m("/tmp/hakurei.0/runtime/9"), acl.Read, acl.Write, acl.Execute).
|
||||||
Ensure("/tmp/hakurei.0/tmpdir", 0700).UpdatePermType(system.User, "/tmp/hakurei.0/tmpdir", acl.Execute).
|
Ensure(m("/tmp/hakurei.0/tmpdir"), 0700).UpdatePermType(system.User, m("/tmp/hakurei.0/tmpdir"), acl.Execute).
|
||||||
Ensure("/tmp/hakurei.0/tmpdir/9", 01700).UpdatePermType(system.User, "/tmp/hakurei.0/tmpdir/9", acl.Read, acl.Write, acl.Execute).
|
Ensure(m("/tmp/hakurei.0/tmpdir/9"), 01700).UpdatePermType(system.User, m("/tmp/hakurei.0/tmpdir/9"), acl.Read, acl.Write, acl.Execute).
|
||||||
Ephemeral(system.Process, "/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c", 0711).
|
Ephemeral(system.Process, m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c"), 0711).
|
||||||
Wayland(new(*os.File), "/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/1971/wayland-0", "org.chromium.Chromium", "ebf083d1b175911782d413369b64ce7c").
|
Wayland(new(*os.File), m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/wayland"), m("/run/user/1971/wayland-0"), "org.chromium.Chromium", "ebf083d1b175911782d413369b64ce7c").
|
||||||
Ensure("/run/user/1971/hakurei", 0700).UpdatePermType(system.User, "/run/user/1971/hakurei", acl.Execute).
|
Ensure(m("/run/user/1971/hakurei"), 0700).UpdatePermType(system.User, m("/run/user/1971/hakurei"), 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(m("/run/user/1971"), 0700).UpdatePermType(system.User, m("/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/hakurei/ebf083d1b175911782d413369b64ce7c", 0700).UpdatePermType(system.Process, "/run/user/1971/hakurei/ebf083d1b175911782d413369b64ce7c", acl.Execute).
|
Ephemeral(system.Process, m("/run/user/1971/hakurei/ebf083d1b175911782d413369b64ce7c"), 0700).UpdatePermType(system.Process, m("/run/user/1971/hakurei/ebf083d1b175911782d413369b64ce7c"), acl.Execute).
|
||||||
Link("/run/user/1971/pulse/native", "/run/user/1971/hakurei/ebf083d1b175911782d413369b64ce7c/pulse").
|
Link(m("/run/user/1971/pulse/native"), m("/run/user/1971/hakurei/ebf083d1b175911782d413369b64ce7c/pulse")).
|
||||||
CopyFile(new([]byte), "/home/ophestra/xdg/config/pulse/cookie", 256, 256).
|
CopyFile(new([]byte), m("/home/ophestra/xdg/config/pulse/cookie"), 256, 256).
|
||||||
MustProxyDBus("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/bus", &dbus.Config{
|
MustProxyDBus(m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/bus"), &dbus.Config{
|
||||||
Talk: []string{
|
Talk: []string{
|
||||||
"org.freedesktop.Notifications",
|
"org.freedesktop.Notifications",
|
||||||
"org.freedesktop.FileManager1",
|
"org.freedesktop.FileManager1",
|
||||||
@ -164,7 +163,7 @@ func TestApp(t *testing.T) {
|
|||||||
"org.freedesktop.portal.*": "@/org/freedesktop/portal/*",
|
"org.freedesktop.portal.*": "@/org/freedesktop/portal/*",
|
||||||
},
|
},
|
||||||
Filter: true,
|
Filter: true,
|
||||||
}, "/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/system_bus_socket", &dbus.Config{
|
}, m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/system_bus_socket"), &dbus.Config{
|
||||||
Talk: []string{
|
Talk: []string{
|
||||||
"org.bluez",
|
"org.bluez",
|
||||||
"org.freedesktop.Avahi",
|
"org.freedesktop.Avahi",
|
||||||
@ -172,8 +171,8 @@ func TestApp(t *testing.T) {
|
|||||||
},
|
},
|
||||||
Filter: true,
|
Filter: true,
|
||||||
}).
|
}).
|
||||||
UpdatePerm("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/bus", acl.Read, acl.Write).
|
UpdatePerm(m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/bus"), acl.Read, acl.Write).
|
||||||
UpdatePerm("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/system_bus_socket", acl.Read, acl.Write),
|
UpdatePerm(m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/system_bus_socket"), acl.Read, acl.Write),
|
||||||
&container.Params{
|
&container.Params{
|
||||||
Dir: m("/home/chronos"),
|
Dir: m("/home/chronos"),
|
||||||
Path: m("/run/current-system/sw/bin/zsh"),
|
Path: m("/run/current-system/sw/bin/zsh"),
|
||||||
@ -280,20 +279,20 @@ func TestApp(t *testing.T) {
|
|||||||
0x4c, 0xf0, 0x73, 0xbd,
|
0x4c, 0xf0, 0x73, 0xbd,
|
||||||
0xb4, 0x6e, 0xb5, 0xc1,
|
0xb4, 0x6e, 0xb5, 0xc1,
|
||||||
},
|
},
|
||||||
system.New(context.TODO(), container.NewMsg(nil), 1000001).
|
system.New(t.Context(), container.NewMsg(nil), 1000001).
|
||||||
Ensure("/tmp/hakurei.0", 0711).
|
Ensure(m("/tmp/hakurei.0"), 0711).
|
||||||
Ensure("/tmp/hakurei.0/runtime", 0700).UpdatePermType(system.User, "/tmp/hakurei.0/runtime", acl.Execute).
|
Ensure(m("/tmp/hakurei.0/runtime"), 0700).UpdatePermType(system.User, m("/tmp/hakurei.0/runtime"), acl.Execute).
|
||||||
Ensure("/tmp/hakurei.0/runtime/1", 0700).UpdatePermType(system.User, "/tmp/hakurei.0/runtime/1", acl.Read, acl.Write, acl.Execute).
|
Ensure(m("/tmp/hakurei.0/runtime/1"), 0700).UpdatePermType(system.User, m("/tmp/hakurei.0/runtime/1"), acl.Read, acl.Write, acl.Execute).
|
||||||
Ensure("/tmp/hakurei.0/tmpdir", 0700).UpdatePermType(system.User, "/tmp/hakurei.0/tmpdir", acl.Execute).
|
Ensure(m("/tmp/hakurei.0/tmpdir"), 0700).UpdatePermType(system.User, m("/tmp/hakurei.0/tmpdir"), acl.Execute).
|
||||||
Ensure("/tmp/hakurei.0/tmpdir/1", 01700).UpdatePermType(system.User, "/tmp/hakurei.0/tmpdir/1", acl.Read, acl.Write, acl.Execute).
|
Ensure(m("/tmp/hakurei.0/tmpdir/1"), 01700).UpdatePermType(system.User, m("/tmp/hakurei.0/tmpdir/1"), acl.Read, acl.Write, acl.Execute).
|
||||||
Ensure("/run/user/1971/hakurei", 0700).UpdatePermType(system.User, "/run/user/1971/hakurei", acl.Execute).
|
Ensure(m("/run/user/1971/hakurei"), 0700).UpdatePermType(system.User, m("/run/user/1971/hakurei"), 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(m("/run/user/1971"), 0700).UpdatePermType(system.User, m("/run/user/1971"), acl.Execute). // this is ordered as is because the previous Ensure only calls mkdir if XDG_RUNTIME_DIR is unset
|
||||||
UpdatePermType(hst.EWayland, "/run/user/1971/wayland-0", acl.Read, acl.Write, acl.Execute).
|
UpdatePermType(hst.EWayland, m("/run/user/1971/wayland-0"), acl.Read, acl.Write, acl.Execute).
|
||||||
Ephemeral(system.Process, "/run/user/1971/hakurei/8e2c76b066dabe574cf073bdb46eb5c1", 0700).UpdatePermType(system.Process, "/run/user/1971/hakurei/8e2c76b066dabe574cf073bdb46eb5c1", acl.Execute).
|
Ephemeral(system.Process, m("/run/user/1971/hakurei/8e2c76b066dabe574cf073bdb46eb5c1"), 0700).UpdatePermType(system.Process, m("/run/user/1971/hakurei/8e2c76b066dabe574cf073bdb46eb5c1"), acl.Execute).
|
||||||
Link("/run/user/1971/pulse/native", "/run/user/1971/hakurei/8e2c76b066dabe574cf073bdb46eb5c1/pulse").
|
Link(m("/run/user/1971/pulse/native"), m("/run/user/1971/hakurei/8e2c76b066dabe574cf073bdb46eb5c1/pulse")).
|
||||||
CopyFile(nil, "/home/ophestra/xdg/config/pulse/cookie", 256, 256).
|
CopyFile(nil, m("/home/ophestra/xdg/config/pulse/cookie"), 256, 256).
|
||||||
Ephemeral(system.Process, "/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1", 0711).
|
Ephemeral(system.Process, m("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1"), 0711).
|
||||||
MustProxyDBus("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1/bus", &dbus.Config{
|
MustProxyDBus(m("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1/bus"), &dbus.Config{
|
||||||
Talk: []string{
|
Talk: []string{
|
||||||
"org.freedesktop.FileManager1", "org.freedesktop.Notifications",
|
"org.freedesktop.FileManager1", "org.freedesktop.Notifications",
|
||||||
"org.freedesktop.ScreenSaver", "org.freedesktop.secrets",
|
"org.freedesktop.ScreenSaver", "org.freedesktop.secrets",
|
||||||
@ -306,7 +305,7 @@ func TestApp(t *testing.T) {
|
|||||||
},
|
},
|
||||||
Call: map[string]string{}, Broadcast: map[string]string{},
|
Call: map[string]string{}, Broadcast: map[string]string{},
|
||||||
Filter: true,
|
Filter: true,
|
||||||
}, "/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1/system_bus_socket", &dbus.Config{
|
}, m("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1/system_bus_socket"), &dbus.Config{
|
||||||
Talk: []string{
|
Talk: []string{
|
||||||
"org.bluez",
|
"org.bluez",
|
||||||
"org.freedesktop.Avahi",
|
"org.freedesktop.Avahi",
|
||||||
@ -314,8 +313,8 @@ func TestApp(t *testing.T) {
|
|||||||
},
|
},
|
||||||
Filter: true,
|
Filter: true,
|
||||||
}).
|
}).
|
||||||
UpdatePerm("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1/bus", acl.Read, acl.Write).
|
UpdatePerm(m("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1/bus"), acl.Read, acl.Write).
|
||||||
UpdatePerm("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1/system_bus_socket", acl.Read, acl.Write),
|
UpdatePerm(m("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1/system_bus_socket"), acl.Read, acl.Write),
|
||||||
&container.Params{
|
&container.Params{
|
||||||
Uid: 1971,
|
Uid: 1971,
|
||||||
Gid: 100,
|
Gid: 100,
|
||||||
|
@ -76,10 +76,10 @@ func (share *shareHost) ensureRuntimeDir() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
share.useRuntimeDir = true
|
share.useRuntimeDir = true
|
||||||
share.seal.sys.Ensure(share.sc.RunDirPath.String(), 0700)
|
share.seal.sys.Ensure(share.sc.RunDirPath, 0700)
|
||||||
share.seal.sys.UpdatePermType(system.User, share.sc.RunDirPath.String(), acl.Execute)
|
share.seal.sys.UpdatePermType(system.User, share.sc.RunDirPath, acl.Execute)
|
||||||
share.seal.sys.Ensure(share.sc.RuntimePath.String(), 0700) // ensure this dir in case XDG_RUNTIME_DIR is unset
|
share.seal.sys.Ensure(share.sc.RuntimePath, 0700) // ensure this dir in case XDG_RUNTIME_DIR is unset
|
||||||
share.seal.sys.UpdatePermType(system.User, share.sc.RuntimePath.String(), acl.Execute)
|
share.seal.sys.UpdatePermType(system.User, share.sc.RuntimePath, acl.Execute)
|
||||||
}
|
}
|
||||||
|
|
||||||
// instance returns a process-specific share path within tmpdir
|
// instance returns a process-specific share path within tmpdir
|
||||||
@ -88,7 +88,7 @@ func (share *shareHost) instance() *container.Absolute {
|
|||||||
return share.sharePath
|
return share.sharePath
|
||||||
}
|
}
|
||||||
share.sharePath = share.sc.SharePath.Append(share.seal.id.String())
|
share.sharePath = share.sc.SharePath.Append(share.seal.id.String())
|
||||||
share.seal.sys.Ephemeral(system.Process, share.sharePath.String(), 0711)
|
share.seal.sys.Ephemeral(system.Process, share.sharePath, 0711)
|
||||||
return share.sharePath
|
return share.sharePath
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,8 +99,8 @@ func (share *shareHost) runtime() *container.Absolute {
|
|||||||
}
|
}
|
||||||
share.ensureRuntimeDir()
|
share.ensureRuntimeDir()
|
||||||
share.runtimeSharePath = share.sc.RunDirPath.Append(share.seal.id.String())
|
share.runtimeSharePath = share.sc.RunDirPath.Append(share.seal.id.String())
|
||||||
share.seal.sys.Ephemeral(system.Process, share.runtimeSharePath.String(), 0700)
|
share.seal.sys.Ephemeral(system.Process, share.runtimeSharePath, 0700)
|
||||||
share.seal.sys.UpdatePerm(share.runtimeSharePath.String(), acl.Execute)
|
share.seal.sys.UpdatePerm(share.runtimeSharePath, acl.Execute)
|
||||||
return share.runtimeSharePath
|
return share.runtimeSharePath
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,26 +308,26 @@ func (k *outcome) finalise(ctx context.Context, msg container.Msg, config *hst.C
|
|||||||
|
|
||||||
k.runDirPath = share.sc.RunDirPath
|
k.runDirPath = share.sc.RunDirPath
|
||||||
k.sys = system.New(k.ctx, msg, k.user.uid.unwrap())
|
k.sys = system.New(k.ctx, msg, k.user.uid.unwrap())
|
||||||
k.sys.Ensure(share.sc.SharePath.String(), 0711)
|
k.sys.Ensure(share.sc.SharePath, 0711)
|
||||||
|
|
||||||
{
|
{
|
||||||
runtimeDir := share.sc.SharePath.Append("runtime")
|
runtimeDir := share.sc.SharePath.Append("runtime")
|
||||||
k.sys.Ensure(runtimeDir.String(), 0700)
|
k.sys.Ensure(runtimeDir, 0700)
|
||||||
k.sys.UpdatePermType(system.User, runtimeDir.String(), acl.Execute)
|
k.sys.UpdatePermType(system.User, runtimeDir, acl.Execute)
|
||||||
runtimeDirInst := runtimeDir.Append(k.user.identity.String())
|
runtimeDirInst := runtimeDir.Append(k.user.identity.String())
|
||||||
k.sys.Ensure(runtimeDirInst.String(), 0700)
|
k.sys.Ensure(runtimeDirInst, 0700)
|
||||||
k.sys.UpdatePermType(system.User, runtimeDirInst.String(), acl.Read, acl.Write, acl.Execute)
|
k.sys.UpdatePermType(system.User, runtimeDirInst, acl.Read, acl.Write, acl.Execute)
|
||||||
k.container.Tmpfs(container.AbsFHSRunUser, 1<<12, 0755)
|
k.container.Tmpfs(container.AbsFHSRunUser, 1<<12, 0755)
|
||||||
k.container.Bind(runtimeDirInst, innerRuntimeDir, container.BindWritable)
|
k.container.Bind(runtimeDirInst, innerRuntimeDir, container.BindWritable)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
tmpdir := share.sc.SharePath.Append("tmpdir")
|
tmpdir := share.sc.SharePath.Append("tmpdir")
|
||||||
k.sys.Ensure(tmpdir.String(), 0700)
|
k.sys.Ensure(tmpdir, 0700)
|
||||||
k.sys.UpdatePermType(system.User, tmpdir.String(), acl.Execute)
|
k.sys.UpdatePermType(system.User, tmpdir, acl.Execute)
|
||||||
tmpdirInst := tmpdir.Append(k.user.identity.String())
|
tmpdirInst := tmpdir.Append(k.user.identity.String())
|
||||||
k.sys.Ensure(tmpdirInst.String(), 01700)
|
k.sys.Ensure(tmpdirInst, 01700)
|
||||||
k.sys.UpdatePermType(system.User, tmpdirInst.String(), acl.Read, acl.Write, acl.Execute)
|
k.sys.UpdatePermType(system.User, tmpdirInst, acl.Read, acl.Write, acl.Execute)
|
||||||
// mount inner /tmp from share so it shares persistence and storage behaviour of host /tmp
|
// mount inner /tmp from share so it shares persistence and storage behaviour of host /tmp
|
||||||
k.container.Bind(tmpdirInst, container.AbsFHSTmp, container.BindWritable)
|
k.container.Bind(tmpdirInst, container.AbsFHSTmp, container.BindWritable)
|
||||||
}
|
}
|
||||||
@ -376,13 +376,13 @@ func (k *outcome) finalise(ctx context.Context, msg container.Msg, config *hst.C
|
|||||||
}
|
}
|
||||||
// downstream socket paths
|
// downstream socket paths
|
||||||
outerPath := share.instance().Append("wayland")
|
outerPath := share.instance().Append("wayland")
|
||||||
k.sys.Wayland(&k.sync, outerPath.String(), socketPath.String(), appID, k.id.String())
|
k.sys.Wayland(&k.sync, outerPath, socketPath, appID, k.id.String())
|
||||||
k.container.Bind(outerPath, innerPath, 0)
|
k.container.Bind(outerPath, innerPath, 0)
|
||||||
} else { // bind mount wayland socket (insecure)
|
} else { // bind mount wayland socket (insecure)
|
||||||
msg.Verbose("direct wayland access, PROCEED WITH CAUTION")
|
msg.Verbose("direct wayland access, PROCEED WITH CAUTION")
|
||||||
share.ensureRuntimeDir()
|
share.ensureRuntimeDir()
|
||||||
k.container.Bind(socketPath, innerPath, 0)
|
k.container.Bind(socketPath, innerPath, 0)
|
||||||
k.sys.UpdatePermType(hst.EWayland, socketPath.String(), acl.Read, acl.Write, acl.Execute)
|
k.sys.UpdatePermType(hst.EWayland, socketPath, acl.Read, acl.Write, acl.Execute)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,7 +410,7 @@ func (k *outcome) finalise(ctx context.Context, msg container.Msg, config *hst.C
|
|||||||
return &hst.AppError{Step: fmt.Sprintf("access X11 socket %q", socketPath), Err: err}
|
return &hst.AppError{Step: fmt.Sprintf("access X11 socket %q", socketPath), Err: err}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
k.sys.UpdatePermType(hst.EX11, socketPath.String(), acl.Read, acl.Write, acl.Execute)
|
k.sys.UpdatePermType(hst.EX11, socketPath, acl.Read, acl.Write, acl.Execute)
|
||||||
if !config.Container.HostAbstract {
|
if !config.Container.HostAbstract {
|
||||||
d = "unix:" + socketPath.String()
|
d = "unix:" + socketPath.String()
|
||||||
}
|
}
|
||||||
@ -450,7 +450,7 @@ func (k *outcome) finalise(ctx context.Context, msg container.Msg, config *hst.C
|
|||||||
// hard link pulse socket into target-executable share
|
// hard link pulse socket into target-executable share
|
||||||
innerPulseRuntimeDir := share.runtime().Append("pulse")
|
innerPulseRuntimeDir := share.runtime().Append("pulse")
|
||||||
innerPulseSocket := innerRuntimeDir.Append("pulse", "native")
|
innerPulseSocket := innerRuntimeDir.Append("pulse", "native")
|
||||||
k.sys.Link(pulseSocket.String(), innerPulseRuntimeDir.String())
|
k.sys.Link(pulseSocket, innerPulseRuntimeDir)
|
||||||
k.container.Bind(innerPulseRuntimeDir, innerPulseSocket, 0)
|
k.container.Bind(innerPulseRuntimeDir, innerPulseSocket, 0)
|
||||||
k.env[pulseServer] = "unix:" + innerPulseSocket.String()
|
k.env[pulseServer] = "unix:" + innerPulseSocket.String()
|
||||||
|
|
||||||
@ -518,7 +518,7 @@ func (k *outcome) finalise(ctx context.Context, msg container.Msg, config *hst.C
|
|||||||
k.env[pulseCookie] = innerDst.String()
|
k.env[pulseCookie] = innerDst.String()
|
||||||
var payload *[]byte
|
var payload *[]byte
|
||||||
k.container.PlaceP(innerDst, &payload)
|
k.container.PlaceP(innerDst, &payload)
|
||||||
k.sys.CopyFile(payload, paCookiePath.String(), 256, 256)
|
k.sys.CopyFile(payload, paCookiePath, 256, 256)
|
||||||
} else {
|
} else {
|
||||||
msg.Verbose("cannot locate PulseAudio cookie (tried " +
|
msg.Verbose("cannot locate PulseAudio cookie (tried " +
|
||||||
"$PULSE_COOKIE, " +
|
"$PULSE_COOKIE, " +
|
||||||
@ -539,7 +539,7 @@ func (k *outcome) finalise(ctx context.Context, msg container.Msg, config *hst.C
|
|||||||
// configure dbus proxy
|
// configure dbus proxy
|
||||||
if f, err := k.sys.ProxyDBus(
|
if f, err := k.sys.ProxyDBus(
|
||||||
config.SessionBus, config.SystemBus,
|
config.SessionBus, config.SystemBus,
|
||||||
sessionPath.String(), systemPath.String(),
|
sessionPath, systemPath,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
@ -550,12 +550,12 @@ func (k *outcome) finalise(ctx context.Context, msg container.Msg, config *hst.C
|
|||||||
sessionInner := innerRuntimeDir.Append("bus")
|
sessionInner := innerRuntimeDir.Append("bus")
|
||||||
k.env[dbusSessionBusAddress] = "unix:path=" + sessionInner.String()
|
k.env[dbusSessionBusAddress] = "unix:path=" + sessionInner.String()
|
||||||
k.container.Bind(sessionPath, sessionInner, 0)
|
k.container.Bind(sessionPath, sessionInner, 0)
|
||||||
k.sys.UpdatePerm(sessionPath.String(), acl.Read, acl.Write)
|
k.sys.UpdatePerm(sessionPath, acl.Read, acl.Write)
|
||||||
if config.SystemBus != nil {
|
if config.SystemBus != nil {
|
||||||
systemInner := container.AbsFHSRun.Append("dbus/system_bus_socket")
|
systemInner := container.AbsFHSRun.Append("dbus/system_bus_socket")
|
||||||
k.env[dbusSystemBusAddress] = "unix:path=" + systemInner.String()
|
k.env[dbusSystemBusAddress] = "unix:path=" + systemInner.String()
|
||||||
k.container.Bind(systemPath, systemInner, 0)
|
k.container.Bind(systemPath, systemInner, 0)
|
||||||
k.sys.UpdatePerm(systemPath.String(), acl.Read, acl.Write)
|
k.sys.UpdatePerm(systemPath, acl.Read, acl.Write)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -569,7 +569,7 @@ func (k *outcome) finalise(ctx context.Context, msg container.Msg, config *hst.C
|
|||||||
}
|
}
|
||||||
|
|
||||||
if p.Ensure {
|
if p.Ensure {
|
||||||
k.sys.Ensure(p.Path.String(), 0700)
|
k.sys.Ensure(p.Path, 0700)
|
||||||
}
|
}
|
||||||
|
|
||||||
perms := make(acl.Perms, 0, 3)
|
perms := make(acl.Perms, 0, 3)
|
||||||
@ -582,7 +582,7 @@ func (k *outcome) finalise(ctx context.Context, msg container.Msg, config *hst.C
|
|||||||
if p.Execute {
|
if p.Execute {
|
||||||
perms = append(perms, acl.Execute)
|
perms = append(perms, acl.Execute)
|
||||||
}
|
}
|
||||||
k.sys.UpdatePermType(system.User, p.Path.String(), perms...)
|
k.sys.UpdatePermType(system.User, p.Path, perms...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// flatten and sort env for deterministic behaviour
|
// flatten and sort env for deterministic behaviour
|
||||||
|
@ -6,19 +6,20 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"slices"
|
"slices"
|
||||||
|
|
||||||
|
"hakurei.app/container"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/system/acl"
|
"hakurei.app/system/acl"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UpdatePerm calls UpdatePermType with the [Process] criteria.
|
// UpdatePerm calls UpdatePermType with the [Process] criteria.
|
||||||
func (sys *I) UpdatePerm(path string, perms ...acl.Perm) *I {
|
func (sys *I) UpdatePerm(path *container.Absolute, perms ...acl.Perm) *I {
|
||||||
sys.UpdatePermType(Process, path, perms...)
|
sys.UpdatePermType(Process, path, perms...)
|
||||||
return sys
|
return sys
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdatePermType maintains [acl.Perms] on a file until its [Enablement] is no longer satisfied.
|
// UpdatePermType maintains [acl.Perms] on a file until its [Enablement] is no longer satisfied.
|
||||||
func (sys *I) UpdatePermType(et hst.Enablement, path string, perms ...acl.Perm) *I {
|
func (sys *I) UpdatePermType(et hst.Enablement, path *container.Absolute, perms ...acl.Perm) *I {
|
||||||
sys.ops = append(sys.ops, &aclUpdateOp{et, path, perms})
|
sys.ops = append(sys.ops, &aclUpdateOp{et, path.String(), perms})
|
||||||
return sys
|
return sys
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,42 +60,42 @@ func TestACLUpdateOp(t *testing.T) {
|
|||||||
0xdeadbeef,
|
0xdeadbeef,
|
||||||
func(_ *testing.T, sys *I) {
|
func(_ *testing.T, sys *I) {
|
||||||
sys.
|
sys.
|
||||||
UpdatePerm("/run/user/1971/hakurei", acl.Execute).
|
UpdatePerm(m("/run/user/1971/hakurei"), acl.Execute).
|
||||||
UpdatePerm("/tmp/hakurei.0/tmpdir/150", acl.Read, acl.Write, acl.Execute)
|
UpdatePerm(m("/tmp/hakurei.0/tmpdir/150"), acl.Read, acl.Write, acl.Execute)
|
||||||
}, []Op{
|
}, []Op{
|
||||||
&aclUpdateOp{Process, "/run/user/1971/hakurei", []acl.Perm{acl.Execute}},
|
&aclUpdateOp{Process, "/run/user/1971/hakurei", []acl.Perm{acl.Execute}},
|
||||||
&aclUpdateOp{Process, "/tmp/hakurei.0/tmpdir/150", []acl.Perm{acl.Read, acl.Write, acl.Execute}},
|
&aclUpdateOp{Process, "/tmp/hakurei.0/tmpdir/150", []acl.Perm{acl.Read, acl.Write, acl.Execute}},
|
||||||
}, stub.Expect{}},
|
}, stub.Expect{}},
|
||||||
|
|
||||||
{"tmpdirp", 0xdeadbeef, func(_ *testing.T, sys *I) {
|
{"tmpdirp", 0xdeadbeef, func(_ *testing.T, sys *I) {
|
||||||
sys.UpdatePermType(User, "/tmp/hakurei.0/tmpdir", acl.Execute)
|
sys.UpdatePermType(User, m("/tmp/hakurei.0/tmpdir"), acl.Execute)
|
||||||
}, []Op{
|
}, []Op{
|
||||||
&aclUpdateOp{User, "/tmp/hakurei.0/tmpdir", []acl.Perm{acl.Execute}},
|
&aclUpdateOp{User, "/tmp/hakurei.0/tmpdir", []acl.Perm{acl.Execute}},
|
||||||
}, stub.Expect{}},
|
}, stub.Expect{}},
|
||||||
|
|
||||||
{"tmpdir", 0xdeadbeef, func(_ *testing.T, sys *I) {
|
{"tmpdir", 0xdeadbeef, func(_ *testing.T, sys *I) {
|
||||||
sys.UpdatePermType(User, "/tmp/hakurei.0/tmpdir/150", acl.Read, acl.Write, acl.Execute)
|
sys.UpdatePermType(User, m("/tmp/hakurei.0/tmpdir/150"), acl.Read, acl.Write, acl.Execute)
|
||||||
}, []Op{
|
}, []Op{
|
||||||
&aclUpdateOp{User, "/tmp/hakurei.0/tmpdir/150", []acl.Perm{acl.Read, acl.Write, acl.Execute}},
|
&aclUpdateOp{User, "/tmp/hakurei.0/tmpdir/150", []acl.Perm{acl.Read, acl.Write, acl.Execute}},
|
||||||
}, stub.Expect{}},
|
}, stub.Expect{}},
|
||||||
|
|
||||||
{"share", 0xdeadbeef, func(_ *testing.T, sys *I) {
|
{"share", 0xdeadbeef, func(_ *testing.T, sys *I) {
|
||||||
sys.UpdatePermType(Process, "/run/user/1971/hakurei/fcb8a12f7c482d183ade8288c3de78b5", acl.Execute)
|
sys.UpdatePermType(Process, m("/run/user/1971/hakurei/fcb8a12f7c482d183ade8288c3de78b5"), acl.Execute)
|
||||||
}, []Op{
|
}, []Op{
|
||||||
&aclUpdateOp{Process, "/run/user/1971/hakurei/fcb8a12f7c482d183ade8288c3de78b5", []acl.Perm{acl.Execute}},
|
&aclUpdateOp{Process, "/run/user/1971/hakurei/fcb8a12f7c482d183ade8288c3de78b5", []acl.Perm{acl.Execute}},
|
||||||
}, stub.Expect{}},
|
}, stub.Expect{}},
|
||||||
|
|
||||||
{"passwd", 0xdeadbeef, func(_ *testing.T, sys *I) {
|
{"passwd", 0xdeadbeef, func(_ *testing.T, sys *I) {
|
||||||
sys.
|
sys.
|
||||||
UpdatePermType(Process, "/tmp/hakurei.0/fcb8a12f7c482d183ade8288c3de78b5/passwd", acl.Read).
|
UpdatePermType(Process, m("/tmp/hakurei.0/fcb8a12f7c482d183ade8288c3de78b5/passwd"), acl.Read).
|
||||||
UpdatePermType(Process, "/tmp/hakurei.0/fcb8a12f7c482d183ade8288c3de78b5/group", acl.Read)
|
UpdatePermType(Process, m("/tmp/hakurei.0/fcb8a12f7c482d183ade8288c3de78b5/group"), acl.Read)
|
||||||
}, []Op{
|
}, []Op{
|
||||||
&aclUpdateOp{Process, "/tmp/hakurei.0/fcb8a12f7c482d183ade8288c3de78b5/passwd", []acl.Perm{acl.Read}},
|
&aclUpdateOp{Process, "/tmp/hakurei.0/fcb8a12f7c482d183ade8288c3de78b5/passwd", []acl.Perm{acl.Read}},
|
||||||
&aclUpdateOp{Process, "/tmp/hakurei.0/fcb8a12f7c482d183ade8288c3de78b5/group", []acl.Perm{acl.Read}},
|
&aclUpdateOp{Process, "/tmp/hakurei.0/fcb8a12f7c482d183ade8288c3de78b5/group", []acl.Perm{acl.Read}},
|
||||||
}, stub.Expect{}},
|
}, stub.Expect{}},
|
||||||
|
|
||||||
{"wayland", 0xdeadbeef, func(_ *testing.T, sys *I) {
|
{"wayland", 0xdeadbeef, func(_ *testing.T, sys *I) {
|
||||||
sys.UpdatePermType(hst.EWayland, "/run/user/1971/wayland-0", acl.Read, acl.Write, acl.Execute)
|
sys.UpdatePermType(hst.EWayland, m("/run/user/1971/wayland-0"), acl.Read, acl.Write, acl.Execute)
|
||||||
}, []Op{
|
}, []Op{
|
||||||
&aclUpdateOp{hst.EWayland, "/run/user/1971/wayland-0", []acl.Perm{acl.Read, acl.Write, acl.Execute}},
|
&aclUpdateOp{hst.EWayland, "/run/user/1971/wayland-0", []acl.Perm{acl.Read, acl.Write, acl.Execute}},
|
||||||
}, stub.Expect{}},
|
}, stub.Expect{}},
|
||||||
|
@ -21,7 +21,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// MustProxyDBus calls ProxyDBus and panics if an error is returned.
|
// MustProxyDBus calls ProxyDBus and panics if an error is returned.
|
||||||
func (sys *I) MustProxyDBus(sessionPath string, session *dbus.Config, systemPath string, system *dbus.Config) *I {
|
func (sys *I) MustProxyDBus(sessionPath *container.Absolute, session *dbus.Config, systemPath *container.Absolute, system *dbus.Config) *I {
|
||||||
if _, err := sys.ProxyDBus(session, system, sessionPath, systemPath); err != nil {
|
if _, err := sys.ProxyDBus(session, system, sessionPath, systemPath); err != nil {
|
||||||
panic(err.Error())
|
panic(err.Error())
|
||||||
} else {
|
} else {
|
||||||
@ -31,7 +31,7 @@ func (sys *I) MustProxyDBus(sessionPath string, session *dbus.Config, systemPath
|
|||||||
|
|
||||||
// ProxyDBus finalises configuration ahead of time and starts xdg-dbus-proxy via [dbus] and terminates it on revert.
|
// ProxyDBus finalises configuration ahead of time and starts xdg-dbus-proxy via [dbus] and terminates it on revert.
|
||||||
// This [Op] is always [Process] scoped.
|
// This [Op] is always [Process] scoped.
|
||||||
func (sys *I) ProxyDBus(session, system *dbus.Config, sessionPath, systemPath string) (func(), error) {
|
func (sys *I) ProxyDBus(session, system *dbus.Config, sessionPath, systemPath *container.Absolute) (func(), error) {
|
||||||
d := new(dbusProxyOp)
|
d := new(dbusProxyOp)
|
||||||
|
|
||||||
// session bus is required as otherwise this is effectively a very expensive noop
|
// session bus is required as otherwise this is effectively a very expensive noop
|
||||||
@ -45,7 +45,7 @@ func (sys *I) ProxyDBus(session, system *dbus.Config, sessionPath, systemPath st
|
|||||||
|
|
||||||
var sessionBus, systemBus dbus.ProxyPair
|
var sessionBus, systemBus dbus.ProxyPair
|
||||||
sessionBus[0], systemBus[0] = sys.dbusAddress()
|
sessionBus[0], systemBus[0] = sys.dbusAddress()
|
||||||
sessionBus[1], systemBus[1] = sessionPath, systemPath
|
sessionBus[1], systemBus[1] = sessionPath.String(), systemPath.String()
|
||||||
d.out = &linePrefixWriter{println: log.Println, prefix: "(dbus) ", buf: new(strings.Builder)}
|
d.out = &linePrefixWriter{println: log.Println, prefix: "(dbus) ", buf: new(strings.Builder)}
|
||||||
if final, err := sys.dbusFinalise(sessionBus, systemBus, session, system); err != nil {
|
if final, err := sys.dbusFinalise(sessionBus, systemBus, session, system); err != nil {
|
||||||
if errors.Is(err, syscall.EINVAL) {
|
if errors.Is(err, syscall.EINVAL) {
|
||||||
|
@ -82,7 +82,7 @@ func TestDBusProxyOp(t *testing.T) {
|
|||||||
Op: "dbus", Err: ErrDBusConfig,
|
Op: "dbus", Err: ErrDBusConfig,
|
||||||
Msg: "attempted to create message bus proxy args without session bus config",
|
Msg: "attempted to create message bus proxy args without session bus config",
|
||||||
}
|
}
|
||||||
if f, err := sys.ProxyDBus(nil, new(dbus.Config), "", ""); !reflect.DeepEqual(err, wantErr) {
|
if f, err := sys.ProxyDBus(nil, new(dbus.Config), nil, nil); !reflect.DeepEqual(err, wantErr) {
|
||||||
t.Errorf("ProxyDBus: error = %v, want %v", err, wantErr)
|
t.Errorf("ProxyDBus: error = %v, want %v", err, wantErr)
|
||||||
} else if f != nil {
|
} else if f != nil {
|
||||||
t.Errorf("ProxyDBus: f = %p", f)
|
t.Errorf("ProxyDBus: f = %p", f)
|
||||||
@ -98,10 +98,10 @@ func TestDBusProxyOp(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
sys.MustProxyDBus(
|
sys.MustProxyDBus(
|
||||||
"/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus", &dbus.Config{
|
m("/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus"), &dbus.Config{
|
||||||
// use impossible value here as an implicit assert that it goes through the stub
|
// use impossible value here as an implicit assert that it goes through the stub
|
||||||
Talk: []string{"session\x00"}, Filter: true,
|
Talk: []string{"session\x00"}, Filter: true,
|
||||||
}, "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket", &dbus.Config{
|
}, m("/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket"), &dbus.Config{
|
||||||
// use impossible value here as an implicit assert that it goes through the stub
|
// use impossible value here as an implicit assert that it goes through the stub
|
||||||
Talk: []string{"system\x00"}, Filter: true,
|
Talk: []string{"system\x00"}, Filter: true,
|
||||||
})
|
})
|
||||||
@ -128,8 +128,8 @@ func TestDBusProxyOp(t *testing.T) {
|
|||||||
// use impossible value here as an implicit assert that it goes through the stub
|
// use impossible value here as an implicit assert that it goes through the stub
|
||||||
Talk: []string{"system\x00"}, Filter: true,
|
Talk: []string{"system\x00"}, Filter: true,
|
||||||
},
|
},
|
||||||
"/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus",
|
m("/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus"),
|
||||||
"/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket"); !reflect.DeepEqual(err, wantErr) {
|
m("/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket")); !reflect.DeepEqual(err, wantErr) {
|
||||||
t.Errorf("ProxyDBus: error = %v", err)
|
t.Errorf("ProxyDBus: error = %v", err)
|
||||||
} else if f != nil {
|
} else if f != nil {
|
||||||
t.Errorf("ProxyDBus: f = %p", f)
|
t.Errorf("ProxyDBus: f = %p", f)
|
||||||
@ -146,10 +146,10 @@ func TestDBusProxyOp(t *testing.T) {
|
|||||||
|
|
||||||
{"full", 0xcafebabe, func(_ *testing.T, sys *I) {
|
{"full", 0xcafebabe, func(_ *testing.T, sys *I) {
|
||||||
sys.MustProxyDBus(
|
sys.MustProxyDBus(
|
||||||
"/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus", &dbus.Config{
|
m("/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus"), &dbus.Config{
|
||||||
// use impossible value here as an implicit assert that it goes through the stub
|
// use impossible value here as an implicit assert that it goes through the stub
|
||||||
Talk: []string{"session\x00"}, Filter: true,
|
Talk: []string{"session\x00"}, Filter: true,
|
||||||
}, "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket", &dbus.Config{
|
}, m("/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket"), &dbus.Config{
|
||||||
// use impossible value here as an implicit assert that it goes through the stub
|
// use impossible value here as an implicit assert that it goes through the stub
|
||||||
Talk: []string{"system\x00"}, Filter: true,
|
Talk: []string{"system\x00"}, Filter: true,
|
||||||
})
|
})
|
||||||
|
@ -3,15 +3,18 @@ package system
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"hakurei.app/container"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Link calls LinkFileType with the [Process] criteria.
|
// Link calls LinkFileType with the [Process] criteria.
|
||||||
func (sys *I) Link(oldname, newname string) *I { return sys.LinkFileType(Process, oldname, newname) }
|
func (sys *I) Link(oldname, newname *container.Absolute) *I {
|
||||||
|
return sys.LinkFileType(Process, oldname, newname)
|
||||||
|
}
|
||||||
|
|
||||||
// LinkFileType maintains a hardlink until its [Enablement] is no longer satisfied.
|
// LinkFileType maintains a hardlink until its [Enablement] is no longer satisfied.
|
||||||
func (sys *I) LinkFileType(et hst.Enablement, oldname, newname string) *I {
|
func (sys *I) LinkFileType(et hst.Enablement, oldname, newname *container.Absolute) *I {
|
||||||
sys.ops = append(sys.ops, &hardlinkOp{et, newname, oldname})
|
sys.ops = append(sys.ops, &hardlinkOp{et, newname.String(), oldname.String()})
|
||||||
return sys
|
return sys
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,13 +40,13 @@ func TestHardlinkOp(t *testing.T) {
|
|||||||
|
|
||||||
checkOpsBuilder(t, "LinkFileType", []opsBuilderTestCase{
|
checkOpsBuilder(t, "LinkFileType", []opsBuilderTestCase{
|
||||||
{"type", 0xcafebabe, func(_ *testing.T, sys *I) {
|
{"type", 0xcafebabe, func(_ *testing.T, sys *I) {
|
||||||
sys.LinkFileType(User, "/run/user/1000/pulse/native", "/run/user/1000/hakurei/9663730666a44cfc2a81610379e02ed6/pulse")
|
sys.LinkFileType(User, m("/run/user/1000/pulse/native"), m("/run/user/1000/hakurei/9663730666a44cfc2a81610379e02ed6/pulse"))
|
||||||
}, []Op{
|
}, []Op{
|
||||||
&hardlinkOp{User, "/run/user/1000/hakurei/9663730666a44cfc2a81610379e02ed6/pulse", "/run/user/1000/pulse/native"},
|
&hardlinkOp{User, "/run/user/1000/hakurei/9663730666a44cfc2a81610379e02ed6/pulse", "/run/user/1000/pulse/native"},
|
||||||
}, stub.Expect{}},
|
}, stub.Expect{}},
|
||||||
|
|
||||||
{"link", 0xcafebabe, func(_ *testing.T, sys *I) {
|
{"link", 0xcafebabe, func(_ *testing.T, sys *I) {
|
||||||
sys.Link("/run/user/1000/pulse/native", "/run/user/1000/hakurei/9663730666a44cfc2a81610379e02ed6/pulse")
|
sys.Link(m("/run/user/1000/pulse/native"), m("/run/user/1000/hakurei/9663730666a44cfc2a81610379e02ed6/pulse"))
|
||||||
}, []Op{
|
}, []Op{
|
||||||
&hardlinkOp{Process, "/run/user/1000/hakurei/9663730666a44cfc2a81610379e02ed6/pulse", "/run/user/1000/pulse/native"},
|
&hardlinkOp{Process, "/run/user/1000/hakurei/9663730666a44cfc2a81610379e02ed6/pulse", "/run/user/1000/pulse/native"},
|
||||||
}, stub.Expect{}},
|
}, stub.Expect{}},
|
||||||
|
@ -5,18 +5,19 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"hakurei.app/container"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ensure ensures the existence of a directory.
|
// Ensure ensures the existence of a directory.
|
||||||
func (sys *I) Ensure(name string, perm os.FileMode) *I {
|
func (sys *I) Ensure(name *container.Absolute, perm os.FileMode) *I {
|
||||||
sys.ops = append(sys.ops, &mkdirOp{User, name, perm, false})
|
sys.ops = append(sys.ops, &mkdirOp{User, name.String(), perm, false})
|
||||||
return sys
|
return sys
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ephemeral ensures the existence of a directory until its [Enablement] is no longer satisfied.
|
// Ephemeral ensures the existence of a directory until its [Enablement] is no longer satisfied.
|
||||||
func (sys *I) Ephemeral(et hst.Enablement, name string, perm os.FileMode) *I {
|
func (sys *I) Ephemeral(et hst.Enablement, name *container.Absolute, perm os.FileMode) *I {
|
||||||
sys.ops = append(sys.ops, &mkdirOp{et, name, perm, true})
|
sys.ops = append(sys.ops, &mkdirOp{et, name.String(), perm, true})
|
||||||
return sys
|
return sys
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,13 +57,13 @@ func TestMkdirOp(t *testing.T) {
|
|||||||
|
|
||||||
checkOpsBuilder(t, "EnsureEphemeral", []opsBuilderTestCase{
|
checkOpsBuilder(t, "EnsureEphemeral", []opsBuilderTestCase{
|
||||||
{"ensure", 0xcafebabe, func(_ *testing.T, sys *I) {
|
{"ensure", 0xcafebabe, func(_ *testing.T, sys *I) {
|
||||||
sys.Ensure("/tmp/hakurei.0", 0700)
|
sys.Ensure(m("/tmp/hakurei.0"), 0700)
|
||||||
}, []Op{
|
}, []Op{
|
||||||
&mkdirOp{User, "/tmp/hakurei.0", 0700, false},
|
&mkdirOp{User, "/tmp/hakurei.0", 0700, false},
|
||||||
}, stub.Expect{}},
|
}, stub.Expect{}},
|
||||||
|
|
||||||
{"ephemeral", 0xcafebabe, func(_ *testing.T, sys *I) {
|
{"ephemeral", 0xcafebabe, func(_ *testing.T, sys *I) {
|
||||||
sys.Ephemeral(Process, "/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9", 0711)
|
sys.Ephemeral(Process, m("/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9"), 0711)
|
||||||
}, []Op{
|
}, []Op{
|
||||||
&mkdirOp{Process, "/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9", 0711, true},
|
&mkdirOp{Process, "/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9", 0711, true},
|
||||||
}, stub.Expect{}},
|
}, stub.Expect{}},
|
||||||
|
@ -133,34 +133,34 @@ func TestEqual(t *testing.T) {
|
|||||||
ChangeHosts("chronos"),
|
ChangeHosts("chronos"),
|
||||||
New(t.Context(), container.NewMsg(nil), 150).
|
New(t.Context(), container.NewMsg(nil), 150).
|
||||||
ChangeHosts("chronos").
|
ChangeHosts("chronos").
|
||||||
Ensure("/run", 0755),
|
Ensure(m("/run"), 0755),
|
||||||
false},
|
false},
|
||||||
|
|
||||||
{"op value mismatch",
|
{"op value mismatch",
|
||||||
New(t.Context(), container.NewMsg(nil), 150).
|
New(t.Context(), container.NewMsg(nil), 150).
|
||||||
ChangeHosts("chronos").
|
ChangeHosts("chronos").
|
||||||
Ensure("/run", 0644),
|
Ensure(m("/run"), 0644),
|
||||||
New(t.Context(), container.NewMsg(nil), 150).
|
New(t.Context(), container.NewMsg(nil), 150).
|
||||||
ChangeHosts("chronos").
|
ChangeHosts("chronos").
|
||||||
Ensure("/run", 0755),
|
Ensure(m("/run"), 0755),
|
||||||
false},
|
false},
|
||||||
|
|
||||||
{"op type mismatch",
|
{"op type mismatch",
|
||||||
New(t.Context(), container.NewMsg(nil), 150).
|
New(t.Context(), container.NewMsg(nil), 150).
|
||||||
ChangeHosts("chronos").
|
ChangeHosts("chronos").
|
||||||
CopyFile(new([]byte), "/home/ophestra/xdg/config/pulse/cookie", 0, 256),
|
CopyFile(new([]byte), m("/home/ophestra/xdg/config/pulse/cookie"), 0, 256),
|
||||||
New(t.Context(), container.NewMsg(nil), 150).
|
New(t.Context(), container.NewMsg(nil), 150).
|
||||||
ChangeHosts("chronos").
|
ChangeHosts("chronos").
|
||||||
Ensure("/run", 0755),
|
Ensure(m("/run"), 0755),
|
||||||
false},
|
false},
|
||||||
|
|
||||||
{"op equals",
|
{"op equals",
|
||||||
New(t.Context(), container.NewMsg(nil), 150).
|
New(t.Context(), container.NewMsg(nil), 150).
|
||||||
ChangeHosts("chronos").
|
ChangeHosts("chronos").
|
||||||
Ensure("/run", 0755),
|
Ensure(m("/run"), 0755),
|
||||||
New(t.Context(), container.NewMsg(nil), 150).
|
New(t.Context(), container.NewMsg(nil), 150).
|
||||||
ChangeHosts("chronos").
|
ChangeHosts("chronos").
|
||||||
Ensure("/run", 0755),
|
Ensure(m("/run"), 0755),
|
||||||
true},
|
true},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ func TestCommitRevert(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{"apply xhost partial mkdir", func(sys *I) {
|
{"apply xhost partial mkdir", func(sys *I) {
|
||||||
sys.
|
sys.
|
||||||
Ephemeral(Process, "/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9", 0711).
|
Ephemeral(Process, m("/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9"), 0711).
|
||||||
ChangeHosts("chronos")
|
ChangeHosts("chronos")
|
||||||
}, 0xff, []stub.Call{
|
}, 0xff, []stub.Call{
|
||||||
call("verbose", stub.ExpectArgs{[]any{"ensuring directory", &mkdirOp{Process, "/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9", 0711, true}}}, nil, nil),
|
call("verbose", stub.ExpectArgs{[]any{"ensuring directory", &mkdirOp{Process, "/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9", 0711, true}}}, nil, nil),
|
||||||
@ -202,7 +202,7 @@ func TestCommitRevert(t *testing.T) {
|
|||||||
|
|
||||||
{"apply xhost", func(sys *I) {
|
{"apply xhost", func(sys *I) {
|
||||||
sys.
|
sys.
|
||||||
Ephemeral(Process, "/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9", 0711).
|
Ephemeral(Process, m("/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9"), 0711).
|
||||||
ChangeHosts("chronos")
|
ChangeHosts("chronos")
|
||||||
}, 0xff, []stub.Call{
|
}, 0xff, []stub.Call{
|
||||||
call("verbose", stub.ExpectArgs{[]any{"ensuring directory", &mkdirOp{Process, "/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9", 0711, true}}}, nil, nil),
|
call("verbose", stub.ExpectArgs{[]any{"ensuring directory", &mkdirOp{Process, "/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9", 0711, true}}}, nil, nil),
|
||||||
@ -216,7 +216,7 @@ func TestCommitRevert(t *testing.T) {
|
|||||||
|
|
||||||
{"revert multi", func(sys *I) {
|
{"revert multi", func(sys *I) {
|
||||||
sys.
|
sys.
|
||||||
Ephemeral(Process, "/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9", 0711).
|
Ephemeral(Process, m("/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9"), 0711).
|
||||||
ChangeHosts("chronos")
|
ChangeHosts("chronos")
|
||||||
}, 0xff, []stub.Call{
|
}, 0xff, []stub.Call{
|
||||||
call("verbose", stub.ExpectArgs{[]any{"ensuring directory", &mkdirOp{Process, "/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9", 0711, true}}}, nil, nil),
|
call("verbose", stub.ExpectArgs{[]any{"ensuring directory", &mkdirOp{Process, "/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9", 0711, true}}}, nil, nil),
|
||||||
@ -234,7 +234,7 @@ func TestCommitRevert(t *testing.T) {
|
|||||||
|
|
||||||
{"success", func(sys *I) {
|
{"success", func(sys *I) {
|
||||||
sys.
|
sys.
|
||||||
Ephemeral(Process, "/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9", 0711).
|
Ephemeral(Process, m("/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9"), 0711).
|
||||||
ChangeHosts("chronos")
|
ChangeHosts("chronos")
|
||||||
}, 0xff, []stub.Call{
|
}, 0xff, []stub.Call{
|
||||||
call("verbose", stub.ExpectArgs{[]any{"ensuring directory", &mkdirOp{Process, "/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9", 0711, true}}}, nil, nil),
|
call("verbose", stub.ExpectArgs{[]any{"ensuring directory", &mkdirOp{Process, "/tmp/hakurei.0/f2f3bcd492d0266438fa9bf164fe90d9", 0711, true}}}, nil, nil),
|
||||||
@ -312,3 +312,5 @@ func TestNop(t *testing.T) {
|
|||||||
new(noCopy).Unlock()
|
new(noCopy).Unlock()
|
||||||
new(noCopy).Lock()
|
new(noCopy).Lock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func m(pathname string) *container.Absolute { return container.MustAbs(pathname) }
|
||||||
|
@ -8,14 +8,15 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"hakurei.app/container"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CopyFile reads up to n bytes from src and writes the resulting byte slice to payloadP.
|
// CopyFile reads up to n bytes from src and writes the resulting byte slice to payloadP.
|
||||||
func (sys *I) CopyFile(payloadP *[]byte, src string, cap int, n int64) *I {
|
func (sys *I) CopyFile(payloadP *[]byte, src *container.Absolute, cap int, n int64) *I {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
buf.Grow(cap)
|
buf.Grow(cap)
|
||||||
sys.ops = append(sys.ops, &tmpfileOp{payloadP, src, n, buf})
|
sys.ops = append(sys.ops, &tmpfileOp{payloadP, src.String(), n, buf})
|
||||||
return sys
|
return sys
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ func TestTmpfileOp(t *testing.T) {
|
|||||||
|
|
||||||
checkOpsBuilder(t, "CopyFile", []opsBuilderTestCase{
|
checkOpsBuilder(t, "CopyFile", []opsBuilderTestCase{
|
||||||
{"pulse", 0xcafebabe, func(_ *testing.T, sys *I) {
|
{"pulse", 0xcafebabe, func(_ *testing.T, sys *I) {
|
||||||
sys.CopyFile(new([]byte), "/home/ophestra/xdg/config/pulse/cookie", 1<<8, 1<<8)
|
sys.CopyFile(new([]byte), m("/home/ophestra/xdg/config/pulse/cookie"), 1<<8, 1<<8)
|
||||||
}, []Op{&tmpfileOp{
|
}, []Op{&tmpfileOp{
|
||||||
new([]byte), "/home/ophestra/xdg/config/pulse/cookie", 1 << 8,
|
new([]byte), "/home/ophestra/xdg/config/pulse/cookie", 1 << 8,
|
||||||
func() *bytes.Buffer { buf := new(bytes.Buffer); buf.Grow(1 << 8); return buf }(),
|
func() *bytes.Buffer { buf := new(bytes.Buffer); buf.Grow(1 << 8); return buf }(),
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"hakurei.app/container"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
"hakurei.app/system/acl"
|
"hakurei.app/system/acl"
|
||||||
"hakurei.app/system/wayland"
|
"hakurei.app/system/wayland"
|
||||||
@ -19,8 +20,8 @@ type waylandConn interface {
|
|||||||
// Wayland maintains a wayland socket with security-context-v1 attached via [wayland].
|
// Wayland maintains a wayland socket with security-context-v1 attached via [wayland].
|
||||||
// The socket stops accepting connections once the pipe referred to by sync is closed.
|
// The socket stops accepting connections once the pipe referred to by sync is closed.
|
||||||
// The socket is pathname only and is destroyed on revert.
|
// The socket is pathname only and is destroyed on revert.
|
||||||
func (sys *I) Wayland(syncFd **os.File, dst, src, appID, instanceID string) *I {
|
func (sys *I) Wayland(syncFd **os.File, dst, src *container.Absolute, appID, instanceID string) *I {
|
||||||
sys.ops = append(sys.ops, &waylandOp{syncFd, dst, src, appID, instanceID, new(wayland.Conn)})
|
sys.ops = append(sys.ops, &waylandOp{syncFd, dst.String(), src.String(), appID, instanceID, new(wayland.Conn)})
|
||||||
return sys
|
return sys
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,8 +218,8 @@ func TestWaylandOp(t *testing.T) {
|
|||||||
{"chromium", 0xcafe, func(_ *testing.T, sys *I) {
|
{"chromium", 0xcafe, func(_ *testing.T, sys *I) {
|
||||||
sys.Wayland(
|
sys.Wayland(
|
||||||
new(*os.File),
|
new(*os.File),
|
||||||
"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland",
|
m("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland"),
|
||||||
"/run/user/1971/wayland-0",
|
m("/run/user/1971/wayland-0"),
|
||||||
"org.chromium.Chromium",
|
"org.chromium.Chromium",
|
||||||
"ebf083d1b175911782d413369b64ce7c",
|
"ebf083d1b175911782d413369b64ce7c",
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user