net: namespace: perform strict checks also for doit handlers
authorJakub Kicinski <jakub.kicinski@netronome.com>
Fri, 18 Jan 2019 18:46:17 +0000 (10:46 -0800)
committerDavid S. Miller <davem@davemloft.net>
Sat, 19 Jan 2019 18:09:58 +0000 (10:09 -0800)
Make RTM_GETNSID's doit handler use strict checks when
NETLINK_F_STRICT_CHK is set.

v2: - don't check size >= sizeof(struct rtgenmsg) (Nicolas).

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/net_namespace.c

index b02fb19df2cc593bfd49814f1315849d12f1d5a8..17f36317363d19dcdeb6a6e75a116220b078c2b0 100644 (file)
@@ -778,6 +778,41 @@ nla_put_failure:
        return -EMSGSIZE;
 }
 
+static int rtnl_net_valid_getid_req(struct sk_buff *skb,
+                                   const struct nlmsghdr *nlh,
+                                   struct nlattr **tb,
+                                   struct netlink_ext_ack *extack)
+{
+       int i, err;
+
+       if (!netlink_strict_get_check(skb))
+               return nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, NETNSA_MAX,
+                                  rtnl_net_policy, extack);
+
+       err = nlmsg_parse_strict(nlh, sizeof(struct rtgenmsg), tb, NETNSA_MAX,
+                                rtnl_net_policy, extack);
+       if (err)
+               return err;
+
+       for (i = 0; i <= NETNSA_MAX; i++) {
+               if (!tb[i])
+                       continue;
+
+               switch (i) {
+               case NETNSA_PID:
+               case NETNSA_FD:
+               case NETNSA_NSID:
+               case NETNSA_TARGET_NSID:
+                       break;
+               default:
+                       NL_SET_ERR_MSG(extack, "Unsupported attribute in peer netns getid request");
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
 static int rtnl_net_getid(struct sk_buff *skb, struct nlmsghdr *nlh,
                          struct netlink_ext_ack *extack)
 {
@@ -793,8 +828,7 @@ static int rtnl_net_getid(struct sk_buff *skb, struct nlmsghdr *nlh,
        struct sk_buff *msg;
        int err;
 
-       err = nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, NETNSA_MAX,
-                         rtnl_net_policy, extack);
+       err = rtnl_net_valid_getid_req(skb, nlh, tb, extack);
        if (err < 0)
                return err;
        if (tb[NETNSA_PID]) {