DragonFlyBSD Kernel Audit
DF-1562 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/netif/pcn/if_pcn.c b/sys/dev/netif/pcn/if_pcn.c
--- a/sys/dev/netif/pcn/if_pcn.c
+++ b/sys/dev/netif/pcn/if_pcn.c
@@ -795,8 +795,21 @@
 
 		/* No errors; receive the packet. */
 		IFNET_STAT_INC(ifp, ipackets, 1);
-		m->m_len = m->m_pkthdr.len =
-		    cur_rx->pcn_rxlen - ETHER_CRC_LEN;
+
+		/*
+		 * DF-1562: pcn_rxlen is a u16 (0..65535) DMA-coherent value.
+		 * With MCLBYTES (2048) cluster and ETHER_ALIGN (2) m_adj the
+		 * usable buffer is 2046 bytes; an attacker-controlled NIC could
+		 * deliver a value up to 65535, walking ~63K past the cluster.
+		 * Also guard the <4 case which would underflow.
+		 */
+		if (cur_rx->pcn_rxlen < ETHER_CRC_LEN ||
+		    cur_rx->pcn_rxlen - ETHER_CRC_LEN > MCLBYTES - ETHER_ALIGN) {
+			IFNET_STAT_INC(ifp, ierrors, 1);
+		} else {
+			m->m_len = m->m_pkthdr.len =
+			    cur_rx->pcn_rxlen - ETHER_CRC_LEN;
+		}
 		m->m_pkthdr.rcvif = ifp;
 
 		ifp->if_input(ifp, m, NULL, -1);