[PATCH net] net: do not bond/team netdevices which use ml_priv

Oliver Hartkopp <[email protected]>
Newsgroups org.kernel.vger.netdev
Message-ID <[email protected]>
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 <[email protected]>
---
 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.