From patchwork Sun Jul 15 19:53:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Wahren X-Patchwork-Id: 10525123 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BF30660245 for ; Sun, 15 Jul 2018 19:53:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A9F2F28941 for ; Sun, 15 Jul 2018 19:53:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9E74E28947; Sun, 15 Jul 2018 19:53:53 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0B85928941 for ; Sun, 15 Jul 2018 19:53:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726940AbeGOURu (ORCPT ); Sun, 15 Jul 2018 16:17:50 -0400 Received: from mout.kundenserver.de ([212.227.126.135]:49306 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726910AbeGOURu (ORCPT ); Sun, 15 Jul 2018 16:17:50 -0400 Received: from localhost.localdomain ([37.4.249.97]) by mrelayeu.kundenserver.de (mreue005 [212.227.15.167]) with ESMTPSA (Nemesis) id 0MW7OX-1fXyeq0zEX-00XKlc; Sun, 15 Jul 2018 21:53:41 +0200 From: Stefan Wahren To: Woojung Huh , UNGLinuxDriver@microchip.com, "David S. Miller" Cc: Greg Kroah-Hartman , Dave Stevenson , netdev@vger.kernel.org, linux-usb@vger.kernel.org, Stefan Wahren , stable , Floris Bos Subject: [PATCH] net: lan78xx: Fix race in tx pending skb size calculation Date: Sun, 15 Jul 2018 21:53:20 +0200 Message-Id: <1531684400-15778-1-git-send-email-stefan.wahren@i2se.com> X-Mailer: git-send-email 2.7.4 X-Provags-ID: V03:K1:HGwn4qDGIC8wWalk+dNLd666YZUGqhluaYgbVvzG+udd5wnk27x l1H6mVxjHm9oci3/rZRn5xtbzvw1fhBgQeodkWDZT7qb+XImVuEToV2RYZz8uiVBaCv1sD0 Tl6Y949P1uHozgP4OHG7pHY5Fsqc7qhyB4ToMKOHHO8mmCAXTI7E+7B0tnWToUH/Cmgo3zU BK8un/sJD/YQbCQhSvo5w== X-UI-Out-Filterresults: notjunk:1; V01:K0:j86elWAbjUI=:50ZfkDK5bcHxnN3k6OvfIB oS8IVZ8ym5tpn/zj5E/jYz7ORt6oM9Z7WteVpuu/KaOmnI/X8qPiiFcA+SU7hcnsmA+7Wrgcu HoLMyDB2XMpsRrlppA8eUallHmLBjlqJlIKV1gCID7U/w+Jjkqz3cz738//tvM6iy4MsNxXsn 25+lxOiPtrD6aoqYi5810bOs5xXMITVZ8wDfS4xw0leW5VGmuDpCf1UesXzfhwZ9yVlUP+ENP j7+YL3dDQEzHTZfFyBxAgtdN1uancQCyPfIAdgov0hOAEaR4iOfTuEyo3yu6kspF5Wdy14R56 neNwiNuWNyoP/YD1lggwDODZ+Vi7xA4a2mp7hQZuroanotjjTLtgSmcnuD2EXH297bo+UbEu2 UGnNi2zeD1O5AUsIgQ15UyDV5ArI2z+I5tDqEyxvY4kvNobTh+YWhHAbgdNF25hHHb2KGR0E3 WqGuZimHn5SH5y6HCT/YH8RTtPbfSf41EMJmohm1Cr4CY3Lzdf8NkrjPC/JROLuezKgwMNOlK MMeXKdMRrgb6dS4MA/sQ9XVR5rr85v0Ali7I2mjQPLeVck2VBn9B7hQxRqTZaPwMPCZni9jXG YQzhatOqie6Ip93ONSTHoF4W7Rri+JO92doCrDAEmpcHEDLMWwWcPmIkw34w2bvskVAglR5GY HdRHbfQo1RxWlbg8RgB2rELniqua0w3IXIbNHK7Cnb2A1F9q+VP/Qozh0A9iA7TVHQZA= Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 Signed-off-by: Floris Bos Signed-off-by: Stefan Wahren --- drivers/net/usb/lan78xx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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);