diff options
| author | Eric Dumazet <edumazet@google.com> | 2017-03-22 11:30:01 +0000 |
|---|---|---|
| committer | android-build-merger <android-build-merger@google.com> | 2017-03-22 11:30:01 +0000 |
| commit | 50aba0e7c5765bb954f7f5be6569c67f13783033 (patch) | |
| tree | 7f52539bdd56f6d8d1a3637dfa2f02f350868dea /net/core | |
| parent | 95bec76ac28eb83e6fe2408d38adaadea9629098 (diff) | |
| parent | 9e7683301beef0cef8254eecb661e7eac3146717 (diff) | |
net: fix socket refcounting in skb_complete_wifi_ack()
am: 9e7683301b
Change-Id: I00fea5d105075ad526ca753b463f91bcd5db30d0
Diffstat (limited to 'net/core')
| -rw-r--r-- | net/core/skbuff.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 4968b5ddea69..370f4f86e2b5 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -3735,7 +3735,7 @@ void skb_complete_wifi_ack(struct sk_buff *skb, bool acked) { struct sock *sk = skb->sk; struct sock_exterr_skb *serr; - int err; + int err = 1; skb->wifi_acked_valid = 1; skb->wifi_acked = acked; @@ -3745,14 +3745,15 @@ void skb_complete_wifi_ack(struct sk_buff *skb, bool acked) serr->ee.ee_errno = ENOMSG; serr->ee.ee_origin = SO_EE_ORIGIN_TXSTATUS; - /* take a reference to prevent skb_orphan() from freeing the socket */ - sock_hold(sk); - - err = sock_queue_err_skb(sk, skb); + /* Take a reference to prevent skb_orphan() from freeing the socket, + * but only if the socket refcount is not zero. + */ + if (likely(atomic_inc_not_zero(&sk->sk_refcnt))) { + err = sock_queue_err_skb(sk, skb); + sock_put(sk); + } if (err) kfree_skb(skb); - - sock_put(sk); } EXPORT_SYMBOL_GPL(skb_complete_wifi_ack); |
