# Escaping Linux Sandboxes via PipeWire (CVE-2026-5674)

PipeWire's PulseAudio compat layer never validates the auth cookie, allows module loading by default, and dlopen()s arbitrary LADSPA plugin paths, letting a sandboxed Flatpak app escape to full user context.

- Payout: Research
- Severity: high
- Program: PipeWire
- Found by (vendor credit): Johann Rehberger (embracethered.com)
- Write-up by: Johann Rehberger
- Disclosed: 2026-07-30
- CVE: CVE-2026-5674
- Write-up quality: 8/10
- Original: https://embracethered.com/blog/posts/2026/pipewire-flatpak-linux-sandbox-escape-cve-2026-5674/
- Library page: https://bugbountylibrary.com/r/blog%3Aembracethered-com-blog-posts-2026-pipewire-flatpak-linux-sandbox-escape-cve-2026-5674
- Tags: area:os domain:desktop domain:oss impact:privesc impact:rce kind:research platform:research sev:high technique:chained technique:source-review vuln:auth-bypass vuln:misconfiguration vuln:rce vuln:sandbox-escape

**Target:** PipeWire PulseAudio compatibility server (pulse-server.c) reachable via --socket=pulseaudio
**Root cause:** PA_COMMAND_AUTH only checks cookie length (256 bytes) and sets authenticated=true without comparing the value; module loading defaults to true; module-ladspa-sink dlopen()s the attacker-supplied plugin= path with no allowlist.
**Steps:**
1. Write malicious .so with __attribute__((constructor)) to a host-visible path like `/tmp/payload.so`
2. Connect to the PulseAudio socket exposed by --socket=pulseaudio
3. Send `PA_COMMAND_AUTH` with 256 bytes of garbage (any value accepted)
4. Send `PA_COMMAND_LOAD_MODULE` with `module-ladspa-sink plugin=/tmp/payload.so`
5. PipeWire (outside sandbox) calls `dlopen(path, RTLD_NOW)`; constructor runs in user context
6. Verify by writing `~/PIPEWIRE_RCE_PROOF.txt` and launching gnome-calculator on host
**How found:** Automated research pipeline (Claude Code + Opus 4.6) flagged the code; author manually reviewed pulse-server.c, noticed the cookie variable is read then never referenced and authenticated=true is set unconditionally, checked git history showing behavior since the compat layer was written, then traced LOAD_MODULE to module-ladspa-sink's dlopen() with no path validation.
**Exploitation:** A Flatpak app with only pulseaudio socket and a host-writable path (e.g. /tmp) writes a malicious LADSPA .so, authenticates with garbage cookie, loads module-ladspa-sink pointing at the .so; PipeWire's dlopen executes the ELF constructor outside the sandbox, giving full user-context code execution (file read, app launch, credential access).
**Escalation:** Chained three independent weaknesses (broken auth, default module loading, unvalidated dlopen path); same primitive applies to Docker containers with PulseAudio socket mounted.
**Insight:** When auditing compat/reimplementation layers (PipeWire vs PulseAudio), diff behavior against the original: a length check that discards the value and sets authenticated=true is a tell. Then follow any 'authenticated' client's reachable commands (LOAD_MODULE) to sinks that call dlopen()/exec on user-controlled paths.
