Browse Source

qcacld-3.0: Avoid possible overflow while parsing scan ie

while parsing the QCA_WLAN_VENDOR_ATTR_SCAN_IE there can be possible
overflow overwriting the next ie pointers.

Hence validate the ie length received before memcpy.

Change-Id: Ic503331e6ee35bad5b3b6518cb140914cda2a447
CRs-Fixed: 2231992
Arunk Khandavalli 7 years ago
parent
commit
354b702aa7
1 changed files with 7 additions and 9 deletions
  1. 7 9
      core/hdd/src/wlan_hdd_scan.c

+ 7 - 9
core/hdd/src/wlan_hdd_scan.c

@@ -868,6 +868,8 @@ struct nla_policy scan_policy[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1] = {
 	[QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS] = {.type = NLA_U32},
 	[QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE] = {.type = NLA_FLAG},
 	[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE] = {.type = NLA_U64},
+	[QCA_WLAN_VENDOR_ATTR_SCAN_IE] = {.type = NLA_BINARY,
+					  .len = MAX_DEFAULT_SCAN_IE_LEN},
 };
 
 /**
@@ -891,7 +893,7 @@ static int __wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy,
 	enum nl80211_band band;
 	uint32_t n_channels = 0, n_ssid = 0;
 	uint32_t tmp, count, j;
-	size_t len, ie_len;
+	size_t len, ie_len = 0;
 	struct ieee80211_channel *chan;
 	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev);
@@ -935,8 +937,6 @@ static int __wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy,
 
 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE])
 		ie_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE]);
-	else
-		ie_len = 0;
 
 	len = sizeof(*request) + (sizeof(*request->ssids) * n_ssid) +
 			(sizeof(*request->channels) * n_channels) + ie_len;
@@ -954,6 +954,7 @@ static int __wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy,
 			request->ie = (void *)(request->channels + n_channels);
 	}
 
+	request->ie_len = ie_len;
 	count = 0;
 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES]) {
 		nla_for_each_nested(attr,
@@ -1012,12 +1013,9 @@ static int __wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy,
 		}
 	}
 
-	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE]) {
-		request->ie_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE]);
-		memcpy((void *)request->ie,
-				nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE]),
-				request->ie_len);
-	}
+	if (ie_len)
+		nla_memcpy((void *)request->ie,
+			   tb[QCA_WLAN_VENDOR_ATTR_SCAN_IE], ie_len);
 
 	for (count = 0; count < HDD_NUM_NL80211_BANDS; count++)
 		if (wiphy->bands[count])