mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-12-20 21:34:24 -05:00
85 lines
2.9 KiB
Diff
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),
|