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.
    
    Signed-off-by: Patrick McHardy <[EMAIL PROTECTED]>

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 224b44e..11e9a48 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -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);

Reply via email to