⬢ DragonFlyBSD Kernel Audit
DF-4079 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/oce/oce_if.c
+++ b/sys/dev/netif/oce/oce_if.c
@@ -1317,6 +1317,21 @@
 		len -= frag_len;
 	}
 
+	/*
+	 * DF-4079: pkt_size (14 bits, up to 16383) is firmware-controlled
+	 * and must not be trusted: with num_fragments (3 bits, max 7) x
+	 * frag_size (2048) the chain can hold at most 14336 bytes, i.e. up
+	 * to 2047 bytes SHORTER than the claimed pkt_size.  If any residual
+	 * length is left after consuming all posted fragments the chain
+	 * would violate m_pkthdr.len == sum(m_len) -- drop it instead of
+	 * handing an inconsistent chain to if_input.
+	 */
+	if (len != 0) {
+		if (m != NULL)
+			m_freem(m);
+		goto exit;
+	}
+
 	if (m) {
 		if (!oce_cqe_portid_valid(sc, cqe)) {
 			 m_freem(m);