mirror of https://gitee.com/openkylin/linux.git
[IPSEC] Fix xfrm_state leaks in error path
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>
This commit is contained in:
parent
f60f6b8f70
commit
7d6dfe1f5b
|
@ -1333,7 +1333,7 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
x->km.state = XFRM_STATE_DEAD;
|
x->km.state = XFRM_STATE_DEAD;
|
||||||
xfrm_state_put(x);
|
xfrm_state_put(x);
|
||||||
return err;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hdr->sadb_msg_type == SADB_ADD)
|
if (hdr->sadb_msg_type == SADB_ADD)
|
||||||
|
@ -1343,8 +1343,8 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
|
||||||
c.seq = hdr->sadb_msg_seq;
|
c.seq = hdr->sadb_msg_seq;
|
||||||
c.pid = hdr->sadb_msg_pid;
|
c.pid = hdr->sadb_msg_pid;
|
||||||
km_state_notify(x, &c);
|
km_state_notify(x, &c);
|
||||||
|
out:
|
||||||
xfrm_state_put(x);
|
xfrm_state_put(x);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -296,7 +296,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
x->km.state = XFRM_STATE_DEAD;
|
x->km.state = XFRM_STATE_DEAD;
|
||||||
xfrm_state_put(x);
|
xfrm_state_put(x);
|
||||||
return err;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
c.seq = nlh->nlmsg_seq;
|
c.seq = nlh->nlmsg_seq;
|
||||||
|
@ -304,8 +304,8 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
|
||||||
c.event = nlh->nlmsg_type;
|
c.event = nlh->nlmsg_type;
|
||||||
|
|
||||||
km_state_notify(x, &c);
|
km_state_notify(x, &c);
|
||||||
|
out:
|
||||||
xfrm_state_put(x);
|
xfrm_state_put(x);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue