Message ID | 1531684400-15778-1-git-send-email-stefan.wahren@i2se.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
From: Stefan Wahren <stefan.wahren@i2se.com> Date: Sun, 15 Jul 2018 21:53:20 +0200 > The skb size calculation in lan78xx_tx_bh is in race with the start_xmit, > which could lead to rare kernel oopses. So protect the whole skb walk with > a spin lock. As a benefit we can unlink the skb directly. > > This patch was tested on Raspberry Pi 3B+ > > Link: https://github.com/raspberrypi/linux/issues/2608 > Fixes: 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to 10/100/1000 Ethernet") > Cc: stable <stable@vger.kernel.org> > Signed-off-by: Floris Bos <bos@je-eigen-domein.nl> > Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com> Applied and queued up for -stable, thanks. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 2e41307..ed10d49 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -3344,6 +3344,7 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev) pkt_cnt = 0; count = 0; length = 0; + spin_lock_irqsave(&tqp->lock, flags); for (skb = tqp->next; pkt_cnt < tqp->qlen; skb = skb->next) { if (skb_is_gso(skb)) { if (pkt_cnt) { @@ -3352,7 +3353,8 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev) } count = 1; length = skb->len - TX_OVERHEAD; - skb2 = skb_dequeue(tqp); + __skb_unlink(skb, tqp); + spin_unlock_irqrestore(&tqp->lock, flags); goto gso_skb; } @@ -3361,6 +3363,7 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev) skb_totallen = skb->len + roundup(skb_totallen, sizeof(u32)); pkt_cnt++; } + spin_unlock_irqrestore(&tqp->lock, flags); /* copy to a single skb */ skb = alloc_skb(skb_totallen, GFP_ATOMIC);