ソースを参照

qcacld-3.0: Pass valid data to kernel upon processing GET_STAWPAIE IOCTL

qcacld-2.0 to qcacld-3.0 propagation.

While processing GET_STAWPAIE, based on interface, driver calls
WLANSap_getstationIE_information()/csrRoamGetWpaRsnReqIE() to
get WPA-RSN IE data. For suppose WPA-RSN IE length is greter than
DOT11F_IE_RSN_MAX_LEN(114), then these functions returns failure
by updating only data length. But as calling functions are not
checking return value, driver updates kernel buffer with invalid
data.
Add check to validate WLANSap_getstationIE_information() and
csrRoamGetWpaRsnReqIE() return value.
Also update DOT11F_IE_RSN_MAX_LEN to 255 from 114 and update
IOCTL numbers.

Change-Id: If021318e526c1b1a5616f9447be11174aa4c6a34
CRs-Fixed: 1000857
(cherry picked from commit cc0e12838a8d5ca3fe509bb152b73caeb478744c)
Manjeet Singh 8 年 前
コミット
fde0c04dc2

+ 6 - 7
core/hdd/src/wlan_hdd_hostapd.c

@@ -4054,13 +4054,12 @@ int __iw_get_genie(struct net_device *dev,
 #endif
 		&length, genIeBytes);
 	if (status == QDF_STATUS_SUCCESS) {
-		length = QDF_MIN(length, DOT11F_IE_RSN_MAX_LEN);
-		if (wrqu->data.length < length ||
-		copy_to_user(wrqu->data.pointer, (void *)genIeBytes, length)) {
-			hdd_notice("failed to copy data to user buffer");
-			return -EFAULT;
-		}
 		wrqu->data.length = length;
+		if (length > DOT11F_IE_RSN_MAX_LEN) {
+			hdd_notice("invalid buffer length length:%d", length);
+			return -E2BIG;
+		}
+		qdf_mem_copy(extra, genIeBytes, length);
 		hdd_notice(" RSN IE of %d bytes returned",
 				wrqu->data.length);
 	} else {
@@ -6026,7 +6025,7 @@ static const struct iw_priv_args hostapd_private_args[] = {
 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getProfileData"
 	}, {
 		QCSAP_IOCTL_GET_STAWPAIE,
-		IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0,
+		0, IW_PRIV_TYPE_BYTE | DOT11F_IE_RSN_MAX_LEN,
 		"get_staWPAIE"
 	}, {
 		QCSAP_IOCTL_SETWPAIE,

+ 7 - 4
core/hdd/src/wlan_hdd_wext.c

@@ -2737,13 +2737,16 @@ static int __iw_get_genie(struct net_device *dev,
 	status = csr_roam_get_wpa_rsn_req_ie(WLAN_HDD_GET_HAL_CTX(pAdapter),
 					     pAdapter->sessionId,
 					     &length, genIeBytes);
-	length = QDF_MIN((uint16_t) length, DOT11F_IE_RSN_MAX_LEN);
-	if (wrqu->data.length < length) {
-		hdd_notice("failed to copy data to user buffer");
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_notice("failed to get WPA-RSN IE data");
 		return -EFAULT;
 	}
-	qdf_mem_copy(extra, (void *)genIeBytes, length);
 	wrqu->data.length = length;
+	if (length > DOT11F_IE_RSN_MAX_LEN) {
+		hdd_notice("invalid buffer length length:%d", length);
+		return -E2BIG;
+	}
+	qdf_mem_copy(extra, (void *)genIeBytes, length);
 
 	hdd_notice("RSN IE of %d bytes returned",
 	       wrqu->data.length);

+ 1 - 1
core/mac/src/include/dot11f.h

@@ -5943,7 +5943,7 @@ typedef struct sDot11fIERSN {
 /* N.B. These #defines do *not* include the EID & length */
 #define DOT11F_IE_RSN_MIN_LEN (6)
 
-#define DOT11F_IE_RSN_MAX_LEN (114)
+#define DOT11F_IE_RSN_MAX_LEN (255)
 
 #ifdef __cplusplus
 extern "C" {