Skip to content

Commit 4a7e7c2

Browse files
Eric Dumazetdavem330
authored andcommitted
netlink: fix races after skb queueing
As soon as an skb is queued into socket receive_queue, another thread can consume it, so we are not allowed to reference skb anymore, or risk use after free. Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent e34fac1 commit 4a7e7c2

File tree

1 file changed

+13
-11
lines changed

1 file changed

+13
-11
lines changed

net/netlink/af_netlink.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -829,12 +829,19 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb,
829829
return 0;
830830
}
831831

832-
int netlink_sendskb(struct sock *sk, struct sk_buff *skb)
832+
static int __netlink_sendskb(struct sock *sk, struct sk_buff *skb)
833833
{
834834
int len = skb->len;
835835

836836
skb_queue_tail(&sk->sk_receive_queue, skb);
837837
sk->sk_data_ready(sk, len);
838+
return len;
839+
}
840+
841+
int netlink_sendskb(struct sock *sk, struct sk_buff *skb)
842+
{
843+
int len = __netlink_sendskb(sk, skb);
844+
838845
sock_put(sk);
839846
return len;
840847
}
@@ -957,8 +964,7 @@ static int netlink_broadcast_deliver(struct sock *sk, struct sk_buff *skb)
957964
if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf &&
958965
!test_bit(0, &nlk->state)) {
959966
skb_set_owner_r(skb, sk);
960-
skb_queue_tail(&sk->sk_receive_queue, skb);
961-
sk->sk_data_ready(sk, skb->len);
967+
__netlink_sendskb(sk, skb);
962968
return atomic_read(&sk->sk_rmem_alloc) > (sk->sk_rcvbuf >> 1);
963969
}
964970
return -1;
@@ -1698,10 +1704,8 @@ static int netlink_dump(struct sock *sk)
16981704

16991705
if (sk_filter(sk, skb))
17001706
kfree_skb(skb);
1701-
else {
1702-
skb_queue_tail(&sk->sk_receive_queue, skb);
1703-
sk->sk_data_ready(sk, skb->len);
1704-
}
1707+
else
1708+
__netlink_sendskb(sk, skb);
17051709
return 0;
17061710
}
17071711

@@ -1715,10 +1719,8 @@ static int netlink_dump(struct sock *sk)
17151719

17161720
if (sk_filter(sk, skb))
17171721
kfree_skb(skb);
1718-
else {
1719-
skb_queue_tail(&sk->sk_receive_queue, skb);
1720-
sk->sk_data_ready(sk, skb->len);
1721-
}
1722+
else
1723+
__netlink_sendskb(sk, skb);
17221724

17231725
if (cb->done)
17241726
cb->done(cb);

0 commit comments

Comments
 (0)