Skip to content

Commit

Permalink
net: lantiq: fix memory corruption in RX ring
Browse files Browse the repository at this point in the history
[ Upstream commit c7718ee ]

In a situation where memory allocation or dma mapping fails, an
invalid address is programmed into the descriptor. This can lead
to memory corruption. If the memory allocation fails, DMA should
reuse the previous skb and mapping and drop the packet. This patch
also increments rx drop counter.

Fixes: fe1a564 ("net: lantiq: Add Lantiq / Intel VRX200 Ethernet driver ")
Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
abajk authored and gregkh committed Jun 3, 2021
1 parent 83201d6 commit 46dd4ab
Showing 1 changed file with 9 additions and 5 deletions.
14 changes: 9 additions & 5 deletions drivers/net/ethernet/lantiq_xrx200.c
Expand Up @@ -154,6 +154,7 @@ static int xrx200_close(struct net_device *net_dev)

static int xrx200_alloc_skb(struct xrx200_chan *ch)
{
dma_addr_t mapping;
int ret = 0;

ch->skb[ch->dma.desc] = netdev_alloc_skb_ip_align(ch->priv->net_dev,
Expand All @@ -163,16 +164,17 @@ static int xrx200_alloc_skb(struct xrx200_chan *ch)
goto skip;
}

ch->dma.desc_base[ch->dma.desc].addr = dma_map_single(ch->priv->dev,
ch->skb[ch->dma.desc]->data, XRX200_DMA_DATA_LEN,
DMA_FROM_DEVICE);
if (unlikely(dma_mapping_error(ch->priv->dev,
ch->dma.desc_base[ch->dma.desc].addr))) {
mapping = dma_map_single(ch->priv->dev, ch->skb[ch->dma.desc]->data,
XRX200_DMA_DATA_LEN, DMA_FROM_DEVICE);
if (unlikely(dma_mapping_error(ch->priv->dev, mapping))) {
dev_kfree_skb_any(ch->skb[ch->dma.desc]);
ret = -ENOMEM;
goto skip;
}

ch->dma.desc_base[ch->dma.desc].addr = mapping;
/* Make sure the address is written before we give it to HW */
wmb();
skip:
ch->dma.desc_base[ch->dma.desc].ctl =
LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) |
Expand All @@ -196,6 +198,8 @@ static int xrx200_hw_receive(struct xrx200_chan *ch)
ch->dma.desc %= LTQ_DESC_NUM;

if (ret) {
ch->skb[ch->dma.desc] = skb;
net_dev->stats.rx_dropped++;
netdev_err(net_dev, "failed to allocate new rx buffer\n");
return ret;
}
Expand Down

0 comments on commit 46dd4ab

Please sign in to comment.