From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg1-f178.google.com ([209.85.215.178]:38971 "EHLO mail-pg1-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727749AbeINUjq (ORCPT ); Fri, 14 Sep 2018 16:39:46 -0400 Received: by mail-pg1-f178.google.com with SMTP id i190-v6so4564961pgc.6 for ; Fri, 14 Sep 2018 08:24:46 -0700 (PDT) Date: Fri, 14 Sep 2018 23:24:42 +0800 From: SZ Lin =?utf-8?B?KOael+S4iuaZuik=?= To: Greg Kroah-Hartman Cc: stable@vger.kernel.org Subject: request for 4.4-stable: d733f7542ad4 ("drivers: net: cpsw: fix segfault in case of bad phy-handle") Message-ID: <20180914152442.GA2619@localhost> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="ReaqsoxgOBHFXBhH" Content-Disposition: inline Content-Transfer-Encoding: 8bit Sender: stable-owner@vger.kernel.org List-ID: --ReaqsoxgOBHFXBhH Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit Hi Greg, This patch is not marked for 4.4-stable, but it's already in 4.9 and 4.14 stable. Please apply to 4.4-stable. This patch adds error handling to avoid segfault situation, I've tweaked patch to use original print function of dev_info() instead of phy_attached_info() which is in commit 2220943a21e26d97d7fd8f83c004b947326b469d upstream. -- SZ Lin (林上智) --ReaqsoxgOBHFXBhH Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="0001-drivers-net-cpsw-fix-segfault-in-case-of-bad-phy-han.patch" Content-Transfer-Encoding: 8bit >>From 194f912f0303146bffe8a1fd0d0c8a5b9208752c Mon Sep 17 00:00:00 2001 From: David Rivshin Date: Wed, 27 Apr 2016 21:32:31 -0400 Subject: [PATCH] drivers: net: cpsw: fix segfault in case of bad phy-handle commit d733f7542ad47cf73e033c90cf55158587e1d060 upstream If an emac node has a phy-handle property that points to something which is not a phy, then a segmentation fault will occur when the interface is brought up. This is because while phy_connect() will return ERR_PTR() on failure, of_phy_connect() will return NULL. The common error check uses IS_ERR(), and so missed when of_phy_connect() fails. The NULL pointer is then dereferenced. Also, the common error message referenced slave->data->phy_id, which would be empty in the case of phy-handle. Instead, use the name of the device_node as a useful identifier. And in the phy_id case add the error code for completeness. Fixes: 9e42f715264f ("drivers: net: cpsw: add phy-handle parsing") Signed-off-by: David Rivshin Signed-off-by: David S. Miller [SZ Lin (林上智): Tweak the patch to use original print function of dev_info()] Signed-off-by: SZ Lin (林上智) --- drivers/net/ethernet/ti/cpsw.c | 38 +++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index c21c80a228d9..c1a4425b54e7 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -1164,25 +1164,35 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, 1 << slave_port, 0, 0, ALE_MCAST_FWD_2); - if (slave->data->phy_node) + if (slave->data->phy_node) { slave->phy = of_phy_connect(priv->ndev, slave->data->phy_node, &cpsw_adjust_link, 0, slave->data->phy_if); - else + if (!slave->phy) { + dev_err(priv->dev, "phy \"%s\" not found on slave %d\n", + slave->data->phy_node->full_name, + slave->slave_num); + return; + } + } else { slave->phy = phy_connect(priv->ndev, slave->data->phy_id, &cpsw_adjust_link, slave->data->phy_if); - if (IS_ERR(slave->phy)) { - dev_err(priv->dev, "phy %s not found on slave %d\n", - slave->data->phy_id, slave->slave_num); - slave->phy = NULL; - } else { - dev_info(priv->dev, "phy found : id is : 0x%x\n", - slave->phy->phy_id); - phy_start(slave->phy); - - /* Configure GMII_SEL register */ - cpsw_phy_sel(&priv->pdev->dev, slave->phy->interface, - slave->slave_num); + if (IS_ERR(slave->phy)) { + dev_err(priv->dev, + "phy \"%s\" not found on slave %d, err %ld\n", + slave->data->phy_id, slave->slave_num, + PTR_ERR(slave->phy)); + slave->phy = NULL; + return; + } } + + dev_info(priv->dev, "phy found : id is : 0x%x\n", + slave->phy->phy_id); + + phy_start(slave->phy); + + /* Configure GMII_SEL register */ + cpsw_phy_sel(&priv->pdev->dev, slave->phy->interface, slave->slave_num); } static inline void cpsw_add_default_vlan(struct cpsw_priv *priv) -- 2.19.0 --ReaqsoxgOBHFXBhH--