Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753548AbdHIUm4 (ORCPT ); Wed, 9 Aug 2017 16:42:56 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:48134 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751904AbdHIUmx (ORCPT ); Wed, 9 Aug 2017 16:42:53 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Wang Yufen , Michael Chan , "David S. Miller" , Sasha Levin Subject: [PATCH 3.18 84/92] tg3: Fix race condition in tg3_get_stats64(). Date: Wed, 9 Aug 2017 13:37:52 -0700 Message-Id: <20170809202158.907628776@linuxfoundation.org> X-Mailer: git-send-email 2.14.0 In-Reply-To: <20170809202155.435709888@linuxfoundation.org> References: <20170809202155.435709888@linuxfoundation.org> User-Agent: quilt/0.65 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1357 Lines: 42 3.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Michael Chan [ Upstream commit f5992b72ebe0dde488fa8f706b887194020c66fc ] The driver's ndo_get_stats64() method is not always called under RTNL. So it can race with driver close or ethtool reconfigurations. Fix the race condition by taking tp->lock spinlock in tg3_free_consistent() when freeing the tp->hw_stats memory block. tg3_get_stats64() is already taking tp->lock. Reported-by: Wang Yufen Signed-off-by: Michael Chan Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/broadcom/tg3.c | 3 +++ 1 file changed, 3 insertions(+) --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -8705,11 +8705,14 @@ static void tg3_free_consistent(struct t tg3_mem_rx_release(tp); tg3_mem_tx_release(tp); + /* Protect tg3_get_stats64() from reading freed tp->hw_stats. */ + tg3_full_lock(tp, 0); if (tp->hw_stats) { dma_free_coherent(&tp->pdev->dev, sizeof(struct tg3_hw_stats), tp->hw_stats, tp->stats_mapping); tp->hw_stats = NULL; } + tg3_full_unlock(tp); } /*