Browse Source

qcacld-3.0: Fix double free in cm_roam_pmkid_request_handler

Currently memory allocated for structure roam_pmkid_req_event
is freed in two places causing usage after free.
Fix is to free memory only once in
target_if_pmkid_request_event_handler api.

Change-Id: Idc70e8437f89cb1cf4f6d35f924085409994714a
CRs-Fixed: 3064667
Amruta Kulkarni 3 years ago
parent
commit
15760d2d1b

+ 3 - 1
components/target_if/connection_mgr/src/target_if_cm_roam_event.c

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. 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 above
@@ -513,7 +514,8 @@ target_if_pmkid_request_event_handler(ol_scn_t scn, uint8_t *event,
 	qdf_status = roam_rx_ops->roam_pmkid_request_event_rx(data);
 
 done:
-	qdf_mem_free(data);
+	if (data)
+		qdf_mem_free(data);
 	return qdf_status_to_os_return(qdf_status);
 }
 

+ 1 - 4
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c

@@ -2448,11 +2448,8 @@ cm_roam_pmkid_request_handler(struct roam_pmkid_req_event *data)
 	QDF_STATUS status;
 
 	status = cm_roam_pmkid_req_ind(data->psoc, data->vdev_id, data);
-	if (QDF_IS_STATUS_ERROR(status)) {
+	if (QDF_IS_STATUS_ERROR(status))
 		mlme_err("Pmkid request failed");
-		qdf_mem_free(data);
-		return status;
-	}
 
 	return status;
 }

+ 7 - 7
components/wmi/src/wmi_unified_roam_tlv.c

@@ -3171,19 +3171,19 @@ extract_roam_pmkid_request_tlv(wmi_unified_t wmi_handle, uint8_t *evt_buf,
 
 	if (!evt_buf || !len) {
 		wmi_err("received null event from target");
-		return -EINVAL;
+		return QDF_STATUS_E_INVAL;
 	}
 
 	param_buf = (WMI_ROAM_PMKID_REQUEST_EVENTID_param_tlvs *)evt_buf;
 	if (!param_buf) {
 		wmi_err("received null buf from target");
-		return -EINVAL;
+		return QDF_STATUS_E_INVAL;
 	}
 
 	roam_pmkid_req_ev = param_buf->fixed_param;
 	if (!roam_pmkid_req_ev) {
 		wmi_err("received null event data from target");
-		return -EINVAL;
+		return QDF_STATUS_E_INVAL;
 	}
 
 	if (roam_pmkid_req_ev->vdev_id >= WLAN_MAX_VDEVS) {
@@ -3195,20 +3195,20 @@ extract_roam_pmkid_request_tlv(wmi_unified_t wmi_handle, uint8_t *evt_buf,
 	if (num_entries > MAX_RSSI_AVOID_BSSID_LIST) {
 		wmi_err("num bssid entries:%d exceeds maximum value",
 			num_entries);
-		return -EINVAL;
+		return QDF_STATUS_E_INVAL;
 	}
 
 	src_list = param_buf->pmkid_request;
 	if (len < (sizeof(*roam_pmkid_req_ev) +
 		(num_entries * sizeof(*src_list)))) {
 		wmi_err("Invalid length: %d", len);
-		return -EINVAL;
+		return QDF_STATUS_E_INVAL;
 	}
 
 	dst_list = qdf_mem_malloc(sizeof(struct roam_pmkid_req_event) +
 				  (sizeof(struct qdf_mac_addr) * num_entries));
 	if (!dst_list)
-		return -ENOMEM;
+		return QDF_STATUS_E_NOMEM;
 
 	dst_list->vdev_id = roam_pmkid_req_ev->vdev_id;
 
@@ -3221,7 +3221,7 @@ extract_roam_pmkid_request_tlv(wmi_unified_t wmi_handle, uint8_t *evt_buf,
 		    qdf_is_macaddr_group(roam_bsslist)) {
 			wmi_err("Invalid bssid");
 			qdf_mem_free(dst_list);
-			return -EINVAL;
+			return QDF_STATUS_E_INVAL;
 		}
 		wmi_debug("Received pmkid fallback for bssid: " QDF_MAC_ADDR_FMT" vdev_id:%d",
 			  QDF_MAC_ADDR_REF(roam_bsslist->bytes),