]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 4 Aug 2017 22:24:17 +0000 (15:24 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 4 Aug 2017 22:24:17 +0000 (15:24 -0700)
added patches:
xfrm-don-t-use-sk_family-for-socket-policy-lookups.patch

queue-3.18/series
queue-3.18/xfrm-don-t-use-sk_family-for-socket-policy-lookups.patch [new file with mode: 0644]

index fe2e5cfa54dc634ce1666a31c389bb2bcab21588..404c73c63fc6a83d7186a5b527f8ca2ce39f27ff 100644 (file)
@@ -47,3 +47,4 @@ vfio-pci-use-32-bit-comparisons-for-register-address-for-gcc-4.5.patch
 asoc-tlv320aic3x-mark-the-reset-register-as-volatile.patch
 spi-dw-make-debugfs-name-unique-between-instances.patch
 vlan-propagate-mac-address-to-vlans.patch
+xfrm-don-t-use-sk_family-for-socket-policy-lookups.patch
diff --git a/queue-3.18/xfrm-don-t-use-sk_family-for-socket-policy-lookups.patch b/queue-3.18/xfrm-don-t-use-sk_family-for-socket-policy-lookups.patch
new file mode 100644 (file)
index 0000000..b07abbf
--- /dev/null
@@ -0,0 +1,63 @@
+From 4c86d77743a54fb2d8a4d18a037a074c892bb3be Mon Sep 17 00:00:00 2001
+From: Steffen Klassert <steffen.klassert@secunet.com>
+Date: Tue, 14 Feb 2017 07:43:56 +0100
+Subject: xfrm: Don't use sk_family for socket policy lookups
+
+From: Steffen Klassert <steffen.klassert@secunet.com>
+
+commit 4c86d77743a54fb2d8a4d18a037a074c892bb3be upstream.
+
+On IPv4-mapped IPv6 addresses sk_family is AF_INET6,
+but the flow informations are created based on AF_INET.
+So the routing set up 'struct flowi4' but we try to
+access 'struct flowi6' what leads to an out of bounds
+access. Fix this by using the family we get with the
+dst_entry, like we do it for the standard policy lookup.
+
+Reported-by: Dmitry Vyukov <dvyukov@google.com>
+Tested-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/xfrm/xfrm_policy.c |    9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1211,15 +1211,14 @@ static inline int policy_to_flow_dir(int
+ }
+ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir,
+-                                               const struct flowi *fl)
++                                               const struct flowi *fl, u16 family)
+ {
+       struct xfrm_policy *pol;
+       struct net *net = sock_net(sk);
+       read_lock_bh(&net->xfrm.xfrm_policy_lock);
+       if ((pol = sk->sk_policy[dir]) != NULL) {
+-              bool match = xfrm_selector_match(&pol->selector, fl,
+-                                               sk->sk_family);
++              bool match = xfrm_selector_match(&pol->selector, fl, family);
+               int err = 0;
+               if (match) {
+@@ -2150,7 +2149,7 @@ struct dst_entry *xfrm_lookup(struct net
+       if (sk && sk->sk_policy[XFRM_POLICY_OUT]) {
+               num_pols = 1;
+-              pols[0] = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl);
++              pols[0] = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl, family);
+               err = xfrm_expand_policies(fl, family, pols,
+                                          &num_pols, &num_xfrms);
+               if (err < 0)
+@@ -2428,7 +2427,7 @@ int __xfrm_policy_check(struct sock *sk,
+       pol = NULL;
+       if (sk && sk->sk_policy[dir]) {
+-              pol = xfrm_sk_policy_lookup(sk, dir, &fl);
++              pol = xfrm_sk_policy_lookup(sk, dir, &fl, family);
+               if (IS_ERR(pol)) {
+                       XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLERROR);
+                       return 0;