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>
This commit is contained in:
Herbert Xu 2010-02-15 20:00:51 +00:00 committed by David S. Miller
parent 10e7454ed7
commit 553f9118ab

View file

@ -1102,7 +1102,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp)
int err = -ENOMEM; int err = -ENOMEM;
struct xfrm_state *x = xfrm_state_alloc(net); struct xfrm_state *x = xfrm_state_alloc(net);
if (!x) if (!x)
goto error; goto out;
memcpy(&x->id, &orig->id, sizeof(x->id)); memcpy(&x->id, &orig->id, sizeof(x->id));
memcpy(&x->sel, &orig->sel, sizeof(x->sel)); 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)
return x; return x;
error: error:
xfrm_state_put(x);
out:
if (errp) if (errp)
*errp = err; *errp = err;
if (x) {
kfree(x->aalg);
kfree(x->ealg);
kfree(x->calg);
kfree(x->encap);
kfree(x->coaddr);
}
kfree(x);
return NULL; return NULL;
} }