Просмотр исходного кода

qcacld-3.0: Add force rsne override and use the RSNE passed by user

Adds support for INI "force_rsne_override" and vendor interface to
enable test mode to force rsne override. Once force rsne override
is set the driver will use the RSN IE's as-is from the connect
request. Exclusively used for the scenarios where the device is used as
a cert test bed and not recommended for production.

With force_rsne_override enabled in INI and once enabled from vendor
command driver will not validate the RSN IE's passed from user space
and thus induce improper IE as it is to test the peer.

Once the force_rsne_override is set, it will be active until its
disabled by vendor interface or driver unload.

If INI force_rsne_override is disabled, the force rsne override mode
cannot be enabled by vendor command.

Change-Id: Ic58474e7a18e6c1f944c61783f630af3953011c0
CRs-Fixed: 2164526
Abhishek Singh 7 лет назад
Родитель
Сommit
6454ad3707

+ 25 - 0
core/hdd/inc/wlan_hdd_cfg.h

@@ -13469,6 +13469,30 @@ enum hdd_external_acs_freq_band {
 #define CFG_ENABLE_SCORING_FOR_ROAM_MIN      (0)
 #define CFG_ENABLE_SCORING_FOR_ROAM_MAX      (1)
 
+/*
+ * <ini>
+ * force_rsne_override - force rsnie override from user
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable test mode to force rsne override used in
+ * security enhancement test cases to pass the RSNIE sent by user in
+ * assoc request.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: internal
+ *
+ * </ini>
+ */
+#define CFG_FORCE_RSNE_OVERRIDE_NAME    "force_rsne_override"
+#define CFG_FORCE_RSNE_OVERRIDE_MIN     (0)
+#define CFG_FORCE_RSNE_OVERRIDE_MAX     (1)
+#define CFG_FORCE_RSNE_OVERRIDE_DEFAULT (0)
+
 /*
  * <ini>
  * gChanSwitchHostapdRateEnabled - Enable/disable hostapd rate when doing SAP
@@ -14824,6 +14848,7 @@ struct hdd_config {
 	uint32_t oce_wan_score_slots11_to_8;
 	uint32_t oce_wan_score_slots15_to_12;
 	bool enable_scoring_for_roam;
+	bool force_rsne_override;
 	bool is_fils_enabled;
 	uint16_t wlm_latency_enable;
 	uint16_t wlm_latency_level;

+ 1 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -1711,6 +1711,7 @@ struct hdd_context {
 	qdf_atomic_t disable_lro_in_concurrency;
 	qdf_atomic_t disable_lro_in_low_tput;
 	bool en_tcp_delack_no_lro;
+	bool force_rsne_override;
 	qdf_wake_lock_t monitor_mode_wakelock;
 	bool lte_coex_ant_share;
 };

+ 62 - 2
core/hdd/src/wlan_hdd_assoc.c

@@ -4942,6 +4942,7 @@ static int32_t hdd_process_genie(struct hdd_adapter *adapter,
 	tDot11fIEWPA dot11WPAIE;
 	uint8_t *pRsnIe;
 	uint16_t RSNIeLen;
+	uint32_t parse_status;
 
 	/*
 	 * Clear struct of tDot11fIERSN and tDot11fIEWPA specifically
@@ -4963,8 +4964,13 @@ static int32_t hdd_process_genie(struct hdd_adapter *adapter,
 		pRsnIe = gen_ie + 2;
 		RSNIeLen = gen_ie_len - 2;
 		/* Unpack the RSN IE */
-		sme_unpack_rsn_ie(halHandle, pRsnIe, RSNIeLen,
+		parse_status = sme_unpack_rsn_ie(halHandle, pRsnIe, RSNIeLen,
 				  &dot11RSNIE, false);
+		if (!DOT11F_SUCCEEDED(parse_status)) {
+			hdd_err("Invalid RSN IE: parse status %d",
+				parse_status);
+			return -EINVAL;
+		}
 		/* Copy out the encryption and authentication types */
 		hdd_debug("pairwise cipher suite count: %d",
 			 dot11RSNIE.pwise_cipher_suite_count);
@@ -4999,8 +5005,13 @@ static int32_t hdd_process_genie(struct hdd_adapter *adapter,
 		pRsnIe = gen_ie + 2 + 4;
 		RSNIeLen = gen_ie_len - (2 + 4);
 		/* Unpack the WPA IE */
-		dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle,
+		parse_status = dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle,
 				     pRsnIe, RSNIeLen, &dot11WPAIE, false);
+		if (!DOT11F_SUCCEEDED(parse_status)) {
+			hdd_err("Invalid WPA IE: parse status %d",
+				parse_status);
+			return -EINVAL;
+		}
 		/* Copy out the encryption and authentication types */
 		hdd_debug("WPA unicast cipher suite count: %d",
 			 dot11WPAIE.unicast_cipher_count);
@@ -5026,6 +5037,37 @@ static int32_t hdd_process_genie(struct hdd_adapter *adapter,
 	return 0;
 }
 
+/**
+ * hdd_set_def_rsne_override() - set default encryption type and auth type
+ * in profile.
+ * @roam_profile: pointer to adapter
+ * @auth_type: pointer to auth type
+ *
+ * Set default value of encryption type and auth type in profile to
+ * search the AP using filter, as in force_rsne_override the RSNIE can be
+ * currupt and we might not get the proper encryption type and auth type
+ * while parsing the RSNIE.
+ *
+ * Return: void
+ */
+static void hdd_set_def_rsne_override(
+	tCsrRoamProfile *roam_profile, eCsrAuthType *auth_type)
+{
+
+	hdd_debug("Set def values in roam profile");
+	roam_profile->MFPCapable = roam_profile->MFPEnabled;
+	roam_profile->EncryptionType.numEntries = 2;
+	roam_profile->mcEncryptionType.numEntries = 2;
+		/* Use the cipher type in the RSN IE */
+	roam_profile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_AES;
+	roam_profile->EncryptionType.encryptionType[1] = eCSR_ENCRYPT_TYPE_TKIP;
+	roam_profile->mcEncryptionType.encryptionType[0] =
+		eCSR_ENCRYPT_TYPE_AES;
+	roam_profile->mcEncryptionType.encryptionType[1] =
+		eCSR_ENCRYPT_TYPE_TKIP;
+	*auth_type = eCSR_AUTH_TYPE_RSN_PSK;
+}
+
 /**
  * hdd_set_genie_to_csr() - set genie to csr
  * @adapter: pointer to adapter
@@ -5041,6 +5083,7 @@ int hdd_set_genie_to_csr(struct hdd_adapter *adapter,
 	uint32_t status = 0;
 	eCsrEncryptionType RSNEncryptType;
 	eCsrEncryptionType mcRSNEncryptType;
+	struct hdd_context *hdd_ctx;
 #ifdef WLAN_FEATURE_11W
 	uint8_t RSNMfpRequired = 0;
 	uint8_t RSNMfpCapable = 0;
@@ -5057,6 +5100,7 @@ int hdd_set_genie_to_csr(struct hdd_adapter *adapter,
 	} else {
 		return 0;
 	}
+
 	/* The actual processing may eventually be more extensive than this. */
 	/* Right now, just consume any PMKIDs that are  sent in by the app. */
 	status = hdd_process_genie(adapter, bssid,
@@ -5067,6 +5111,7 @@ int hdd_set_genie_to_csr(struct hdd_adapter *adapter,
 #endif
 				   pWextState->WPARSNIE[1] + 2,
 				   pWextState->WPARSNIE);
+
 	if (status == 0) {
 		/*
 		 * Now copy over all the security attributes
@@ -5107,6 +5152,21 @@ int hdd_set_genie_to_csr(struct hdd_adapter *adapter,
 		hdd_debug("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d",
 			 *RSNAuthType, RSNEncryptType, mcRSNEncryptType);
 	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	if (hdd_ctx->force_rsne_override &&
+	    (pWextState->WPARSNIE[0] == DOT11F_EID_RSN)) {
+		hdd_warn("Test mode enabled set def Auth and enc type. RSN IE passed in connect req: ");
+		qdf_trace_hex_dump(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN,
+				   pWextState->roamProfile.pRSNReqIE,
+				   pWextState->roamProfile.nRSNReqIELength);
+
+		pWextState->roamProfile.force_rsne_override = true;
+		/* If parsing failed set the def value for the roam profile */
+		if (status)
+			hdd_set_def_rsne_override(&pWextState->roamProfile,
+					    RSNAuthType);
+	}
 	return 0;
 }
 

+ 10 - 0
core/hdd/src/wlan_hdd_cfg.c

@@ -5266,6 +5266,13 @@ struct reg_table_entry g_registry_table[] = {
 		CFG_ENABLE_SCORING_FOR_ROAM_MIN,
 		CFG_ENABLE_SCORING_FOR_ROAM_MAX),
 
+	REG_VARIABLE(CFG_FORCE_RSNE_OVERRIDE_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, force_rsne_override,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_FORCE_RSNE_OVERRIDE_DEFAULT,
+		     CFG_FORCE_RSNE_OVERRIDE_MIN,
+		     CFG_FORCE_RSNE_OVERRIDE_MAX),
+
 	REG_VARIABLE(CFG_MBO_CANDIDATE_RSSI_THRESHOLD_NAME,
 		WLAN_PARAM_SignedInteger, struct hdd_config,
 		mbo_candidate_rssi_thres,
@@ -7223,6 +7230,9 @@ void hdd_cfg_print(struct hdd_context *hdd_ctx)
 	hdd_debug("Name = [%s] value = [%u]",
 		CFG_OCE_WAN_SCORE_IDX15_TO_12_NAME,
 		hdd_ctx->config->oce_wan_score_slots15_to_12);
+	hdd_debug("Name = [%s] Value = [%u]",
+		CFG_FORCE_RSNE_OVERRIDE_NAME,
+		hdd_ctx->config->force_rsne_override);
 	hdd_debug("Name = [%s] value = [0x%x]", CFG_VC_MODE_BITMAP,
 		hdd_ctx->config->vc_mode_cfg_bitmap);
 	hdd_debug("Name = [%s] Value = [%u]",

+ 17 - 0
core/hdd/src/wlan_hdd_cfg80211.c

@@ -6269,6 +6269,7 @@ wlan_hdd_wifi_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1] = {
 	[QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL] = {.type = NLA_U16 },
 	[QCA_WLAN_VENDOR_ATTR_CONFIG_TOTAL_BEACON_MISS_COUNT] = {.type = NLA_U8},
 	[QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_ENABLE] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE] = {.type = NLA_U8},
 };
 
 /**
@@ -7176,6 +7177,22 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
 		}
 	}
 
+	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE] &&
+	    hdd_ctx->config->force_rsne_override) {
+		uint8_t force_rsne_override;
+
+		force_rsne_override =
+			nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE]);
+		if (force_rsne_override > 1) {
+			hdd_err("Invalid test_mode %d", force_rsne_override);
+			ret_val = -EINVAL;
+		}
+
+		hdd_ctx->force_rsne_override = force_rsne_override;
+		hdd_debug("force_rsne_override - %d",
+			   hdd_ctx->force_rsne_override);
+	}
+
 	return ret_val;
 }
 

+ 1 - 0
core/mac/inc/sir_api.h

@@ -1260,6 +1260,7 @@ typedef struct sSirSmeJoinReq {
 #endif
 	/* Pls make this as last variable in struct */
 	bool force_24ghz_in_ht20;
+	bool force_rsne_override;
 	tSirBssDescription bssDescription;
 	/*
 	 * WARNING: Pls make bssDescription as last variable in struct

+ 7 - 1
core/mac/src/pe/lim/lim_sme_req_utils.c

@@ -490,7 +490,13 @@ uint8_t lim_is_sme_join_req_valid(tpAniSirGlobal pMac, tpSirSmeJoinReq pJoinReq)
 {
 	uint8_t valid = true;
 
-	if (!lim_is_rsn_ie_valid_in_sme_req_message(pMac, &pJoinReq->rsnIE)) {
+	/*
+	 * If force_rsne_override is enabled that mean User has provided the
+	 * test RSNIE which need to be send as it is in assoc req and thus RSNIE
+	 * validity is not required.
+	 */
+	if (!pJoinReq->force_rsne_override &&
+	    !lim_is_rsn_ie_valid_in_sme_req_message(pMac, &pJoinReq->rsnIE)) {
 		pe_err("received SME_JOIN_REQ with invalid RSNIE");
 		valid = false;
 		goto end;

+ 1 - 0
core/sme/inc/csr_api.h

@@ -1002,6 +1002,7 @@ typedef struct csr_roam_profile {
 	uint32_t hlp_ie_len;
 	struct cds_fils_connection_info *fils_con_info;
 #endif
+	bool force_rsne_override;
 } tCsrRoamProfile;
 
 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH

+ 3 - 0
core/sme/src/csr/csr_api_roam.c

@@ -8053,6 +8053,7 @@ QDF_STATUS csr_roam_copy_profile(tpAniSirGlobal pMac,
 	pDstProfile->dfs_regdomain   = pSrcProfile->dfs_regdomain;
 	pDstProfile->chan_switch_hostapd_rate_enabled  =
 		pSrcProfile->chan_switch_hostapd_rate_enabled;
+	pDstProfile->force_rsne_override = pSrcProfile->force_rsne_override;
 end:
 	if (!QDF_IS_STATUS_SUCCESS(status)) {
 		csr_release_profile(pMac, pDstProfile);
@@ -14972,6 +14973,8 @@ QDF_STATUS csr_send_join_req_msg(tpAniSirGlobal pMac, uint32_t sessionId,
 				csr_retrieve_rsn_ie(pMac, sessionId, pProfile,
 						    pBssDescription, pIes,
 						    (tCsrRSNIe *) (wpaRsnIE));
+			csr_join_req->force_rsne_override =
+						pProfile->force_rsne_override;
 		}
 #ifdef FEATURE_WLAN_WAPI
 		else if (csr_is_profile_wapi(pProfile)) {

+ 16 - 0
core/sme/src/csr/csr_util.c

@@ -4693,6 +4693,22 @@ uint8_t csr_retrieve_rsn_ie(tHalHandle hHal, uint32_t sessionId,
 	do {
 		if (!csr_is_profile_rsn(pProfile))
 			break;
+		/* copy RSNIE from user as it is if test mode is enabled */
+		if (pProfile->force_rsne_override &&
+		    pProfile->nRSNReqIELength && pProfile->pRSNReqIE) {
+			sme_debug("force_rsne_override, copy RSN IE provided by user");
+			if (pProfile->nRSNReqIELength <=
+					DOT11F_IE_RSN_MAX_LEN) {
+				cbRsnIe = (uint8_t) pProfile->nRSNReqIELength;
+				qdf_mem_copy(pRsnIe, pProfile->pRSNReqIE,
+					     cbRsnIe);
+			} else {
+				sme_warn("csr_retrieve_rsn_ie detect invalid RSN IE length (%d)",
+					pProfile->nRSNReqIELength);
+			}
+			break;
+		}
+
 		if (csr_roam_is_fast_roam_enabled(pMac, sessionId)) {
 			/* If "Legacy Fast Roaming" is enabled ALWAYS rebuild
 			 * the RSN IE from scratch. So it contains the current