ethtool: fix reference leak in ethnl_set_privflags()
authorMichal Kubecek <mkubecek@suse.cz>
Fri, 27 Mar 2020 23:01:03 +0000 (00:01 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 30 Mar 2020 05:32:36 +0000 (22:32 -0700)
Andrew noticed that some handlers for *_SET commands leak a netdev
reference if required ethtool_ops callbacks do not exist. One of them is
ethnl_set_privflags(), a simple reproducer would be e.g.

  ip link add veth1 type veth peer name veth2
  ethtool --set-priv-flags veth1 foo on
  ip link del veth1

Make sure dev_put() is called when ethtool_ops check fails.

Fixes: f265d799596a ("ethtool: set device private flags with PRIVFLAGS_SET request")
Reported-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ethtool/privflags.c

index e8f03b33db9b1bc8a608bee072bd6bf81edf660d..77447dceb109f01d1123b482740ba81f0992fdc2 100644 (file)
@@ -175,9 +175,10 @@ int ethnl_set_privflags(struct sk_buff *skb, struct genl_info *info)
                return ret;
        dev = req_info.dev;
        ops = dev->ethtool_ops;
+       ret = -EOPNOTSUPP;
        if (!ops->get_priv_flags || !ops->set_priv_flags ||
            !ops->get_sset_count || !ops->get_strings)
-               return -EOPNOTSUPP;
+               goto out_dev;
 
        rtnl_lock();
        ret = ethnl_ops_begin(dev);
@@ -204,6 +205,7 @@ out_ops:
        ethnl_ops_complete(dev);
 out_rtnl:
        rtnl_unlock();
+out_dev:
        dev_put(dev);
        return ret;
 }