DivestOS/Patches/Linux_CVEs/CVE-2017-0705/0.patch

85 lines
2.9 KiB
Diff

From e58dd312d3d28331b2e28674c6a49f815a55d4bc Mon Sep 17 00:00:00 2001
From: Insun Song <insun.song@broadcom.com>
Date: Fri, 21 Apr 2017 14:38:21 -0700
Subject: [PATCH] net: wireless: bcmdhd: adding boundary check in SWC gscan
config
Since there's no boundary checking while looping NL structures, it could
corrupt kernel memory heap and leave room for security vulnerability
issue.
The proposed fix is adding a new NL attribute indicating how many SWC
bssids included. and it bounds NL iteration not to overwrite the
buffer.
Signed-off-by: Insun Song <insun.song@broadcom.com>
Bug: 34973477
Change-Id: I03e079b6054b930487230ca313bb96a7f9e63e64
---
drivers/net/wireless/bcmdhd/wl_cfgvendor.c | 34 +++++++++++++++++++++++++++---
1 file changed, 31 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/bcmdhd/wl_cfgvendor.c b/drivers/net/wireless/bcmdhd/wl_cfgvendor.c
index 1f5152f66ab36..4e5fee09b5f33 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfgvendor.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfgvendor.c
@@ -1168,11 +1168,15 @@ static int wl_cfgvendor_significant_change_cfg(struct wiphy *wiphy,
const struct nlattr *outer, *inner, *iter;
bool flush = FALSE;
wl_pfn_significant_bssid_t *pbssid;
+ uint16 num_bssid = 0;
+ uint16 max_buf_size = sizeof(gscan_swc_params_t) +
+ sizeof(wl_pfn_significant_bssid_t) * (PFN_SWC_MAX_NUM_APS - 1);
+
+ significant_params = kzalloc(max_buf_size, GFP_KERNEL);
- significant_params = (gscan_swc_params_t *) kzalloc(len, GFP_KERNEL);
if (!significant_params) {
- WL_ERR(("Cannot Malloc mem to parse config commands size - %d bytes \n", len));
- return -1;
+ WL_ERR(("Cannot Malloc mem size:%d\n", len));
+ return BCME_NOMEM;
}
@@ -1192,9 +1196,27 @@ static int wl_cfgvendor_significant_change_cfg(struct wiphy *wiphy,
case GSCAN_ATTRIBUTE_MIN_BREACHING:
significant_params->swc_threshold = nla_get_u16(iter);
break;
+ case GSCAN_ATTRIBUTE_NUM_BSSID:
+ num_bssid = nla_get_u16(iter);
+ if (num_bssid > PFN_SWC_MAX_NUM_APS) {
+ WL_ERR(("ovar max SWC bssids:%d\n",
+ num_bssid));
+ err = BCME_BADARG;
+ goto exit;
+ }
+ break;
case GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS:
+ if (num_bssid == 0) {
+ WL_ERR(("num_bssid : 0\n"));
+ err = BCME_BADARG;
+ goto exit;
+ }
pbssid = significant_params->bssid_elem_list;
nla_for_each_nested(outer, iter, tmp) {
+ if (j >= num_bssid) {
+ j++;
+ break;
+ }
nla_for_each_nested(inner, outer, tmp1) {
switch (nla_type(inner)) {
case GSCAN_ATTRIBUTE_BSSID:
@@ -1217,6 +1239,12 @@ static int wl_cfgvendor_significant_change_cfg(struct wiphy *wiphy,
break;
}
}
+ if (j != num_bssid) {
+ WL_ERR(("swc bssids count:%d not matched to num_bssid:%d\n",
+ j, num_bssid));
+ err = BCME_BADARG;
+ goto exit;
+ }
significant_params->nbssid = j;
if (dhd_dev_pno_set_cfg_gscan(bcmcfg_to_prmry_ndev(cfg),