diff --git a/sys/netgraph7/bluetooth/l2cap/ng_l2cap_evnt.c b/sys/netgraph7/bluetooth/l2cap/ng_l2cap_evnt.c --- a/sys/netgraph7/bluetooth/l2cap/ng_l2cap_evnt.c +++ b/sys/netgraph7/bluetooth/l2cap/ng_l2cap_evnt.c @@ -1315,6 +1315,8 @@ get_next_l2cap_opt(struct mbuf *m, int *off, union ng_l2cap_flow_p *val) default: if (hint) + if (*off + hdr->length > m->m_pkthdr.len) + return (-2); *off += hdr->length; else return (-3); diff --git a/sys/netgraph7/bluetooth/l2cap/ng_l2cap_evnt.c b/sys/netgraph7/bluetooth/l2cap/ng_l2cap_evnt.c --- a/sys/netgraph7/bluetooth/l2cap/ng_l2cap_evnt.c +++ b/sys/netgraph7/bluetooth/l2cap/ng_l2cap_evnt.c @@ -596,7 +596,11 @@ ng_l2cap_process_cfg_req(ng_l2cap_chan_p chan) */ m_adj(m, off - sizeof(hdr)); - m->m_pkthdr.len = sizeof(hdr) + hdr.length; + /* DF-0508: clamp to actual mbuf data length, not attacker-controlled hdr.length */ + u_int newlen = sizeof(hdr) + hdr.length; + if (newlen > m->m_pkthdr.len) + newlen = m->m_pkthdr.len; + m->m_pkthdr.len = newlen; result = NG_L2CAP_UNKNOWN_OPTION;