summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorSteffen Klassert <steffen.klassert@secunet.com>2018-01-10 12:14:28 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-01-31 14:03:41 +0100
commitceab06885c09f685910779a8685b7659d66de4b5 (patch)
tree5bf04521c572a53012746989390077c95fd0c902 /net
parent19848ca7b7dad5153860239c893c1eadd603217e (diff)
downloadlinux-stable-ceab06885c09f685910779a8685b7659d66de4b5.tar.gz
linux-stable-ceab06885c09f685910779a8685b7659d66de4b5.tar.bz2
linux-stable-ceab06885c09f685910779a8685b7659d66de4b5.zip
xfrm: Fix a race in the xdst pcpu cache.
commit 76a4201191814a0061cb5c861fafb9ecaa764846 upstream. We need to run xfrm_resolve_and_create_bundle() with bottom halves off. Otherwise we may reuse an already released dst_enty when the xfrm lookup functions are called from process context. Fixes: c30d78c14a813db39a647b6a348b428 ("xfrm: add xdst pcpu cache") Reported-by: Darius Ski <darius.ski@gmail.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> Acked-by: David Miller <davem@davemloft.net>, Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net')
-rw-r--r--net/xfrm/xfrm_policy.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 6bc16bb61b55..688ed34f0671 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2056,8 +2056,11 @@ xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir,
if (num_xfrms <= 0)
goto make_dummy_bundle;
+ local_bh_disable();
xdst = xfrm_resolve_and_create_bundle(pols, num_pols, fl, family,
- xflo->dst_orig);
+ xflo->dst_orig);
+ local_bh_enable();
+
if (IS_ERR(xdst)) {
err = PTR_ERR(xdst);
if (err != -EAGAIN)
@@ -2144,9 +2147,12 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
goto no_transform;
}
+ local_bh_disable();
xdst = xfrm_resolve_and_create_bundle(
pols, num_pols, fl,
family, dst_orig);
+ local_bh_enable();
+
if (IS_ERR(xdst)) {
xfrm_pols_put(pols, num_pols);
err = PTR_ERR(xdst);