DragonFlyBSD Kernel Audit
DF-0508 / fix.diff
← back to finding ↓ download raw
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;