: Fix leak of expired xfrm_states
Subsystems (3)
This patch fixes a xfrm_state leak, which appears to be a regression from the reference count simplifications.
commit 817252c2a475371f9764883c7d0f0cde63b3cfe8
Author: Patrick McHardy <[email protected]> Date: Mon Nov 26 16:00:50 2007 +0100
[XFRM]: Fix leak of expired xfrm_states
The xfrm_timer calls __xfrm_state_delete, which drops the final reference manually without triggering destruction of the state.
net/xfrm/xfrm_state.c +5 -1
@@ -416,7 +416,7 @@ static inline unsigned long make_jiffies(long secs)static void xfrm_timer_handler (unsigned long data) { -struct xfrm_state *x = (struct xfrm_state *)data; +struct xfrm_state *x = (struct xfrm_state *)data, *del =NULL ;unsigned long now =get_seconds ();long next =LONG_MAX ;int warn =0 ;
@@ -479,6 +479,8 @@ expired: goto resched; } + del = x; +xfrm_state_hold (del); err =__xfrm_state_delete (x);if (!err && x->id.spi)km_state_expired (x,1 ,0 );
@@ -488,6 +490,8 @@ expired: out:spin_unlock (&x->lock); +if (del) +xfrm_state_put (del); }static void xfrm_replay_timer_handler (unsigned long data);
Herbert Xu
maintainerQuoted 2 lines · Patrick McHardy
This patch fixes a
xfrm_stateleak, which appears to be a regression from the reference count simplifications.
I was going to say this was a good find :)
But digging deeper it seems that it might not be a bug after all. Even though the ref count on x may now drop to zero, it won't be freed until del_timer_sync returns which should be sufficient, no?
Thanks,
Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txtQuoted 10 lines · Herbert Xu
Quoted 2 lines · Patrick McHardy
This patch fixes a
xfrm_stateleak, which appears to be a regression from the reference count simplifications.I was going to say this was a good find :)
But digging deeper it seems that it might not be a bug after all. Even though the ref count on x may now drop to zero, it won't be freed until
del_timer_syncreturns which should be sufficient, no?
It actually won't get freed at all currently since nothing is calling __xfrm_state_destroy(). __xfrm_state_delete() uses __xfrm_state_put(), which only decrements the refcount, but doesn't perform destruction.
This is visible when looking at the xfrm[46]_mode_{tunnel,transport} module reference counts, they climb higher and higher over time.
Herbert Xu
maintainerQuoted 8 lines · Patrick McHardy
It actually won't get freed at all currently since nothing is calling
__xfrm_state_destroy().__xfrm_state_delete()uses__xfrm_state_put(), which only decrements the refcount, but doesn't perform destruction.This is visible when looking at the xfrm[46]_mode_{tunnel,transport} module reference counts, they climb higher and higher over time.
Oh I see. How about just removing those double underscores then?
Thanks,
Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txtQuoted 10 lines · Herbert Xu
Quoted 7 lines · Patrick McHardy
It actually won't get freed at all currently since nothing is calling
__xfrm_state_destroy().__xfrm_state_delete()uses__xfrm_state_put(), which only decrements the refcount, but doesn't perform destruction.This is visible when looking at the xfrm[46]_mode_{tunnel,transport} module reference counts, they climb higher and higher over time.
Oh I see. How about just removing those double underscores then?
That should work as long as we keep the del_timer_sync to avoid a use-after-free. It seems a bit fragile though.
Herbert Xu
maintainerQuoted 3 lines · Patrick McHardy
That should work as long as we keep the
del_timer_syncto avoid a use-after-free. It seems a bit fragile though.
Well we're relying on the del_timer_sync already to avoid the ref count on the timer. Otherwise if the admin deletes the SA while the timer is running it'll go up in smoke too.
If you look in the history you'll find that the same patch that removed the ref count on the timer introduced the call to del_timer_sync :)
Cheers,
Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txtQuoted 11 lines · Herbert Xu
Quoted 2 lines · Patrick McHardy
That should work as long as we keep the
del_timer_syncto avoid a use-after-free. It seems a bit fragile though.Well we're relying on the
del_timer_syncalready to avoid the ref count on the timer. Otherwise if the admin deletes the SA while the timer is running it'll go up in smoke too.If you look in the history you'll find that the same patch that removed the ref count on the timer introduced the call to
del_timer_sync:)
OK, here's a patch to use xfrm_state_put in __xfrm_state_delete(). I've checked the other callers and it should be fine. lock ordering between x->lock and xfrm_state_gc_lock also doesn't seem to be an issue.
commit ba63b1baf5d8a63f3bb3097a7201de75c1b77e2d
Author: Patrick McHardy <[email protected]> Date: Mon Nov 26 16:00:50 2007 +0100
[XFRM]: Fix leak of expired xfrm_states
The xfrm_timer calls __xfrm_state_delete, which drops the final reference manually without triggering destruction of the state. Change it to use xfrm_state_put to add the state to the gc list when we're dropping the last reference. The timer function may still continue to use the state safely since the final destruction does a del_timer_sync().
net/xfrm/xfrm_state.c +1 -1
@@ -552,7 +552,7 @@ int __xfrm_state_delete(struct xfrm_state *x)* The xfrm_state_alloc call gives a reference, and that * is what we are dropping here. */ -__xfrm_state_put (x); +xfrm_state_put (x); err =0 ; }
Herbert Xu
maintainerQuoted 5 lines · Patrick McHardy
OK, here's a patch to use
xfrm_state_putin__xfrm_state_delete(). I've checked the other callers and it should be fine. lock ordering betweenx->lockandxfrm_state_gc_lockalso doesn't seem to be an issue.
Patch applied. Thanks a lot Patrick!
Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt