hst: add pipewire flag
All checks were successful
Test / Create distribution (push) Successful in 36s
Test / Sandbox (push) Successful in 2m36s
Test / Sandbox (race detector) (push) Successful in 4m47s
Test / Hpkg (push) Successful in 4m55s
Test / Hakurei (push) Successful in 4m59s
Test / Hakurei (race detector) (push) Successful in 6m26s
Test / Flake checks (push) Successful in 1m31s

These are for #26. None of them are implemented yet. This fixes up test cases for the change to happen. Existing source code and JSON configuration continue to have the same effect. Existing flags get its EPulse bit replaced by EPipeWire.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
Ophestra 2025-12-07 22:33:45 +09:00
parent 093e30c788
commit 1931b54600
Signed by: cat
SSH Key Fingerprint: SHA256:gQ67O0enBZ7UdZypgtspB2FDM1g3GVw8nX0XSdcFw8Q
9 changed files with 47 additions and 18 deletions

View File

@ -32,7 +32,7 @@ var (
PID: 0xbeef,
ShimPID: 0xcafe,
Config: &hst.Config{
Enablements: hst.NewEnablements(hst.EWayland | hst.EPulse),
Enablements: hst.NewEnablements(hst.EWayland | hst.EPipeWire),
Identity: 1,
Container: &hst.ContainerConfig{
Shell: check.MustAbs("/bin/sh"),
@ -62,7 +62,7 @@ func TestPrintShowInstance(t *testing.T) {
{"nil", nil, nil, false, false, "Error: invalid configuration!\n\n", false},
{"config", nil, hst.Template(), false, false, `App
Identity: 9 (org.chromium.Chromium)
Enablements: wayland, dbus, pulseaudio
Enablements: wayland, dbus, pipewire, pulseaudio
Groups: video, dialout, plugdev
Flags: multiarch, compat, devel, userns, net, abstract, tty, mapuid, device, runtime, tmpdir
Home: /data/data/org.chromium.Chromium
@ -159,7 +159,7 @@ Session bus
App
Identity: 9 (org.chromium.Chromium)
Enablements: wayland, dbus, pulseaudio
Enablements: wayland, dbus, pipewire, pulseaudio
Groups: video, dialout, plugdev
Flags: multiarch, compat, devel, userns, net, abstract, tty, mapuid, device, runtime, tmpdir
Home: /data/data/org.chromium.Chromium
@ -215,6 +215,7 @@ App
"enablements": {
"wayland": true,
"dbus": true,
"pipewire": true,
"pulse": true
},
"session_bus": {
@ -366,6 +367,7 @@ App
"enablements": {
"wayland": true,
"dbus": true,
"pipewire": true,
"pulse": true
},
"session_bus": {
@ -564,6 +566,7 @@ func TestPrintPs(t *testing.T) {
"enablements": {
"wayland": true,
"dbus": true,
"pipewire": true,
"pulse": true
},
"session_bus": {
@ -715,7 +718,7 @@ func TestPrintPs(t *testing.T) {
"shim_pid": 51966,
"enablements": {
"wayland": true,
"pulse": true
"pipewire": true
},
"identity": 1,
"groups": null,

View File

@ -23,9 +23,20 @@ type Config struct {
// System D-Bus proxy configuration.
// If set to nil, system bus proxy is disabled.
SystemBus *BusConfig `json:"system_bus,omitempty"`
// Direct access to wayland socket, no attempt is made to attach security-context-v1
// and the bare socket is made available to the container.
//
// This option is unsupported and most likely enables full control over the Wayland
// session. Do not set this to true unless you are sure you know what you are doing.
DirectWayland bool `json:"direct_wayland,omitempty"`
// Direct access to PulseAudio socket, no attempt is made to establish pipewire-pulse
// server via a PipeWire socket with a SecurityContext attached and the bare socket
// is made available to the container.
//
// This option is unsupported and enables arbitrary code execution as the PulseAudio
// server. Do not set this to true, this is insecure under any configuration.
DirectPulse bool `json:"direct_pulse,omitempty"`
// Extra acl updates to perform before setuid.
ExtraPerms []ExtraPermConfig `json:"extra_perms,omitempty"`

View File

@ -17,6 +17,8 @@ const (
EX11
// EDBus enables the per-container xdg-dbus-proxy daemon.
EDBus
// EPipeWire exposes a pipewire pathname socket via SecurityContext.
EPipeWire
// EPulse copies the PulseAudio cookie to [hst.PrivateTmp] and exposes the PulseAudio socket.
EPulse
@ -35,6 +37,8 @@ func (e Enablement) String() string {
return "x11"
case EDBus:
return "dbus"
case EPipeWire:
return "pipewire"
case EPulse:
return "pulseaudio"
default:
@ -62,10 +66,11 @@ type Enablements Enablement
// enablementsJSON is the [json] representation of [Enablements].
type enablementsJSON = struct {
Wayland bool `json:"wayland,omitempty"`
X11 bool `json:"x11,omitempty"`
DBus bool `json:"dbus,omitempty"`
Pulse bool `json:"pulse,omitempty"`
Wayland bool `json:"wayland,omitempty"`
X11 bool `json:"x11,omitempty"`
DBus bool `json:"dbus,omitempty"`
PipeWire bool `json:"pipewire,omitempty"`
Pulse bool `json:"pulse,omitempty"`
}
// Unwrap returns the underlying [Enablement].
@ -81,10 +86,11 @@ func (e *Enablements) MarshalJSON() ([]byte, error) {
return nil, syscall.EINVAL
}
return json.Marshal(&enablementsJSON{
Wayland: Enablement(*e)&EWayland != 0,
X11: Enablement(*e)&EX11 != 0,
DBus: Enablement(*e)&EDBus != 0,
Pulse: Enablement(*e)&EPulse != 0,
Wayland: Enablement(*e)&EWayland != 0,
X11: Enablement(*e)&EX11 != 0,
DBus: Enablement(*e)&EDBus != 0,
PipeWire: Enablement(*e)&EPipeWire != 0,
Pulse: Enablement(*e)&EPulse != 0,
})
}
@ -108,6 +114,9 @@ func (e *Enablements) UnmarshalJSON(data []byte) error {
if v.DBus {
ve |= EDBus
}
if v.PipeWire {
ve |= EPipeWire
}
if v.Pulse {
ve |= EPulse
}

View File

@ -32,6 +32,7 @@ func TestEnablementString(t *testing.T) {
{hst.EWayland | hst.EDBus | hst.EPulse, "wayland, dbus, pulseaudio"},
{hst.EX11 | hst.EDBus | hst.EPulse, "x11, dbus, pulseaudio"},
{hst.EWayland | hst.EX11 | hst.EDBus | hst.EPulse, "wayland, x11, dbus, pulseaudio"},
{hst.EM - 1, "wayland, x11, dbus, pipewire, pulseaudio"},
{1 << 5, "e20"},
{1 << 6, "e40"},
@ -62,8 +63,9 @@ func TestEnablements(t *testing.T) {
{"wayland", hst.NewEnablements(hst.EWayland), `{"wayland":true}`, `{"value":{"wayland":true},"magic":3236757504}`},
{"x11", hst.NewEnablements(hst.EX11), `{"x11":true}`, `{"value":{"x11":true},"magic":3236757504}`},
{"dbus", hst.NewEnablements(hst.EDBus), `{"dbus":true}`, `{"value":{"dbus":true},"magic":3236757504}`},
{"pipewire", hst.NewEnablements(hst.EPipeWire), `{"pipewire":true}`, `{"value":{"pipewire":true},"magic":3236757504}`},
{"pulse", hst.NewEnablements(hst.EPulse), `{"pulse":true}`, `{"value":{"pulse":true},"magic":3236757504}`},
{"all", hst.NewEnablements(hst.EWayland | hst.EX11 | hst.EDBus | hst.EPulse), `{"wayland":true,"x11":true,"dbus":true,"pulse":true}`, `{"value":{"wayland":true,"x11":true,"dbus":true,"pulse":true},"magic":3236757504}`},
{"all", hst.NewEnablements(hst.EM - 1), `{"wayland":true,"x11":true,"dbus":true,"pipewire":true,"pulse":true}`, `{"value":{"wayland":true,"x11":true,"dbus":true,"pipewire":true,"pulse":true},"magic":3236757504}`},
}
for _, tc := range testCases {

View File

@ -70,7 +70,7 @@ func Template() *Config {
return &Config{
ID: "org.chromium.Chromium",
Enablements: NewEnablements(EWayland | EDBus | EPulse),
Enablements: NewEnablements(EWayland | EDBus | EPipeWire | EPulse),
SessionBus: &BusConfig{
See: nil,

View File

@ -105,6 +105,7 @@ func TestTemplate(t *testing.T) {
"enablements": {
"wayland": true,
"dbus": true,
"pipewire": true,
"pulse": true
},
"session_bus": {

View File

@ -172,6 +172,8 @@ type outcomeStateSys struct {
// Copied from [hst.Config]. Safe for read by spWaylandOp.toSystem only.
directWayland bool
// Copied from [hst.Config]. Safe for read by spPulseOp.toSystem only.
directPulse bool
// Copied header from [hst.Config]. Safe for read by spFilesystemOp.toSystem only.
extraPerms []hst.ExtraPermConfig
// Copied address from [hst.Config]. Safe for read by spDBusOp.toSystem only.
@ -185,7 +187,8 @@ type outcomeStateSys struct {
func (s *outcomeState) newSys(config *hst.Config, sys *system.I) *outcomeStateSys {
return &outcomeStateSys{
appId: config.ID, et: config.Enablements.Unwrap(),
directWayland: config.DirectWayland, extraPerms: config.ExtraPerms,
directWayland: config.DirectWayland, directPulse: config.DirectPulse,
extraPerms: config.ExtraPerms,
sessionBus: config.SessionBus, systemBus: config.SystemBus,
sys: sys, outcomeState: s,
}

View File

@ -47,9 +47,9 @@ func TestEntryData(t *testing.T) {
{"inconsistent enablement", "\x00\xff\xca\xfe\x00\x00\xff\x00" + templateStateGob, NewTemplateState(), &hst.AppError{
Step: "validate state enablement", Err: os.ErrInvalid,
Msg: "state entry aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa has unexpected enablement byte 0xd, 0xff"}},
Msg: "state entry aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa has unexpected enablement byte 0x1d, 0xff"}},
{"template", "\x00\xff\xca\xfe\x00\x00\x0d\xf2" + templateStateGob, NewTemplateState(), nil},
{"template", "\x00\xff\xca\xfe\x00\x00\x1d\xe2" + templateStateGob, NewTemplateState(), nil},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {

View File

@ -34,7 +34,7 @@ func TestEntryHeader(t *testing.T) {
{"success high", [entryHeaderSize]byte{0x00, 0xff, 0xca, 0xfe, 0x00, 0x00,
0xff, 0x00}, 0xff, nil},
{"success", [entryHeaderSize]byte{0x00, 0xff, 0xca, 0xfe, 0x00, 0x00,
0x09, 0xf6}, hst.EWayland | hst.EPulse, nil},
0x09, 0xf6}, hst.EWayland | hst.EPipeWire, nil},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {