diff options
Diffstat (limited to 'main/linux-grsec/0021-xfrm-do-not-assume-that-template-resolving-always-returns-xfrms.patch')
-rw-r--r-- | main/linux-grsec/0021-xfrm-do-not-assume-that-template-resolving-always-returns-xfrms.patch | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/main/linux-grsec/0021-xfrm-do-not-assume-that-template-resolving-always-returns-xfrms.patch b/main/linux-grsec/0021-xfrm-do-not-assume-that-template-resolving-always-returns-xfrms.patch new file mode 100644 index 000000000..bc660dd5c --- /dev/null +++ b/main/linux-grsec/0021-xfrm-do-not-assume-that-template-resolving-always-returns-xfrms.patch @@ -0,0 +1,66 @@ +From d809ec895505e6f35fb1965f0946381ab4eaa474 Mon Sep 17 00:00:00 2001 +From: =?utf8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi> +Date: Mon, 12 Jul 2010 21:29:42 +0000 +Subject: [PATCH] xfrm: do not assume that template resolving always returns xfrms +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf8 +Content-Transfer-Encoding: 8bit + +xfrm_resolve_and_create_bundle() assumed that, if policies indicated +presence of xfrms, bundle template resolution would always return +some xfrms. This is not true for 'use' level policies which can +result in no xfrm's being applied if there is no suitable xfrm states. +This fixes a crash by this incorrect assumption. + +Reported-by: George Spelvin <linux@horizon.com> +Bisected-by: George Spelvin <linux@horizon.com> +Tested-by: George Spelvin <linux@horizon.com> +Signed-off-by: Timo Teräs <timo.teras@iki.fi> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + net/xfrm/xfrm_policy.c | 15 +++++++++++++-- + 1 files changed, 13 insertions(+), 2 deletions(-) + +diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c +index af1c173..a7ec5a8 100644 +--- a/net/xfrm/xfrm_policy.c ++++ b/net/xfrm/xfrm_policy.c +@@ -1594,8 +1594,8 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols, + + /* Try to instantiate a bundle */ + err = xfrm_tmpl_resolve(pols, num_pols, fl, xfrm, family); +- if (err < 0) { +- if (err != -EAGAIN) ++ if (err <= 0) { ++ if (err != 0 && err != -EAGAIN) + XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR); + return ERR_PTR(err); + } +@@ -1678,6 +1678,13 @@ xfrm_bundle_lookup(struct net *net, struct flowi *fl, u16 family, u8 dir, + goto make_dummy_bundle; + dst_hold(&xdst->u.dst); + return oldflo; ++ } else if (new_xdst == NULL) { ++ num_xfrms = 0; ++ if (oldflo == NULL) ++ goto make_dummy_bundle; ++ xdst->num_xfrms = 0; ++ dst_hold(&xdst->u.dst); ++ return oldflo; + } + + /* Kill the previous bundle */ +@@ -1760,6 +1767,10 @@ restart: + xfrm_pols_put(pols, num_pols); + err = PTR_ERR(xdst); + goto dropdst; ++ } else if (xdst == NULL) { ++ num_xfrms = 0; ++ drop_pols = num_pols; ++ goto no_transform; + } + + spin_lock_bh(&xfrm_policy_sk_bundle_lock); +-- +1.7.1.1 + |