Skip to content

fix: set the sandbox helper Chromium actually reads setuid - #587

Merged
omartelo merged 2 commits into
mainfrom
fix/sandbox-helper-beside-libcef
Sep 11, 2026
Merged

omartelo merged 2 commits into
mainfrom
fix/sandbox-helper-beside-libcef

Conversation

@omartelo

Copy link
Copy Markdown
Collaborator

A user's lich 0.49.0 on Ubuntu opened no window: every launch ended in signal: trace/breakpoint trap (core dumped) about a second in. Chromium looks for its setuid sandbox helper in cef/, beside libcef.so, not beside lich-shell. The deb, rpm and AUR packages installed a root-owned 4755 copy beside lich-shell and left the one in cef/ at 755, so on a desktop that denies unprivileged user namespaces (Ubuntu's AppArmor policy) Chromium fell back to the helper, found it unusable and aborted. chmod 4755 on cef/chrome-sandbox is what got that user's window open.

Which file Chromium reads

Measured without AppArmor by forcing the fallback: lich-shell --ozone-platform=headless --disable-namespace-sandbox on the installed AUR package exits 133, and the FATAL reads "You need to make sure that /usr/lib/lich/shell/cef/chrome-sandbox is owned by root and has mode 4755", with a root 4755 copy sitting beside lich-shell the whole time.

Packaging

nfpm cannot mark one file of the window's tree setuid: a second contents entry for cef/chrome-sandbox fails with content collision, and the archlinux packager drops a setuid bit read from the source file (it writes int64(fs.FileMode), and Go keeps setuid outside the Unix permission bits). The mode now comes from postinstall.sh; pacman runs that only on a first install, so it is wired to archlinux.scripts.postupgrade as well. The stray copy is gone from all three formats, and the package managers remove it on upgrade. The trade-off, written into the ceiling: rpm -V and pacman -Qkk report a mode mismatch on the helper.

The AUR package() chmods the copy in cef/ instead of installing a second one.

lich-shell

sandbox_available() checked the helper beside the executable, so it could count a machine as sandboxed when its only usable helper was one Chromium never reads. It now checks cef/chrome-sandbox, pinned by a test.

Not in this PR, each on its own branch: the user-namespace probe only tries unshare, which Ubuntu's AppArmor allows before denying the id maps, so a tarball install on Ubuntu still skips --no-sandbox; and the window's stderr, where this FATAL was printed, never reaches lich.log or lich rage.

Test plan

  • cargo fmt --check, cargo clippy --release --all-targets -- -D warnings and cargo test --release (13 passed) in shell/
  • No Go or frontend code touched
  • Packages built with nfpm from main and from this branch around stub binaries, installed in containers with dpkg (Debian 12), rpm (Fedora 42) and pacman (Arch). main: chrome-sandbox 4755 and cef/chrome-sandbox 755. Upgrade to this branch: stray copy removed, cef/chrome-sandbox 4755 root. Fresh install: 4755 root
  • The PKGBUILD package() under fakeroot: cef/chrome-sandbox is -rwsr-xr-x root root in the archive
  • install.sh on clean Debian 12, Fedora 42 and Arch containers installs the v0.49.0 window and lich doctor finds it
  • The next release's deb opens its window on an Ubuntu desktop with AppArmor

Chromium looks for chrome-sandbox in cef/, beside libcef.so, not beside
lich-shell. The deb, rpm and AUR packages installed a root-owned 4755 copy
beside lich-shell and left the one in cef/ at 755, so on a desktop that
denies unprivileged user namespaces (Ubuntu's AppArmor policy) Chromium
found an unusable helper and aborted the window with SIGTRAP.

nfpm cannot mark a file inside the window's tree setuid: a second entry for
the same destination collides, and the archlinux packager drops a setuid bit
read from the source file. The mode is set from the install script instead,
wired to post_upgrade for pacman too. The AUR PKGBUILD chmods the copy in
cef/, and lich-shell's --no-sandbox decision checks that same file.
@omartelo
omartelo merged commit 96485b0 into main Sep 11, 2026
7 checks passed
@omartelo
omartelo deleted the fix/sandbox-helper-beside-libcef branch September 11, 2026 16:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant