Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754538AbdHDXfu (ORCPT ); Fri, 4 Aug 2017 19:35:50 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:49626 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752619AbdHDX23 (ORCPT ); Fri, 4 Aug 2017 19:28:29 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Ben Hutchings , "David S. Miller" , Amit Pundir Subject: [PATCH 3.18 29/50] sh_eth: Fix ethtool operation crash when net device is down Date: Fri, 4 Aug 2017 16:16:15 -0700 Message-Id: <20170804231552.734236320@linuxfoundation.org> X-Mailer: git-send-email 2.13.4 In-Reply-To: <20170804231550.830518786@linuxfoundation.org> References: <20170804231550.830518786@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: 2079 Lines: 71 3.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Ben Hutchings commit 4f9dce230b32eec45cec8c28cae61efdfa2f7d57 upstream. The driver connects and disconnects the PHY device whenever the net device is brought up and down. The ethtool get_settings, set_settings and nway_reset operations will dereference a null or dangling pointer if called while it is down. I think it would be preferable to keep the PHY connected, but there may be good reasons not to. As an immediate fix for this bug: - Set the phydev pointer to NULL after disconnecting the PHY - Change those three operations to return -ENODEV while the PHY is not connected Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller Signed-off-by: Amit Pundir Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/renesas/sh_eth.c | 10 ++++++++++ 1 file changed, 10 insertions(+) --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1832,6 +1832,9 @@ static int sh_eth_get_settings(struct ne unsigned long flags; int ret; + if (!mdp->phydev) + return -ENODEV; + spin_lock_irqsave(&mdp->lock, flags); ret = phy_ethtool_gset(mdp->phydev, ecmd); spin_unlock_irqrestore(&mdp->lock, flags); @@ -1846,6 +1849,9 @@ static int sh_eth_set_settings(struct ne unsigned long flags; int ret; + if (!mdp->phydev) + return -ENODEV; + spin_lock_irqsave(&mdp->lock, flags); /* disable tx and rx */ @@ -1880,6 +1886,9 @@ static int sh_eth_nway_reset(struct net_ unsigned long flags; int ret; + if (!mdp->phydev) + return -ENODEV; + spin_lock_irqsave(&mdp->lock, flags); ret = phy_start_aneg(mdp->phydev); spin_unlock_irqrestore(&mdp->lock, flags); @@ -2189,6 +2198,7 @@ static int sh_eth_close(struct net_devic if (mdp->phydev) { phy_stop(mdp->phydev); phy_disconnect(mdp->phydev); + mdp->phydev = NULL; } free_irq(ndev->irq, ndev);