Herbert Xu wrote:
> @@ -1254,6 +1326,7 @@ static int pfkey_add(struct sock *sk, st
>       if (IS_ERR(x))
>               return PTR_ERR(x);
>
> +     xfrm_state_hold(x);
This introduces a leak when xfrm_state_add()/xfrm_state_update()
fail. We hold two references (one from xfrm_state_alloc(), one
from xfrm_state_hold()), but only drop one. We need to take the
reference because the reference from xfrm_state_alloc() can
be dropped by __xfrm_state_delete(), so the fix is to drop both
references on error. Same problem in xfrm_user.c.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
        if (err < 0) {
                x->km.state = XFRM_STATE_DEAD;
                xfrm_state_put(x);
-               return err;
+               goto out;
        }
 
        if (hdr->sadb_msg_type == SADB_ADD)
        c.seq = hdr->sadb_msg_seq;
        c.pid = hdr->sadb_msg_pid;
        km_state_notify(x, &c);
+out:
        xfrm_state_put(x);
-
        return err;
 }
 
 
        if (err < 0) {
                x->km.state = XFRM_STATE_DEAD;
                xfrm_state_put(x);
-               return err;
+               goto out;
        }
 
        c.seq = nlh->nlmsg_seq;
        c.event = nlh->nlmsg_type;
 
        km_state_notify(x, &c);
+out:
        xfrm_state_put(x);
-
        return err;
 }