DF-0543 / hci_event_analysis.sh
#!/bin/sh # DF-0543 source-level reproduction analysis (NOT a runnable runtime trigger). # # The vulnerable code (sys/netgraph7/bluetooth/hci/ng_hci_evnt.c) is opt-in # (optional netgraph7_bluetooth), NOT compiled/shipped/loadable on the default # guest, so there is no live PoC. This file documents what a triggering HCI # event would look like and why it panics. # # Path: ng_hci_process_event (ng_hci_evnt.c:86) # -> case NG_HCI_EVENT_NUM_COMPL_PKTS (:171) -> num_compl_pkts (:878) # # num_compl_pkts pulls sizeof(ng_hci_num_compl_pkts_ep)=1 byte # (num_con_handles) then loops while num_con_handles>0, consuming 4 bytes per # entry (sizeof(h)=2 + sizeof(p)=2) and NEVER checking the mbuf length. # # A crafted HCI NUMBER_OF_COMPLETED_PACKETS event that triggers the bug: # byte 0 : 0x13 (event = NG_HCI_EVENT_NUM_COMPL_PKTS) # byte 1..2 : length = 0x0001 (HCI event "length" param, NOT enforced) # byte 3 : num_con_handles = 0xFF (255 -- attacker controlled) # <no more data> # # num_compl_pkts m_adj(1) drops the num_con_handles byte, leaving 0 bytes. The # first loop iter does m_copydata(event,0,2,&h). m_copydata # (sys/kern/uipc_mbuf.c:1671) finds m->m_len == 0, m=m->m_next (NULL), and the # len>0 loop hits: # KASSERT(m != NULL, "%s: length > size of mbuf chain") # uipc_mbuf.c:1687 # => panic (INVARIANTS / GENERIC). Non-INVARIANTS => NULL deref => page-fault # panic. (No copyout: parsed h/p only update an in-kernel counter -> DoS.) # # Per-entry consumption = sizeof(h)=2 + sizeof(p)=2 = 4 # Fix in fix.diff: stop when event->m_pkthdr.len < (sizeof(h)+sizeof(p)). echo "DF-0543: source-level analysis only (netgraph7 BT not reachable on default guest)." echo "See README.md / VERDICT.md / fix.diff." |