DF-2216 / verdict.json
{ "finding_id": "DF-2216", "status": "reproduced", "reproduced": 1, "impact": "denial_of_service", "confidence": "certain", "verdict": "Reproduced with the verbatim production dmi_match() compiled kernel-resident (harness kernel DFV22X; runtime kldload of drm GPFs on this guest). Over 16384 calls mixing the strcmp-match arm (returns true) and the fall-through arm (returns false), the M_KENV malloc accounting grows by exactly 1703936 bytes = 104 bytes per call (101 requested + slab quantization); the paired kgetenv+kfreeenv control loop returns to 0 delta and the fix-2216 patched variant (kfreeenv on every path, extracted from fix.diff-applied bytes in the same kernel) also returns to 0 delta. Each of the four kenv arms leaks 104 bytes in a single-shot sweep. The leak is real, per-call, on both return paths, and unbounded; impact is kernel-heap exhaustion (DoS) reachable only through the sole in-tree caller radeon_atom_pick_dig_encoder on DCE3.2 hardware via display hotplug/mode-set events, so practical severity stays Low. No memory-corruption or info-disclosure primitive exists (pure availability), so no privesc chain is possible; fix validated A/B in the same kernel.", "exploit_chain": "", "evidence": "run.log lines DF2216 CONTROL/BASELINE/FIXED/VERDICT: control delta=0, baseline delta=1703936 (104/call), per-arm single calls +104 each, fixed delta=0; run.first_meterbug.log documents the first-iteration meter artifact (ks_loosememuse double count) that was corrected by summing only ks_use[].memuse as the kernel itself does (kern_slaballoc.c:451)", "kernel_refs": ["sys/dev/drm/linux_dmi.c:44", "sys/dev/drm/linux_dmi.c:49", "sys/dev/drm/linux_dmi.c:54", "sys/dev/drm/linux_dmi.c:59", "sys/kern/kern_environment.c:229", "sys/kern/kern_environment.c:242", "sys/kern/kern_environment.c:369", "sys/kern/kern_slaballoc.c:1135", "sys/dev/drm/radeon/atombios_encoders.c:2251"], "poc_changes": "Rebuilt the finding PoC sketch as a verbatim-code kernel-compiled rig (rig_head/mid/tail.c + build.sh): sha256-gated verbatim inclusion of linux_dmi.c, kenv boundary fabricated with a 100-char value, deterministic in-kernel meter over malloc_type ks_use[].memuse; first iteration double-counted ks_loosememuse (up-only fold counter, never decremented on free) and was corrected after the +131104 = 131072+32 artifact identified the fold", "attempts": 2, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #1: Tue Oct 20 23:24:18 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/DFV22X x86_64", "runtime_sec": 15, "guest_dirty": 0, "build_cmd": "sh /root/poc/df22x/build.sh (nativekernel KERNCONF=DFV22X, rig compiled kernel-resident)", "run_cmd": "sh /root/poc/df22x/run.sh (sysctl kern.df22x_run=1 as root on the DFV22X harness kernel)", "code_hash": "c646506a8cbeda4dcb0ade737617a507fac86cf3d381b7df14e25aad5ab10fae", "notes": "Batch verification run with DF-2220/2223/2224 in the same harness kernel; leak bytes persist until reboot and the guest was reset with-src before return. Reachability on the audit guest is nil (no radeon GPU); the defect is proven through the verbatim code path with real dynamic kenv. Practical ceiling: kenv heap drain of ~104 bytes per display event on DCE3.2 systems", "recommended_fix": "Free the kgetenv buffer with kfreeenv(s) on every path of all four arms of dmi_match (see fix.diff)", "fix_status": "fixed", "fix_validated": 1, "fix_diff": "fix.diff" } |