summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2022-10-13 20:16:00 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-10-15 07:59:05 +0200
commit7d998f6b7365d50a9905bf57fd28b41c7ebe8e9d (patch)
tree95d3c67aadbf227658dce48841d86b324570486d
parentfee48f3bdd7516bb63da507213916227cf147211 (diff)
downloadlinux-stable-7d998f6b7365d50a9905bf57fd28b41c7ebe8e9d.tar.gz
linux-stable-7d998f6b7365d50a9905bf57fd28b41c7ebe8e9d.tar.bz2
linux-stable-7d998f6b7365d50a9905bf57fd28b41c7ebe8e9d.zip
mac80211: fix memory leaks with element parsing
commit 8223ac199a3849257e86ec27865dc63f034b1cf1 upstream. My previous commit 5d24828d05f3 ("mac80211: always allocate struct ieee802_11_elems") had a few bugs and leaked the new allocated struct in a few error cases, fix that. Fixes: 5d24828d05f3 ("mac80211: always allocate struct ieee802_11_elems") Signed-off-by: Johannes Berg <johannes.berg@intel.com> Link: https://lore.kernel.org/r/20211001211108.9839928e42e0.Ib81ca187d3d3af7ed1bfeac2e00d08a4637c8025@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com> Cc: Felix Fietkau <nbd@nbd.name> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--net/mac80211/agg-rx.c3
-rw-r--r--net/mac80211/ibss.c10
-rw-r--r--net/mac80211/mlme.c36
3 files changed, 25 insertions, 24 deletions
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index ffa4f31f6c2b..0d2bab9d351c 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -499,13 +499,14 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
elems = ieee802_11_parse_elems(mgmt->u.action.u.addba_req.variable,
ies_len, true, mgmt->bssid, NULL);
if (!elems || elems->parse_error)
- return;
+ goto free;
}
__ieee80211_start_rx_ba_session(sta, dialog_token, timeout,
start_seq_num, ba_policy, tid,
buf_size, true, false,
elems ? elems->addba_ext_ie : NULL);
+free:
kfree(elems);
}
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 4b721b48f86a..48e0260f3424 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -1663,11 +1663,11 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
mgmt->u.action.u.chan_switch.variable,
ies_len, true, mgmt->bssid, NULL);
- if (!elems || elems->parse_error)
- break;
-
- ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt, skb->len,
- rx_status, elems);
+ if (elems && !elems->parse_error)
+ ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt,
+ skb->len,
+ rx_status,
+ elems);
kfree(elems);
break;
}
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 45efa1d1c550..cc6d38a2e6d5 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3374,8 +3374,10 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
bss_ies = kmemdup(ies, sizeof(*ies) + ies->len,
GFP_ATOMIC);
rcu_read_unlock();
- if (!bss_ies)
- return false;
+ if (!bss_ies) {
+ ret = false;
+ goto out;
+ }
bss_elems = ieee802_11_parse_elems(bss_ies->data, bss_ies->len,
false, mgmt->bssid,
@@ -4358,13 +4360,11 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
mgmt->u.action.u.chan_switch.variable,
ies_len, true, mgmt->bssid, NULL);
- if (!elems || elems->parse_error)
- break;
-
- ieee80211_sta_process_chanswitch(sdata,
- rx_status->mactime,
- rx_status->device_timestamp,
- elems, false);
+ if (elems && !elems->parse_error)
+ ieee80211_sta_process_chanswitch(sdata,
+ rx_status->mactime,
+ rx_status->device_timestamp,
+ elems, false);
kfree(elems);
} else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) {
struct ieee802_11_elems *elems;
@@ -4384,17 +4384,17 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
mgmt->u.action.u.ext_chan_switch.variable,
ies_len, true, mgmt->bssid, NULL);
- if (!elems || elems->parse_error)
- break;
+ if (elems && !elems->parse_error) {
+ /* for the handling code pretend it was an IE */
+ elems->ext_chansw_ie =
+ &mgmt->u.action.u.ext_chan_switch.data;
- /* for the handling code pretend this was also an IE */
- elems->ext_chansw_ie =
- &mgmt->u.action.u.ext_chan_switch.data;
+ ieee80211_sta_process_chanswitch(sdata,
+ rx_status->mactime,
+ rx_status->device_timestamp,
+ elems, false);
+ }
- ieee80211_sta_process_chanswitch(sdata,
- rx_status->mactime,
- rx_status->device_timestamp,
- elems, false);
kfree(elems);
}
break;