Commit 8223ac19 authored by Johannes Berg's avatar Johannes Berg

mac80211: fix memory leaks with element parsing

My previous commit 5d24828d ("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: 5d24828d ("mac80211: always allocate struct ieee802_11_elems")
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Link: https://lore.kernel.org/r/20211001211108.9839928e42e0.Ib81ca187d3d3af7ed1bfeac2e00d08a4637c8025@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 10de5a59
...@@ -498,13 +498,14 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, ...@@ -498,13 +498,14 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
elems = ieee802_11_parse_elems(mgmt->u.action.u.addba_req.variable, elems = ieee802_11_parse_elems(mgmt->u.action.u.addba_req.variable,
ies_len, true, mgmt->bssid, NULL); ies_len, true, mgmt->bssid, NULL);
if (!elems || elems->parse_error) if (!elems || elems->parse_error)
return; goto free;
} }
__ieee80211_start_rx_ba_session(sta, dialog_token, timeout, __ieee80211_start_rx_ba_session(sta, dialog_token, timeout,
start_seq_num, ba_policy, tid, start_seq_num, ba_policy, tid,
buf_size, true, false, buf_size, true, false,
elems ? elems->addba_ext_ie : NULL); elems ? elems->addba_ext_ie : NULL);
free:
kfree(elems); kfree(elems);
} }
......
...@@ -1659,11 +1659,11 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, ...@@ -1659,11 +1659,11 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
mgmt->u.action.u.chan_switch.variable, mgmt->u.action.u.chan_switch.variable,
ies_len, true, mgmt->bssid, NULL); ies_len, true, mgmt->bssid, NULL);
if (!elems || elems->parse_error) if (elems && !elems->parse_error)
break; ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt,
skb->len,
ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt, skb->len, rx_status,
rx_status, elems); elems);
kfree(elems); kfree(elems);
break; break;
} }
......
...@@ -3353,8 +3353,10 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, ...@@ -3353,8 +3353,10 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
bss_ies = kmemdup(ies, sizeof(*ies) + ies->len, bss_ies = kmemdup(ies, sizeof(*ies) + ies->len,
GFP_ATOMIC); GFP_ATOMIC);
rcu_read_unlock(); rcu_read_unlock();
if (!bss_ies) if (!bss_ies) {
return false; ret = false;
goto out;
}
bss_elems = ieee802_11_parse_elems(bss_ies->data, bss_ies->len, bss_elems = ieee802_11_parse_elems(bss_ies->data, bss_ies->len,
false, mgmt->bssid, false, mgmt->bssid,
...@@ -4331,13 +4333,11 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, ...@@ -4331,13 +4333,11 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
mgmt->u.action.u.chan_switch.variable, mgmt->u.action.u.chan_switch.variable,
ies_len, true, mgmt->bssid, NULL); ies_len, true, mgmt->bssid, NULL);
if (!elems || elems->parse_error) if (elems && !elems->parse_error)
break; ieee80211_sta_process_chanswitch(sdata,
rx_status->mactime,
ieee80211_sta_process_chanswitch(sdata, rx_status->device_timestamp,
rx_status->mactime, elems, false);
rx_status->device_timestamp,
elems, false);
kfree(elems); kfree(elems);
} else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) { } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) {
struct ieee802_11_elems *elems; struct ieee802_11_elems *elems;
...@@ -4357,17 +4357,17 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, ...@@ -4357,17 +4357,17 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
mgmt->u.action.u.ext_chan_switch.variable, mgmt->u.action.u.ext_chan_switch.variable,
ies_len, true, mgmt->bssid, NULL); ies_len, true, mgmt->bssid, NULL);
if (!elems || elems->parse_error) if (elems && !elems->parse_error) {
break; /* 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 */ ieee80211_sta_process_chanswitch(sdata,
elems->ext_chansw_ie = rx_status->mactime,
&mgmt->u.action.u.ext_chan_switch.data; rx_status->device_timestamp,
elems, false);
}
ieee80211_sta_process_chanswitch(sdata,
rx_status->mactime,
rx_status->device_timestamp,
elems, false);
kfree(elems); kfree(elems);
} }
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment