Commit c3e7724b6bc2f25e46c38dbe68f09d71fafeafb8
Committed by
John W. Linville
1 parent
5bcbc3fcbd
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
mac80211: use ieee80211_free_txskb to fix possible skb leaks
A few places free skbs using dev_kfree_skb even though they're called after ieee80211_subif_start_xmit might have cloned it for tracking tx status. Use ieee80211_free_txskb here to prevent skb leaks. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Cc: stable@vger.kernel.org Signed-off-by: John W. Linville <linville@tuxdriver.com>
Showing 2 changed files with 14 additions and 12 deletions Side-by-side Diff
net/mac80211/status.c
... | ... | @@ -34,7 +34,7 @@ |
34 | 34 | skb_queue_len(&local->skb_queue_unreliable); |
35 | 35 | while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT && |
36 | 36 | (skb = skb_dequeue(&local->skb_queue_unreliable))) { |
37 | - dev_kfree_skb_irq(skb); | |
37 | + ieee80211_free_txskb(hw, skb); | |
38 | 38 | tmp--; |
39 | 39 | I802_DEBUG_INC(local->tx_status_drop); |
40 | 40 | } |
... | ... | @@ -159,7 +159,7 @@ |
159 | 159 | "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n", |
160 | 160 | skb_queue_len(&sta->tx_filtered[ac]), |
161 | 161 | !!test_sta_flag(sta, WLAN_STA_PS_STA), jiffies); |
162 | - dev_kfree_skb(skb); | |
162 | + ieee80211_free_txskb(&local->hw, skb); | |
163 | 163 | } |
164 | 164 | |
165 | 165 | static void ieee80211_check_pending_bar(struct sta_info *sta, u8 *addr, u8 tid) |
net/mac80211/tx.c
... | ... | @@ -354,7 +354,7 @@ |
354 | 354 | total += skb_queue_len(&sta->ps_tx_buf[ac]); |
355 | 355 | if (skb) { |
356 | 356 | purged++; |
357 | - dev_kfree_skb(skb); | |
357 | + ieee80211_free_txskb(&local->hw, skb); | |
358 | 358 | break; |
359 | 359 | } |
360 | 360 | } |
... | ... | @@ -466,7 +466,7 @@ |
466 | 466 | ps_dbg(tx->sdata, |
467 | 467 | "STA %pM TX buffer for AC %d full - dropping oldest frame\n", |
468 | 468 | sta->sta.addr, ac); |
469 | - dev_kfree_skb(old); | |
469 | + ieee80211_free_txskb(&local->hw, old); | |
470 | 470 | } else |
471 | 471 | tx->local->total_ps_buffered++; |
472 | 472 | |
... | ... | @@ -1103,7 +1103,7 @@ |
1103 | 1103 | spin_unlock(&tx->sta->lock); |
1104 | 1104 | |
1105 | 1105 | if (purge_skb) |
1106 | - dev_kfree_skb(purge_skb); | |
1106 | + ieee80211_free_txskb(&tx->local->hw, purge_skb); | |
1107 | 1107 | } |
1108 | 1108 | |
1109 | 1109 | /* reset session timer */ |
... | ... | @@ -1214,7 +1214,7 @@ |
1214 | 1214 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
1215 | 1215 | if (WARN_ON_ONCE(q >= local->hw.queues)) { |
1216 | 1216 | __skb_unlink(skb, skbs); |
1217 | - dev_kfree_skb(skb); | |
1217 | + ieee80211_free_txskb(&local->hw, skb); | |
1218 | 1218 | continue; |
1219 | 1219 | } |
1220 | 1220 | #endif |
... | ... | @@ -1356,7 +1356,7 @@ |
1356 | 1356 | if (unlikely(res == TX_DROP)) { |
1357 | 1357 | I802_DEBUG_INC(tx->local->tx_handlers_drop); |
1358 | 1358 | if (tx->skb) |
1359 | - dev_kfree_skb(tx->skb); | |
1359 | + ieee80211_free_txskb(&tx->local->hw, tx->skb); | |
1360 | 1360 | else |
1361 | 1361 | __skb_queue_purge(&tx->skbs); |
1362 | 1362 | return -1; |
... | ... | @@ -1393,7 +1393,7 @@ |
1393 | 1393 | res_prepare = ieee80211_tx_prepare(sdata, &tx, skb); |
1394 | 1394 | |
1395 | 1395 | if (unlikely(res_prepare == TX_DROP)) { |
1396 | - dev_kfree_skb(skb); | |
1396 | + ieee80211_free_txskb(&local->hw, skb); | |
1397 | 1397 | goto out; |
1398 | 1398 | } else if (unlikely(res_prepare == TX_QUEUED)) { |
1399 | 1399 | goto out; |
... | ... | @@ -1465,7 +1465,7 @@ |
1465 | 1465 | headroom = max_t(int, 0, headroom); |
1466 | 1466 | |
1467 | 1467 | if (ieee80211_skb_resize(sdata, skb, headroom, may_encrypt)) { |
1468 | - dev_kfree_skb(skb); | |
1468 | + ieee80211_free_txskb(&local->hw, skb); | |
1469 | 1469 | rcu_read_unlock(); |
1470 | 1470 | return; |
1471 | 1471 | } |
... | ... | @@ -2050,8 +2050,10 @@ |
2050 | 2050 | head_need += IEEE80211_ENCRYPT_HEADROOM; |
2051 | 2051 | head_need += local->tx_headroom; |
2052 | 2052 | head_need = max_t(int, 0, head_need); |
2053 | - if (ieee80211_skb_resize(sdata, skb, head_need, true)) | |
2054 | - goto fail; | |
2053 | + if (ieee80211_skb_resize(sdata, skb, head_need, true)) { | |
2054 | + ieee80211_free_txskb(&local->hw, skb); | |
2055 | + return NETDEV_TX_OK; | |
2056 | + } | |
2055 | 2057 | } |
2056 | 2058 | |
2057 | 2059 | if (encaps_data) { |
... | ... | @@ -2184,7 +2186,7 @@ |
2184 | 2186 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
2185 | 2187 | |
2186 | 2188 | if (WARN_ON(!info->control.vif)) { |
2187 | - kfree_skb(skb); | |
2189 | + ieee80211_free_txskb(&local->hw, skb); | |
2188 | 2190 | continue; |
2189 | 2191 | } |
2190 | 2192 |