DragonFlyBSD Kernel Audit
DF-2830 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-2830",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "leak",
  "confidence": "certain",
  "verdict": "For zone names >= 13 chars, tmpname[len]=':' (vm_zone.c:841) overwrites the only NUL of the 14-byte stack buffer tmpname (clamp at :835 allows len==13), so ksnprintf's %s (:854) reads past the buffer, copying kernel-stack residue into the world-readable vm.zone sysctl output. Reproduced on the stock INVARIANTS guest with KLD-created 13/16-char zones: unprivileged reads showed >100 bytes of stack content per affected row; the bytes after tmpname are the previous execution's tmpbuf on the reused kernel stack, so the leak self-echoes and amplifies to ksnprintf's 127-byte cap (stable fixed point, identical md5 across 3 runs); rows also lose newlines and their stats columns get truncated. In-tree trigger: 'rfcomm_credit' (exactly 13 chars, rfcomm_session.c:162) on device-bluetooth kernels; stock GENERIC zone names are <= 9 chars, hence Medium. Fixed by clamping to 12 chars: patched kernel #1 renders clean padded rows with zero echo.",
  "exploit_chain": "unpriv user -> repeated sysctl vm.zone reads -> up to ~113 bytes of kernel-stack residue per affected zone row per read (CWE-125 read primitive via CWE-170 NUL clobber); no write primitive, no escalation",
  "evidence": "run.hexdump.log / leak_sample.txt: 'AAAAAAAAAAAAA:AAAAAAAAAAAAA:...(9+ echoes)...:ASWAPMETA:' with rows merged (no newline) from 'su -m nobody'-readable output; fix_hex.log: patched kernel prints 'AAAAAAAAAAAA: 000064, 00000000, 000000, 000000, 00000000' cleanly",
  "kernel_refs": ["sys/vm/vm_zone.c:816", "sys/vm/vm_zone.c:834-841", "sys/vm/vm_zone.c:854-858", "sys/netbt/rfcomm_session.c:162"],
  "poc_changes": "self-authored harness (no seed): KLD creates zones named AAAAAAAAAAAAA (13) and BBBBBBBBBBBBBBBB (16); 'leakmark_zone' (13 chars, DF-2829 harness) independently exhibited the same over-read",
  "attempts": 1,
  "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": 960,
  "guest_dirty": 0,
  "build_cmd": "cd /root/df2830 && make (KLD: cc -O2 -D_KERNEL ... -c df2830_harness.c; cc -Wl,... -r -o df2830.ko)",
  "run_cmd": "kldload /root/df2830/df2830.ko && su -m nobody -c 'sysctl vm.zone' | hexdump -C",
  "code_hash": "39d43bca0cb2931cd040f7a981c71f6f2277632698c141bb9ebaa681a3ad6425",
  "notes": "An alternate fix is widening tmpname; the applied minimal fix truncates names to 12 chars (maintainer's choice). The leak content is stack-residue-dependent: first read on a given kstack emits whatever it last held; repeats converge to self-echo. Stats-column truncation is a functional symptom of the same bug.",
  "recommended_fix": "Clamp len to sizeof(tmpname)-2 so the ':' fits at tmpname[12] and the NUL at tmpname[13] survives (see fix.diff)",
  "fix_status": "fixed",
  "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #1: Tue Sep  1 20:57:06 UTC 2026  root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Applied fix.diff (with DF-2829's fix) to guest /usr/src/sys/vm/vm_zone.c, make nativekernel KERNCONF=X86_64_GENERIC, installkernel + reboot into #1. Identical PoC rerun: 'AAAAAAAAAAAA:' / 'BBBBBBBBBBBB:' rows render cleanly, no stack echo, no merged rows, intact newlines - OOB read eliminated.",
  "fix_evidence": "findings/poc/DF-2830/fix_validation.log and fix_hex.log (patched), run.hexdump.log + leak_sample.txt (baseline)"
}