| From 3d94a4a8373bf5f45cf5f939e88b8354dbf2311b Mon Sep 17 00:00:00 2001 |
| From: Ganapathi Bhat <gbhat@marvell.com> |
| Date: Thu, 21 Nov 2019 21:34:38 +0530 |
| Subject: mwifiex: fix possible heap overflow in mwifiex_process_country_ie() |
| |
| From: Ganapathi Bhat <gbhat@marvell.com> |
| |
| commit 3d94a4a8373bf5f45cf5f939e88b8354dbf2311b upstream. |
| |
| mwifiex_process_country_ie() function parse elements of bss |
| descriptor in beacon packet. When processing WLAN_EID_COUNTRY |
| element, there is no upper limit check for country_ie_len before |
| calling memcpy. The destination buffer domain_info->triplet is an |
| array of length MWIFIEX_MAX_TRIPLET_802_11D(83). The remote |
| attacker can build a fake AP with the same ssid as real AP, and |
| send malicous beacon packet with long WLAN_EID_COUNTRY elemen |
| (country_ie_len > 83). Attacker can force STA connect to fake AP |
| on a different channel. When the victim STA connects to fake AP, |
| will trigger the heap buffer overflow. Fix this by checking for |
| length and if found invalid, don not connect to the AP. |
| |
| This fix addresses CVE-2019-14895. |
| |
| Reported-by: huangwen <huangwenabc@gmail.com> |
| Signed-off-by: Ganapathi Bhat <gbhat@marvell.com> |
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/net/wireless/mwifiex/sta_ioctl.c | 11 ++++++++++- |
| 1 file changed, 10 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/net/wireless/mwifiex/sta_ioctl.c |
| +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c |
| @@ -223,6 +223,14 @@ static int mwifiex_process_country_ie(st |
| "11D: skip setting domain info in FW\n"); |
| return 0; |
| } |
| + |
| + if (country_ie_len > |
| + (IEEE80211_COUNTRY_STRING_LEN + MWIFIEX_MAX_TRIPLET_802_11D)) { |
| + wiphy_dbg(priv->wdev->wiphy, |
| + "11D: country_ie_len overflow!, deauth AP\n"); |
| + return -EINVAL; |
| + } |
| + |
| memcpy(priv->adapter->country_code, &country_ie[2], 2); |
| |
| domain_info->country_code[0] = country_ie[2]; |
| @@ -266,7 +274,8 @@ int mwifiex_bss_start(struct mwifiex_pri |
| priv->scan_block = false; |
| |
| if (bss) { |
| - mwifiex_process_country_ie(priv, bss); |
| + if (mwifiex_process_country_ie(priv, bss)) |
| + return -EINVAL; |
| |
| /* Allocate and fill new bss descriptor */ |
| bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor), |