aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBing Zhao <bzhao@marvell.com>2013-04-12 13:34:17 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-04-22 15:38:35 -0400
commitd837a2ae40fd37bcbb5a42126e3d89c68c90fccc (patch)
treed952e47adcbfbb9c7797b5593149df161de3f4e6
parent8bc77a4d2c8ca3c07d74465a3738bf60a4e5de41 (diff)
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>
-rw-r--r--drivers/net/wireless/mwifiex/scan.c8
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c14
2 files changed, 17 insertions, 5 deletions
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index e7f6deaf715e..37b24e830844 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1533,10 +1533,18 @@ static int mwifiex_update_curr_bss_params(struct mwifiex_private *priv,
1533 /* Make a copy of current BSSID descriptor */ 1533 /* Make a copy of current BSSID descriptor */
1534 memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc, 1534 memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc,
1535 sizeof(priv->curr_bss_params.bss_descriptor)); 1535 sizeof(priv->curr_bss_params.bss_descriptor));
1536
1537 /* The contents of beacon_ie will be copied to its own buffer
1538 * in mwifiex_save_curr_bcn()
1539 */
1536 mwifiex_save_curr_bcn(priv); 1540 mwifiex_save_curr_bcn(priv);
1537 spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags); 1541 spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags);
1538 1542
1539done: 1543done:
1544 /* beacon_ie buffer was allocated in function
1545 * mwifiex_fill_new_bss_desc(). Free it now.
1546 */
1547 kfree(bss_desc->beacon_buf);
1540 kfree(bss_desc); 1548 kfree(bss_desc);
1541 return 0; 1549 return 0;
1542} 1550}
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index e6c9b2ae22ed..27729cfef151 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -140,12 +140,13 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
140/* 140/*
141 * This function fills bss descriptor structure using provided 141 * This function fills bss descriptor structure using provided
142 * information. 142 * information.
143 * beacon_ie buffer is allocated in this function. It is caller's
144 * responsibility to free the memory.
143 */ 145 */
144int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, 146int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
145 struct cfg80211_bss *bss, 147 struct cfg80211_bss *bss,
146 struct mwifiex_bssdescriptor *bss_desc) 148 struct mwifiex_bssdescriptor *bss_desc)
147{ 149{
148 int ret;
149 u8 *beacon_ie; 150 u8 *beacon_ie;
150 size_t beacon_ie_len; 151 size_t beacon_ie_len;
151 struct mwifiex_bss_priv *bss_priv = (void *)bss->priv; 152 struct mwifiex_bss_priv *bss_priv = (void *)bss->priv;
@@ -165,6 +166,7 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
165 166
166 memcpy(bss_desc->mac_address, bss->bssid, ETH_ALEN); 167 memcpy(bss_desc->mac_address, bss->bssid, ETH_ALEN);
167 bss_desc->rssi = bss->signal; 168 bss_desc->rssi = bss->signal;
169 /* The caller of this function will free beacon_ie */
168 bss_desc->beacon_buf = beacon_ie; 170 bss_desc->beacon_buf = beacon_ie;
169 bss_desc->beacon_buf_size = beacon_ie_len; 171 bss_desc->beacon_buf_size = beacon_ie_len;
170 bss_desc->beacon_period = bss->beacon_interval; 172 bss_desc->beacon_period = bss->beacon_interval;
@@ -182,10 +184,7 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
182 else 184 else
183 bss_desc->bss_mode = NL80211_IFTYPE_STATION; 185 bss_desc->bss_mode = NL80211_IFTYPE_STATION;
184 186
185 ret = mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc); 187 return mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc);
186
187 kfree(beacon_ie);
188 return ret;
189} 188}
190 189
191static int mwifiex_process_country_ie(struct mwifiex_private *priv, 190static 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 } 348 }
350 349
351done: 350done:
351 /* beacon_ie buffer was allocated in function
352 * mwifiex_fill_new_bss_desc(). Free it now.
353 */
354 if (bss_desc)
355 kfree(bss_desc->beacon_buf);
352 kfree(bss_desc); 356 kfree(bss_desc);
353 return ret; 357 return ret;
354} 358}