From 7183f16961a6ccba9f26db22f72d6a2295f43103 Mon Sep 17 00:00:00 2001 From: Markus Fritsche Date: Wed, 29 Apr 2026 18:14:36 +0000 Subject: [PATCH] upstream-submissions/firefox-fourier: bugzilla 1969297 comment draft MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Independent firefox-fourier campaign (RK3399 H.264 stateless via rkvdec) overlaps significantly with David's HEVC work outlined in comment #3 — same gfxinfo / FFmpeg / sandbox plumbing. Posting our findings, including a non-obvious sandbox/libudev interaction (Mozilla's OpenAtTrap rejects fd-relative openat used by systemd's chase() inside udev_enumerate_scan_devices), would save duplicate effort. Draft is the proposed comment text plus upload notes. Final submission still needs human review + bugzilla account to post. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../bugzilla-1969297-comment.md | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 upstream-submissions/firefox-fourier/bugzilla-1969297-comment.md diff --git a/upstream-submissions/firefox-fourier/bugzilla-1969297-comment.md b/upstream-submissions/firefox-fourier/bugzilla-1969297-comment.md new file mode 100644 index 000000000..608d2041b --- /dev/null +++ b/upstream-submissions/firefox-fourier/bugzilla-1969297-comment.md @@ -0,0 +1,127 @@ +# bugzilla.mozilla.org bug 1969297 — comment draft + +**Bug**: https://bugzilla.mozilla.org/show_bug.cgi?id=1969297 +**Title**: Implement hardware decoding of h.265/HEVC with v4l2-stateless +**Owner**: david.turner@raspberrypi.com +**Status**: ASSIGNED, Linux/ARM64, Core :: Audio/Video: Playback + +This bug tracks H.265/HEVC stateless. Our work targeted H.264 +stateless on Rockchip RK3399 (Pinebook Pro, mainline kernel, rkvdec +driver) but the plumbing — gfxinfo fourcc detection, libavcodec +hwaccel routing, RDD sandbox carve-out — is identical in shape to +what David outlined in comment #3 ("work that needs doing"). Posting +findings here in case it saves duplicate effort and to flag a sandbox +interaction that any V4L2 stateless implementation will hit. + +--- + +## Comment to post (markdown — Bugzilla renders ` ``` ` blocks) + +Posting independent findings from a parallel firefox-fourier +campaign on Rockchip RK3399 / Pinebook Pro / mainline rkvdec (H.264 +stateless). The plumbing is identical to what David described in +comment #3 for HEVC, so this should fold into bug 1969297 cleanly +once H.265-specific bits are layered on. + +**Patch series** (validated end-to-end, RDD CPU 78% software → 5% +hardware on bbb 1080p30 H.264, default RDD sandbox enabled, no env +overrides): + +1. `widget/gtk/GfxInfo.cpp` — recognize V4L2 stateless fourccs + `S264`, `S265`, `VP9F` alongside the existing stateful set +2. `dom/media/platforms/ffmpeg/FFmpegLibWrapper` — silent + `av_hwdevice_ctx_create` wrapper (suppresses libavutil's stderr + spam when the autodetect tries unsupported devices) +3. `dom/media/platforms/ffmpeg/FFmpegVideoDecoder` — split V4L2 + stateless init (`InitV4L2RequestDecoder`) from stateful + (`InitV4L2Decoder`), with a two-pass codec-name-first / + `hw_configs`-fallback probe so it works against both legacy + (`AV_HWDEVICE_TYPE_DRM`) and modern (`AV_HWDEVICE_TYPE_V4L2REQUEST`, + value 15 in Kwiboo's fork) FFmpeg vintages +4. `modules/libpref/init/StaticPrefList.yaml` — gate behind + `media.ffmpeg.v4l2-request.enabled` (default true) +5. `security/sandbox/linux/{broker/SandboxBrokerPolicyFactory,SandboxFilter}.cpp` + — RDD sandbox extension: `/dev/media*` (driver-matched against + the existing `/dev/video*` walk), MEDIA_IOC_* ioctl family `'|'`, + plus AddTree on `/sys/class`, `/sys/bus`, `/sys/dev/char`, + `/sys/devices/platform`, `/run/udev`, `/etc/udev/udev.conf`, + `/proc/self`, `/dev/dma_heap` + +The series is published on git.reauktion.de/marfrit/marfrit-packages +under `arch/firefox-fourier/patches/`. + +**The non-obvious finding worth surfacing here:** +`udev_enumerate_scan_devices()` returns `-EUNATCH` (-49) inside +RDD's sandbox even with all the broker carve-outs above in place. +Mozilla's `OpenAtTrap` in `security/sandbox/linux/SandboxFilter.cpp` +explicitly rejects fd-relative `openat()`: + +```c +if (fd != AT_FDCWD && path[0] != '/') { + SANDBOX_LOG("unsupported fd-relative openat(%d, \"%s\", 0%o)", fd, path, flags); + return BlockedSyscallTrap(aArgs, nullptr); // returns -ENOSYS +} +``` + +systemd v255+ uses fd-relative `openat()` extensively inside its +`chase()` symlink-resolver for TOCTOU safety, and `chase()` is the +spine of `udev_enumerate_scan_devices`. So libudev fails inside the +sandbox no matter how permissive the broker policy is — the calls +never reach the broker. Confirmed by bpftrace comparison +(sandbox-on vs sandbox-off): full `openat("/")`, `openat("sys")`, +`openat("bus")`, `openat("..")` chase flurry under sandbox-off, +zero `openat()` events under sandbox-on. + +**Workaround we shipped** (in our ffmpeg-v4l2-request fork): a +brute-force fallback inside `libavutil/hwcontext_v4l2request.c`'s +`v4l2request_open_decoder` that enumerates `/dev/media[0..15]` +directly via absolute paths plus `MEDIA_IOC_DEVICE_INFO` and +`MEDIA_IOC_G_TOPOLOGY`, with stat()-based major/minor matching to +resolve `/dev/videoN` paths. The fallback only activates when +libudev's scan returns negative. Same approach Chromium uses in +`media/gpu/v4l2/stateless/` for ChromeOS where the sandbox has the +same constraint. + +This is a libavcodec-side fix, not a Firefox-side one — so it'd be +appropriate either to upstream to FFmpeg (the v4l2_request hwaccel +predates wider sandboxed-Linux deployment, so the libudev assumption +was reasonable at the time) or carry it as a Firefox-bundled +libavcodec patch. + +The alternative — teaching Mozilla's broker to handle fd-relative +`openat()` via `/proc/self/fd//` resolution — would close +the gap for any future libudev consumer in the sandbox, but has +TOCTOU implications I haven't audited; the libavcodec-side bypass +felt cheaper to ship. + +Validation log on RK3399 / Pinebook Pro / mainline rkvdec, default +RDD sandbox, `MOZ_LOG=FFmpegLib:5`: + +``` +V4L2 stateless FFmpeg init successful +Format drm_prime chosen by get_format(). +Format drm_prime requires hwaccel h264_v4l2request initialisation. +libudev probe failed (-2), falling back to brute-force /dev/media* +Using V4L2 media driver rkvdec (brute-force) for S264 +Reinit context to 1920x1088, pix_fmt: drm_prime +``` + +Happy to coordinate / split work / share patches if that helps the +HEVC track. None of patches 1-4 above are H.264-specific; 5 is +codec-agnostic. The libavcodec libudev-bypass has zero codec +coupling. + +--- + +## Notes for upload + +- This is just the comment text. Don't attach the patches — Mozilla + prefers Phabricator (D-numbers) for code review. If the H.264 work + is upstreamed it should go through Phabricator with David tagged. +- Suggest emailing David first (david.turner@raspberrypi.com) before + pasting in the bug, in case he's already half-implemented something + similar — saves a thrash if there's overlap. +- The /proc/self/fd/ trick mentioned at the end is real (and is how + Chromium handles its own broker for some paths). If pursued upstream + in Mozilla, see security/sandbox/linux/broker/SandboxBroker.cpp + RealPath() + SymlinkPermissions() for the existing precedent.