DF-3240 / verdict.json
{ "finding_id": "DF-3240", "status": "reproduced", "reproduced": 1, "impact": "none", "confidence": "certain", "verdict": "Guard bypass reproduced as predicted, impact ceiling genuinely none. pread(fd,buf,0x1000,0x7ffffffffffffff8) on /proc/self/map makes buflen=uio_offset+uio_resid wrap negative past the `buflen >= INT_MAX test (procfs_map.c:61,75); sbuf_new truncates buflen+1 to int (4095-byte buffer); the inflated map overflows the sbuf so sbuf_finish returns ENOMEM and buflen keeps the wrapped 0x8000000000000FFE; uiomove_frombuf then performs uiomove(heap_kva + 0x7ffffffffffffff8, ...) -- a wild kernel-side read that wraps into the top of USER VA. std_copyouts onfault catches the fault: pread returns EFAULT (observed) or echoes the attackers own mapped bytes. No kernel disclosure possible (wrapped address always < 2^63), no panic (fault-protected), no DoS. Filed Low/hardening; also documents that DF-0924s INT_MAX allocation cap is bypassable via the same wrap.", "exploit_chain": "", "evidence": [ "run.log: plain map size = 1416 bytes then pread -> n=-1 errno=14 (Bad address) \u2014 EFAULT can only originate from uiomove faulting on the wild source address; a bounds-respecting path returns 0/EINVAL", "VERDICT.md: full arithmetic (buflen=0x8000000000000FFE, int-truncated length 0xFFF) and why KASSERT-negative-length is mathematically unreachable" ], "kernel_refs": [ "sys/vfs/procfs/procfs_map.c:61", "sys/vfs/procfs/procfs_map.c:75", "sys/vfs/procfs/procfs_map.c:77", "sys/vfs/procfs/procfs_map.c:243", "sys/kern/kern_subr.c:276", "sys/kern/subr_sbuf.c:210" ], "poc_changes": "Initial draft (from the finding sketch) returned n=0: the 128 identical adjacent anon mappings merged into one entry so the truncated sbuf never overflowed. Fixed by alternating protections per mapping and adding a plain-read sanity print of the map size.", "attempts": 3, "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": 45, "guest_dirty": 0, "build_cmd": "cc -O2 -Wall -o df3240_buflen_overflow df3240_buflen_overflow.c", "run_cmd": "./df3240_buflen_overflow (unprivileged)", "code_hash": "1b458e4d70dad6f9f1846830dcd0919bbf69f276273b18f4f988b2f308333135", "notes": "MAP_NORESERVE does not exist on DragonFly (removed from the PoC).", "recommended_fix": "Overflow-safe bound: reject when uio_offset > INT_MAX - uio_resid (both already non-negative) instead of testing the wrapped sum (see fix.diff).", "fix_status": "not_testable", "fix_kernel_uname": "", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "Observable (EFAULT) is benign by construction; a second kernel build to watch EFAULT become EINVAL is not warranted for a Low/hardening finding \u2014 fix.diff is line-accurate against the cited guard.", "fix_evidence": "fix.diff; run.log" } |