wifi: cfg80211: ensure cfg80211_bss_update frees IEs on error
cfg80211_bss_update is expected to consume the IEs that are passed into it in the temporary internal BSS. This did not happen in some error cases (which are also WARN_ON paths), so change the code to use a common label and use that everywhere. Signed-off-by: Benjamin Berg <benjamin.berg@intel.com> Reviewed-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://msgid.link/20231220133549.8e72ea105e17.Ic81e9431e980419360e97502ce8c75c58793f05a@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
32af9a9e10
commit
31c5e92be5
@ -1818,15 +1818,15 @@ __cfg80211_bss_update(struct cfg80211_registered_device *rdev,
|
||||
bool signal_valid, unsigned long ts)
|
||||
{
|
||||
struct cfg80211_internal_bss *found = NULL;
|
||||
struct cfg80211_bss_ies *ies;
|
||||
|
||||
if (WARN_ON(!tmp->pub.channel))
|
||||
return NULL;
|
||||
goto free_ies;
|
||||
|
||||
tmp->ts = ts;
|
||||
|
||||
if (WARN_ON(!rcu_access_pointer(tmp->pub.ies))) {
|
||||
return NULL;
|
||||
}
|
||||
if (WARN_ON(!rcu_access_pointer(tmp->pub.ies)))
|
||||
goto free_ies;
|
||||
|
||||
found = rb_find_bss(rdev, tmp, BSS_CMP_REGULAR);
|
||||
|
||||
@ -1836,7 +1836,6 @@ __cfg80211_bss_update(struct cfg80211_registered_device *rdev,
|
||||
} else {
|
||||
struct cfg80211_internal_bss *new;
|
||||
struct cfg80211_internal_bss *hidden;
|
||||
struct cfg80211_bss_ies *ies;
|
||||
|
||||
/*
|
||||
* create a copy -- the "res" variable that is passed in
|
||||
@ -1845,15 +1844,8 @@ __cfg80211_bss_update(struct cfg80211_registered_device *rdev,
|
||||
*/
|
||||
new = kzalloc(sizeof(*new) + rdev->wiphy.bss_priv_size,
|
||||
GFP_ATOMIC);
|
||||
if (!new) {
|
||||
ies = (void *)rcu_dereference(tmp->pub.beacon_ies);
|
||||
if (ies)
|
||||
kfree_rcu(ies, rcu_head);
|
||||
ies = (void *)rcu_dereference(tmp->pub.proberesp_ies);
|
||||
if (ies)
|
||||
kfree_rcu(ies, rcu_head);
|
||||
return NULL;
|
||||
}
|
||||
if (!new)
|
||||
goto free_ies;
|
||||
memcpy(new, tmp, sizeof(*new));
|
||||
new->refcount = 1;
|
||||
INIT_LIST_HEAD(&new->hidden_list);
|
||||
@ -1913,6 +1905,16 @@ __cfg80211_bss_update(struct cfg80211_registered_device *rdev,
|
||||
bss_ref_get(rdev, found);
|
||||
|
||||
return found;
|
||||
|
||||
free_ies:
|
||||
ies = (void *)rcu_dereference(tmp->pub.beacon_ies);
|
||||
if (ies)
|
||||
kfree_rcu(ies, rcu_head);
|
||||
ies = (void *)rcu_dereference(tmp->pub.proberesp_ies);
|
||||
if (ies)
|
||||
kfree_rcu(ies, rcu_head);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct cfg80211_internal_bss *
|
||||
|
Loading…
Reference in New Issue
Block a user