xfrm: Fix xfrm sel prefix length validation [Linux 4.4.187]

This Linux kernel change "xfrm: Fix xfrm sel prefix length validation" is included in the Linux 4.4.187 release. This change is authored by Anirudh Gupta <anirudhrudr [at] gmail.com> on Tue May 21 20:59:47 2019 +0530. The commit for this change in Linux stable tree is 228b0ef (patch) which is from upstream commit b38ff40. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream b38ff40.

xfrm: Fix xfrm sel prefix length validation

[ Upstream commit b38ff4075a80b4da5cb2202d7965332ca0efb213 ]

Family of src/dst can be different from family of selector src/dst.
Use xfrm selector family to validate address prefix length,
while verifying new sa from userspace.

Validated patch with this command:
ip xfrm state add src 1.1.6.1 dst 1.1.6.2 proto esp spi 4260196 \
reqid 20004 mode tunnel aead "rfc4106(gcm(aes))" \
0x1111016400000000000000000000000044440001 128 \
sel src 1011:1:4::2/128 sel dst 1021:1:4::2/128 dev Port5

Fixes: 07bf7908950a ("xfrm: Validate address prefix lengths in the xfrm selector.")
Signed-off-by: Anirudh Gupta <anirudh.gupta@sophos.com>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>

There are 16 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 net/xfrm/xfrm_user.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index b04c030..10fda9a 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -151,6 +151,22 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
    err = -EINVAL;
    switch (p->family) {
    case AF_INET:
+       break;
+
+   case AF_INET6:
+#if IS_ENABLED(CONFIG_IPV6)
+       break;
+#else
+       err = -EAFNOSUPPORT;
+       goto out;
+#endif
+
+   default:
+       goto out;
+   }
+
+   switch (p->sel.family) {
+   case AF_INET:
        if (p->sel.prefixlen_d > 32 || p->sel.prefixlen_s > 32)
            goto out;

Leave a Reply

Your email address will not be published. Required fields are marked *