cdbbcf5d065b19ffa38203048b74fd0a335dfd16
[openwrt/staging/nbd.git] / package / kernel / mac80211 / patches / subsys / 333-mac80211-fix-memory-leak-on-filtered-powersave-frame.patch
1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Fri, 16 Oct 2020 19:54:49 +0200
3 Subject: [PATCH] mac80211: fix memory leak on filtered powersave frames
4
5 After the status rework, ieee80211_tx_status_ext is leaking un-acknowledged
6 packets for stations in powersave mode.
7 To fix this, move the code handling those packets from __ieee80211_tx_status
8 into ieee80211_tx_status_ext
9
10 Reported-by: Tobias Waldvogel <tobias.waldvogel@gmail.com>
11 Fixes: 3318111cf63d ("mac80211: reduce duplication in tx status functions")
12 Signed-off-by: Felix Fietkau <nbd@nbd.name>
13 ---
14
15 --- a/net/mac80211/status.c
16 +++ b/net/mac80211/status.c
17 @@ -49,7 +49,8 @@ static void ieee80211_handle_filtered_fr
18 int ac;
19
20 if (info->flags & (IEEE80211_TX_CTL_NO_PS_BUFFER |
21 - IEEE80211_TX_CTL_AMPDU)) {
22 + IEEE80211_TX_CTL_AMPDU |
23 + IEEE80211_TX_CTL_HW_80211_ENCAP)) {
24 ieee80211_free_txskb(&local->hw, skb);
25 return;
26 }
27 @@ -924,15 +925,6 @@ static void __ieee80211_tx_status(struct
28 ieee80211_mpsp_trigger_process(
29 ieee80211_get_qos_ctl(hdr), sta, true, acked);
30
31 - if (!acked && test_sta_flag(sta, WLAN_STA_PS_STA)) {
32 - /*
33 - * The STA is in power save mode, so assume
34 - * that this TX packet failed because of that.
35 - */
36 - ieee80211_handle_filtered_frame(local, sta, skb);
37 - return;
38 - }
39 -
40 if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL) &&
41 (ieee80211_is_data(hdr->frame_control)) &&
42 (rates_idx != -1))
43 @@ -1159,6 +1151,12 @@ void ieee80211_tx_status_ext(struct ieee
44 -info->status.ack_signal);
45 }
46 } else if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
47 + /*
48 + * The STA is in power save mode, so assume
49 + * that this TX packet failed because of that.
50 + */
51 + if (skb)
52 + ieee80211_handle_filtered_frame(local, sta, skb);
53 return;
54 } else if (noack_success) {
55 /* nothing to do here, do not account as lost */