#!/bin/sh
# DF-0542 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_INQUIRY_RESULT (:127) -> inquiry_result (:370)
#
# inquiry_result pulls sizeof(ng_hci_inquiry_result_ep)=1 byte (num_responses)
# then loops while num_responses>0, consuming 14 bytes per response and NEVER
# checking the mbuf length.
#
# A crafted HCI INQUIRY_RESULT event that triggers the bug:
#   byte 0    : 0x02   (event = NG_HCI_EVENT_INQUIRY_RESULT)
#   byte 1..2 : length = 0x0001  (HCI event "length" param, NOT enforced)
#   byte 3    : num_responses = 0xFF   (255 -- attacker controlled, 1st body byte)
#   <no more data>
#
# inquiry_result m_adj(1) drops the num_responses byte, leaving 0 bytes in the
# chain. The first loop iter then does m_copydata(event,0,6,&bdaddr). m_copydata
# (sys/kern/uipc_mbuf.c:1671) finds m->m_len == 0, sets 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 m->m_len deref =>
#    page-fault panic. Prior *mtod reads (:408,:414) leak stale mbuf residue
#    into the neighbor cache (in-kernel; limited).
#
# Per-response consumption = sizeof(bdaddr_t)=6 + 3*(u_int8_t)=3 +
#                            NG_HCI_CLASS_SIZE=3 + sizeof(clock_offset)=2 = 14
# Fix in fix.diff: stop when event->m_pkthdr.len < NG_HCI_INQUIRY_RESULT_SIZE.
echo "DF-0542: source-level analysis only (netgraph7 BT not reachable on default guest)."
echo "See README.md / VERDICT.md / fix.diff."
