Public bug reported:
# bubblewrap 0.9.0-1ubuntu0.2 (CVE-2026-87766): bind-mount destination
mis-resolves relative symlinks containing "..", breaking flatpak apps
## Summary
The security patch in **bubblewrap 0.9.0-1ubuntu0.2** (noble-security,
2026-09-14, CVE-2026-87766) introduced a regression in destination-path
resolution: when a bind-mount **destination** traverses a relative symlink
whose target contains `..`, bubblewrap resolves it incorrectly (one `..` is
effectively dropped). It then attempts the mount at a non-existent path and
fails with `ENOENT`.
This breaks Flatpak apps whose manifest grants a per-app `xdg-run` directory
with `:create` (e.g. Discord IPC / `xdg-run/app/com.discordapp.Discord:create`).
Such apps no longer start at all.
Regression is present in `0.9.0-1ubuntu0.2` and absent in
`0.9.0-1ubuntu0.1`.
## Environment
- OS: Linux Mint 22.3 (Zena), based on Ubuntu 24.04 (noble), amd64
- Kernel: 6.14.0-37-generic
- bubblewrap: `0.9.0-1ubuntu0.2` (noble-security), `/usr/bin/bwrap` non-setuid
(unprivileged user namespaces; `kernel.unprivileged_userns_clone=1`,
`kernel.apparmor_restrict_unprivileged_userns=0`)
- Flatpak: 1.14.6
- Affected example: `com.heroicgameslauncher.hgl` (Heroic Games Launcher)
## Regression source
`/usr/share/doc/bubblewrap/changelog.Debian.gz`:
```
bubblewrap (0.9.0-1ubuntu0.2) noble-security; urgency=medium
* SECURITY UPDATE: Improper link resolution during sandbox setup
- debian/patches/CVE-2026-87766-1.patch: Import safe_openat() from crun
in chroot_realpath.c, meson.build, safe_openat.c, and utils.h
- debian/patches/CVE-2026-87766-2.patch: Create and resolve destinations
without following symlinks, and reject mount operations on symlink
destinations in bubblewrap.c
- CVE-2026-87766
-- Kyle Kernick <[email protected]> Mon, 14 Sep 2026 12:44:27 -0600
```
The `CVE-2026-87766-2.patch` rewriting of destination creation/resolution
mis-handles relative symlinks that contain `..`, which Flatpak legitimately
relies on (see below).
## Steps to reproduce
A self-contained reproducer that needs neither Flatpak nor any app is attached
(`bubblewrap-symlink-dest-repro.sh`). Core of it:
```sh
R=$(mktemp -d)
mkdir -p "$R/root/run/user/1000" "$R/root/run/flatpak/app" "$R/root/bin"
"$R/src"
ln -sfn ../../flatpak/app "$R/root/run/user/1000/app" # same link Flatpak
creates
ln -sfn /usr/bin/true "$R/root/bin/true"
bwrap --bind "$R/root" / \
--bind "$R/src" /run/user/1000/app/com.discordapp.Discord \
-- /bin/true
```
Real-world reproduction (Flatpak):
```sh
flatpak run --branch=stable --arch=x86_64 --command=true
com.heroicgameslauncher.hgl
```
## Expected result
bwrap follows the symlink `/run/user/1000/app -> ../../flatpak/app` while
resolving the destination. The symlink lives in directory `/run/user/1000`,
so the target resolves to `/run/flatpak/app`; the destination is therefore
```
/newroot/run/flatpak/app/com.discordapp.Discord
```
which exists (bwrap creates it / Flatpak's `:create` grant), and the bind
mount succeeds.
## Actual result
Both the minimal reproducer and the real Flatpak run fail:
```
bwrap: Can't bind mount /oldroot/.../src on
/newroot/run/user/flatpak/app/com.discordapp.Discord: Unable to mount source on
destination: No such file or directory
```
Note the bogus path component `/run/user/flatpak/...` (one `..` was dropped:
the correct path is `/run/flatpak/...`).
## strace evidence
```
readlink("/newroot/run/user", ..., 4095) = -1 EINVAL
readlink("/newroot/run/user/1000", ..., 4095) = -1 EINVAL
readlink("/newroot/run/user/1000/app", "../../flatpak/app", 4095) = 17
readlink("/newroot/run/user/flatpak", ..., 4095) = -1 ENOENT
mount("/oldroot/.../src",
"/newroot/run/user/flatpak/app/com.discordapp.Discord",
NULL, MS_BIND|MS_REC|MS_SILENT, NULL) = -1 ENOENT
```
bwrap resolves `../../flatpak/app` relative to the wrong base directory:
after `readlink(".../1000/app") = "../../flatpak/app"` it should walk up to
`/newroot/run` and append `flatpak/app`, yielding `/newroot/run/flatpak/app`.
Instead it reaches `/newroot/run/user/flatpak`, i.e. it applies one `..` less
than expected.
## Root cause / analysis
1. Flatpak's per-app runtime directory
`/run/user/<uid>/.flatpak/<app-id>/xdg-run/` contains relative symlinks
such as `app -> ../../flatpak/app`, `bus -> ../../flatpak/bus`,
`doc -> ../../flatpak/doc`, `.flatpak -> ../../flatpak/.flatpak`, etc.
This directory is bind-mounted to `/run/user/<uid>` inside the sandbox, so
inside the sandbox `/run/user/<uid>/app` is that relative symlink.
2. Flatpak emits the operation
`--bind /run/user/1000/app/com.discordapp.Discord
/run/user/1000/app/com.discordapp.Discord`
(source == destination; the `:create` grant).
3. The new destination resolution code added by
`CVE-2026-87766-2.patch` resolves the destination path component by
component. On encountering the relative symlink it computes the result
incorrectly, producing `/run/user/flatpak/app/...` instead of
`/run/flatpak/app/...`.
4. `mount(2)` is then called with a destination that does not exist, and
fails with `ENOENT`, aborting sandbox setup.
The symptom is specific to destinations that traverse a **relative symlink
containing `..`**; simple destinations and absolute symlinks are unaffected.
That is why e.g. `org.flatpak.Builder` still launches (it has no `xdg-run/app`
grant), while Heroic fails.
## Impact
Users on noble (and derivatives such as Linux Mint 22.x) who updated
bubblewrap to `0.9.0-1ubuntu0.2` can no longer launch affected Flatpak apps.
Impact is `bwrap` aborting before exec, i.e. complete failure to start, not a
degraded sandbox.
## Workaround
Replace the offending symlink in the app's runtime directory with a real
directory (Flatpak prints a harmless warning and proceeds):
```sh
D=/run/user/$UID/.flatpak/com.heroicgameslauncher.hgl/xdg-run
rm "$D/app"
mkdir "$D/app"
```
Verified: `flatpak run ... --command=true com.heroicgameslauncher.hgl` then
exits 0. The symlinks are recreated by Flatpak at login, so the workaround may
need to be repeated. A cleaner temporary workaround is downgrading:
```sh
sudo apt install bubblewrap=0.9.0-1ubuntu0.1
```
## Suggested fix
Correct the destination component resolution introduced in
`CVE-2026-87766-2.patch` so that relative symlink targets are resolved
correctly with respect to the symlink's containing directory (each `..` pops
one component of the resolved path). Absolute symlinks and symlink-free paths
already behave correctly.
## Attachments
- `bubblewrap-symlink-dest-repro.sh` — minimal reproducer (no Flatpak
needed)
** Affects: bubblewrap (Ubuntu)
Importance: Undecided
Status: New
** Attachment added: "bubblewrap-symlink-dest-repro.sh"
https://bugs.launchpad.net/bugs/2167649/+attachment/6000912/+files/bubblewrap-symlink-dest-repro.sh
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2167649
Title:
bubblewrap 0.9.0-1ubuntu0.2 (CVE-2026-87766): bind-mount destination
mis-resolves relative symlinks with "..", breaks flatpak apps
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/bubblewrap/+bug/2167649/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs