Skip to content

Commit 587acad

Browse files
karstengrkuba-moo
authored andcommitted
net/smc: Fix NULL pointer dereferencing in smc_vlan_by_tcpsk()
Coverity reports a possible NULL dereferencing problem: in smc_vlan_by_tcpsk(): 6. returned_null: netdev_lower_get_next returns NULL (checked 29 out of 30 times). 7. var_assigned: Assigning: ndev = NULL return value from netdev_lower_get_next. 1623 ndev = (struct net_device *)netdev_lower_get_next(ndev, &lower); CID 1468509 (#1 of 1): Dereference null return value (NULL_RETURNS) 8. dereference: Dereferencing a pointer that might be NULL ndev when calling is_vlan_dev. 1624 if (is_vlan_dev(ndev)) { Remove the manual implementation and use netdev_walk_all_lower_dev() to iterate over the lower devices. While on it remove an obsolete function parameter comment. Fixes: cb9d43f ("net/smc: determine vlan_id of stacked net_device") Suggested-by: Julian Wiedmann <[email protected]> Signed-off-by: Karsten Graul <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 06e5ba7 commit 587acad

File tree

1 file changed

+18
-17
lines changed

1 file changed

+18
-17
lines changed

net/smc/smc_core.c

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1672,14 +1672,26 @@ static void smc_link_down_work(struct work_struct *work)
16721672
mutex_unlock(&lgr->llc_conf_mutex);
16731673
}
16741674

1675-
/* Determine vlan of internal TCP socket.
1676-
* @vlan_id: address to store the determined vlan id into
1677-
*/
1675+
static int smc_vlan_by_tcpsk_walk(struct net_device *lower_dev,
1676+
struct netdev_nested_priv *priv)
1677+
{
1678+
unsigned short *vlan_id = (unsigned short *)priv->data;
1679+
1680+
if (is_vlan_dev(lower_dev)) {
1681+
*vlan_id = vlan_dev_vlan_id(lower_dev);
1682+
return 1;
1683+
}
1684+
1685+
return 0;
1686+
}
1687+
1688+
/* Determine vlan of internal TCP socket. */
16781689
int smc_vlan_by_tcpsk(struct socket *clcsock, struct smc_init_info *ini)
16791690
{
16801691
struct dst_entry *dst = sk_dst_get(clcsock->sk);
1692+
struct netdev_nested_priv priv;
16811693
struct net_device *ndev;
1682-
int i, nest_lvl, rc = 0;
1694+
int rc = 0;
16831695

16841696
ini->vlan_id = 0;
16851697
if (!dst) {
@@ -1697,20 +1709,9 @@ int smc_vlan_by_tcpsk(struct socket *clcsock, struct smc_init_info *ini)
16971709
goto out_rel;
16981710
}
16991711

1712+
priv.data = (void *)&ini->vlan_id;
17001713
rtnl_lock();
1701-
nest_lvl = ndev->lower_level;
1702-
for (i = 0; i < nest_lvl; i++) {
1703-
struct list_head *lower = &ndev->adj_list.lower;
1704-
1705-
if (list_empty(lower))
1706-
break;
1707-
lower = lower->next;
1708-
ndev = (struct net_device *)netdev_lower_get_next(ndev, &lower);
1709-
if (is_vlan_dev(ndev)) {
1710-
ini->vlan_id = vlan_dev_vlan_id(ndev);
1711-
break;
1712-
}
1713-
}
1714+
netdev_walk_all_lower_dev(ndev, smc_vlan_by_tcpsk_walk, &priv);
17141715
rtnl_unlock();
17151716

17161717
out_rel:

0 commit comments

Comments
 (0)