]> git.baikalelectronics.ru Git - kernel.git/commitdiff
ethtool: reject unrecognized request flags
authorMichal Kubecek <mkubecek@suse.cz>
Sun, 15 Mar 2020 17:17:53 +0000 (18:17 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 16 Mar 2020 09:04:24 +0000 (02:04 -0700)
As pointed out by Jakub Kicinski, we ethtool netlink code should respond
with an error if request head has flags set which are not recognized by
kernel, either as a mistake or because it expects functionality introduced
in later kernel versions.

To avoid unnecessary roundtrips, use extack cookie to provide the
information about supported request flags.

Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ethtool/netlink.c

index 180c194fab0768848b14ee58f488257ff06c4c5d..fc9e0b80688982e6087e58216bc1d30a61c4cdfe 100644 (file)
@@ -40,6 +40,7 @@ int ethnl_parse_header(struct ethnl_req_info *req_info,
        struct nlattr *tb[ETHTOOL_A_HEADER_MAX + 1];
        const struct nlattr *devname_attr;
        struct net_device *dev = NULL;
+       u32 flags = 0;
        int ret;
 
        if (!header) {
@@ -50,8 +51,17 @@ int ethnl_parse_header(struct ethnl_req_info *req_info,
                               ethnl_header_policy, extack);
        if (ret < 0)
                return ret;
-       devname_attr = tb[ETHTOOL_A_HEADER_DEV_NAME];
+       if (tb[ETHTOOL_A_HEADER_FLAGS]) {
+               flags = nla_get_u32(tb[ETHTOOL_A_HEADER_FLAGS]);
+               if (flags & ~ETHTOOL_FLAG_ALL) {
+                       NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_HEADER_FLAGS],
+                                           "unrecognized request flags");
+                       nl_set_extack_cookie_u32(extack, ETHTOOL_FLAG_ALL);
+                       return -EOPNOTSUPP;
+               }
+       }
 
+       devname_attr = tb[ETHTOOL_A_HEADER_DEV_NAME];
        if (tb[ETHTOOL_A_HEADER_DEV_INDEX]) {
                u32 ifindex = nla_get_u32(tb[ETHTOOL_A_HEADER_DEV_INDEX]);
 
@@ -90,9 +100,7 @@ int ethnl_parse_header(struct ethnl_req_info *req_info,
        }
 
        req_info->dev = dev;
-       if (tb[ETHTOOL_A_HEADER_FLAGS])
-               req_info->flags = nla_get_u32(tb[ETHTOOL_A_HEADER_FLAGS]);
-
+       req_info->flags = flags;
        return 0;
 }