DF-5742 / verdict.json
{ "finding_id": "DF-5742", "status": "reproduced", "reproduced": true, "verdict": "hci_mtap (hci_socket.c:1003-1010) copies every matching HCI packet into each tap sockets so_rcv via sbappendaddr with no ssb_space/hiwat check - a non-reading raw HCI socket accumulates mbufs without bound from the GLOBAL mbuf pool. Demonstrated on the guest: with non-draining promiscuous taps and controller traffic injected through production paths, Warning: objcache(mbuf pkthdr) exhausted fired on cpu0..cpu3 and both guests then hard-hung unrecoverably (exhaustion.txt, race4/5 logs recorded during the DF-5740 rig sessions whose taps were not draining - the exhaustion is this bugs, independent of the close-race also running). Unprivileged: HCI sockets are unprivileged, and with DF-5741 any user can open full-filter promiscuous taps and generate the tapped traffic themselves.", "impact": "dos", "confidence": "certain", "exploit_chain": "unpriv user: open N raw HCI sockets, bind ANY (promiscuous), setsockopt full SO_HCI_PKT_FILTER/SO_HCI_EVT_FILTER, never read; send allowed (or with DF-5741 any) commands to generate Command Complete/Status traffic -> every packet copied N times unboundedly -> global mbuf pool exhaustion -> kernel-wide allocation failure -> hard hang (observed).", "evidence": "exhaustion.txt (all-cpu warnings + hang, two runs); race4.log/race5.log (trigger-side); fix.diff (ssb_space gate, proposed)", "kernel_refs": [ "sys/netbt/hci_socket.c:1003", "sys/netbt/hci_socket.c:1004", "sys/kern/uipc_sockbuf.c:231" ], "poc_changes": "no separate PoC build; evidence captured with the DF-5740 rig (same pack) with non-draining taps - which is precisely the bugs trigger", "attempts": 2, "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": 90, "guest_dirty": 0, "build_cmd": "(DF-5740 rig build.sh)", "run_cmd": "rig + sysctl hw.hsh_setup=1; sysctl hw.hsh_fire=99999 &; ./trigger 100 48 40 (taps not drained)", "code_hash": "n/a (evidence via DF-5740 rig)", "notes": "first crash of the DF-5740 session (race1/2 page fault on NULL mbuf) was enabled by THIS bug draining the pool - documented as confound there. Fix proposed but not separately runtime-validated (resource-exhaustion class).", "recommended_fix": "gate the tap on receive-buffer space: if (ssb_space(&so->so_rcv) < pktlen) { free copy; continue; } before sbappendaddr (fix.diff).", "fix_status": "not_tested", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "baseline exhaustion/hang reproduced twice; fix.diff authored (standard tap pattern) but not rebuilt on the guest in this run - marked not_tested honestly", "fix_evidence": "exhaustion.txt; fix.diff" } |