Repository navigation
fix(scene): the nightly and the browser suite pass on every path - #78
Conversation
Quest-Claim: e5bfe46250aa1a7f
…ly runs the browser suite - The helper passes `--password-store=basic`: Chromium otherwise reads the profile's cookies only once the desktop keyring hands over its key, and a locked keyring with no one to answer its prompt held every network page in Starting (cookies_survive_a_restart on nixos2). - copy_and_cut_reach_the_clipboard reads the X clipboard where CEF copies natively (the X11 GPU path), and the helper's relay elsewhere, through the new Helper::relays_copies. - The nightly render job lets the runner create unprivileged user namespaces, which Chromium's sandbox needs; Ubuntu's AppArmor forbade them, and every helper aborted with SIGTRAP. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 51 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed commit: 6d78325
Base: 2bbdd5b
No actionable findings.
Direction: the clipboard test now observes the actual X11 path while sharing its routing predicate with the helper, and distinct copy/cut payloads avoid accepting an old clipboard value. The runner change permits Chromium's namespace sandbox rather than disabling Chromium sandboxing. The basic cookie store removes the locked-keyring dependency, with an explicit security tradeoff: profile cookies lose keyring-backed encryption and existing encrypted logins need signing in again. That is product behavior, not just a test fix; the README and PR disclose it. Stock Ubuntu sandbox setup and background networking remain identified follow-ups, not fixes delivered here.
Verification: GitHub-only static review of the changes and browser startup/copy paths. GitHub reports Software render, macOS and v4l2loopback camera successful in run 42345881655, at earlier head 63665fa. I did not run the final head's tests, inspect keyring/network traces, exercise an existing profile's migration, or reproduce the X11/Wayland hardware results. COMMENT only, not approval or security certification.
(Written by review (OpenAI))
|
Decisions (maintainer, /quest-complete, 2026-11-07):
(Written by Claude Opus 5.5) |
Chromium's sandbox needs unprivileged user namespaces, which Ubuntu 24.04's AppArmor and a Flatpak deny, so every helper aborted with SIGTRAP there. The maintainer chose to disable it, as OBS does, over lifting the restriction on the CI runner, so the nightly's sysctl step goes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Design change: per the maintainer's decision in #78 (comment), the browser helper now runs without Chromium's sandbox on Linux ( (Written by Claude Opus 5.5) |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Incremental review of 03c845b against base 3ff7dc9, following review 5810654195 at 6d78325.
No new actionable implementation findings in the focused change. The helper now appends --no-sandbox, the nightly sysctl change is removed, and the README explicitly warns about unsandboxed pages. The host module is gated to Linux with the cef feature. This matches the subsequently recorded design decision and supersedes my previous review's statement that Chromium's sandbox remains enabled.
Direction: this is a material product security tradeoff, not just a CI adjustment. Chromium renderer isolation is disabled on every supported Linux host, including hosts where it would otherwise work; a renderer exploit is no longer contained by Chromium's sandbox. Keep the warning visible and treat all loaded page content and its subresources accordingly. The PR description still says the sandbox is kept and lists setup selection as a future decision; update those stale sections to match the committed code and the later design-change comment.
Verification limits: GitHub-only static comparison of the old/current base-relative changes, startup callback, Linux module gating and recorded decision comments. No browser launch, sandbox-status inspection, Ubuntu/Flatpak test or final-head CI execution was performed. The earlier successful sandboxed nightly is not evidence for this new configuration. No security certification or merge approval is implied.
(Written by review (OpenAI))
|
Pick (/quest-complete, maintainer away under /afk, recommended option): ✅ /quest-merge on head 7533590. Both maintainer decisions are applied, and the Codex review counts for this head, since the later merge changed none of the PR's own lines. (Written by Claude Opus 5.5) |

Problem
quest/m0/nightly-green.md: the nightly has failed every night since 2026-11-04, and the browser suite (
rs/moq-studio/tests/browser.rs) did not pass on every path. The latest nightly (run 42235026329, 2026-11-06) still had one failure, the same one as the 11-04 and 11-05 runs. The newv4l2loopback camerajob had not run yet. Three causes, one per known failure:render-swon GitHub's runner: every browser helper aborts with SIGTRAP. The suite first ran in the nightly on 11-04, when moq-dev/studio#8 landed it, and it has never passed there. Chromium's log says:FATAL:setuid_sandbox_host.cc:172 The SUID sandbox helper binary was found, but is not configured correctly. Chromium sandboxes its processes in unprivileged user namespaces. Ubuntu 24.04's AppArmor (kernel.apparmor_restrict_unprivileged_userns=1) lets only programs with a profile create them. So Chromium falls back to the setuidchrome-sandboxthat CEF ships, which is not setuid root, and aborts instead of running unsandboxed. Reproduced on nixos by running the suite in a user namespace that may create no more (max_user_namespacescapped in a parent namespace): same FATAL line, same SIGTRAP.cookies_survive_a_restarton nixos2: no page served over HTTP ever paints. This is not about cookies at all. A plainhttp://127.0.0.1page with a static background fails the same way, whiledata:pages paint. The net log shows the main-frame request enteringURL_REQUEST_START_JOBand never reaching the HTTP cache, which is where Chromium waits for the cookie store to load. Chromium encrypts the profile's cookies with a key it reads from the desktop keyring (org.freedesktop.secrets). nixos2's GNOME keyring is locked (Locked = true; nixos's is unlocked), and its unlock prompt goes to a session with no monitor. So the cookie store never loads, and every network page staysStartinguntil the test's 20 s wait gives up. With--password-store=basicthe same tests pass at once.copy_and_cut_reach_the_clipboardon the X11 GPU path. The test read only the helper's relay (Helper::copied()). Through an X display, CEF copies to the X clipboard itself (moq-dev/studio#59 kept that so page copy handlers apply), so the relay stays empty by design.Approach
--no-sandboxon Linux, so Chromium never needs user namespaces or a setuid-rootchrome-sandbox. It runs every page unsandboxed, as OBS's browser source does. macOS and Windows have no browser sources yet and are unchanged.--password-store=basic, so the profile's cookies never wait on the desktop keyring. This is the store Chromium already uses on a desktop without a keyring, which includes the CI runner.Helper::relays_copies()says whether copies come back throughcopied(). The test reads the X clipboard (aConvertSelectionofCLIPBOARDasUTF8_STRING, throughx11rb, which the studio already depends on) where CEF copies itself, and the relay elsewhere. Each step now copies a different text, tagged with the test's process id, so a copy is told apart from whatever the X clipboard held before. The cut now targets a second text box.Raster::native_copy()is the one place that decides it, for the helper and forrelays_copies().Impact
Startingbehind a locked keyring, for example under auto-login or with no monitor attached. In exchange, the profile's cookies are no longer encrypted with the keyring's key. Chromium's basic store uses a fixed key, so anything that can read the profile directory can read them. README says so. Cookies an existing profile saved under the keyring's key can no longer be decrypted, so those logins need signing in again once.browser::Helper::relays_copies()(Linux). Wire: none. The helper protocol is unchanged.Decisions
Settled by the maintainer in #78 (comment), which replaced this PR's earlier choice to keep the sandbox and lift
kernel.apparmor_restrict_unprivileged_usernson the CI runner (recorded in #78 (comment)).sysctlis no longer needed.--password-store=basic: never block on the keyring. The README says cookies in the studio's browser profile are not keyring-encrypted. A studio profile holds overlay logins, not saved passwords, and the keyring's protection against a process of the same user is nil once it is unlocked.Choices made without asking
Alternatives
Validation
Hosts: nixos (RTX 3070 Ti, GNOME with a monitor, under heavy load from other runners: load 30 to 65, about 37% iowait) and nixos2 (Intel UHD 630 running GNOME with no monitor, plus an RTX 2070), over ssh. Every GPU run used the logged-in GNOME session (
XDG_RUNTIME_DIR=/run/user/1000): Wayland withWAYLAND_DISPLAY=wayland-0, X11 withDISPLAY=:0and the session's XAUTHORITY. Every CPU run unset both, with Mesa's lavapipe asjust render-swsets it. "User namespaces blocked" ran the suite as the same uid in a user namespace whose parent capsuser.max_user_namespacesat 1, so it can create none (unshare --user truefails with ENOSPC), as Ubuntu's AppArmor restriction does to Chromium.binary(browser)--password-store=basicsysctl)relays_copies() == false, printed by a temporaryeprintln!, not committed)sysctl)engine::tests::the_program_reaches_a_relay(decode: Mux(Moq(Stream(NotFound)))), which this PR does not touch; see belowOther checks:
origin/mainat 3ff7dc9 (#76) without conflicts.nix develop --command quest gate just render-swon nixos2 at 03c845b, as CI runs it: 49 + 4 + 10 + 1 tests pass.nix develop --command quest gate just cion nixos2 (Linux) at 03c845b: passes, 278 tests, including both clippy runs (--features cefcovers the test).engine::tests::the_program_reaches_a_relayfailed once on the runner (attempt 1 of run 42350943682): its decoder readStream(NotFound)from the relay 0.6 s in. The PR changes nothing it builds or runs (it runs withoutcef). It passed on attempt 2, injust render-swon nixos2, and 30 of 30 times undercargo nextest run --stress-count 30on nixos2 at 03c845b, so it is a runner-only flake not reproduced here.nix develop --command quest gate just cipasses (278 tests), andnix develop --command quest gate just render-swpasses (49 + 4 + 10 + 1).quest checkandquest check --base origin/mainon macOS: pass. Nothing was built on macOS (disk space).initializewith no monitor (every test hits nextest's 60 s limit). That is the known no-wl_outputhang that quest/m0/cef-headless.md waits on a dummy plug for, not this quest's. No helpers were left behind afterwards.Studio::new(wgpu device setup, before any CEF code), and the same single test took 2.9 s once the host settled. The full Wayland suite passed in two other runs on this head and in one with fix(scene): browser sources under X11 paint only on the X server's GPU #76 merged. At 03c845b, the first blocked CPU run on nixos (load 37, while a build held the cargo lock) timed out every wait at once with no helper failure; the next blocked run, an unblocked run, and a single blocked test all passed within 6 s. No retry or timeout was changed.Follow-ups
engine::tests::the_program_reaches_a_relayflaked on GitHub's runner withStream(NotFound)(see Validation), which can fail the nightly before the browser suite runs. No open PR fixes it.update.googleapis.com,edgedl.me.gvt1.com), the spellcheck dictionary (redirector.gvt1.com), network time (clients2.google.com), andwww.google.com/async/folae. Each one is a privacy leak and a network dependency nobody asked for. Chromium's switches for these, such as--disable-component-updateand--disable-background-networking, plus turning spellcheck off, would stop them, and the suite could then assert that no outside request is made.Review
quest review --new, after the design change), gpt-6.1-sol, medium effort.origin/mainat 167cdca (#77, #79). The local merge had no conflicts (GitHub flagged quest link lists its merge cannot resolve), and the changed lines ofgit diff origin/main...7533590match those ofgit diff 3ff7dc9...03c845bexactly, so the review above covers it.(Written by Claude Opus 5.5)
🤖 Generated with Claude Code