DF-2701 / verdict.json
{ "finding_id": "DF-2701", "status": "untested", "reproduced": 0, "impact": "none", "confidence": "likely", "verdict": "Info-severity use-after-free READ confined to the 20-second-timeout diagnostic kprintf in swap_pager_getpage(): after vn_strategy() the bp must be considered freed (relpbuf in swp_pager_async_iodone), yet the timeout path dereferences bio->bio_offset and bp->b_bcount. If completion races the timeout wakeup, freed/reused pbuf memory is read and printed to console. Not verified: triggering requires a swap I/O stalled >20 s and the impact is console output only. The same run's guest validation (findings/poc/DF-2701/swap_allocs.txt, 400 allocations) proved the pass-2 central negative claim: blist never returns runs crossing a SWB_DMMAX stripe (leaf radix 64 == SWB_DMMAX, source-proven in sys/kern/subr_blist.c blst_meta_alloc/blst_leaf_alloc), which killed the candidate cross-device sw_nused mis-accounting finding, and captured 40 live fires of known DF-0948's exact-stripe-boundary trim trigger.", "exploit_chain": "", "evidence": [ "sys/vm/swap_pager.c:1486-1490 (bp invalid after vn_strategy)", "sys/vm/swap_pager.c:1514-1537 (timeout loop)", "sys/vm/swap_pager.c:1527-1535 (stale bp/bio deref in kprintf)", "sys/vm/swap_pager.c:2099-2108 (relpbuf on completion)", "findings/poc/DF-2701/swap_allocs.txt (400 swap_alloc records: 0 stripe crossings under heavy fragmentation; 40 exact-boundary DF-0948 trigger fires)" ], "kernel_refs": [ "sys/vm/swap_pager.c:1527", "sys/vm/swap_pager.c:1533", "sys/vm/swap_pager.c:2099" ], "poc_changes": "none; finding left untested (Info). hog.c/swap_allocs.txt are the negative-result validation artifacts reused from DF-2672's storm pattern.", "attempts": 0, "guest_uname": "DragonFly dfbsd 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": 120, "guest_dirty": 0, "build_cmd": "cc -O2 -o /tmp/hog /tmp/hog.c", "run_cmd": "sysctl vm.report_swap_allocs=400; /tmp/hog; dmesg | grep swap_alloc", "code_hash": "", "notes": "Guest was up the whole run; only a userspace hog ran and exited; no kernel changes. swap state returned to 0 used. Validation artifacts included for the record; the finding itself was not triggered (would need an artificially stalled swap device for >20 s).", "recommended_fix": "Snapshot bio_offset/b_bcount into locals before vn_strategy() and print the locals in the timeout diagnostic." } |