Re: [bug report] mlxsw: spectrum_switchdev: Replay switchdev objects on port join

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dan Carpenter <dan.carpenter@xxxxxxxxxx> writes:

> Hello Petr Machata,
>
> The patch ec4643ca3d98: "mlxsw: spectrum_switchdev: Replay switchdev
> objects on port join" from Jul 19, 2023 (linux-next), leads to the
> following Smatch static checker warning:
>
> 	drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c:2679 mlxsw_sp_bridge_8021d_port_join()
> 	error: we previously assumed 'mlxsw_sp_port_vlan->fid' could be null (see line 2664)

Thanks for the report!

> drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
>     2642 static int
>     2643 mlxsw_sp_bridge_8021d_port_join(struct mlxsw_sp_bridge_device *bridge_device,
>     2644                                 struct mlxsw_sp_bridge_port *bridge_port,
>     2645                                 struct mlxsw_sp_port *mlxsw_sp_port,
>     2646                                 struct netlink_ext_ack *extack)
>     2647 {
>     2648         struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
>     2649         struct net_device *dev = bridge_port->dev;
>     2650         u16 vid;
>     2651         int err;
>     2652 
>     2653         vid = is_vlan_dev(dev) ? vlan_dev_vlan_id(dev) : MLXSW_SP_DEFAULT_VID;
>     2654         mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid);
>     2655         if (WARN_ON(!mlxsw_sp_port_vlan))
>     2656                 return -EINVAL;
>     2657 
>     2658         if (mlxsw_sp_port_is_br_member(mlxsw_sp_port, bridge_device->dev)) {
>     2659                 NL_SET_ERR_MSG_MOD(extack, "Can not bridge VLAN uppers of the same port");
>     2660                 return -EINVAL;
>     2661         }
>     2662 
>     2663         /* Port is no longer usable as a router interface */
>     2664         if (mlxsw_sp_port_vlan->fid)
>
> This has a check for NULL.
>
>     2665                 mlxsw_sp_port_vlan_router_leave(mlxsw_sp_port_vlan);

The function mlxsw_sp_bridge_8021d_port_join() deals only with
VLAN-unaware bridges. It is invoked in response to netlink changeupper
notifications.

If there is a FID in that situation, it cannot be a VLAN FID, it must be
a router FID. So leave the router. So as of line 2666,
mlxsw_sp_port_vlan->fid is NULL.

>     2666 
>     2667         err = mlxsw_sp_port_vlan_bridge_join(mlxsw_sp_port_vlan, bridge_port,
>     2668                                              extack);
>
> Most of the time this would set ->fid but if mlxsw_sp_port_vlan->bridge_port
> then it wouldn't

mlxsw_sp_port_vlan->bridge_port is only ever set in one place, later in
mlxsw_sp_port_vlan_bridge_join(). So if it is set, we have been through
that function once already. In that case, mlxsw_sp_port_vlan->fid is
already non-NULL and nothing needs to be done.

This is only relevant for 802.1q bridges, when PVID / egress_untagged
flags change on a VLAN. Here we deal with 802.1d bridges, where it ought
not to happen.

mlxsw_sp_port_vlan_bridge_join() then constructs the proper 802.1d FID.
At line 2671, mlxsw_sp_port_vlan->fid is non-NULL.

>
>     2669         if (err)
>     2670                 return err;
>     2671 
>     2672         err = mlxsw_sp_bridge_port_replay(bridge_port, mlxsw_sp_port, extack);
>     2673         if (err)
>     2674                 goto err_replay;
>     2675 
>     2676         return 0;
>     2677 
>     2678 err_replay:
> --> 2679         mlxsw_sp_port_vlan_bridge_leave(mlxsw_sp_port_vlan);
>
> ->fid dereferenced without being checked.

And we rely on that here.

>
>     2680         return err;
>     2681 }
>
> regards,
> dan carpenter




[Index of Archives]     [Kernel Development]     [Kernel Announce]     [Kernel Newbies]     [Linux Networking Development]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Device Mapper]

  Powered by Linux