DragonFlyBSD Kernel Audit
DF-2662 / panic.txt
← back to finding ↓ download raw
DF-2662 crash evidence — captured from the QEMU serial console (vm.sh log)
after running the DF-2661 trigger on kernel B (= stock + DF-2661 fix +
EIO injector; the DF-2661 assert is fixed, so this crash is purely DF-2662).

Transcript (serial console, round 1 of trigger_df2661.sh):

  hammer2_mount: devstr="/dev/vn2@DATA"
  hammer2_mount: "/dev/vn2": no recovery needed
  hammer2_mount: hmp=0xfffff80118320000 pmp=0xfffff80118b00000
  HAMMER2: VOLDATA DUMP
  HAMMER2: INITIATE SPANs
  hammer2_chain_load_data: I/O error 000000000240040a: 5

  Fatal trap 12: page fault while in kernel mode
  cpuid = 2; lapic id = 2
  fault virtual address	= 0x90
  fault code		= supervisor read data, page not present
  instruction pointer	= 0x8:0xffffffff80967933
  stack pointer	        = 0x10:0xfffff801182dd870
  frame pointer	        = 0x10:0xfffff801182dd8d0
  code segment		= base 0x0, limit 0xfffff, type 0x1b
  			= DPL 0, pres 1, long 1, def32 0, gran 1
  processor eflags	= interrupt enabled, resume, IOPL = 0
  current process	= Idle
  current thread          = pri 12
  kernel: type 12 trap, code=0

  CPU2 stopping CPUs: 0x0000003b
   stopped
  Stopped at      hammer2_autodmsg+0x273: movq    0x90(%r15),%rax
  db>

Disassembly of the faulting instruction (kernel B, /boot/kernel/kernel,
saved in disasm_autodmsg.txt):

  ffffffff80967924: callq  kdmsg_msg_alloc        <- rmsg alloc (LNK_SPAN|CREATE)
  ffffffff80967929: lea    0x100(%r15),%rsi        <- ripdata->filename
  ffffffff80967933: mov    0x90(%r15),%rax         <- FAULT: ripdata->meta.pfs_clid
  ffffffff80967945: mov    0x98(%r15),%rax         <- ripdata->meta.pfs_fsid
  ffffffff80967953: mov    0xa0(%r15),%rax         <- ripdata->meta.pfs_type

r15 == 0 (fault VA 0x90).  r15 is `ripdata = &chain->data->ipdata`
(hammer2_iocom.c:313) => chain->data == NULL.

Offset check against struct hammer2_inode_data (ipdata.meta.pfs_clid at
0x90 / pfs_fsid 0x98 / pfs_type 0xa0 / filename 0x100) matches exactly.

Root cause: hammer2_update_spans() walks the super-root's PFS directory
asynchronously after mount (from hammer2_autodmsg()'s "VOLDATA DUMP"
branch, iocom.c:237).  hammer2_chain_lookup() returned an INODE chain
whose hammer2_chain_load_data() FAILED (EIO injected on data_off
0x240040a = a PFS inode under the super-root): chain->error = EIO,
chain->data = NULL — and update_spans never checks either before
dereferencing chain->data->ipdata.