mwifiex: fix use-after-free in beacon_ie processing
beacon_ie buffer is allocated in mwifiex_fill_new_bss_desc() and the buffer pointer is saved in bss_desc->beacon_buf. beacon_ie is freed before the function returns. However, bss_desc->beacon_buf is still being accessed afterwards. Fix it by freeing beacon_ie (bss_desc->beacon_buf) in caller's scope. Reviewed-by: Doug Anderson <dianders@chromium.org> Reviewed-by: Paul Stewart <pstew@chromium.org> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>hifive-unleashed-5.1
parent
8bc77a4d2c
commit
d837a2ae40
|
@ -1533,10 +1533,18 @@ static int mwifiex_update_curr_bss_params(struct mwifiex_private *priv,
|
||||||
/* Make a copy of current BSSID descriptor */
|
/* Make a copy of current BSSID descriptor */
|
||||||
memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc,
|
memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc,
|
||||||
sizeof(priv->curr_bss_params.bss_descriptor));
|
sizeof(priv->curr_bss_params.bss_descriptor));
|
||||||
|
|
||||||
|
/* The contents of beacon_ie will be copied to its own buffer
|
||||||
|
* in mwifiex_save_curr_bcn()
|
||||||
|
*/
|
||||||
mwifiex_save_curr_bcn(priv);
|
mwifiex_save_curr_bcn(priv);
|
||||||
spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags);
|
spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
/* beacon_ie buffer was allocated in function
|
||||||
|
* mwifiex_fill_new_bss_desc(). Free it now.
|
||||||
|
*/
|
||||||
|
kfree(bss_desc->beacon_buf);
|
||||||
kfree(bss_desc);
|
kfree(bss_desc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,12 +140,13 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
|
||||||
/*
|
/*
|
||||||
* This function fills bss descriptor structure using provided
|
* This function fills bss descriptor structure using provided
|
||||||
* information.
|
* information.
|
||||||
|
* beacon_ie buffer is allocated in this function. It is caller's
|
||||||
|
* responsibility to free the memory.
|
||||||
*/
|
*/
|
||||||
int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
|
int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
|
||||||
struct cfg80211_bss *bss,
|
struct cfg80211_bss *bss,
|
||||||
struct mwifiex_bssdescriptor *bss_desc)
|
struct mwifiex_bssdescriptor *bss_desc)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
u8 *beacon_ie;
|
u8 *beacon_ie;
|
||||||
size_t beacon_ie_len;
|
size_t beacon_ie_len;
|
||||||
struct mwifiex_bss_priv *bss_priv = (void *)bss->priv;
|
struct mwifiex_bss_priv *bss_priv = (void *)bss->priv;
|
||||||
|
@ -165,6 +166,7 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
|
||||||
|
|
||||||
memcpy(bss_desc->mac_address, bss->bssid, ETH_ALEN);
|
memcpy(bss_desc->mac_address, bss->bssid, ETH_ALEN);
|
||||||
bss_desc->rssi = bss->signal;
|
bss_desc->rssi = bss->signal;
|
||||||
|
/* The caller of this function will free beacon_ie */
|
||||||
bss_desc->beacon_buf = beacon_ie;
|
bss_desc->beacon_buf = beacon_ie;
|
||||||
bss_desc->beacon_buf_size = beacon_ie_len;
|
bss_desc->beacon_buf_size = beacon_ie_len;
|
||||||
bss_desc->beacon_period = bss->beacon_interval;
|
bss_desc->beacon_period = bss->beacon_interval;
|
||||||
|
@ -182,10 +184,7 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
|
||||||
else
|
else
|
||||||
bss_desc->bss_mode = NL80211_IFTYPE_STATION;
|
bss_desc->bss_mode = NL80211_IFTYPE_STATION;
|
||||||
|
|
||||||
ret = mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc);
|
return mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc);
|
||||||
|
|
||||||
kfree(beacon_ie);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mwifiex_process_country_ie(struct mwifiex_private *priv,
|
static int mwifiex_process_country_ie(struct mwifiex_private *priv,
|
||||||
|
@ -349,6 +348,11 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
/* beacon_ie buffer was allocated in function
|
||||||
|
* mwifiex_fill_new_bss_desc(). Free it now.
|
||||||
|
*/
|
||||||
|
if (bss_desc)
|
||||||
|
kfree(bss_desc->beacon_buf);
|
||||||
kfree(bss_desc);
|
kfree(bss_desc);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue