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:
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user