DF-3235 / verdict.json
{ "finding_id": "DF-3235", "status": "reproduced", "reproduced": 1, "impact": "leak", "confidence": "certain", "verdict": "procfs_docmdline() snapshots bp=p->p_args->ar_args (procfs_status.c:241) and later copies from it via a potentially blocking uiomove_frombuf() (procfs_status.c:292); blocking drops the callers p_token (lwkt_token.c:40), so a concurrent execve in the target frees the pargs chunk (kern_exec.c:589-596) and any processs next exec recycles the slab chunk, whose bytes are then copied to the unprivileged reader: kernel heap UAF read disclosing other processes argv past the CHECKIO/p_trespass gate. Reproduced 4x on stock kernel #0 (impossible F/MARKER filler bytes returned from /proc/<victim>/cmdline, torn mid-read). Same flaw reaches lwp_lpmap/p_upmap titles (freed by lwp_userunmap/proc_userunmap during exec/exit).", "exploit_chain": "unpriv user: (1) victim process cycles exec small-argv (pargs cached, 192B slab zone) / exec big-argv (pargs freed, no realloc); (2) filler processes exec MARKER-argv of identical byte count (same slab zone, same-CPU magazine) to recycle the freed chunk; (3) reader readv(/proc/<victim>/cmdline, 184x1B iovecs) into never-touched 4KB-strided pages of a 3.5GB file: each iovec copyout takes a cold disk fault, blocking mid-read for 35-500ms with p_token dropped; (4) resumed copy returns the recycled chunks bytes = another processs argv (any local uid). Ceiling: repeated cross-user argv/stale-heap disclosure (M_PARS zone, default <=256B per chunk); bounded read, no write primitive, no uid=0 chain.", "evidence": [ "run.13.log / run.15.log: [reader] HIT: 184B ...AAAA...FFFF... + RESULT: UAF-READ REPRODUCED", "run.12.log: torn read 184B 8.00ms A-tail->F-tail mid-chunk", "leak_sample.txt: all four torn reads collected", "run.fix.1.log + run.fix.2.log: patched kernel, ~22k blocked p_args reads, anom=0, no hit (fix validated)", "VERDICT.md: full path:line trace and engineering notes" ], "kernel_refs": [ "sys/vfs/procfs/procfs_status.c:202-247", "sys/vfs/procfs/procfs_status.c:292", "sys/vfs/procfs/procfs_subr.c:281-306", "sys/kern/kern_exec.c:589-608", "sys/kern/kern_exec.c:432-433", "sys/kern/kern_exec.c:981-982", "sys/kern/kern_proc.c:1943-1949", "sys/kern/kern_proc.c:1300-1310", "sys/kern/kern_proc.c:1356-1383", "sys/kern/kern_exit.c:688", "sys/kern/kern_exit.c:1269", "sys/kern/lwkt_token.c:40", "sys/kern/kern_subr.c:96-160" ], "poc_changes": "Seed concept fully rewritten: added usched_set CPU pinning (magazine locality), exact argv byte-count matching to share the 192-byte slab zone (kern_slaballoc.c chunking), big-argv exec phase so p_args is freed WITHOUT same-process realloc, 3.5GB cold backing file (guest RAM 4GB), 184x1-byte readv into strided cold pages so the copyout faults serialize into a 35-500ms post-snapshot window, sigsetjmp SEGV guard, tail-anomaly + MARKER detection, controller SIGCHLD fix.", "attempts": 15, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64", "runtime_sec": 1380, "guest_dirty": 0, "build_cmd": "cc -O2 -Wall -pthread -o /home/maxx/racer /home/maxx/racer.c", "run_cmd": "cd /home/maxx && ./racer 240 6", "code_hash": "27b3040802eac842649fd69e29d7ea156ba31c8fb5514d278b3510a3e673661a", "notes": "fix validated in-guest: make nativekernel (1117s) + installkernel + reboot into #1 Wed Sep 9 02:37:12 2026; 2x300s re-runs of the exact PoC: zero anomalies with ~22k blocked p_args reads (window present, primitive gone); regression-checked cmdline/ps/status nodes. Guest reset to clean with-src snapshot afterwards. Torn reads observed: 4 in 3 stock runs. Severity context: race-gated local info leak of other processes argv (CHECKIO bypass) + stale M_PARS heap content; read-only primitive.", "recommended_fix": "Hold a pargs reference across the blocking copy (refcount_acquire/release exactly like sysctl_kern_proc_args, kern_proc.c:1943-1949) and bcopy the lpmap/upmap titles into a pre-allocated snapshot buffer before uiomove; full diff in fix.diff.", "fix_status": "fixed", "fix_kernel_uname": "DragonFly 6.5-DEVELOPMENT #1: Wed Sep 9 02:37:12 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "With fix.diff applied (pargs refcount + title snapshot), the exact PoC produced zero torn/reused reads over 600s (2 runs, ~22k ms-blocked p_args reads, slow==args, anom=0) vs 4 torn reads in ~780s on stock; cmdline functionality regression-checked.", "fix_evidence": [ "run.fix.1.log", "run.fix.2.log", "fix_build.log", "fix.diff" ] } |