From 845f95c8c58ed2b221d26b7dce8aefcbcdf8ea60 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 4 Aug 2017 15:24:17 -0700 Subject: [PATCH] 3.18-stable patches added patches: xfrm-don-t-use-sk_family-for-socket-policy-lookups.patch --- queue-3.18/series | 1 + ...-sk_family-for-socket-policy-lookups.patch | 63 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 queue-3.18/xfrm-don-t-use-sk_family-for-socket-policy-lookups.patch diff --git a/queue-3.18/series b/queue-3.18/series index fe2e5cfa54d..404c73c63fc 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -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 index 00000000000..b07abbf3acf --- /dev/null +++ b/queue-3.18/xfrm-don-t-use-sk_family-for-socket-policy-lookups.patch @@ -0,0 +1,63 @@ +From 4c86d77743a54fb2d8a4d18a037a074c892bb3be Mon Sep 17 00:00:00 2001 +From: Steffen Klassert +Date: Tue, 14 Feb 2017 07:43:56 +0100 +Subject: xfrm: Don't use sk_family for socket policy lookups + +From: Steffen Klassert + +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 +Tested-by: Dmitry Vyukov +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman + +--- + 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; -- 2.47.3