DragonFlyBSD Kernel Audit
DF-0817 / panic.txt
← back to finding ↓ download raw
DF-0817 panic signature (unpatched 6.5-DEVELOPMENT #0 kernel, KVM guest)
=========================================================================

Trigger: as unprivileged uid 1001 (maxx), opened /mnt/h2t (a hammer2 mount
backed by an 8GB image whose live FREEMAP_NODE block at dev offset 0xc0000
had 4 bytes corrupted, breaking its CRC) and issued HAMMER2IOC_BULKFREE_SCAN.

The bulkfree scan walked the corrupted freemap tree, hit a CRC failure on
the FREEMAP_NODE chain, and then took the buggy error path at
sys/vfs/hammer2/hammer2_bulkfree.c:1050 which dereferences
`live_chain->error` while `live_chain == NULL`.

--- kernel serial log (dfbsd-qemu/boot.log) -------------------------------

hammer2: bulkfree buf=1M
hammer2: pass 0000000000000000-0000000200000000 (all media)
hammer2_bulkfree: Scanning DATA
hammer2_bulkfree: Scanning LOCAL
bulkfree lastdrop 1 0
hammer2_bulkfree - range 0000000014400c00-0000000200000000
chain 00000000000c000f.05 meth=50 CHECK FAIL                          <-- CRC fail on FREEMAP_NODE block @ dev 0xc0000, type=5
freemap.icrc 40cf4bb0 icrc32 7a7209dc (32768)                         <-- stored CRC != recomputed CRC
dio 0xfffff80118e66480 buf 00000000000c0000,65536 bdata 0xfffff80073116000/0xfffff80073116000
Fatal user address access from kernel mode from df0817 at ffffffff8096410e


Fatal trap 12: page fault while in kernel mode
cpuid = 2; lapic id = 2
fault virtual address	= 0x170                                      <-- NULL + offsetof(hammer2_chain_t, error)
fault code		= supervisor read data, page not present
instruction pointer	= 0x8:0xffffffff8096410e
stack pointer	        = 0x10:0xfffff8011912b348
frame pointer	        = 0x10:0xfffff8011912b538
code segment		= base 0x0, limit 0xfffff, type 0x1b
			= DPL 0, pres 1, long 0, def32 0, gran 1
processor eflags	= interrupt enabled, resume, IOPL = 0
current process		= 1485                                     <-- the df0817 PoC process
current thread          = pri 10
kernel: type 12 trap, code=0

CPU2 stopping CPUs: 0x0000003b
 stopped
Stopped at      hammer2_bulkfree_pass+0xdbe:    movl    0x170(%rax),%edi  <-- reads *(NULL + 0x170) = live_chain->error

(h2_bulkfree_sync is inlined into hammer2_bulkfree_pass by gcc; this is
 the access at hammer2_bulkfree.c:1050 — `hammer2_error_str(live_chain->error)`
 with live_chain == NULL.)