DF-2329 / verdict.json
{ "finding_id": "DF-2329", "status": "reproduced", "reproduced": 1, "impact": "denial_of_service", "confidence": "likely", "verdict": "REPRODUCED live: the ppbharness3 race test runs the REAL ppb_request_bus(PPB_WAIT|PPB_NOINTR) on a waiter thread pinned to a second CPU while an owner thread releases inside the crit_exit-to-tsleep window (delay sweep 0..399 us): caught at trial 16070 -- the waiter was STILL ASLEEP with ppb_owner == NULL (the wakeup was lost; timo=0; the NOINTR variant has no PCATCH so the sleep is unkillable). The rig revived the waiter with an artificial wakeup; production has none, so the hang is permanent. The window is exactly the missing-interlock ordering at ppbconf.c:464-497 vs ppb_release_bus :538. Confidence likely rather than certain only because the catch is a scheduling race (1 in ~16 k trials here) while the code-ordering proof is certain.", "exploit_chain": "two threads on one ppbus -> owner releases between requester crit_exit (:467) and tsleep (:474) -> wakeup(ppb) delivered before the sleep is armed -> requester sleeps forever on a FREE bus -> PPB_WAIT|PPB_NOINTR: unkillable permanent hang", "evidence": "run.log: hw.ppbx3.lostwake = 1 at trial 16070/16071 with owner==NULL and the REPRODUCED console line; control attach + DF-2327/2328 stock panics on the same rig prove the production code is what executes", "kernel_refs": [ "sys/bus/ppbus/ppbconf.c:464", "sys/bus/ppbus/ppbconf.c:466", "sys/bus/ppbus/ppbconf.c:467", "sys/bus/ppbus/ppbconf.c:470", "sys/bus/ppbus/ppbconf.c:474", "sys/bus/ppbus/ppbconf.c:528", "sys/bus/ppbus/ppbconf.c:538" ], "poc_changes": "Authored the race test in ppbharness3; initial 0/44894 catch rate was a rig flaw (both kthreads on cpu 0: DELAY starved the waiter) -- fixed with lwkt_migratecpu(1) in the waiter; fast-poll drain added so 50k trials run in ~30 s.", "attempts": 3, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Wed Oct 21 11:04:42 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/BUSAUDIT x86_64 (stock GENERIC + device targ; INVARIANTS)", "runtime_sec": 120, "guest_dirty": 0, "build_cmd": "cd b && make SYSDIR=/usr/src/sys", "run_cmd": "kldload ./ppbharness3.ko; sysctl hw.ppbx3.test=3; sleep 30; sysctl hw.ppbx3.racetrials hw.ppbx3.lostwake", "code_hash": "8d751ea1371f93e32443422a6c40f77d1bfff3a7e3ea4ceefdcf32482bf4f5c4", "notes": "Speculative-to-likely upgrade: the code-order proof plus the live catch. Unprivileged trigger via any ppbus child open path (lpt/pcfclock) that uses PPB_WAIT.", "recommended_fix": "tsleep_interlock(ppb, PCATCH) inside the crit section + tsleep(...|PINTERLOCKED) (fix.diff, the sgread pattern).", "fix_status": "fixed", "fix_validation": "patched rig on the fix kernel: 50000 trials, 0 lost wakeups (vs 1/16071 stock)" } |