DF-2718 / verdict.json
{ "finding_id": "DF-2718", "status": "reproduced", "reproduced": 1, "impact": "leak", "confidence": "certain", "verdict": "PT_INTERP interpreter string is copied with exactly p_filesz bytes and never NUL-terminated (imgact_elf.c:668 kmalloc, extract_interpreter:1817-1863); consumers treat it as a C string and uprintf(\"ELF interpreter %s not found\") at imgact_elf.c:844 discloses kernel heap bytes past the allocation to the unprivileged user's controlling terminal. Reproduced 18/20 iterations leaking the 24-byte residue of a previously-freed M_TEMP allocation plus one iteration leaking genuine kernel path-string residue ('.ssh/autho', '/home/maxx'). Leak-only primitive; no uid=0 chain.", "exploit_chain": "", "evidence": [ "findings/poc/DF-2718/run2.log \u2014 18/20 iterations print A*1000+B*24 after the 1000-byte interp (cross-allocation residue)", "findings/poc/DF-2718/run2.log iteration 15 \u2014 'xx/.ssh/autho/home/maxx' real kernel heap strings", "findings/poc/DF-2718/run.log \u2014 baseline: A*1024 exactly (OOB walk into fresh slab, stops at zero)", "findings/poc/DF-2718/leak_sample.txt \u2014 raw captured bytes", "VERDICT.md \u2014 narrative" ], "kernel_refs": [ "sys/kern/imgact_elf.c:663", "sys/kern/imgact_elf.c:668", "sys/kern/imgact_elf.c:844", "sys/kern/imgact_elf.c:1817", "sys/kern/imgact_elf.c:1838", "sys/kern/imgact_elf.c:1859" ], "poc_changes": "Seed PoCs rewritten from scratch: python3 ELF64 generators (make_poc.py single 1024-A interp, make_poc2.py seed1024/leak1000 pair for the 1024-size-class residue groom); run under script(1) so uprintf reaches a controlling tty", "attempts": 40, "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": "python3 make_poc.py && python3 make_poc2.py && scp to guest && chmod +x", "run_cmd": "sh run2.sh (guest, uid 1001: script -q /tmp/s.log /tmp/seed1024; script -q /tmp/l.log /tmp/leak1000; grep 'ELF interpreter' /tmp/l.log)", "code_hash": "17414cb73c942534382893a2f2692454a2fc46c7be6c2d4955f4f8ef20a23cfc", "notes": "Leak length unbounded until first NUL; content is M_TEMP size-class residue (paths; binary pointers possible). No panic observed across 40+ execs. Fix mirrors FreeBSD's extract_interpreter NUL check.", "recommended_fix": "Reject PT_INTERP strings lacking a NUL terminator in extract_interpreter: if (data[pathsz-1] != '\\0') return failure (both copy paths), plus reject pathsz < 2", "fix_status": "fixed", "fix_kernel_uname": "DragonFly 6.5-DEVELOPMENT #1: Mon Aug 31 07:00:26 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 (fix.diff: NUL-termination check in extract_interpreter, both copy paths + pathsz<2 reject) built via make nativekernel and booted. Baseline leak (18/20) eliminated: 0 leak lines in 8/8 seed/leak pairs; /bin/ls and /usr/bin/true exec normally.", "fix_evidence": [ "findings/poc/DF-2718/fix_run.log", "findings/poc/DF-2718/fix.diff", "findings/poc/DF-2718/fix_build.log" ] } |