⬢ DragonFlyBSD Kernel Audit
DF-4474 / run.log
← back to finding ↓ download raw
DF-4474 baseline (unpatched kernel, dm.ko from clean /usr/src)
Guest: DragonFly dfbsd 6.5-DEVELOPMENT #0 Thu Jul 2 06:02:54 UTC 2026 (X86_64_GENERIC)

Run 1 -- 100 failed reloads (fat cmd_data: 400 x ~300B) + 20000 deps + 20000 status:
$ vmstat -m | grep -E "^ +temp"
               temp     470    333K    0    390M     5.50K
$ ./dm_errleak 100 20000
---- vmstat -m (after failed reloads) ----
               temp     570    337K    0    390M    91.5K
---- vmstat -m (after deps/status) ----
               temp     570    337K    0    390M     404K

Run 2 -- another 100 failed reloads (same parameters):
               temp     670    341K    0    390M     490K

Run 3 -- 60 failed reloads with 4000-entry cmd_data trees (~1.4MB XML each):
$ sysctl vm.stats.vm.v_free_count
vm.stats.vm.v_free_count: 821767
$ ./dm_errleak 60 0 4000 >/dev/null 2>&1
$ sysctl vm.stats.vm.v_free_count
vm.stats.vm.v_free_count: 746491          (-75276 pages = ~294MB consumed)
$ ./dm_errleak 0 60000 1 >/dev/null 2>&1   (unrelated churn afterwards)
$ vmstat -m | grep -E "^ +temp"
               temp     740    344K    0    390M     1.96M
$ sysctl vm.stats.vm.v_free_count
vm.stats.vm.v_free_count: 768188          (still ~208MB below the start)

Observations:
- M_TEMP InUse grows by EXACTLY +1 object (~40B) per failed reload, is
  permanent and accumulates linearly: 470 -> 570 -> 670 -> 740 tracks the
  100+100+60 failed reloads one-for-one. Never drops.
- The leaked object is the prop_array_iterator created at dm_ioctl.c:708
  (M_TEMP calloc, sys/libprop/prop_array.c:520) -- the ENOENT returns at
  :713/:741 never release it. The iterator also takes a reference on the
  cmd_data array (prop_array.c:525 prop_object_retain(pa)), and with large
  cmd_data payloads ~3.5MB of kernel memory stays consumed per failed call
  (page-accounting evidence above; M_TEMP zone accounting under-reports the
  retained tree).
- deps/status ENOENT paths (dm_ioctl.c:602->606, :895->899) leak the created
  cmd_array (code-evident; per-object zone accounting masks it).

--------------------------------------------------------------------------------
DF-4474 fix validation (patched dm.ko built from fix.diff):

$ vmstat -m | grep -E "^ +temp"
               temp     470    333K    0    390M     (baseline after fresh boot)
$ ./dm_errleak 200 30000 200
---- vmstat -m (after failed reloads) ----
               temp     470    333K    0    390M     659K
---- vmstat -m (after deps/status) ----
               temp     470    333K    0    390M    1.10M
$ sysctl vm.stats.vm.v_free_count
vm.stats.vm.v_free_count: 826089

=> InUse unchanged at 470 after 200 failed reloads + 60000 deps/status ENOENT
   calls: ZERO leaked objects (baseline grew +1 per failed reload). Free-page
   count healthy. Leak closed.