diff --git a/sys/netgraph7/bluetooth/hci/ng_hci_evnt.c b/sys/netgraph7/bluetooth/hci/ng_hci_evnt.c --- a/sys/netgraph7/bluetooth/hci/ng_hci_evnt.c +++ b/sys/netgraph7/bluetooth/hci/ng_hci_evnt.c @@ -384,7 +384,19 @@ ep = mtod(event, ng_hci_inquiry_result_ep *); m_adj(event, sizeof(*ep)); - for (; ep->num_responses > 0; ep->num_responses --) { + /* + * Each response consumes sizeof(bdaddr) + 1 + 1 + 1 + NG_HCI_CLASS_SIZE + * + sizeof(clock_offset) bytes from the mbuf. The remote controller- + * supplied num_responses is not trusted; stop as soon as the remaining + * mbuf cannot hold a full response, otherwise m_copydata()/mtod() will + * read past the exhausted chain (KASSERT/NULL-deref panic, and stale + * *mtod reads leak residue into the neighbor cache). + */ +#define NG_HCI_INQUIRY_RESULT_SIZE \ + (sizeof(bdaddr_t) + 3 + NG_HCI_CLASS_SIZE + sizeof(u_int16_t)) + for (; ep->num_responses > 0 && + event->m_pkthdr.len >= NG_HCI_INQUIRY_RESULT_SIZE; + ep->num_responses --) { /* Get remote unit address */ m_copydata(event, 0, sizeof(bdaddr), &bdaddr); m_adj(event, sizeof(bdaddr));