fix(browser): a root caller operates the seat's store as the seat, and setup clears inherited setgid (DIVE-4348) - #64
Merged
Conversation
…d setup clears inherited setgid (DIVE-4348) The dashboard reaches every browser verb through shelld's whitelist, sudo -n /usr/local/bin/5dive browser ... — root with SUDO_USER=claude. _seat resolved that to claude but _audit compared the store owner to id -u (0), so every verb but setup exited 77 and GET /sites read every box as unavailable. Root now re-executes as the seat via runuser. Separately /var/lib/5dive is 2750 on every box; a directory made under it inherits setgid and GNU chmod 700 preserves that bit, so setup left every seat store 2700 and the audit (want 700) refused. setup now uses the 5-digit chmod form, which clears it. Both measured on exact-swallow 2026-09-12. browser 1.1.0 -> 1.1.1. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What was broken (measured on exact-swallow, 2026-09-12, while executing DIVE-4348 steps 1–3)
1. The dashboard's only path refused every verb but
setup.GET /server/browser/sites→execOnServer→ shelld/shell/exec→sudo -n /usr/local/bin/5dive browser ls(root,SUDO_USER=claude)._seatresolves toclaude, but_auditcompares the store owner toid -u(0):So the API returned
available:falseon every box, and DIVE-4239's tile could never list a site. Both grades of #164 read the exec path against a mock.2. Every seat store was 2700, and the audit wants 700.
/var/lib/5diveis2750on every box; a directory made under it inherits setgid; GNUchmod 700PRESERVES that bit on a directory. Sosetupleftbrowser-profiles/<seat>at2700:The fix
SUDO_USERre-executes as that seat (runuser -u) before any store is touched, for every verb exceptsetup(root's by design — it chowns).runuserkeeps the environment and sets HOME/USER to the seat's (verified on the control plane).setupuses the 5-digit chmod form (00711root,00700seat,00700site), which clears an inherited setgid. The audit stays strict and still never repairs.1.1.0 → 1.1.1; CHANGES entry.Verified
tests/browser_plugin_unit.sh: 199 passed, 0 failed (6 new arms T2c2–T2c7: the setgid control + the 5-digit clear, and the static guards for the re-exec and forsetupstaying root).chmod g-s) turned5dive browser lsas claude from exit 77 to exit 0 — the mechanism in (2). The root-path fix (1) is verified on that box in DIVE-4348's body once the fixed binary is on it.Rows: DIVE-4348 (the recipe that found it).
🤖 Generated with Claude Code