internal/outcome: expose pipewire via pipewire-pulse
All checks were successful
Test / Create distribution (push) Successful in 28s
Test / Sandbox (push) Successful in 42s
Test / Hakurei (push) Successful in 3m20s
Test / Hpkg (push) Successful in 2m13s
Test / Sandbox (race detector) (push) Successful in 4m25s
Test / Hakurei (race detector) (push) Successful in 3m21s
Test / Flake checks (push) Successful in 1m30s

This no longer exposes the pipewire socket to the container, and instead mediates access via pipewire-pulse. This makes insecure parts of the protocol inaccessible as explained in the doc comment in hst.

Closes #29.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
2025-12-15 12:43:58 +09:00
parent 2e80660169
commit 54610aaddc
14 changed files with 113 additions and 77 deletions

View File

@@ -14,7 +14,6 @@ import (
_ "unsafe" // for go:linkname
"hakurei.app/command"
"hakurei.app/container"
"hakurei.app/container/check"
"hakurei.app/container/fhs"
"hakurei.app/hst"
@@ -187,14 +186,6 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr
}})
}
// start pipewire-pulse: this most likely exists on host if PipeWire is available
if flagPulse {
config.Container.Filesystem = append(config.Container.Filesystem, hst.FilesystemConfigJSON{FilesystemConfig: &hst.FSDaemon{
Target: fhs.AbsRunUser.Append(strconv.Itoa(container.OverflowUid(msg)), "pulse/native"),
Exec: shell, Args: []string{"-lc", "exec pipewire-pulse"},
}})
}
config.Container.Filesystem = append(config.Container.Filesystem,
// opportunistically bind kvm
hst.FilesystemConfigJSON{FilesystemConfig: &hst.FSBind{

View File

@@ -257,6 +257,10 @@ type outcomeStateParams struct {
// Populated by spRuntimeOp.
runtimeDir *check.Absolute
// Path to pipewire-pulse server.
// Populated by spPipeWireOp if DirectPipeWire is false.
pipewirePulsePath *check.Absolute
as hst.ApplyState
*outcomeState
}

View File

@@ -100,7 +100,6 @@ func TestOutcomeRun(t *testing.T) {
"GOOGLE_DEFAULT_CLIENT_ID=77185425430.apps.googleusercontent.com",
"GOOGLE_DEFAULT_CLIENT_SECRET=OTJgUOQcT7lO7GsGZq2G4IlT",
"HOME=/data/data/org.chromium.Chromium",
"PIPEWIRE_REMOTE=/run/user/1971/pipewire-0",
"SHELL=/run/current-system/sw/bin/zsh",
"TERM=xterm-256color",
"USER=chronos",
@@ -150,9 +149,6 @@ func TestOutcomeRun(t *testing.T) {
// spWaylandOp
Bind(m("/tmp/hakurei.0/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/wayland"), m("/run/user/1971/wayland-0"), 0).
// spPipeWireOp
Bind(m("/tmp/hakurei.0/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/pipewire"), m("/run/user/1971/pipewire-0"), 0).
// spDBusOp
Bind(m("/tmp/hakurei.0/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bus"), m("/run/user/1971/bus"), 0).
Bind(m("/tmp/hakurei.0/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/system_bus_socket"), m("/var/run/dbus/system_bus_socket"), 0).
@@ -174,7 +170,7 @@ func TestOutcomeRun(t *testing.T) {
Remount(fhs.AbsRoot, syscall.MS_RDONLY),
}},
{"nixos permissive defaults no enablements", new(stubNixOS), &hst.Config{Container: &hst.ContainerConfig{
{"nixos permissive defaults no enablements", new(stubNixOS), &hst.Config{DirectPipeWire: true, Container: &hst.ContainerConfig{
Filesystem: []hst.FilesystemConfigJSON{
{FilesystemConfig: &hst.FSBind{
Target: fhs.AbsRoot,
@@ -256,6 +252,8 @@ func TestOutcomeRun(t *testing.T) {
}},
{"nixos permissive defaults chromium", new(stubNixOS), &hst.Config{
DirectPipeWire: true,
ID: "org.chromium.Chromium",
Identity: 9,
Groups: []string{"video"},
@@ -426,6 +424,8 @@ func TestOutcomeRun(t *testing.T) {
}},
{"nixos chromium direct wayland", new(stubNixOS), &hst.Config{
DirectPipeWire: true,
ID: "org.chromium.Chromium",
Enablements: hst.NewEnablements(hst.EWayland | hst.EDBus | hst.EPipeWire | hst.EPulse),
Container: &hst.ContainerConfig{

View File

@@ -15,9 +15,11 @@ import (
"hakurei.app/container"
"hakurei.app/container/check"
"hakurei.app/container/fhs"
"hakurei.app/container/seccomp"
"hakurei.app/container/std"
"hakurei.app/hst"
"hakurei.app/internal/pipewire"
"hakurei.app/message"
)
@@ -266,6 +268,79 @@ func shimEntrypoint(k syscallDispatcher) {
// bounds and default enforced in finalise.go
z.WaitDelay = state.Shim.WaitDelay
if stateParams.pipewirePulsePath != nil {
zpw := container.NewCommand(ctx, msg, stateParams.pipewirePulsePath, pipewirePulseName)
zpw.Hostname = "hakurei-" + pipewirePulseName
zpw.SeccompFlags |= seccomp.AllowMultiarch
zpw.SeccompPresets |= std.PresetStrict
zpw.Env = []string{
// pipewire SecurityContext socket path
pipewire.Remote + "=" + stateParams.instancePath().Append("pipewire").String(),
// pipewire-pulse socket directory path
envXDGRuntimeDir + "=" + sp.String(),
}
if msg.IsVerbose() {
zpw.Stdin, zpw.Stdout, zpw.Stderr = os.Stdin, os.Stdout, os.Stderr
}
zpw.
Bind(fhs.AbsRoot, fhs.AbsRoot, 0).
Bind(sp.unwrap(), sp.unwrap(), std.BindWritable).
Proc(fhs.AbsProc).Dev(fhs.AbsDev, true)
socketPath := sp.unwrap().Append("pulse", "native")
innerSocketPath := stateParams.runtimeDir.Append("pulse", "native")
if err := k.containerStart(zpw); err != nil {
sp.destroy()
printMessageError(func(v ...any) { k.fatal(fmt.Sprintln(v...)) },
"cannot start "+pipewirePulseName+" container:", err)
}
if err := k.containerServe(zpw); err != nil {
sp.destroy()
printMessageError(func(v ...any) { k.fatal(fmt.Sprintln(v...)) },
"cannot configure "+pipewirePulseName+" container:", err)
}
done := make(chan error, 1)
k.new(func(k syscallDispatcher, msg message.Msg) { done <- k.containerWait(zpw) })
socketTimer := time.NewTimer(shimPipeWireTimeout)
for {
select {
case <-socketTimer.C:
sp.destroy()
k.fatal(pipewirePulseName + " exceeded deadline before socket appeared")
break
case err := <-done:
var exitError *exec.ExitError
if !errors.As(err, &exitError) {
msg.Verbosef("cannot wait: %v", err)
k.exit(127)
}
sp.destroy()
k.fatal(pipewirePulseName + " " + exitError.ProcessState.String())
break
default:
if _, err := k.stat(socketPath.String()); err != nil {
if !errors.Is(err, os.ErrNotExist) {
sp.destroy()
k.fatal(err)
break
}
time.Sleep(500 * time.Microsecond)
continue
}
}
break
}
z.Bind(socketPath, innerSocketPath, 0)
z.Env = append(z.Env, "PULSE_SERVER=unix:"+innerSocketPath.String())
}
if err := k.containerStart(z); err != nil {
var f func(v ...any)
if logger := msg.GetLogger(); logger != nil {

View File

@@ -41,9 +41,13 @@ func (s *spPipeWireOp) toSystem(state *outcomeStateSys) error {
}
func (s *spPipeWireOp) toContainer(state *outcomeStateParams) error {
if s.CompatServerPath == nil {
innerPath := state.runtimeDir.Append(pipewire.PW_DEFAULT_REMOTE)
state.env[pipewire.Remote] = innerPath.String()
state.params.Bind(state.instancePath().Append("pipewire"), innerPath, 0)
}
// pipewire-pulse behaviour implemented in shim.go
state.pipewirePulsePath = s.CompatServerPath
return nil
}

View File

@@ -68,7 +68,7 @@ in
home-manager =
let
privPackages = mapAttrs (username: userid: {
privPackages = mapAttrs (_: userid: {
home.packages = foldlAttrs (
acc: id: app:
[
@@ -196,15 +196,6 @@ in
}
]
)
++ optional (app.enablements.pipewire && app.pulse) {
type = "daemon";
dst = if app.mapRealUid then "/run/user/${toString config.users.users.${username}.uid}/pulse/native" else "/run/user/65534/pulse/native";
path = cfg.shell;
args = [
"-lc"
"exec pipewire-pulse"
];
}
++ [
{
type = "bind";

View File

@@ -35,7 +35,7 @@ package
*Default:*
` <derivation hakurei-static-x86_64-unknown-linux-musl-0.3.1> `
` <derivation hakurei-static-x86_64-unknown-linux-musl-0.3.2> `
@@ -73,11 +73,11 @@ null or boolean
## environment\.hakurei\.apps\.\<name>\.enablements\.pulse
## environment\.hakurei\.apps\.\<name>\.enablements\.pipewire
Whether to share the PulseAudio socket and cookie\.
Whether to share the PipeWire server via pipewire-pulse on a SecurityContext socket\.
@@ -95,7 +95,7 @@ null or boolean
Whether to share the Wayland socket\.
Whether to share the Wayland server via security-context-v1\.
@@ -805,7 +805,7 @@ package
*Default:*
` <derivation hakurei-hsu-0.3.1> `
` <derivation hakurei-hsu-0.3.2> `

View File

@@ -242,19 +242,11 @@ in
type = nullOr bool;
default = true;
description = ''
Whether to share the PipeWire server via SecurityContext.
Whether to share the PipeWire server via pipewire-pulse on a SecurityContext socket.
'';
};
};
pulse = mkOption {
type = nullOr bool;
default = true;
description = ''
Whether to run the PulseAudio compatibility daemon.
'';
};
share = mkOption {
type = nullOr package;
default = null;

View File

@@ -41,7 +41,6 @@ in
"DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus"
"DISPLAY=unix:/tmp/.X11-unix/X0"
"HOME=/var/lib/hakurei/u0/a4"
"PIPEWIRE_REMOTE=/run/user/65534/pipewire-0"
"SHELL=/run/current-system/sw/bin/bash"
"TERM=linux"
"USER=u0_a4"
@@ -49,6 +48,7 @@ in
"XDG_RUNTIME_DIR=/run/user/65534"
"XDG_SESSION_CLASS=user"
"XDG_SESSION_TYPE=wayland"
"PULSE_SERVER=unix:/run/user/65534/pulse/native"
];
fs = fs "dead" {
@@ -138,12 +138,8 @@ in
user = fs "800001ed" {
"65534" = fs "800001c0" {
bus = fs "10001fd" null null;
pulse = fs "800001c0" {
native = fs "10001ff" null null;
pid = fs "1a4" null null;
} null;
pulse = fs "800001c0" { native = fs "10001ff" null null; } null;
wayland-0 = fs "1000038" null null;
pipewire-0 = fs "1000038" null null;
} null;
} null;
} null;
@@ -229,7 +225,6 @@ in
(ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10004,gid=10004")
(ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent "/tmp/.X11-unix" "/tmp/.X11-unix" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent ignore "/run/user/65534/pipewire-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
@@ -246,6 +241,7 @@ in
(ent "/" "/.hakurei/store" "rw,relatime" "overlay" "overlay" "rw,lowerdir=/host/nix/.ro-store:/host/nix/.rw-store/upper,upperdir=/host/tmp/.hakurei-store-rw/upper,workdir=/host/tmp/.hakurei-store-rw/work,redirect_dir=nofollow,userxattr")
(ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent "/var/lib/hakurei/u0/a4" "/var/lib/hakurei/u0/a4" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
];
seccomp = true;

View File

@@ -49,7 +49,6 @@ in
env = [
"DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus"
"HOME=/var/lib/hakurei/u0/a3"
"PIPEWIRE_REMOTE=/run/user/1000/pipewire-0"
"SHELL=/run/current-system/sw/bin/bash"
"TERM=linux"
"USER=u0_a3"
@@ -57,6 +56,7 @@ in
"XDG_RUNTIME_DIR=/run/user/1000"
"XDG_SESSION_CLASS=user"
"XDG_SESSION_TYPE=wayland"
"PULSE_SERVER=unix:/run/user/1000/pulse/native"
];
fs = fs "dead" {
@@ -163,12 +163,8 @@ in
user = fs "800001ed" {
"1000" = fs "800001f8" {
bus = fs "10001fd" null null;
pulse = fs "800001c0" {
native = fs "10001ff" null null;
pid = fs "1a4" null null;
} null;
pulse = fs "800001c0" { native = fs "10001ff" null null; } null;
wayland-0 = fs "1000038" null null;
pipewire-0 = fs "1000038" null null;
} null;
} null;
} null;
@@ -256,7 +252,6 @@ in
(ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10003,gid=10003")
(ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10003,gid=10003")
(ent ignore "/run/user/1000/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent ignore "/run/user/1000/pipewire-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent ignore "/run/user/1000/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
@@ -273,6 +268,7 @@ in
(ent "/" "/.hakurei/store" "rw,relatime" "overlay" "overlay" "rw,lowerdir=/host/nix/.ro-store:/host/nix/.rw-store/upper,upperdir=/host/tmp/.hakurei-store-rw/upper,workdir=/host/tmp/.hakurei-store-rw/work,redirect_dir=nofollow,userxattr")
(ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent "/var/lib/hakurei/u0/a3" "/var/lib/hakurei/u0/a3" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent ignore "/run/user/1000/pulse/native" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
];
seccomp = true;

View File

@@ -49,7 +49,6 @@ in
env = [
"DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus"
"HOME=/var/lib/hakurei/u0/a5"
"PIPEWIRE_REMOTE=/run/user/65534/pipewire-0"
"SHELL=/run/current-system/sw/bin/bash"
"TERM=linux"
"USER=u0_a5"
@@ -57,6 +56,7 @@ in
"XDG_RUNTIME_DIR=/run/user/65534"
"XDG_SESSION_CLASS=user"
"XDG_SESSION_TYPE=wayland"
"PULSE_SERVER=unix:/run/user/65534/pulse/native"
];
fs = fs "dead" {
@@ -161,12 +161,8 @@ in
user = fs "800001ed" {
"65534" = fs "800001f8" {
bus = fs "10001fd" null null;
pulse = fs "800001c0" {
native = fs "10001ff" null null;
pid = fs "1a4" null null;
} null;
pulse = fs "800001c0" { native = fs "10001ff" null null; } null;
wayland-0 = fs "1000038" null null;
pipewire-0 = fs "1000038" null null;
} null;
} null;
} null;
@@ -254,7 +250,6 @@ in
(ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10005,gid=10005")
(ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10005,gid=10005")
(ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent ignore "/run/user/65534/pipewire-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
@@ -268,6 +263,7 @@ in
(ent "/var/tmp" "/var/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent "/var/lib/hakurei/u0/a5" "/var/lib/hakurei/u0/a5" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
];
seccomp = true;

View File

@@ -49,7 +49,6 @@ in
env = [
"DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus"
"HOME=/var/lib/hakurei/u0/a1"
"PIPEWIRE_REMOTE=/run/user/65534/pipewire-0"
"SHELL=/run/current-system/sw/bin/bash"
"TERM=linux"
"USER=u0_a1"
@@ -57,6 +56,7 @@ in
"XDG_RUNTIME_DIR=/run/user/65534"
"XDG_SESSION_CLASS=user"
"XDG_SESSION_TYPE=wayland"
"PULSE_SERVER=unix:/run/user/65534/pulse/native"
];
fs = fs "dead" {
@@ -160,12 +160,8 @@ in
user = fs "800001ed" {
"65534" = fs "800001c0" {
bus = fs "10001fd" null null;
pulse = fs "800001c0" {
native = fs "10001ff" null null;
pid = fs "1a4" null null;
} null;
pulse = fs "800001c0" { native = fs "10001ff" null null; } null;
wayland-0 = fs "1000038" null null;
pipewire-0 = fs "1000038" null null;
} null;
} null;
} null;
@@ -251,7 +247,6 @@ in
(ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10001,gid=10001")
(ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10001,gid=10001")
(ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent ignore "/run/user/65534/pipewire-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
@@ -265,6 +260,7 @@ in
(ent "/var/tmp" "/var/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent "/var/lib/hakurei/u0/a1" "/var/lib/hakurei/u0/a1" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
];
seccomp = true;

View File

@@ -50,7 +50,6 @@ in
"DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus"
"DISPLAY=:0"
"HOME=/var/lib/hakurei/u0/a2"
"PIPEWIRE_REMOTE=/run/user/65534/pipewire-0"
"SHELL=/run/current-system/sw/bin/bash"
"TERM=linux"
"USER=u0_a2"
@@ -58,6 +57,7 @@ in
"XDG_RUNTIME_DIR=/run/user/65534"
"XDG_SESSION_CLASS=user"
"XDG_SESSION_TYPE=wayland"
"PULSE_SERVER=unix:/run/user/65534/pulse/native"
];
fs = fs "dead" {
@@ -165,12 +165,8 @@ in
user = fs "800001ed" {
"65534" = fs "800001f8" {
bus = fs "10001fd" null null;
pulse = fs "800001c0" {
native = fs "10001ff" null null;
pid = fs "1a4" null null;
} null;
pulse = fs "800001c0" { native = fs "10001ff" null null; } null;
wayland-0 = fs "1000038" null null;
pipewire-0 = fs "1000038" null null;
} null;
} null;
} null;
@@ -262,7 +258,6 @@ in
(ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10002,gid=10002")
(ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent "/tmp/.X11-unix" "/tmp/.X11-unix" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent ignore "/run/user/65534/pipewire-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
@@ -279,6 +274,7 @@ in
(ent "/" "/.hakurei/store" "rw,relatime" "overlay" "overlay" "rw,lowerdir=/host/nix/.ro-store:/host/nix/.rw-store/upper,upperdir=/host/tmp/.hakurei-store-rw/upper,workdir=/host/tmp/.hakurei-store-rw/work,redirect_dir=nofollow,uuid=on,userxattr")
(ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent "/var/lib/hakurei/u0/a2" "/var/lib/hakurei/u0/a2" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
(ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
];
seccomp = true;

View File

@@ -226,15 +226,14 @@ machine.send_chars("clear; pactl info && touch /var/tmp/pulse-ok\n")
machine.wait_for_file("/var/tmp/pulse-ok", timeout=15)
collect_state_ui("pulse_wayland")
check_state("pa-foot", {"wayland": True, "pipewire": True})
# Test PipeWire:
machine.send_chars("clear; pw-cli i 0 && touch /var/tmp/pw-ok\n")
machine.wait_for_file("/var/tmp/pw-ok", timeout=15)
collect_state_ui("pipewire_wayland")
machine.send_chars("exit\n")
machine.wait_until_fails("pgrep foot", timeout=5)
# Test PipeWire SecurityContext:
machine.succeed("sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 hakurei -v run --pulse pactl info")
machine.fail("sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 hakurei -v run --pulse pactl set-sink-mute @DEFAULT_SINK@ toggle")
# Test PipeWire direct access:
machine.succeed("sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 pw-dump")
machine.fail("sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 hakurei -v run --pipewire pw-dump")
# Test XWayland (foot does not support X):
swaymsg("exec x11-alacritty")