This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new a8f6014bbda drivers/net/ftmac100: Validate RX frame length before
memcpy
a8f6014bbda is described below
commit a8f6014bbda67e7f6884b89d52facbf7e53ad752
Author: Swatantra Yadav <[email protected]>
AuthorDate: Sat Oct 31 18:57:05 2026 +0530
drivers/net/ftmac100: Validate RX frame length before memcpy
In ftmac100_receive(), the device-reported frame length was read
directly from the DMA descriptor (FTMAC100_RXDES0_RFL, 0..2047)
and copied into priv->ft_dev.d_buf without verifying that it fits
within CONFIG_NET_ETH_PKTSIZE or satisfies the minimum Ethernet
frame header length ETH_HDRLEN.
An oversized packet could trigger an out-of-bounds write past the
fixed packet buffer into adjacent BSS memory.
Add a bounds check to drop frames with invalid lengths (< ETH_HDRLEN
or > CONFIG_NET_ETH_PKTSIZE), increment NETDEV_RXERRORS, and return
the descriptor to hardware DMA ownership without performing memcpy.
Fixes #21111.
Signed-off-by: Swatantra Yadav <[email protected]>
Assisted-by: Google Gemini
---
drivers/net/ftmac100.c | 31 ++++++++++++++++++++++++-------
1 file changed, 24 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ftmac100.c b/drivers/net/ftmac100.c
index 81c7d8ec41f..79b00b2bee7 100644
--- a/drivers/net/ftmac100.c
+++ b/drivers/net/ftmac100.c
@@ -379,10 +379,11 @@ static void ftmac100_reset(FAR struct ftmac100_driver_s
*priv)
ninfo("%s(): iobase=%p\n", __func__, iobase);
- putreg32 (FTMAC100_MACCR_SW_RST, &iobase->maccr);
+ putreg32(FTMAC100_MACCR_SW_RST, &iobase->maccr);
- while (getreg32 (&iobase->maccr) & FTMAC100_MACCR_SW_RST)
- ;
+ while ((getreg32(&iobase->maccr) & FTMAC100_MACCR_SW_RST) != 0)
+ {
+ }
}
/****************************************************************************
@@ -624,11 +625,27 @@ static void ftmac100_receive(FAR struct ftmac100_driver_s
*priv)
len = FTMAC100_RXDES0_RFL(rxdes->rxdes0);
data = (FAR uint8_t *)rxdes->rxdes2;
- ninfo ("RX buffer %d (%08x), %x received (%d)\n",
- priv->rx_pointer, data, len,
- (rxdes->rxdes0 & FTMAC100_RXDES0_LRS));
+ ninfo("RX buffer %d (%08x), %x received (%d)\n",
+ priv->rx_pointer, data, len,
+ (rxdes->rxdes0 & FTMAC100_RXDES0_LRS));
+
+ /* Check for a usable packet length */
+
+ if (len < ETH_HDRLEN || len > CONFIG_NET_ETH_PKTSIZE)
+ {
+ nerr("ERROR: Bad packet size dropped (%u)\n", (unsigned int)len);
+ NETDEV_RXERRORS(&priv->ft_dev);
+
+ priv->rx_pointer = (priv->rx_pointer + 1) &
+ (CONFIG_FTMAC100_RX_DESC - 1);
+
+ rxdes->rxdes1 &= FTMAC100_RXDES1_EDORR;
+ rxdes->rxdes1 |= FTMAC100_RXDES1_RXBUF_SIZE(RX_BUF_SIZE);
+ rxdes->rxdes0 |= FTMAC100_RXDES0_RXDMA_OWN;
+ continue;
+ }
- /* Copy the data data from the hardware to priv->ft_dev.d_buf. Set
+ /* Copy the data from the hardware to priv->ft_dev.d_buf. Set
* amount of data in priv->ft_dev.d_len
*/