From c0c60a1d1dc451a51136867b51df6a4ec34e336b Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 17 Feb 2019 15:16:22 -0800 Subject: [PATCH] net: dsa: Prevent oops while enslaving non-DSA devices DSA currently does not check that the target network device of a switchdev operation is actually a DSA slave network device Signed-off-by: Florian Fainelli --- net/dsa/slave.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 1c45c1d6d241..3ceef299b030 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -278,9 +278,14 @@ static int dsa_slave_port_attr_set(struct net_device *dev, const struct switchdev_attr *attr, struct switchdev_trans *trans) { - struct dsa_port *dp = dsa_slave_to_port(dev); + struct dsa_port *dp; int ret; + if (!dsa_slave_dev_check(dev)) + return -EOPNOTSUPP; + + dp = dsa_slave_to_port(dev); + switch (attr->id) { case SWITCHDEV_ATTR_ID_PORT_STP_STATE: ret = dsa_port_set_state(dp, attr->u.stp_state, trans); @@ -304,9 +309,14 @@ static int dsa_slave_port_obj_add(struct net_device *dev, const struct switchdev_obj *obj, struct switchdev_trans *trans) { - struct dsa_port *dp = dsa_slave_to_port(dev); + struct dsa_port *dp; int err; + if (!dsa_slave_dev_check(dev)) + return -EOPNOTSUPP; + + dp = dsa_slave_to_port(dev); + /* For the prepare phase, ensure the full set of changes is feasable in * one go in order to signal a failure properly. If an operation is not * supported, return -EOPNOTSUPP. @@ -338,9 +348,14 @@ static int dsa_slave_port_obj_add(struct net_device *dev, static int dsa_slave_port_obj_del(struct net_device *dev, const struct switchdev_obj *obj) { - struct dsa_port *dp = dsa_slave_to_port(dev); + struct dsa_port *dp; int err; + if (!dsa_slave_dev_check(dev)) + return -EOPNOTSUPP; + + dp = dsa_slave_to_port(dev); + switch (obj->id) { case SWITCHDEV_OBJ_ID_PORT_MDB: err = dsa_port_mdb_del(dp, SWITCHDEV_OBJ_PORT_MDB(obj)); @@ -365,9 +380,16 @@ static int dsa_slave_port_obj_del(struct net_device *dev, static int dsa_slave_port_attr_get(struct net_device *dev, struct switchdev_attr *attr) { - struct dsa_port *dp = dsa_slave_to_port(dev); - struct dsa_switch *ds = dp->ds; - struct dsa_switch_tree *dst = ds->dst; + struct dsa_switch_tree *dst; + struct dsa_switch *ds; + struct dsa_port *dp; + + if (!dsa_slave_dev_check(dev)) + return -EOPNOTSUPP; + + dp = dsa_slave_to_port(dev); + ds = dp->ds; + dst = ds->dst; switch (attr->id) { case SWITCHDEV_ATTR_ID_PORT_PARENT_ID: -- 2.17.1