From: Antony Antony Extract verify_xfrm_family() and verify_selector_prefixlen() from verify_newsa_info() to allow reuse by other netlink handlers. verify_xfrm_family() validates that a given address family is AF_INET or AF_INET6 (with CONFIG_IPV6 guard). verify_selector_prefixlen() validates that the selector prefix lengths are within the bounds for the given address family. No functional change. Signed-off-by: Antony Antony Signed-off-by: Steffen Klassert --- net/xfrm/xfrm_user.c | 80 ++++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 62eccdbe245f..de857ef65b2f 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -264,66 +264,74 @@ static int verify_mtimer_thresh(bool has_encap, u8 dir, return 0; } -static int verify_newsa_info(struct xfrm_usersa_info *p, - struct nlattr **attrs, - struct netlink_ext_ack *extack) +static int verify_xfrm_family(u16 family, struct netlink_ext_ack *extack) { - int err; - u8 sa_dir = nla_get_u8_default(attrs[XFRMA_SA_DIR], 0); - u16 family = p->sel.family; - - err = -EINVAL; - switch (p->family) { + switch (family) { case AF_INET: - break; - + return 0; case AF_INET6: #if IS_ENABLED(CONFIG_IPV6) - break; + return 0; #else - err = -EAFNOSUPPORT; NL_SET_ERR_MSG(extack, "IPv6 support disabled"); - goto out; + return -EAFNOSUPPORT; #endif - default: NL_SET_ERR_MSG(extack, "Invalid address family"); - goto out; + return -EINVAL; } +} - if (!family && !(p->flags & XFRM_STATE_AF_UNSPEC)) - family = p->family; - +static int verify_selector_prefixlen(u16 family, + const struct xfrm_selector *sel, + struct netlink_ext_ack *extack) +{ switch (family) { case AF_UNSPEC: - break; - + return 0; case AF_INET: - 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)"); - goto out; + if (sel->prefixlen_d > 32 || sel->prefixlen_s > 32) { + NL_SET_ERR_MSG(extack, + "Invalid prefix length in selector (must be <= 32 for IPv4)"); + return -EINVAL; } - - break; - + return 0; case AF_INET6: #if IS_ENABLED(CONFIG_IPV6) - 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)"); - goto out; + if (sel->prefixlen_d > 128 || sel->prefixlen_s > 128) { + NL_SET_ERR_MSG(extack, + "Invalid prefix length in selector (must be <= 128 for IPv6)"); + return -EINVAL; } - - break; + return 0; #else NL_SET_ERR_MSG(extack, "IPv6 support disabled"); - err = -EAFNOSUPPORT; - goto out; + return -EAFNOSUPPORT; #endif - default: NL_SET_ERR_MSG(extack, "Invalid address family in selector"); - goto out; + return -EINVAL; } +} + +static int verify_newsa_info(struct xfrm_usersa_info *p, + struct nlattr **attrs, + struct netlink_ext_ack *extack) +{ + int err; + u8 sa_dir = nla_get_u8_default(attrs[XFRMA_SA_DIR], 0); + u16 family = p->sel.family; + + err = verify_xfrm_family(p->family, extack); + if (err) + goto out; + + if (!family && !(p->flags & XFRM_STATE_AF_UNSPEC)) + family = p->family; + + err = verify_selector_prefixlen(family, &p->sel, extack); + if (err) + goto out; err = -EINVAL; switch (p->id.proto) { -- 2.43.0