Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753167AbdHISYN (ORCPT ); Wed, 9 Aug 2017 14:24:13 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:57506 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752839AbdHISPf (ORCPT ); Wed, 9 Aug 2017 14:15:35 -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 4.9 71/93] tg3: Fix race condition in tg3_get_stats64(). Date: Wed, 9 Aug 2017 11:14:04 -0700 Message-Id: <20170809181338.543470696@linuxfoundation.org> X-Mailer: git-send-email 2.14.0 In-Reply-To: <20170809181335.658857427@linuxfoundation.org> References: <20170809181335.658857427@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: 1356 Lines: 42 4.9-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 @@ -8720,11 +8720,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); } /*