| From 4052adcbc022da6f93540e273ec71bdfa28ecc0d Mon Sep 17 00:00:00 2001 |
| From: Ganapathi Bhat <gbhat@marvell.com> |
| Date: Thu, 21 Nov 2019 21:34:38 +0530 |
| Subject: [PATCH] mwifiex: fix possible heap overflow in |
| mwifiex_process_country_ie() |
| |
| 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: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c |
| index 74e50566db1f..6dd835f1efc2 100644 |
| --- a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c |
| +++ b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c |
| @@ -229,6 +229,14 @@ static int mwifiex_process_country_ie(struct mwifiex_private *priv, |
| "11D: skip setting domain info in FW\n"); |
| return 0; |
| } |
| + |
| + if (country_ie_len > |
| + (IEEE80211_COUNTRY_STRING_LEN + MWIFIEX_MAX_TRIPLET_802_11D)) { |
| + mwifiex_dbg(priv->adapter, ERROR, |
| + "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]; |
| @@ -272,8 +280,9 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, |
| priv->scan_block = false; |
| |
| if (bss) { |
| - if (adapter->region_code == 0x00) |
| - mwifiex_process_country_ie(priv, bss); |
| + if (adapter->region_code == 0x00 && |
| + mwifiex_process_country_ie(priv, bss)) |
| + return -EINVAL; |
| |
| /* Allocate and fill new bss descriptor */ |
| bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor), |
| -- |
| 2.7.4 |
| |