ramips: reject invalid frame engine RX lengths

fe_poll_rx() takes the packet length directly from the RX descriptor and
passes it to skb_put() without checking that it fits in the allocated
buffer.  A malformed or stale descriptor can therefore extend the skb
beyond its tailroom and corrupt memory.

Reject lengths larger than skb_tailroom(), account the packet in
rx_length_errors and rx_dropped, free the affected skb, and continue by
installing the replacement descriptor.

Signed-off-by: Nickolay Savchenko <n.savchenko@axioma.lv>
Link: https://github.com/openwrt/openwrt/pull/24268
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
This commit is contained in:
Nickolay Savchenko
2026-07-20 15:48:26 +02:00
committed by Jonas Jelonek
parent 7c2586ffe7
commit 364b4c0d24
@@ -970,6 +970,16 @@ static int fe_poll_rx(struct napi_struct *napi, int budget,
ring->rx_buf_size, DMA_FROM_DEVICE);
pktlen = RX_DMA_GET_PLEN0(trxd.rxd2);
skb->dev = netdev;
if (unlikely(pktlen > skb_tailroom(skb))) {
if (net_ratelimit())
netdev_warn(netdev,
"dropping invalid RX length %u (buffer %u, descriptor %08x)\n",
pktlen, skb_tailroom(skb), trxd.rxd2);
stats->rx_length_errors++;
stats->rx_dropped++;
dev_kfree_skb_any(skb);
goto replace_desc;
}
skb_put(skb, pktlen);
if (trxd.rxd4 & checksum_bit)
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -987,6 +997,7 @@ static int fe_poll_rx(struct napi_struct *napi, int budget,
napi_gro_receive(napi, skb);
replace_desc:
ring->rx_data[idx] = new_data;
rxd->rxd1 = (unsigned int)dma_addr;