summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteffen Klassert <steffen.klassert@secunet.com>2018-08-01 13:45:11 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-11-04 14:52:37 +0100
commit3b5d512831af3a43303d1c3615a0a7d6c693bce9 (patch)
tree189fb39c219a14846cb47abf4db14bf9173e97c7
parente7405910ca5553eae8744af4e5c03e64ee048cb1 (diff)
downloadlinux-stable-3b5d512831af3a43303d1c3615a0a7d6c693bce9.tar.gz
linux-stable-3b5d512831af3a43303d1c3615a0a7d6c693bce9.tar.bz2
linux-stable-3b5d512831af3a43303d1c3615a0a7d6c693bce9.zip
xfrm: Validate address prefix lengths in the xfrm selector.
[ Upstream commit 07bf7908950a8b14e81aa1807e3c667eab39287a ] We don't validate the address prefix lengths in the xfrm selector we got from userspace. This can lead to undefined behaviour in the address matching functions if the prefix is too big for the given address family. Fix this by checking the prefixes and refuse SA/policy insertation when a prefix is invalid. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: Air Icy <icytxw@gmail.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--net/xfrm/xfrm_user.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 5554d28a32eb..4292347bf45e 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -151,10 +151,16 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
err = -EINVAL;
switch (p->family) {
case AF_INET:
+ if (p->sel.prefixlen_d > 32 || p->sel.prefixlen_s > 32)
+ goto out;
+
break;
case AF_INET6:
#if IS_ENABLED(CONFIG_IPV6)
+ if (p->sel.prefixlen_d > 128 || p->sel.prefixlen_s > 128)
+ goto out;
+
break;
#else
err = -EAFNOSUPPORT;
@@ -1353,10 +1359,16 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
switch (p->sel.family) {
case AF_INET:
+ if (p->sel.prefixlen_d > 32 || p->sel.prefixlen_s > 32)
+ return -EINVAL;
+
break;
case AF_INET6:
#if IS_ENABLED(CONFIG_IPV6)
+ if (p->sel.prefixlen_d > 128 || p->sel.prefixlen_s > 128)
+ return -EINVAL;
+
break;
#else
return -EAFNOSUPPORT;