From 080490d4a741a6336a25db867c73a6c33169aadc Mon Sep 17 00:00:00 2001 From: claude-noether Date: Tue, 5 May 2026 17:48:34 +0000 Subject: [PATCH] firefox-fourier: add user-facing README explaining quick vs proper path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two paths for HW decode through Firefox: 1. Easy: stock Firefox + MOZ_DISABLE_RDD_SANDBOX=1 (sandbox off, defense-in-depth lost — OK for personal-machine use) 2. Proper: apply 0001-rdd-allow-stateless-v4l2-request-api.patch to firefox-150.0.1 source, build (Arch overlay or generic mach build), install. Sandbox stays on; HW decode works. Patch covers all three sandbox gates discovered iter3-5: - Broker: cap-filter widening + /dev/media* enumeration - Seccomp: ioctl magic byte '|' (linux/media.h) README also points at the companion libva-v4l2-request-fourier repo which carries the libva-side fixes (request_fd lifecycle, DPB FFmpeg-semantics, B-slice L1, multi-context safety) needed alongside the Firefox patch. Top-level README cross-link added. Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 2 + firefox-fourier/README.md | 105 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 firefox-fourier/README.md diff --git a/README.md b/README.md index d579729..b1ad322 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,8 @@ Reference history (context, NOT data this campaign anchors to) — orthogonal sc - [`~/src/x11-session-research/phase0_evidence/x11_baseline_2026-05-03/x1_summary.md`](../x11-session-research/phase0_evidence/x11_baseline_2026-05-03/x1_summary.md) — confirms the scanout-plane gap isn't fixable by switching session servers either. mpv-xv {SW,HW} and mpv-gpu {SW,HW} all leave Plane 39 in XRGB8888 throughout. It's a kernel/Mesa/Xorg-DDX gap, not a hardware-decoding gap. **Don't expect this campaign to "fix the video pipeline end-to-end"** — fixing libva-multi-planar fixes the decode side; the scanout-plane question stays open after. - [`~/src/kwin_overlay_subsurface/`](../kwin_overlay_subsurface/) — closed without patch (`phase8_handover.md`); its `feedback_replicate_baseline_first.md` lesson is the discipline that this campaign inherits. +**Firefox patch** for the RDD sandbox: see [`firefox-fourier/README.md`](firefox-fourier/README.md). Two ways to get HW decode working — quick (env var, sandbox off) or proper (patched Firefox, sandbox kept on). Patch is ~50 lines, applies cleanly to firefox-150.0.1 source. + External reference: - Mozilla bug 1833354 / 1965646 (Firefox HW decode on RK3566/RK3588 explicitly needs libva-v4l2-request, not v4l2-m2m). diff --git a/firefox-fourier/README.md b/firefox-fourier/README.md new file mode 100644 index 0000000..4e09d87 --- /dev/null +++ b/firefox-fourier/README.md @@ -0,0 +1,105 @@ +# firefox-fourier — Firefox patch for V4L2 stateless RDD sandbox + +Lets Firefox 150 hardware-decode H.264 video on Linux V4L2-stateless decoders (Rockchip hantro G1/G2, Allwinner cedrus, Sun8i, etc.) **without disabling Firefox's RDD sandbox**. + +## The problem + +Stock Firefox 150 (and earlier) blocks V4L2 stateless decoders inside the RDD process sandbox in two places: + +1. **Broker policy** (`security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp`): `AddV4l2Dependencies()` filters `/dev/video*` by `VIDEO_M2M | VIDEO_M2M_MPLANE` capability. Stateless decoders advertise `CAPTURE_MPLANE + OUTPUT_MPLANE + STREAMING` but typically not M2M, so `/dev/video1` is silently dropped. And `GetRDDPolicy()` never references `/dev/media*` at all — the V4L2 request API (`MEDIA_REQUEST_IOC_QUEUE` et al), required for stateless decode, lives on `/dev/media*` nodes the broker won't open from RDD. + +2. **Seccomp policy** (`security/sandbox/linux/SandboxFilter.cpp`): `RDDSandboxPolicy::EvaluateSyscall`'s ioctl handler allowlists ioctl magic byte `'V'` (V4L2) but not `'|'` (``). Even after broker permits the open, the kernel ioctl path is filtered, returning ENOSYS (silent — Mozilla's seccomp uses `SECCOMP_RET_ERRNO`, not SIGSYS). + +Existing M2M-stateful decoders work (per Mozilla bugs 1833354 / 1965646); stateless never did. + +## Two ways to use HW decode + +### Easy path — env var (sandbox disabled) + +Stock Firefox 150 + this env var: + +```bash +LIBVA_DRIVER_NAME=v4l2_request \ +LIBVA_V4L2_REQUEST_VIDEO_PATH=/dev/video1 \ +LIBVA_V4L2_REQUEST_MEDIA_PATH=/dev/media0 \ +MOZ_DISABLE_RDD_SANDBOX=1 \ +firefox +``` + +`MOZ_DISABLE_RDD_SANDBOX=1` disables the RDD process sandbox entirely. HW decode works because the broker policy isn't enforced; you also lose the RDD process's defense-in-depth boundary. + +OK for personal-machine use; **not** OK for production / hostile environments. + +### Proper path — patched Firefox (sandbox kept on) + +Apply [`0001-rdd-allow-stateless-v4l2-request-api.patch`](0001-rdd-allow-stateless-v4l2-request-api.patch) to firefox-150.0.1 source. + +The patch: +1. Widens `AddV4l2Dependencies` cap filter to admit nodes with `(CAPTURE_MPLANE & OUTPUT_MPLANE & STREAMING)` for stateless decoders. +2. Adds a new `AddV4l2RequestApiDependencies()` that enumerates `/dev/media*` and adds each rdwr to the RDD broker policy. +3. Adds ioctl magic byte `'|'` (linux/media.h) to `RDDSandboxPolicy`'s seccomp allowlist alongside the existing `'V'`. + +Tested on hantro G1 (Rockchip RK3568 / PineTab2) running bbb_1080p30 H.264 with full sandbox enabled. ENETDOWN gone, libva initializes inside RDD, decode reaches end-of-stream. + +## Build instructions (Arch / ALARM) + +The repo ships an Arch-style PKGBUILD overlay against upstream Arch's `firefox` PKGBUILD. See [`PKGBUILD-overlay.md`](PKGBUILD-overlay.md) for the full reproducible recipe — verified working on aarch64 (`firefox 150.0.1-1.1`, single-pass non-PGO build, ~169 MB libxul). + +TL;DR: +```bash +# In an Arch-ish container or host with build deps: +~/firefox-fourier/bootstrap.sh +makepkg --syncdeps --skippgpcheck --noconfirm +sudo pacman -U firefox-150.0.1-1.1-aarch64.pkg.tar.xz +``` + +The `bootstrap.sh` script: +- Fetches upstream Arch firefox PKGBUILD + companion source files +- Drops in the `0001-...patch` as `0005-rdd-allow-stateless-v4l2-request-api.patch` +- Applies five PKGBUILD overlay edits (pkgrel bump to `1.1`, add aarch64 to arch=, wire patch into source=() + prepare(), strip onnxruntime which isn't in ALARM) +- Runs updpkgsums + +Required deps NOT in upstream ALARM extra (install before running bootstrap, see `PKGBUILD-overlay.md`): +- `wasi-libc`, `wasi-compiler-rt`, `wasi-libc++`, `wasi-libc++abi` — pull from upstream Arch x86_64 directly (`arch=any`, identical artifact) since ALARM's are 4 years stale. + +## Build instructions (other distros) + +Generic shape: +```bash +# 1. Get firefox-150.0.1 source from https://archive.mozilla.org/pub/firefox/releases/150.0.1/source/ +# 2. Apply the patch: +cd firefox-150.0.1 +patch -Np1 < /path/to/0001-rdd-allow-stateless-v4l2-request-api.patch +# 3. Build per Mozilla's standard instructions, e.g.: +./mach build && ./mach package +``` + +The patch applies cleanly to firefox-150.0.1 source. It uses unified-diff with line-anchored hunks; minor whitespace drift in newer Firefox versions may need re-anchoring (see `firefox-fourier/PKGBUILD-overlay.md` for how the campaign repo handles this on top of upstream Arch). + +## What the libva-side needs + +The Firefox patch alone isn't sufficient. You also need a working V4L2-stateless libva backend. The companion repo `marfrit/libva-v4l2-request-fourier` carries the libva backend with iter1+iter2+iter3+iter4+iter5 fixes (DPB FFmpeg semantics matching, fresh `request_fd` per frame, B-slice L1 reflist, multi-context safety, debug instrumentation removed). + +```bash +# Clone, build, install +git clone https://git.reauktion.de:2222/marfrit/libva-v4l2-request-fourier.git +cd libva-v4l2-request-fourier +meson setup build --buildtype=release +ninja -C build +sudo cp build/src/v4l2_request_drv_video.so /usr/lib/dri/ +``` + +Then either patched Firefox OR `MOZ_DISABLE_RDD_SANDBOX=1` will work for HW decode. + +## Upstream status + +Not upstreamed at this writing (campaign discipline: no PR/MR without explicit operator instruction). The patch is Mozilla-bug-and-PR-ready in shape and ~50 lines across two files. Whoever picks it up to file with Mozilla should reference the existing `Bug 1833354` and `Bug 1965646` (V4L2-M2M precedent) as related work; this is the V4L2-stateless analogue. + +## File map + +| File | What it is | +|---|---| +| `0001-rdd-allow-stateless-v4l2-request-api.patch` | The patch. Apply with `patch -Np1`. | +| `bootstrap.sh` | Reproducible PKGBUILD overlay script for Arch/ALARM container builds. | +| `PKGBUILD-overlay.md` | Detailed step-by-step build recipe (Arch convention). | +| `README.md` | This file. |