METEORSVIDEO ioctl allows unprivileged user to set arbitrary physical DMA target address
Summary
METEORSVIDEO ioctl at bktr_core.c:1396-1402 stores user-supplied video->addr (32-bit physical address) into bktr->video with ZERO priv check and ZERO address validation. Every RISC DMA builder (rgb_vbi_prog:2670, rgb_prog:2840, yuvpack_prog:2995, yuv422_prog:3113, yuv12_prog:3214) uses it as bt848 bus-master DMA write target. Device nodes created mode 0444 (world-readable) at bktr_os.c:325, ioctls not gated by open mode. Any unprivileged user: open /dev/bktr0 O_RDONLY -> METEORSVIDEO addr=phys -> METEORCAPTUR continuous -> bt848 writes video frames to arbitrary physical memory. No suser/priv_check/caps_priv_check anywhere in bktr_core.c. Arbitrary physical-memory write primitive -> reliable root escalation. Fix: caps_priv_check_td(td, SYSCAP_RESTRICTEDROOT) when addr!=0.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1215 Β· 26 files| File | Type | Description | Size | |
|---|---|---|---|---|
| poc_rig.c | trigger-source | decisive PoC: unpriv METEORSVIDEO via production video_ioctl (rig) | 2.0 KB | view raw |
| bktrig.c | trigger-source | KLD rig dispatching to production video_ioctl from bktr.ko | 3.5 KB | view raw |
| bktrig_nodep.c | trigger-source | nodep rig variant for the fix-built kernel | 3.5 KB | view raw |
| poc_physdma.c | trigger-source | original hardware trigger PoC (real bt848 only) | 1.4 KB | view raw |
| Makefile.kld | build-script | rig module Makefile (bsd.kmod.mk) | 256 B | β download |
| rig_setup.sh | build-script | exact guest rig setup (build+load, root) | 1.9 KB | view raw |
| build.sh | build-script | userland PoC build | 154 B | view raw |
| run.sh | run-script | decisive unprivileged run | 162 B | view raw |
| build.log | build-log | combined decisive build record | 1.7 KB | view raw |
| run.log | run-log | combined decisive baseline run (ENOENT + rig attack accepted) | 1.5 KB | view raw |
| baseline_run.log | run-log | original PoC: /dev/bktr0 ENOENT (no bt848 PCI) | 261 B | view raw |
| rig_build.log | build-log | rig module compile/link (U video_ioctl) | 4.4 KB | view raw |
| rig_load.log | run-log | rig load; production bktr.ko auto-loaded; video_ioctl=0xffffffff82606190 | 431 B | view raw |
| baseline_rig_run.log | run-log | BASELINE ATTACK: uid=1001 METEORSVIDEO rc=0, readback 0x100000 | 278 B | view raw |
| fix.diff | suggested-fix | caps_priv_check_td gate on METEORSVIDEO when addr!=0 | 1.1 KB | view raw |
| fix_build.log | build-log | FULL nativekernel DF1215FIX build (rc=0, 315s) | 5.6 MB | β download |
| fix_install.log | build-log | installkernel into /boot/kernel | 80.4 KB | view raw |
| fixed_rig_load.log | run-log | rig on DF1215FIX (video_ioctl kernel global, fixed) | 314 B | view raw |
| fixed_rig_run.log | run-log | FIXED: uid=1001 gets EPERM; addr=0 path intact | 267 B | view raw |
| fixed_root_run.log | run-log | root contrast on fixed kernel: redirect still allowed | 530 B | view raw |
| dmesg_fixed.txt | environment | fixed-kernel dmesg (boot-stable) | 13.6 KB | view raw |
| kldstat_fixed.txt | environment | kldstat -v on fixed kernel | 5.6 KB | view raw |
| env.txt | environment | guest env: unames, PCI inventory, module state, symbols | 2.1 KB | view raw |
| fix_build_pass1.log | build-log | pass-1 combined fix build (superseded by behavioral A/B) | 5.6 MB | β download |
| VERDICT.md | verdict | full narrative verdict | 4.6 KB | β raw |
| verdict.json | verdict | machine verdict (persist_poc/persist_fix input) | 5.8 KB | view raw |
DF-1215 VERDICT -- inconclusive (impact: none; confidence: certain)
Bottom line
Authorization bypass REPRODUCED with unmodified production code: a KLD rig (/dev/bktrig0 -> production video_ioctl() from the stock unfixed /boot/kernel/bktr.ko, synthetic post-attach softc) let uid=1001 METEORSVIDEO an arbitrary physical DMA target (addr=0x100000 -> rc=0, METEORGVIDEO readback 0x100000) -- the exact field every bt848 RISC DMA builder consumes (bktr_core.c:2670/2841/2996/3114/3215) -- with no privilege check anywhere in the driver (nodes 0444, bktr_os.c:325). The corruption SINK (bt848 bus-master DMA write) cannot fire on this guest: QEMU has no Brooktree PCI device (pciconf: none; /dev/bktr0 ENOENT, re-verified), so no panic/uid0 is demonstrable here -- hence inconclusive rather than reproduced, and not not_reproduced (nothing failed; the bypass half did reproduce). On real bt848 hardware the stored target makes METEORCAPTUR DMA attacker-deterministic bytes to arbitrary physical memory -> ucred/function-pointer overwrite -> uid=0 (no SMAP/SMEP/KASLR). Fix VALIDATED behaviorally this run: DF1215FIX kernel (GENERIC+device bktr+fix.diff, nativekernel rc=0 315s) -> identical rig+user gets EPERM for addr!=0, addr=0 path intact, root retains redirect.
Reproduce
build: guest: (maxx) cc -O2 -Wall -o poc_physdma poc_physdma.c; cc -O2 -Wall -o poc_rig poc_rig.c; (root /root/bktrig[/nodep]) make -m /usr/src/share/mk SYSDIR=/usr/src/sys -- see rig_setup.sh / build.sh run: guest: (root once) kldload /root/bktrig/bktrig.ko; (maxx) ./poc_rig -- see run.sh
Evidence in this pack
run.log (combined decisive run); baseline_rig_run.log (THE ATTACK: uid=1001 METEORSVIDEO addr=0x100000 rc=0, readback 0x100000); rig_load.log (production bktr.ko loaded, video_ioctl=0xffffffff82606190); baseline_run.log (/dev/bktr0 ENOENT, no bt848 PCI); fixed_rig_run.log (EPERM on fixed kernel); fixed_root_run.log (root retains redirect); fix_build.log/fix_install.log (DF1215FIX rc=0); VERDICT.md for the full narrative
Kernel references
sys/dev/video/bktr/bktr_core.c:1202sys/dev/video/bktr/bktr_core.c:1396sys/dev/video/bktr/bktr_core.c:1398sys/dev/video/bktr/bktr_core.c:1502sys/dev/video/bktr/bktr_core.c:2670sys/dev/video/bktr/bktr_core.c:2841sys/dev/video/bktr/bktr_core.c:2996sys/dev/video/bktr/bktr_core.c:3114sys/dev/video/bktr/bktr_core.c:3215sys/dev/video/bktr/bktr_os.c:325sys/dev/video/bktr/bktr_os.c:615sys/dev/video/bktr/bktr_os.c:643sys/conf/files:1916
Exploit chain
On real bt848 hardware: open /dev/bktr0 O_RDONLY (mode 0444, any user) -> ioctl METEORSVIDEO addr=
Fix validation (A/B)
Gate METEORSVIDEO redirect on caps_priv_check_td(td, SYSCAP_RESTRICTEDROOT) when video->addr != 0 (fix.diff; behaviorally validated); additionally consider 0600 device nodes and an auth check on METEORCAPTUR.
Baseline vs post-fix behavior is in run.log / run_fixed*.log (userspace) or panic.txt/hang.txt vs run_fixed_kernel.log (kernel); the identical rig ran both sides.
poc_changes
poc_physdma.c unchanged. Added poc_rig.c + KLD rig (bktrig.c / bktrig_nodep.c): production video_ioctl is a global symbol so the rig dispatches /dev/bktrig0 ioctls to it on a synthetic zeroed bktr_softc (bigbuf!=0 = post-attach state); fixed include path (dev/video/bktr/ioctl_bt848.h), added
Guest: DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64 Attempts: 6 Runtime: ~1380s
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
Fix verification
fixedDF1215FIX kernel (X86_64_GENERIC + device bktr + fix.diff; nativekernel rc=0 in 315s, -Werror clean; installkernel rc=0; boot-stable, kern.version #0 Sun Oct 11 21:52:44 UTC 2026). Identical rig + identical uid=1001 attack: METEORSVIDEO addr=0x100000 -> EPERM (baseline: rc=0 acceptance via unfixed production bktr.ko), METEORGVIDEO readback 0x0, addr=0 kernel-buffer mode still rc=0, root retains redirect (rc=0, readback 0x100000). Bad behavior GONE, legitimate use preserved.
fix_run.log (combined A/B); fixed_rig_run.log (EPERM); fixed_root_run.log (root contrast); fix_build.log (full nativekernel log, rc=0); fix_install.log; fixed_rig_load.log (video_ioctl kernel global 0xffffffff80830790 on DF1215FIX); patched-source gate at sys/dev/video/bktr/bktr_core.c:1409
Confirmed kernel references
- sys/dev/video/bktr/bktr_core.c:1202
- sys/dev/video/bktr/bktr_core.c:1396
- sys/dev/video/bktr/bktr_core.c:1398
- sys/dev/video/bktr/bktr_core.c:1502
- sys/dev/video/bktr/bktr_core.c:2670
- sys/dev/video/bktr/bktr_core.c:2841
- sys/dev/video/bktr/bktr_core.c:2996
- sys/dev/video/bktr/bktr_core.c:3114
- sys/dev/video/bktr/bktr_core.c:3215
- sys/dev/video/bktr/bktr_os.c:325
- sys/dev/video/bktr/bktr_os.c:615
- sys/dev/video/bktr/bktr_os.c:643
- sys/conf/files:1916
Detail
Exploit chain
On real bt848 hardware: open /dev/bktr0 O_RDONLY (mode 0444, any user) -> ioctl METEORSVIDEO addr=
Evidence (decisive lines)
run.log (combined decisive run); baseline_rig_run.log (THE ATTACK: uid=1001 METEORSVIDEO addr=0x100000 rc=0, readback 0x100000); rig_load.log (production bktr.ko loaded, video_ioctl=0xffffffff82606190); baseline_run.log (/dev/bktr0 ENOENT, no bt848 PCI); fixed_rig_run.log (EPERM on fixed kernel); fixed_root_run.log (root retains redirect); fix_build.log/fix_install.log (DF1215FIX rc=0); VERDICT.md for the full narrative
PoC changes
poc_physdma.c unchanged. Added poc_rig.c + KLD rig (bktrig.c / bktrig_nodep.c): production video_ioctl is a global symbol so the rig dispatches /dev/bktrig0 ioctls to it on a synthetic zeroed bktr_softc (bigbuf!=0 = post-attach state); fixed include path (dev/video/bktr/ioctl_bt848.h), added
Verified recommended fix
Gate METEORSVIDEO redirect on caps_priv_check_td(td, SYSCAP_RESTRICTEDROOT) when video->addr != 0 (fix.diff; behaviorally validated); additionally consider 0600 device nodes and an auth check on METEORCAPTUR.
Verdict
Authorization bypass REPRODUCED with unmodified production code: a KLD rig (/dev/bktrig0 -> production video_ioctl() from the stock unfixed /boot/kernel/bktr.ko, synthetic post-attach softc) let uid=1001 METEORSVIDEO an arbitrary physical DMA target (addr=0x100000 -> rc=0, METEORGVIDEO readback 0x100000) -- the exact field every bt848 RISC DMA builder consumes (bktr_core.c:2670/2841/2996/3114/3215) -- with no privilege check anywhere in the driver (nodes 0444, bktr_os.c:325). The corruption SINK (bt848 bus-master DMA write) cannot fire on this guest: QEMU has no Brooktree PCI device (pciconf: none; /dev/bktr0 ENOENT, re-verified), so no panic/uid0 is demonstrable here -- hence inconclusive rather than reproduced, and not not_reproduced (nothing failed; the bypass half did reproduce). On real bt848 hardware the stored target makes METEORCAPTUR DMA attacker-deterministic bytes to arbitrary physical memory -> ucred/function-pointer overwrite -> uid=0 (no SMAP/SMEP/KASLR). Fix VALIDATED behaviorally this run: DF1215FIX kernel (GENERIC+device bktr+fix.diff, nativekernel rc=0 315s) -> identical rig+user gets EPERM for addr!=0, addr=0 path intact, root retains redirect.
No comments yet.