mac80211: fix memory leak on filtered powersave frames
authorFelix Fietkau <nbd@nbd.name>
Fri, 16 Oct 2020 19:42:11 +0000 (21:42 +0200)
committerFelix Fietkau <nbd@nbd.name>
Sat, 17 Oct 2020 14:43:17 +0000 (16:43 +0200)
After the status rework, ieee80211_tx_status_ext is leaking un-acknowledged
packets for stations in powersave mode.
To fix this, move the code handling those packets from __ieee80211_tx_status
into ieee80211_tx_status_ext

Reported-by: Tobias Waldvogel <tobias.waldvogel@gmail.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
package/kernel/mac80211/patches/subsys/333-mac80211-fix-memory-leak-on-filtered-powersave-frame.patch [new file with mode: 0644]

diff --git a/package/kernel/mac80211/patches/subsys/333-mac80211-fix-memory-leak-on-filtered-powersave-frame.patch b/package/kernel/mac80211/patches/subsys/333-mac80211-fix-memory-leak-on-filtered-powersave-frame.patch
new file mode 100644 (file)
index 0000000..cdbbcf5
--- /dev/null
@@ -0,0 +1,55 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Fri, 16 Oct 2020 19:54:49 +0200
+Subject: [PATCH] mac80211: fix memory leak on filtered powersave frames
+
+After the status rework, ieee80211_tx_status_ext is leaking un-acknowledged
+packets for stations in powersave mode.
+To fix this, move the code handling those packets from __ieee80211_tx_status
+into ieee80211_tx_status_ext
+
+Reported-by: Tobias Waldvogel <tobias.waldvogel@gmail.com>
+Fixes: 3318111cf63d ("mac80211: reduce duplication in tx status functions")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/net/mac80211/status.c
++++ b/net/mac80211/status.c
+@@ -49,7 +49,8 @@ static void ieee80211_handle_filtered_fr
+       int ac;
+       if (info->flags & (IEEE80211_TX_CTL_NO_PS_BUFFER |
+-                         IEEE80211_TX_CTL_AMPDU)) {
++                         IEEE80211_TX_CTL_AMPDU |
++                         IEEE80211_TX_CTL_HW_80211_ENCAP)) {
+               ieee80211_free_txskb(&local->hw, skb);
+               return;
+       }
+@@ -924,15 +925,6 @@ static void __ieee80211_tx_status(struct
+                       ieee80211_mpsp_trigger_process(
+                               ieee80211_get_qos_ctl(hdr), sta, true, acked);
+-              if (!acked && test_sta_flag(sta, WLAN_STA_PS_STA)) {
+-                      /*
+-                       * The STA is in power save mode, so assume
+-                       * that this TX packet failed because of that.
+-                       */
+-                      ieee80211_handle_filtered_frame(local, sta, skb);
+-                      return;
+-              }
+-
+               if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL) &&
+                   (ieee80211_is_data(hdr->frame_control)) &&
+                   (rates_idx != -1))
+@@ -1159,6 +1151,12 @@ void ieee80211_tx_status_ext(struct ieee
+                                                           -info->status.ack_signal);
+                               }
+                       } else if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
++                              /*
++                               * The STA is in power save mode, so assume
++                               * that this TX packet failed because of that.
++                               */
++                              if (skb)
++                                      ieee80211_handle_filtered_frame(local, sta, skb);
+                               return;
+                       } else if (noack_success) {
+                               /* nothing to do here, do not account as lost */