DF-1562 / fix.diff
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); |