Skip to content

Commit c7718ee

Browse files
abajkdavem330
authored andcommitted
net: lantiq: fix memory corruption in RX ring
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent fc516d3 commit c7718ee

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

drivers/net/ethernet/lantiq_xrx200.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ static int xrx200_close(struct net_device *net_dev)
154154

155155
static int xrx200_alloc_skb(struct xrx200_chan *ch)
156156
{
157+
dma_addr_t mapping;
157158
int ret = 0;
158159

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

166-
ch->dma.desc_base[ch->dma.desc].addr = dma_map_single(ch->priv->dev,
167-
ch->skb[ch->dma.desc]->data, XRX200_DMA_DATA_LEN,
168-
DMA_FROM_DEVICE);
169-
if (unlikely(dma_mapping_error(ch->priv->dev,
170-
ch->dma.desc_base[ch->dma.desc].addr))) {
167+
mapping = dma_map_single(ch->priv->dev, ch->skb[ch->dma.desc]->data,
168+
XRX200_DMA_DATA_LEN, DMA_FROM_DEVICE);
169+
if (unlikely(dma_mapping_error(ch->priv->dev, mapping))) {
171170
dev_kfree_skb_any(ch->skb[ch->dma.desc]);
172171
ret = -ENOMEM;
173172
goto skip;
174173
}
175174

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

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

0 commit comments

Comments
 (0)