DragonFlyBSD Kernel Audit
DF-2586 / panic.txt
← back to finding ↓ download raw
DF-2586 — panic signature on UNPATCHED #0 baseline (decisive root-only trigger)
==============================================================================

PoC: ./msgbuf_oob_decisive  (sets msg_bufx=msg_size, msg_bufr=msg_size/2+100000
                              via kvm_write, then sysctlbyname("kern.msgbuf",...))

This is the same buggy geometry as the natural post-msgbuf_clear path:
  xindex_modulo == 0, rindex_modulo (= 624272) > msg_size/2 (= 524272)
  n = 424272,  buggy length = n - rindex_modulo = -200000 -> u_int 4294767296 (underflow)

The ~4 GiB length reaches sysctl_old_user which clips it to oldlen (1 MiB) and
copyouts 1 MiB from msg_ptr + rindex_modulo, running past msg_ptr + msg_size
into unmapped kernel memory -> page fault -> KASSERT(obj != NULL) -> panic.

Captured from dfbsd-qemu/boot.log (serial console):

panic: assertion "obj != NULL" failed in vm_object_hold_shared at /usr/src/sys/vm/vm_object.c:330
cpuid = 4
Trace beginning at frame 0xfffff80117927318
vm_object_hold_shared() at vm_object_hold_shared+0x3f 0xffffffff809ab9bf
vm_object_hold_shared() at vm_object_hold_shared+0x3f 0xffffffff809ab9bf
vm_fault() at vm_fault+0x408 0xffffffff8099e0b8
trap_pfault() at trap_pfault+0x9a 0xffffffff80bd52ca
trap() at trap+0x17c 0xffffffff80bd5bcc
calltrap() at calltrap+0x9 0xffffffff80b991fa
--- trap 000000000000000c, rip = ffffffff80bcaeaa, rsp = fffff80117927730, rbp = fffff80117927768 ---
std_copyout() at std_copyout+0x15a 0xffffffff80bcaeaa
Debugger("panic")
Stopped at      Debugger+0x7c:  movb    $0,0xbdaf09(%rip)
db>

trap 0xc = page fault raised INSIDE std_copyout's source-side read.