DF-2936 / verdict.json
{ "finding_id": "DF-2936", "status": "reproduced", "reproduced": 1, "impact": "none", "confidence": "certain", "verdict": "module_register_init (sys/kern/kern_module.c:110-116) destroys the module registry entry (module_unload + module_release) when MOD_LOAD fails, but the failure is invisible up the chain: linker_file_sysinit discards SYSINIT errors, linker_load_file marks the file LINKED and returns 0, and kldload(2) reports success. Reproduced in-guest with boom.ko (MOD_LOAD returns 5): kldload rc=0, boom.ko stays loaded while 'kldstat -m boom' says no such module, MOD_UNLOAD is dispatched at load time, and kldunload later runs the module's SYSUNINIT for the long-destroyed module without a second MOD_UNLOAD. Privileged trigger (SYSCAP_NOKLD kldload, or boot-time static-module MOD_LOAD failure); impact ceiling is module-dependent crash/double-free at kldunload via teardown-order inversion, so severity Low, direct impact none.", "exploit_chain": "", "evidence": [ "findings/poc/DF-2936/run.log: KLDLOAD_RC=0 + kldstat lists boom.ko id 8 while 'kldstat -m boom' -> can't find module boom", "findings/poc/DF-2936/run.log dmesg: MOD_LOAD failing -> MOD_UNLOAD dispatched (at load time) -> module_register_init error 5 -> SYSUNINIT runs at kldunload", "findings/poc/DF-2936/run.fix.log (patched kernel #1): module stays registered (Id 325 Refs 1), no MOD_UNLOAD at load, kldunload dispatches MOD_UNLOAD once + SYSUNINIT then registry entry properly released" ], "kernel_refs": [ "sys/kern/kern_module.c:110", "sys/kern/kern_module.c:112", "sys/kern/kern_module.c:113", "sys/kern/kern_module.c:134", "sys/kern/kern_module.c:141", "sys/kern/kern_module.c:177", "sys/kern/kern_linker.c:346", "sys/kern/kern_linker.c:350", "sys/kern/kern_linker.c:505", "sys/kern/kern_linker.c:521", "sys/kern/kern_linker.c:820" ], "poc_changes": "Wrote the KLD from scratch: DECLARE_MODULE with a MOD_LOAD handler returning 5 plus a SYSUNINIT kprintf tag to expose dispatch ordering; Makefile uses SYSDIR=/usr/src/sys and KERNBUILDDIR=/usr/obj/usr/src/sys/X86_64_GENERIC (guest has full kernel obj tree).", "attempts": 2, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64", "runtime_sec": 480, "guest_dirty": 0, "build_cmd": "cd /tmp/df2936 && make", "run_cmd": "kldload ./boom.ko; kldstat; kldstat -m boom; kldunload boom; dmesg | tail", "code_hash": "23f960ac92989d687360b0bd612c4f0db318bea7774728454d5c3905c8c23426", "notes": "Fix validated on rebuilt kernel #1 (make nativekernel + installkernel + reboot): all three baseline bad behaviors gone. Guest reset with-src afterwards. The residual 'kldload reports success despite MOD_LOAD failure' is a kern_linker.c defect (SYSINIT errors cannot propagate) - documented in the finding, out of scope for this file. Reserved IDs DF-2937..DF-2941 unused.", "recommended_fix": "Do not module_unload+module_release in module_register_init's MOD_LOAD-failure path; leave the registration to be dropped by linker_file_unload so the module lifecycle stays symmetric with the linker file lifecycle.", "fix_status": "fixed", "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #1: Thu Sep 3 17:08:57 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "Patched kernel eliminates the registry desync: module remains visible (kldstat -m boom -> Id 325), MOD_UNLOAD dispatched exactly once at kldunload, SYSUNINIT symmetric, registration released by linker_file_unload.", "fix_evidence": "findings/poc/DF-2936/run.fix.log; findings/poc/DF-2936/fix.diff" } |