iter5 amendment: extend Firefox sandbox patch to UtilitySandboxPolicy
Real-world YouTube avc1 playback on the iter5-G binary surfaced a seccomp violation (`syscall 29`, `0x80047C05` = `MEDIA_IOC_REQUEST_ALLOC`) that the autonomous Phase 7G test missed because seccomp returns ENOSYS silently and Firefox falls back to SW decode. Two distinct gaps: - patch-sync drift: campaign 113-line patch (broker+RDD-seccomp) had drifted from container 84-line patch (broker only); iter5-G shipped with the broker fix but no RDD seccomp fix. - coverage gap: FF150 routes VAAPI to the Utility process; iter3's RDD-only seccomp allowlist never covered Utility. Combined patch now hits three gates across two files (six hunks): - broker: cap-filter widen + AddV4l2RequestApiDependencies + RDD wire-in - RDD seccomp: kMediaType allow alongside existing kVideoType - Utility seccomp: new __NR_ioctl override mirroring RDD's allowlist Build: incremental `makepkg -e` on existing iter5-G object tree took 2:22 wall vs the 2h27m from-scratch alternative. phase8_iteration5_close.md: appended amendment section with verdict- gap analysis, patch breakdown, deploy-pending status. firefox-fourier/README.md: rewrote "The problem" from 2 gates to 3 (broker + RDD seccomp + Utility seccomp); patch summary now explains the six hunks. Pending: pkg deploy to ohm + lsof /dev/video1 verification once network route to ohm is restored. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -124,3 +124,77 @@ Outstanding for upstream-readiness: cap_pool race fix (~30 lines for iter6), msy
|
||||
- **Track B:** "≥30s of bbb_1080p30 without segfault — OR root cause documented as upstream issue with operator-actionable workaround." ✓ HIT (31s stream pos, 0 segfaults; mpv handles cap_pool race via SW fallback gracefully; cap_pool race documented as iter6+ candidate).
|
||||
|
||||
**Joint success:** all four tracks independently verifiable on the same iter5-end driver build (sha256 `4bed52ec5d44b389...`). Phase 7 verified each. Phase 5 sonnet review caveats addressed. iter5 closes GREEN.
|
||||
|
||||
---
|
||||
|
||||
## Iter5 amendment (2026-05-05, same-day post-close) — Track F seccomp gap
|
||||
|
||||
**Trigger.** First real-world use of the iter5-G Firefox binary on ohm — playing a YouTube avc1 stream with `LIBVA_DRIVER_NAME=v4l2_request` env vars + sandbox enabled — emitted seccomp violations:
|
||||
|
||||
```
|
||||
Sandbox: seccomp sandbox violation: pid <N>, tid <N>, syscall 29, ...
|
||||
```
|
||||
|
||||
Decoded `0x80047C05` = `_IOR('|', 0x05, int)` = `MEDIA_IOC_REQUEST_ALLOC`. Two distinct gaps surfaced:
|
||||
|
||||
### Gap 1: Track G "GREEN" verdict was structural-only
|
||||
The Phase 7G test measured "0 ENETDOWN, 0 EINVAL, 538 RDD ProcessDecode events, 22.3s mTime in 35s wall" on a `--headless --screenshot` autonomous run with synthetic playback — but never confirmed VAAPI bytes actually flowed through `/dev/video1`. The seccomp filter was returning `ENOSYS` to Firefox's media stack silently (`SECCOMP_RET_ERRNO`, not `SIGSYS`), so Firefox fell back to SW decode and the autonomous test couldn't tell the difference.
|
||||
|
||||
### Gap 2: Patch-sync drift between campaign repo and container
|
||||
Campaign repo's `firefox-fourier/0001-rdd-allow-stateless-v4l2-request-api.patch` (113 lines, broker + RDD seccomp) had drifted from the container's `/build/aur/firefox-fourier/0005-rdd-allow-stateless-v4l2-request-api.patch` (84 lines, broker only). The iter5-G build used the stale 84-line patch — the iter3 RDD seccomp fix never made it into the iter5-G binary at all.
|
||||
|
||||
### Gap 3: VAAPI work moved from RDD to Utility process
|
||||
Even with the RDD seccomp restored, FF150 routes VAAPI decode through the **Utility process**, not RDD. `UtilitySandboxPolicy::EvaluateSyscall` falls through to `SandboxPolicyCommon` for `__NR_ioctl`, which doesn't allow `'|'` (or `'V'`, or `'d'`, or `'b'`). The iter3 patch needed extending to mirror the RDD ioctl allowlist into Utility.
|
||||
|
||||
### Amendment patch (combined, 160 lines)
|
||||
|
||||
`firefox-fourier/0001-rdd-allow-stateless-v4l2-request-api.patch` regenerated as combined broker + RDD-seccomp + Utility-seccomp:
|
||||
|
||||
- Broker: 3 hunks (cap-filter widen + `AddV4l2RequestApiDependencies` + RDD wire-in) — unchanged from prior 84-line container patch.
|
||||
- RDD seccomp: 2 hunks (`kMediaType` constant + `.ElseIf` allow) — restored from campaign 113-line patch.
|
||||
- Utility seccomp: 1 hunk (entire `case __NR_ioctl:` override mirroring RDD's allowlist) — **new in iter5 amendment**.
|
||||
|
||||
Authored as `claude-noether <claude@reauktion.de>`.
|
||||
|
||||
### Build approach — incremental, ~2:22 wall
|
||||
|
||||
Per operator's standard flow: edit src/ in place, `makepkg -e --skippgpcheck`. Container src tree from iter5-G already had broker hunks applied; only the seccomp hunks needed manual application. Then `makepkg -e` skipped extract+prepare and re-ran build/package on existing object cache.
|
||||
|
||||
Result:
|
||||
- pkg: `firefox-150.0.1-1.1-aarch64.pkg.tar.xz` (65.5 MB, sha256 `675bbc7dd0a187ee8baefef5c3b36d15c64919cd80edf725e29c23f2675ed4a8`)
|
||||
- Build wall time: 19:01 → 19:03:22 = **~2:22** (vs from-scratch ~2h27m for iter5-G)
|
||||
- Saved: ~2h25m by reusing existing ccache + object tree
|
||||
|
||||
Backed up prior pkg as `firefox-150.0.1-1.1-aarch64.pkg.tar.xz.iter5g`.
|
||||
|
||||
### Verification (pending — deploy to ohm)
|
||||
|
||||
Definitive HW-decode test (couldn't run pre-amendment because seccomp blocked the path silently):
|
||||
```
|
||||
LIBVA_DRIVER_NAME=v4l2_request \
|
||||
LIBVA_V4L2_REQUEST_VIDEO_PATH=/dev/video1 \
|
||||
LIBVA_V4L2_REQUEST_MEDIA_PATH=/dev/media0 \
|
||||
firefox <video-url> &
|
||||
sleep 8
|
||||
sudo lsof /dev/video1 /dev/media0
|
||||
# expect: a Firefox-spawned Utility process holding both nodes
|
||||
```
|
||||
|
||||
If `lsof` shows the Utility process on `/dev/video1` during avc1 playback → Track F closes properly. If empty → another sandbox layer to chase.
|
||||
|
||||
### Lessons captured
|
||||
|
||||
The Track G "GREEN" verdict was right by its own success criterion ("libxul materially smaller, firefox --version works") but the criterion didn't include "actually does HW decode in production use." Lesson for Phase 1 lock: criteria for sandbox/release-build tracks should include **end-user playback verification with `lsof` proof of device handle ownership**, not just structural metrics.
|
||||
|
||||
Adding to memory: `feedback_seccomp_silent_enosys.md` already covers the silent-ENOSYS pattern; this episode reinforces it. The patch-sync-drift between campaign repo and container is a process bug — fixed by syncing the combined patch back to container in this amendment, but the underlying mismatch (PKGBUILD numbers patches `0005-...` while campaign uses `0001-...`) remains. Tolerable for a personal-machine campaign; would need normalizing for upstream.
|
||||
|
||||
### Status post-amendment
|
||||
|
||||
| Element | State |
|
||||
|---|---|
|
||||
| Combined 160-line patch | Authored, in campaign repo + container 0005-... |
|
||||
| Container src/ tree | Broker (from iter5-G prepare) + seccomp (manually patched in iter5 amend) |
|
||||
| Built pkg | `675bbc7d…` on boltzmann:/tmp/, awaiting deploy to ohm |
|
||||
| ohm deploy | Pending operator-side scp (vpn route closed at amendment author time) |
|
||||
| HW-decode lsof verification | Pending |
|
||||
| Campaign git commit | Pending |
|
||||
|
||||
Reference in New Issue
Block a user