⬢ DragonFlyBSD Kernel Audit
DF-4472 / run.log
← back to finding ↓ download raw
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.