Validate the ACL payload-length claim against the bytes actually present in the mbuf before using it for reassembly accounting. --- a/sys/netgraph7/bluetooth/l2cap/ng_l2cap_llpi.c +++ b/sys/netgraph7/bluetooth/l2cap/ng_l2cap_llpi.c @@ -627,6 +627,14 @@ ng_l2cap_lp_receive(ng_l2cap_p l2cap, struct mbuf *m) con_handle = NG_HCI_CON_HANDLE(acl_hdr->con_handle); pb = NG_HCI_PB_FLAG(acl_hdr->con_handle); length = le16toh(acl_hdr->length); + + /* The ACL length field must not exceed the bytes that are + * actually present in the mbuf after the ACL header was + * stripped; otherwise the reassembly accounting below inflates + * m_pkthdr.len past the end of the chain (llpi.c:702) and the + * lie propagates into outgoing ACL headers / driver TX. */ + if (length > m->m_pkthdr.len) { + error = EMSGSIZE; + goto drop; + } NG_L2CAP_INFO( "%s: %s - got ACL data packet, con_handle=%d, PB=%#x, length=%d\n",