Commit d837a2ae authored by Bing Zhao's avatar Bing Zhao Committed by John W. Linville

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: default avatarDoug Anderson <dianders@chromium.org>
Reviewed-by: default avatarPaul Stewart <pstew@chromium.org>
Signed-off-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 8bc77a4d
...@@ -1533,10 +1533,18 @@ static int mwifiex_update_curr_bss_params(struct mwifiex_private *priv, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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;
} }
......
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