diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2010-02-15 15:00:51 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-16 17:53:24 -0500 |
commit | 553f9118abc4fc53674fff87f6fe5fa3f56a41ed (patch) | |
tree | 8b6fcbbfc3709915cc733aa48a49f95d9f930e89 /net | |
parent | 10e7454ed7a2da39f1f6255f63d7df27ab4bb67f (diff) |
xfrm: Fix xfrm_state_clone leak
xfrm_state_clone calls kfree instead of xfrm_state_put to free
a failed state. Depending on the state of the failed state, it
can cause leaks to things like module references.
All states should be freed by xfrm_state_put past the point of
xfrm_init_state.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/xfrm/xfrm_state.c | 12 |
1 files changed, 3 insertions, 9 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index b36cc344474b..f445ea1c5f52 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -1102,7 +1102,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp) | |||
1102 | int err = -ENOMEM; | 1102 | int err = -ENOMEM; |
1103 | struct xfrm_state *x = xfrm_state_alloc(net); | 1103 | struct xfrm_state *x = xfrm_state_alloc(net); |
1104 | if (!x) | 1104 | if (!x) |
1105 | goto error; | 1105 | goto out; |
1106 | 1106 | ||
1107 | memcpy(&x->id, &orig->id, sizeof(x->id)); | 1107 | memcpy(&x->id, &orig->id, sizeof(x->id)); |
1108 | memcpy(&x->sel, &orig->sel, sizeof(x->sel)); | 1108 | memcpy(&x->sel, &orig->sel, sizeof(x->sel)); |
@@ -1160,16 +1160,10 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp) | |||
1160 | return x; | 1160 | return x; |
1161 | 1161 | ||
1162 | error: | 1162 | error: |
1163 | xfrm_state_put(x); | ||
1164 | out: | ||
1163 | if (errp) | 1165 | if (errp) |
1164 | *errp = err; | 1166 | *errp = err; |
1165 | if (x) { | ||
1166 | kfree(x->aalg); | ||
1167 | kfree(x->ealg); | ||
1168 | kfree(x->calg); | ||
1169 | kfree(x->encap); | ||
1170 | kfree(x->coaddr); | ||
1171 | } | ||
1172 | kfree(x); | ||
1173 | return NULL; | 1167 | return NULL; |
1174 | } | 1168 | } |
1175 | 1169 | ||