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.kicin...@netronome.com>
---
CC: ktk...@virtuozzo.com
CC: nicolas.dich...@6wind.com
---
 net/core/net_namespace.c | 38 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index b02fb19df2cc..17f36317363d 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -778,6 +778,41 @@ static int rtnl_net_fill(struct sk_buff *skb, struct 
net_fill_args *args)
        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]) {
-- 
2.19.2

Reply via email to