Commit 8ba68464e478 ("bonding: refuse to enslave CAN devices") already addressed a syzbot kernel paging request crash report for bonding. The same problem is also valid for the team device driver as both work on netdevices without taking care of the private mid-layer data structures. To reject ARPHRD_CAN, ARPHRD_IEEE802154, and ARPHRD_IEEE802154_MONITOR netdevices does not solve the root cause of the problem as ml_priv is also used by some ancient ethernet drivers like S/390 or 82596 based drivers. Today those ethernet drivers likely would not use ml_priv at all. Make sure that only capable netdevices are offered to teaming and bonding by checking that ml_priv is unused. Fixes: 8ba68464e478 ("bonding: refuse to enslave CAN devices") Signed-off-by: Oliver Hartkopp --- drivers/net/bonding/bond_main.c | 4 ++-- drivers/net/team/team_core.c | 7 +++++++ include/linux/netdevice.h | 5 +++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 522eab060f9e..bbb344b67458 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1892,13 +1892,13 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev, const struct net_device_ops *slave_ops = slave_dev->netdev_ops; struct slave *new_slave = NULL, *prev_slave; struct sockaddr_storage ss; int res = 0, i; - if (slave_dev->type == ARPHRD_CAN) { + if (netdev_has_ml_priv(slave_dev)) { BOND_NL_ERR(bond_dev, extack, - "CAN devices cannot be enslaved"); + "devices using ml_priv cannot be enslaved"); return -EPERM; } if (slave_dev->flags & IFF_MASTER && !netif_is_bond_master(slave_dev)) { diff --git a/drivers/net/team/team_core.c b/drivers/net/team/team_core.c index feaa75fbf8fc..8bf4c1c5d657 100644 --- a/drivers/net/team/team_core.c +++ b/drivers/net/team/team_core.c @@ -1215,10 +1215,17 @@ static int team_port_add(struct team *team, struct net_device *port_dev, struct net_device *dev = netdev_from_priv(team); struct team_port *port; char *portname = port_dev->name; int err; + if (netdev_has_ml_priv(port_dev)) { + NL_SET_ERR_MSG(extack, "devices using ml_priv can't be added as a team port"); + netdev_err(dev, "Device %s using ml_priv can't be added as a team port\n", + portname); + return -EINVAL; + } + if (port_dev->flags & IFF_LOOPBACK) { NL_SET_ERR_MSG(extack, "Loopback device can't be added as a team port"); netdev_err(dev, "Device %s is loopback device. Loopback devices can't be added as a team port\n", portname); return -EINVAL; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 8840b126979f..74536f642b41 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2784,10 +2784,15 @@ static inline void netdev_set_ml_priv(struct net_device *dev, dev->ml_priv = ml_priv; dev->ml_priv_type = type; } +static inline bool netdev_has_ml_priv(struct net_device *dev) +{ + return (dev->ml_priv != NULL); +} + /* * Net namespace inlines */ static inline struct net *dev_net(const struct net_device *dev) -- 2.53.0