From 08ccf853c567bf02f4a5c9f9aef19a40ecdf57d1 Mon Sep 17 00:00:00 2001 From: Insun Song Date: Mon, 5 Jun 2017 14:39:26 -0700 Subject: net: wireless: bcmdhd: adding boundary check for pfn events adding boundary check for bssid count in dhd_pno_process_epno_result and dhd_handle_hotlist_scan_evt function to prevent heap overflow. Signed-off-by: Insun Song Bug: 37722328 Bug: 37722970 Change-Id: I1f0bc25ef4e7f5ba8f1aa9d9271919ee84d780a1 --- drivers/net/wireless/bcmdhd/dhd_pno.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/bcmdhd/dhd_pno.c b/drivers/net/wireless/bcmdhd/dhd_pno.c index 8ebdf53..1a8e4ee 100644 --- a/drivers/net/wireless/bcmdhd/dhd_pno.c +++ b/drivers/net/wireless/bcmdhd/dhd_pno.c @@ -92,6 +92,11 @@ #define ENTRY_OVERHEAD strlen("bssid=\nssid=\nfreq=\nlevel=\nage=\ndist=\ndistSd=\n====") #define TIME_MIN_DIFF 5 +#define EVENT_DATABUF_MAXLEN (512 - sizeof(bcm_event_t)) +#define EVENT_MAX_NETCNT \ + ((EVENT_DATABUF_MAXLEN - sizeof(wl_pfn_scanresults_t)) \ + / sizeof(wl_pfn_net_info_t) + 1) + #ifdef GSCAN_SUPPORT static int _dhd_pno_flush_ssid(dhd_pub_t *dhd); static wl_pfn_gscan_ch_bucket_cfg_t * @@ -3575,7 +3580,12 @@ dhd_pno_process_epno_result(dhd_pub_t *dhd, const void *data, uint32 event, int if (event == WLC_E_PFN_NET_FOUND || event == WLC_E_PFN_NET_LOST) { wl_pfn_scanresults_t *pfn_result = (wl_pfn_scanresults_t *)data; wl_pfn_net_info_t *net; - + if ((pfn_result->count == 0) || + (pfn_result->count > EVENT_MAX_NETCNT)) { + DHD_ERROR(("%s event %d: incorrect results count:%d\n", + __FUNCTION__, event, pfn_result->count)); + return NULL; + } if (pfn_result->version != PFN_SCANRESULT_VERSION) { DHD_ERROR(("%s event %d: Incorrect version %d %d\n", __FUNCTION__, event, pfn_result->version, PFN_SCANRESULT_VERSION)); @@ -3690,7 +3700,9 @@ void *dhd_handle_hotlist_scan_evt(dhd_pub_t *dhd, const void *event_data, int *s gscan_params = &(_pno_state->pno_params_arr[INDEX_OF_GSCAN_PARAMS].params_gscan); - if (!results->count) { + if ((results->count == 0) || (results->count > EVENT_MAX_NETCNT)) { + DHD_ERROR(("%s: wrong count:%d\n", __FUNCTION__, + results->count)); *send_evt_bytes = 0; return ptr; } -- cgit v1.1