โฌข DragonFlyBSD Kernel Audit
DF-4751 / panic.txt
โ† back to finding โ†“ download raw
# DF-4751 โ€” three captured Fatal trap 12 panics (kernel page faults)
# All from: ./dm_unloadrace 30..45  (create<->remove churn on
# /dev/mapper/control while another thread loops `kldunload dm; kldload dm`)
#
# Run 1 (dirty guest, stock dm.ko):   in-flight ioctl on control dev raced unload
Fatal trap 12: page fault while in kernel mode
cpuid = 5; lapic id = 5
fault virtual address	= 0xffffffff8260848c
fault code		= supervisor read data, page not present
instruction pointer	= 0x8:0xffffffff8062cd6b
kernel: type 12 trap, code=0
Stopped at      dev_dioctl+0x1b:        movl    0xc(%rax),%edi
#  -> dev_dioctl (sys/kern/kern_device.c:237) reading through freed/stale ops

# Run 2 (fresh `vm.sh reset with-src` guest, stock dm.ko): call through zeroed ops
Fatal trap 12: page fault while in kernel mode
cpuid = 4; lapic id = 4
fault virtual address	= 0x0
fault code		= supervisor read instruction, page not present
instruction pointer	= 0x8:0x0
kernel: type 12 trap, code=10
Stopped at      0:
#  -> dispatch through a NULL/freed d_ioctl entry

# Run 3 (fix v1: destroy_dev+re-arm before counter check, patched dm.ko):
# still panics โ€” executing freed module text
fault virtual address	= 0xffffffff82601029
fault code		= supervisor read instruction, page not present
instruction pointer	= 0x8:0xffffffff82601029
Stopped at      -0x7d9fefd7:

# Run 4 (fix v2: + sync_devs(), patched dm.ko): still panics โ€” INSIDE dmioctl
Fatal trap 12: page fault while in kernel mode
cpuid = 4; lapic id = 4
fault virtual address	= 0xffffffff8260078f
fault code		= supervisor read instruction, page not present
instruction pointer	= 0x8:0xffffffff8260078f
Stopped at      dmioctl+0x2bf:  movq    -0x38(%rbp),%rdi
#  => an ioctl already executing dmioctl (sys/dev/disk/dm/device-mapper.c:241)
#     when the linker freed the module text: dev_dioctl holds no reference on
#     si_ops across the dispatch (kern_device.c:258), and destroy_dev()'s
#     revector to dead_dev_ops happens asynchronously in the devfs core
#     (sys/vfs/devfs/devfs_core.c:755-765), so sync_devs() cannot cover
#     already-entered calls.

# Corroborating console noise on EVERY crashing run (counter-check race):
malloc_uninit: 1984 bytes of 'dm' still allocated on cpu 6
#  -> devices/allocations created after the unlocked dm_dev_counter>0 read
#     (device-mapper.c:161) still existed when dmdestroy() ran.