DF-4472 / run.log
DF-4472 baseline (unpatched kernel, dm.ko from clean /usr/src) -- groom mode, 50 rounds
Guest: DragonFly dfbsd 6.5-DEVELOPMENT #0 Thu Jul 2 06:02:54 UTC 2026 (X86_64_GENERIC)
Module: dm.ko kldload-ed, /dev/mapper/control 0640 root:operator.
$ kldload dm
$ cd /tmp && cc -o dm_uninit_type dm_uninit_type.c -lprop -lpthread && ./dm_uninit_type 50
[*] create 'df4472dev': rv=17 (File exists)
round 0: reload#1 rv=0, inactive entries=1 (loaded)
round 1: reload#1 rv=0, inactive entries=1 (loaded)
round 2: reload#1 rv=0, inactive entries=1 (loaded)
round 3: reload#1 rv=0, inactive entries=1 (loaded)
round 4: reload#1 rv=0, inactive entries=1 (loaded)
... 25/50 rounds (stale-match=0 destroy-proof=25) last rv2=2
... 50/50 rounds (stale-match=0 destroy-proof=50) last rv2=2
[*] groom done: rounds=50 stale-match=0 destroy-proof=50
(An earlier 200-round run gave destroy-proof=200/200 the same way:
... 25/200 rounds (stale-match=0 destroy-proof=25) last rv2=2
... 200/200 rounds (stale-match=0 destroy-proof=200) last rv2=2
[*] groom done: rounds=200 stale-match=0 destroy-proof=200)
Interpretation (see VERDICT.md): every typeless reload returned ENOENT (rv2=2)
AND wiped the 1-entry inactive table loaded by reload#1 of the same round.
dm_ioctl.c has exactly one ENOENT return after the dm_table_destroy at :722-723
-- the target-lookup failure at :741 -- so dm_target_lookup(type) executed with
the uninitialized `type' on 100% of rounds. rv2=2 is ENOENT.
--------------------------------------------------------------------------------
DF-4472 baseline (unpatched) -- flood mode: 8 threads x 800 malformed reloads
$ ./dm_uninit_type --flood 8 800
(ssh session died; guest went down -- serial console / boot.log:)
dm: could not autoload module for target <garbage bytes> (x20 lines)
Fatal user address access from kernel mode from dm_uninit_type at ffffffff809d75cc
Fatal trap 12: page fault while in kernel mode
cpuid = 4; lapic id = 4
fault virtual address = 0x8
fault code = supervisor read data, page not present
instruction pointer = 0x8:0xffffffff809d75cc
stack pointer = 0x10:0xfffff80117b3d620
frame pointer = 0x10:0xfffff80117b3d638
current process = 1196
kernel: type 12 trap, code=0
CPU4 stopping CPUs: 0x0000002f
Stopped at strcmp+0xc: movzbl (%rdi,%rax,1),%edx
db>
=> Guest down (vm.sh status: down). Full serial excerpt in panic.txt.
--------------------------------------------------------------------------------
DF-4472 fix validation (patched dm.ko built from fix.diff):
$ cd /usr/src/sys/dev/disk/dm && patch -N < /tmp/fix.diff (8 hunks OK)
$ make (-Werror clean, dm.ko)
$ kldload /tmp/dm_fixed.ko
$ ./dm_uninit_type 50
[*] create 'df4472dev': rv=0 (ok)
round 0: reload#1 rv=0, inactive entries=1 (loaded)
round 1: reload#1 rv=0, inactive entries=1 (loaded)
round 2: reload#1 rv=0, inactive entries=1 (loaded)
round 3: reload#1 rv=0, inactive entries=1 (loaded)
round 4: reload#1 rv=0, inactive entries=1 (loaded)
... 25/50 rounds (stale-match=0 destroy-proof=0) last rv2=22
... 50/50 rounds (stale-match=0 destroy-proof=0) last rv2=22
[*] groom done: rounds=50 stale-match=0 destroy-proof=0
=> rv2=22 (EINVAL) every round: the missing-"type" entry is now rejected
before any lookup; no wild read. destroy-proof=0 because the EINVAL path
is a different errno than the wild-lookup ENOENT.
$ ./dm_uninit_type --flood 8 800
[*] flood: 8 threads x 800 malformed reloads -- expect possible panic (wild strcmp)
[t2] done rv=22 (Invalid argument)
[t6] done rv=22 (Invalid argument)
[t4] done rv=22 (Invalid argument)
[*] flood finished without panic
FLOOD-EXIT=0
$ vm.sh status -> up
=> No panic on the patched module; guest healthy.