Skip to content

Commit dd4f107

Browse files
edumazetdavem330
authored andcommitted
net: fix socket refcounting in skb_complete_wifi_ack()
TX skbs do not necessarily hold a reference on skb->sk->sk_refcnt By the time TX completion happens, sk_refcnt might be already 0. sock_hold()/sock_put() would then corrupt critical state, like sk_wmem_alloc. Fixes: bf7fa55 ("mac80211: Resolve sk_refcnt/sk_wmem_alloc issue in wifi ack path") Signed-off-by: Eric Dumazet <[email protected]> Cc: Alexander Duyck <[email protected]> Cc: Johannes Berg <[email protected]> Cc: Soheil Hassas Yeganeh <[email protected]> Cc: Willem de Bruijn <[email protected]> Acked-by: Soheil Hassas Yeganeh <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 146d8fe commit dd4f107

File tree

1 file changed

+8
-7
lines changed

1 file changed

+8
-7
lines changed

net/core/skbuff.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3893,7 +3893,7 @@ void skb_complete_wifi_ack(struct sk_buff *skb, bool acked)
38933893
{
38943894
struct sock *sk = skb->sk;
38953895
struct sock_exterr_skb *serr;
3896-
int err;
3896+
int err = 1;
38973897

38983898
skb->wifi_acked_valid = 1;
38993899
skb->wifi_acked = acked;
@@ -3903,14 +3903,15 @@ void skb_complete_wifi_ack(struct sk_buff *skb, bool acked)
39033903
serr->ee.ee_errno = ENOMSG;
39043904
serr->ee.ee_origin = SO_EE_ORIGIN_TXSTATUS;
39053905

3906-
/* take a reference to prevent skb_orphan() from freeing the socket */
3907-
sock_hold(sk);
3908-
3909-
err = sock_queue_err_skb(sk, skb);
3906+
/* Take a reference to prevent skb_orphan() from freeing the socket,
3907+
* but only if the socket refcount is not zero.
3908+
*/
3909+
if (likely(atomic_inc_not_zero(&sk->sk_refcnt))) {
3910+
err = sock_queue_err_skb(sk, skb);
3911+
sock_put(sk);
3912+
}
39103913
if (err)
39113914
kfree_skb(skb);
3912-
3913-
sock_put(sk);
39143915
}
39153916
EXPORT_SYMBOL_GPL(skb_complete_wifi_ack);
39163917

0 commit comments

Comments
 (0)