diff options
author | Felix Fietkau <nbd@nbd.name> | 2020-02-20 12:41:39 +0100 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2020-03-03 17:30:25 +0200 |
commit | b102f0c522cf668c8382c56a4f771b37d011cda2 (patch) | |
tree | 7241c52d1e25587c46fe14df15ee207c0c11eeaf /drivers/net/wireless | |
parent | a9149d243f259ad8f02b1e23dfe8ba06128f15e1 (diff) | |
download | linux-b102f0c522cf668c8382c56a4f771b37d011cda2.tar.bz2 |
mt76: fix array overflow on receiving too many fragments for a packet
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>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/dma.c | 9 |
1 files changed, 6 insertions, 3 deletions
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; |