diff options
author | David Miller <davem@davemloft.net> | 2017-10-10 20:59:38 -0700 |
---|---|---|
committer | Steffen Klassert <steffen.klassert@secunet.com> | 2017-10-11 10:15:58 +0200 |
commit | 10a7ef33679073d13bf1dd05e3f1b7912f999543 (patch) | |
tree | e7f34e807961b7197301792b9181e06f46469e1b /net/xfrm | |
parent | c0576e3975084d4699b7bfef578613fb8e1144f6 (diff) | |
download | linux-10a7ef33679073d13bf1dd05e3f1b7912f999543.tar.gz linux-10a7ef33679073d13bf1dd05e3f1b7912f999543.tar.bz2 linux-10a7ef33679073d13bf1dd05e3f1b7912f999543.zip |
ipsec: Fix dst leak in xfrm_bundle_create().
If we cannot find a suitable inner_mode value, we will leak
the currently allocated 'xdst'.
The fix is to make sure it is linked into the chain before
erroring out.
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/xfrm')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index f06253969972..2746b62a8944 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1573,6 +1573,14 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, goto put_states; } + if (!dst_prev) + dst0 = dst1; + else + /* Ref count is taken during xfrm_alloc_dst() + * No need to do dst_clone() on dst1 + */ + dst_prev->child = dst1; + if (xfrm[i]->sel.family == AF_UNSPEC) { inner_mode = xfrm_ip2inner_mode(xfrm[i], xfrm_af2proto(family)); @@ -1584,14 +1592,6 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, } else inner_mode = xfrm[i]->inner_mode; - if (!dst_prev) - dst0 = dst1; - else - /* Ref count is taken during xfrm_alloc_dst() - * No need to do dst_clone() on dst1 - */ - dst_prev->child = dst1; - xdst->route = dst; dst_copy_metrics(dst1, dst); |