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 | |
| 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>
| -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 | ||
