| From b102f0c522cf668c8382c56a4f771b37d011cda2 Mon Sep 17 00:00:00 2001 |
| From: Felix Fietkau <nbd@nbd.name> |
| Date: Thu, 20 Feb 2020 12:41:39 +0100 |
| Subject: [PATCH] mt76: fix array overflow on receiving too many fragments for |
| a packet |
| |
| commit b102f0c522cf668c8382c56a4f771b37d011cda2 upstream. |
| |
| If the hardware receives an oversized packet with too many rx fragments, |
| skb_shinfo(skb)->frags can overflow and corrupt memory of adjacent pages. |
| This becomes especially visible if it corrupts the freelist pointer of |
| a slab page. |
| |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Felix Fietkau <nbd@nbd.name> |
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c |
| index 6173c80189ba..1847f55e199b 100644 |
| --- a/drivers/net/wireless/mediatek/mt76/dma.c |
| +++ b/drivers/net/wireless/mediatek/mt76/dma.c |
| @@ -447,10 +447,13 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data, |
| struct page *page = virt_to_head_page(data); |
| int offset = data - page_address(page); |
| struct sk_buff *skb = q->rx_head; |
| + struct skb_shared_info *shinfo = skb_shinfo(skb); |
| |
| - offset += q->buf_offset; |
| - skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, offset, len, |
| - q->buf_size); |
| + if (shinfo->nr_frags < ARRAY_SIZE(shinfo->frags)) { |
| + offset += q->buf_offset; |
| + skb_add_rx_frag(skb, shinfo->nr_frags, page, offset, len, |
| + q->buf_size); |
| + } |
| |
| if (more) |
| return; |
| -- |
| 2.7.4 |
| |