From 00f80b60948200b701bd65ae0389685cd087500a Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Thu, 3 Jan 2019 14:13:11 +0530 Subject: [PATCH] qcacmn: fix out of bound access of memories in wlan_cfg80211_scan In wlan_cfg80211_scan the number of ssid, ssid length and number of channels are not checked for max size of array and thus can lead to Out of bound access of memories. Fix is to add bound check before copying the params. Change-Id: Ie6d4e546fb9c884d5988493b611ef7b217f0a95c CRs-Fixed: 2375217 --- os_if/linux/scan/src/wlan_cfg80211_scan.c | 23 +++++++++++++------ .../dispatcher/inc/wlan_scan_public_structs.h | 8 +++---- wmi/inc/wmi_unified_param.h | 1 - wmi/src/wmi_unified_tlv.c | 4 ++-- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/os_if/linux/scan/src/wlan_cfg80211_scan.c b/os_if/linux/scan/src/wlan_cfg80211_scan.c index 584a7f7528e3..816f4e0d1770 100644 --- a/os_if/linux/scan/src/wlan_cfg80211_scan.c +++ b/os_if/linux/scan/src/wlan_cfg80211_scan.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -1225,17 +1225,24 @@ int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev, int j; req->scan_req.num_ssids = request->n_ssids; + if (req->scan_req.num_ssids > WLAN_SCAN_MAX_NUM_SSID) { + cfg80211_info("number of ssid received %d is greater than MAX %d so copy only MAX nuber of SSIDs", + req->scan_req.num_ssids, + WLAN_SCAN_MAX_NUM_SSID); + req->scan_req.num_ssids = WLAN_SCAN_MAX_NUM_SSID; + } /* copy all the ssid's and their length */ - for (j = 0; j < request->n_ssids; j++) { + for (j = 0; j < req->scan_req.num_ssids; j++) { pssid = &req->scan_req.ssid[j]; /* get the ssid length */ pssid->length = request->ssids[j].ssid_len; + if (pssid->length > WLAN_SSID_MAX_LEN) + pssid->length = WLAN_SSID_MAX_LEN; qdf_mem_copy(pssid->ssid, &request->ssids[j].ssid[0], pssid->length); - pssid->ssid[pssid->length] = '\0'; - cfg80211_notice("SSID number %d: %s", j, - pssid->ssid); + cfg80211_info("SSID number %d: %.*s", j, pssid->length, + pssid->ssid); } } if (request->ssids || @@ -1321,9 +1328,11 @@ int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev, req->scan_req.chan_list.chan[num_chan].phymode = SCAN_PHY_MODE_11A; num_chan++; + if (num_chan >= WLAN_SCAN_MAX_NUM_CHANNELS) + break; } - cfg80211_notice("Channel-List: %s", chl); - cfg80211_notice("No. of Scan Channels: %d", num_chan); + cfg80211_info("Channel-List: %s", chl); + cfg80211_info("No. of Scan Channels: %d", num_chan); } if (!num_chan) { cfg80211_err("Received zero non-dsrc channels"); diff --git a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h index 76742444a768..b8da3115d289 100644 --- a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h +++ b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -32,9 +32,9 @@ typedef uint16_t wlan_scan_requester; typedef uint32_t wlan_scan_id; -#define WLAN_SCAN_MAX_NUM_SSID 10 -#define WLAN_SCAN_MAX_NUM_BSSID 10 -#define WLAN_SCAN_MAX_NUM_CHANNELS 40 +#define WLAN_SCAN_MAX_NUM_SSID 16 +#define WLAN_SCAN_MAX_NUM_BSSID 4 +#define WLAN_SCAN_MAX_NUM_CHANNELS 68 #define SCM_CANCEL_SCAN_WAIT_TIME 50 #define SCM_CANCEL_SCAN_WAIT_ITERATION 600 diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index b61e92fc2592..4180edb64e91 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -37,7 +37,6 @@ #define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */ #define WMI_MAC_MAX_SSID_LENGTH 32 -#define WMI_SCAN_MAX_NUM_SSID 0x0A #ifndef CONFIG_HL_SUPPORT #define mgmt_tx_dl_frm_len 64 #else diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 0d97c526d415..0aa443206260 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -2569,8 +2569,8 @@ static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, buf_ptr += WMI_TLV_HDR_SIZE + (params->chan_list.num_chan * sizeof(uint32_t)); - if (params->num_ssids > WMI_SCAN_MAX_NUM_SSID) { - WMI_LOGE("Invalid value for numSsid"); + if (params->num_ssids > WLAN_SCAN_MAX_NUM_SSID) { + WMI_LOGE("Invalid value for num_ssids %d", params->num_ssids); goto error; }