Kaynağa Gözat

qcacld-3.0: Avoid double free in sch_gen_timing_advert_frame

In sch_gen_timing_advert_frame, the memory allocated for buffer
timing_advert->template_value is freed but not reset to NULL.
This creates a dangling pointer, and it is freed again inside
__wlan_hdd_cfg80211_ocb_start_timing_advert.

To avoid this issue, reset the pointer to buffer
timing_advert->template_value to NULL before returning from
sch_gen_timing_advert_frame.

Change-Id: I2445c53f217d0fd22cbe3026b0869284fe13b851
CRs-Fixed: 3229906
Aditya Kodukula 2 yıl önce
ebeveyn
işleme
3f9ed9d291
2 değiştirilmiş dosya ile 15 ekleme ve 17 silme
  1. 14 16
      core/mac/src/pe/sch/sch_api.c
  2. 1 1
      core/sme/src/common/sme_api.c

+ 14 - 16
core/mac/src/pe/sch/sch_api.c

@@ -892,52 +892,50 @@ uint32_t lim_send_probe_rsp_template_to_hal(struct mac_context *mac,
  * @timestamp_offset: return for the offset of the timestamp field
  * @time_value_offset: return for the time_value field in the TA IE
  *
- * Return: the length of the buffer.
+ * Return: the length of the buffer on success and error code on failure.
  */
 int sch_gen_timing_advert_frame(struct mac_context *mac_ctx, tSirMacAddr self_addr,
 	uint8_t **buf, uint32_t *timestamp_offset, uint32_t *time_value_offset)
 {
-	tDot11fTimingAdvertisementFrame frame;
+	tDot11fTimingAdvertisementFrame frame = {0};
 	uint32_t payload_size, buf_size;
 	int status;
 	struct qdf_mac_addr wildcard_bssid = {
 		{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
 	};
 
-	qdf_mem_zero((uint8_t *)&frame, sizeof(tDot11fTimingAdvertisementFrame));
-
 	/* Populate the TA fields */
 	status = populate_dot11f_timing_advert_frame(mac_ctx, &frame);
-	if (status) {
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
 		pe_err("Error populating TA frame %x", status);
-		return status;
+		return qdf_status_to_os_return(status);
 	}
 
 	status = dot11f_get_packed_timing_advertisement_frame_size(mac_ctx,
 		&frame, &payload_size);
 	if (DOT11F_FAILED(status)) {
 		pe_err("Error getting packed frame size %x", status);
-		return status;
-	} else if (DOT11F_WARNED(status)) {
-		pe_warn("Warning getting packed frame size");
+		return -EINVAL;
 	}
+	if (DOT11F_WARNED(status))
+		pe_warn("Warning getting packed frame size");
 
 	buf_size = sizeof(tSirMacMgmtHdr) + payload_size;
 	*buf = qdf_mem_malloc(buf_size);
 	if (!*buf)
-		return QDF_STATUS_E_FAILURE;
+		return -ENOMEM;
 
 	payload_size = 0;
 	status = dot11f_pack_timing_advertisement_frame(mac_ctx, &frame,
 		*buf + sizeof(tSirMacMgmtHdr), buf_size -
 		sizeof(tSirMacMgmtHdr), &payload_size);
-	pe_err("TA payload size2 = %d", payload_size);
+	pe_debug("TA payload size2 = %d", payload_size);
 	if (DOT11F_FAILED(status)) {
 		pe_err("Error packing frame %x", status);
 		goto fail;
-	} else if (DOT11F_WARNED(status)) {
-		pe_warn("Warning packing frame");
 	}
+	if (DOT11F_WARNED(status))
+		pe_warn("Warning packing frame");
 
 	lim_populate_mac_header(mac_ctx, *buf, SIR_MAC_MGMT_FRAME,
 		SIR_MAC_MGMT_TIME_ADVERT, wildcard_bssid.bytes, self_addr);
@@ -964,7 +962,7 @@ int sch_gen_timing_advert_frame(struct mac_context *mac_ctx, tSirMacAddr self_ad
 	return payload_size + sizeof(tSirMacMgmtHdr);
 
 fail:
-	if (*buf)
-		qdf_mem_free(*buf);
-	return status;
+	qdf_mem_free(*buf);
+	*buf = NULL;
+	return -EINVAL;
 }

+ 1 - 1
core/sme/src/common/sme_api.c

@@ -7500,7 +7500,7 @@ void sme_get_command_q_status(mac_handle_t mac_handle)
  * @timestamp_offset: return for the offset of the timestamp field
  * @time_value_offset: return for the time_value field in the TA IE
  *
- * Return: the length of the buffer.
+ * Return: the length of the buffer on success and error code on failure.
  */
 int sme_ocb_gen_timing_advert_frame(mac_handle_t mac_handle,
 				    tSirMacAddr self_addr, uint8_t **buf,