Browse Source

qcacmn: Implement crypto locking mechanism

Implement a locking mechanism for retrieving and
storing crypto keys. Currently, due to race condition,
Host driver is fetching information in one thread while
simultaneously writing key information in another thread,
resulting in synchronization issues.

This change is to add lock mechanism while reading and writing
crypto keys.

Change-Id: I156b619cf7c3c052ad3122a6f808d732fb5e4f51
CRs-Fixed: 3669552
Aasir Rasheed 1 năm trước cách đây
mục cha
commit
c062f5394b

+ 13 - 1
os_if/linux/crypto/src/wlan_cfg80211_crypto.c

@@ -148,12 +148,15 @@ int wlan_cfg80211_store_link_key(struct wlan_objmgr_psoc *psoc,
 	 * key may already exist at times and may be retrieved only to
 	 * update it.
 	 */
+	wlan_crypto_aquire_lock();
 	crypto_key = wlan_crypto_get_ml_sta_link_key(psoc, key_index,
 						     link_addr, link_id);
 	if (!crypto_key) {
+		wlan_crypto_release_lock();
 		crypto_key = qdf_mem_malloc(sizeof(*crypto_key));
 		if (!crypto_key)
 			return -EINVAL;
+		wlan_crypto_aquire_lock();
 	}
 
 	wlan_cfg80211_translate_ml_sta_key(key_index, key_type, mac_addr,
@@ -162,10 +165,12 @@ int wlan_cfg80211_store_link_key(struct wlan_objmgr_psoc *psoc,
 	status = wlan_crypto_save_ml_sta_key(psoc, key_index, crypto_key,
 					     link_addr, link_id);
 	if (QDF_IS_STATUS_ERROR(status)) {
+		wlan_crypto_release_lock();
 		osif_err("Failed to save key");
 		qdf_mem_free(crypto_key);
 		return -EINVAL;
 	}
+	wlan_crypto_release_lock();
 	return 0;
 }
 
@@ -213,11 +218,14 @@ int wlan_cfg80211_store_key(struct wlan_objmgr_vdev *vdev,
 	 * key may already exist at times and may be retrieved only to
 	 * update it.
 	 */
+	wlan_crypto_aquire_lock();
 	crypto_key = wlan_crypto_get_key(vdev, key_index);
 	if (!crypto_key) {
+		wlan_crypto_release_lock();
 		crypto_key = qdf_mem_malloc(sizeof(*crypto_key));
 		if (!crypto_key)
 			return -EINVAL;
+		wlan_crypto_aquire_lock();
 	}
 
 	wlan_cfg80211_translate_key(vdev, key_index, key_type, mac_addr,
@@ -225,10 +233,12 @@ int wlan_cfg80211_store_key(struct wlan_objmgr_vdev *vdev,
 
 	status = wlan_crypto_save_key(vdev, key_index, crypto_key);
 	if (QDF_IS_STATUS_ERROR(status)) {
+		wlan_crypto_release_lock();
 		osif_err("Failed to save key");
 		qdf_mem_free(crypto_key);
 		return -EINVAL;
 	}
+	wlan_crypto_release_lock();
 	return 0;
 }
 
@@ -268,11 +278,14 @@ int wlan_cfg80211_crypto_add_key(struct wlan_objmgr_vdev *vdev,
 		.timeout_ms = WLAN_WAIT_TIME_ADD_KEY,
 	};
 
+	wlan_crypto_aquire_lock();
 	crypto_key = wlan_crypto_get_key(vdev, key_index);
 	if (!crypto_key) {
+		wlan_crypto_release_lock();
 		osif_err("Crypto KEY is NULL");
 		return -EINVAL;
 	}
+	wlan_crypto_release_lock();
 
 	if (sync) {
 		priv = wlan_get_vdev_crypto_obj(vdev);
@@ -309,7 +322,6 @@ int wlan_cfg80211_crypto_add_key(struct wlan_objmgr_vdev *vdev,
 	} else {
 		status  = ucfg_crypto_set_key_req(vdev, crypto_key, key_type);
 	}
-
 	return qdf_status_to_os_return(status);
 }
 

+ 9 - 0
umac/cmn_services/crypto/inc/wlan_crypto_global_api.h

@@ -1224,5 +1224,14 @@ wlan_crypto_set_ltf_keyseed(struct wlan_objmgr_psoc *psoc,
  */
 QDF_STATUS wlan_crypto_create_fils_rik(uint8_t *rrk, uint8_t rrk_len,
 				       uint8_t *rik, uint32_t *rik_len);
+/**
+ * wlan_crypto_aquire_lock() - Acquire the crypto lock before crypto set/get
+ */
+void wlan_crypto_aquire_lock(void);
+
+/**
+ * wlan_crypto_release_lock() - Release the crypto lock after crypto set/get
+ */
+void wlan_crypto_release_lock(void);
 #endif /* WLAN_FEATURE_FILS_SK */
 #endif /* end of _WLAN_CRYPTO_GLOBAL_API_H_ */

+ 19 - 1
umac/cmn_services/crypto/src/wlan_crypto_obj_mgr.c

@@ -41,7 +41,8 @@
 
 #define CRYPTO_MAX_HASH_IDX 16
 #define CRYPTO_MAX_HASH_ENTRY 1024
-qdf_mutex_t crypto_lock;
+
+static qdf_mutex_t crypto_lock;
 
 extern const struct wlan_crypto_cipher
 				*wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_MAX];
@@ -673,6 +674,16 @@ void wlan_crypto_free_vdev_key(struct wlan_objmgr_vdev *vdev)
 }
 #endif
 
+void wlan_crypto_aquire_lock(void)
+{
+	qdf_mutex_acquire(&crypto_lock);
+}
+
+void wlan_crypto_release_lock(void)
+{
+	qdf_mutex_release(&crypto_lock);
+}
+
 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
 void wlan_crypto_free_key_by_link_id(struct wlan_objmgr_psoc *psoc,
 				     struct qdf_mac_addr *link_addr,
@@ -902,6 +913,9 @@ QDF_STATUS __wlan_crypto_init(void)
 {
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
+	/* Initialize crypto global lock*/
+	qdf_mutex_create(&crypto_lock);
+
 	status = register_psoc_create_handler();
 	if (QDF_IS_STATUS_ERROR(status)) {
 		crypto_err("psoc creation failure");
@@ -1018,5 +1032,9 @@ QDF_STATUS __wlan_crypto_deinit(void)
 			!= QDF_STATUS_SUCCESS) {
 		return QDF_STATUS_E_FAILURE;
 	}
+
+	/* Destroy crypto global lock */
+	qdf_mutex_destroy(&crypto_lock);
+
 	return QDF_STATUS_SUCCESS;
 }