xfrm: add extack support to verify_newpolicy_info
authorSabrina Dubroca <sd@queasysnail.net>
Tue, 30 Aug 2022 14:23:08 +0000 (16:23 +0200)
committerSteffen Klassert <steffen.klassert@secunet.com>
Wed, 31 Aug 2022 09:23:46 +0000 (11:23 +0200)
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
net/xfrm/xfrm_user.c

index cfa35d76fb7e1f6e444d65348552ad4b4958c871..fa6024b2c88bbe87f818ce370b32c201ba1a393c 100644 (file)
@@ -1512,7 +1512,8 @@ static int verify_policy_type(u8 type)
        return 0;
 }
 
-static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
+static int verify_newpolicy_info(struct xfrm_userpolicy_info *p,
+                                struct netlink_ext_ack *extack)
 {
        int ret;
 
@@ -1524,6 +1525,7 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
                break;
 
        default:
+               NL_SET_ERR_MSG(extack, "Invalid policy share");
                return -EINVAL;
        }
 
@@ -1533,35 +1535,44 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
                break;
 
        default:
+               NL_SET_ERR_MSG(extack, "Invalid policy action");
                return -EINVAL;
        }
 
        switch (p->sel.family) {
        case AF_INET:
-               if (p->sel.prefixlen_d > 32 || p->sel.prefixlen_s > 32)
+               if (p->sel.prefixlen_d > 32 || p->sel.prefixlen_s > 32) {
+                       NL_SET_ERR_MSG(extack, "Invalid prefix length in selector (must be <= 32 for IPv4)");
                        return -EINVAL;
+               }
 
                break;
 
        case AF_INET6:
 #if IS_ENABLED(CONFIG_IPV6)
-               if (p->sel.prefixlen_d > 128 || p->sel.prefixlen_s > 128)
+               if (p->sel.prefixlen_d > 128 || p->sel.prefixlen_s > 128) {
+                       NL_SET_ERR_MSG(extack, "Invalid prefix length in selector (must be <= 128 for IPv6)");
                        return -EINVAL;
+               }
 
                break;
 #else
+               NL_SET_ERR_MSG(extack, "IPv6 support disabled");
                return  -EAFNOSUPPORT;
 #endif
 
        default:
+               NL_SET_ERR_MSG(extack, "Invalid selector family");
                return -EINVAL;
        }
 
        ret = verify_policy_dir(p->dir);
        if (ret)
                return ret;
-       if (p->index && (xfrm_policy_id2dir(p->index) != p->dir))
+       if (p->index && (xfrm_policy_id2dir(p->index) != p->dir)) {
+               NL_SET_ERR_MSG(extack, "Policy index doesn't match direction");
                return -EINVAL;
+       }
 
        return 0;
 }
@@ -1768,7 +1779,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
        int err;
        int excl;
 
-       err = verify_newpolicy_info(p);
+       err = verify_newpolicy_info(p, extack);
        if (err)
                return err;
        err = verify_sec_ctx_len(attrs);
@@ -2501,7 +2512,7 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
 
        xfrm_mark_get(attrs, &mark);
 
-       err = verify_newpolicy_info(&ua->policy);
+       err = verify_newpolicy_info(&ua->policy, extack);
        if (err)
                goto free_state;
        err = verify_sec_ctx_len(attrs);
@@ -3284,7 +3295,7 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
        *dir = -EINVAL;
 
        if (len < sizeof(*p) ||
-           verify_newpolicy_info(p))
+           verify_newpolicy_info(p, NULL))
                return NULL;
 
        nr = ((len - sizeof(*p)) / sizeof(*ut));