Skip to content

Commit d733f75

Browse files
David Rivshindavem330
authored andcommitted
drivers: net: cpsw: fix segfault in case of bad phy-handle
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: 9e42f71 ("drivers: net: cpsw: add phy-handle parsing") Signed-off-by: David Rivshin <drivshin@allworx.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 552165b commit d733f75

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

drivers/net/ethernet/ti/cpsw.c

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,25 +1147,34 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv)
11471147
cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
11481148
1 << slave_port, 0, 0, ALE_MCAST_FWD_2);
11491149

1150-
if (slave->data->phy_node)
1150+
if (slave->data->phy_node) {
11511151
slave->phy = of_phy_connect(priv->ndev, slave->data->phy_node,
11521152
&cpsw_adjust_link, 0, slave->data->phy_if);
1153-
else
1153+
if (!slave->phy) {
1154+
dev_err(priv->dev, "phy \"%s\" not found on slave %d\n",
1155+
slave->data->phy_node->full_name,
1156+
slave->slave_num);
1157+
return;
1158+
}
1159+
} else {
11541160
slave->phy = phy_connect(priv->ndev, slave->data->phy_id,
11551161
&cpsw_adjust_link, slave->data->phy_if);
1156-
if (IS_ERR(slave->phy)) {
1157-
dev_err(priv->dev, "phy %s not found on slave %d\n",
1158-
slave->data->phy_id, slave->slave_num);
1159-
slave->phy = NULL;
1160-
} else {
1161-
phy_attached_info(slave->phy);
1162+
if (IS_ERR(slave->phy)) {
1163+
dev_err(priv->dev,
1164+
"phy \"%s\" not found on slave %d, err %ld\n",
1165+
slave->data->phy_id, slave->slave_num,
1166+
PTR_ERR(slave->phy));
1167+
slave->phy = NULL;
1168+
return;
1169+
}
1170+
}
11621171

1163-
phy_start(slave->phy);
1172+
phy_attached_info(slave->phy);
11641173

1165-
/* Configure GMII_SEL register */
1166-
cpsw_phy_sel(&priv->pdev->dev, slave->phy->interface,
1167-
slave->slave_num);
1168-
}
1174+
phy_start(slave->phy);
1175+
1176+
/* Configure GMII_SEL register */
1177+
cpsw_phy_sel(&priv->pdev->dev, slave->phy->interface, slave->slave_num);
11691178
}
11701179

11711180
static inline void cpsw_add_default_vlan(struct cpsw_priv *priv)

0 commit comments

Comments
 (0)