Browse Source

qcacld-3.0: Fix incorrect buffer handling in OEM response handlers

qcacld-2.0 to qcacld-3.0 propagation.

Fix incorrect buffer handling in OEM response handlers.

This change set will fix,
1. Add appropriate check on the response length before malloc.
2. Add correct check for malloc failure.
3. Copy correct number of bytes into response buffer.

Change-Id: I621e391b9cdadbf01c98fdbf3ac1979373bb963c
CRs-Fixed: 996236
Krishna Kumaar Natarajan 9 years ago
parent
commit
a96ee0f6ee
2 changed files with 56 additions and 22 deletions
  1. 1 1
      core/sme/inc/oem_data_api.h
  2. 55 21
      core/wma/src/wma_features.c

+ 1 - 1
core/sme/inc/oem_data_api.h

@@ -59,7 +59,7 @@ typedef struct tagOemDataReq {
 } tOemDataReq, tOemDataReqConfig;
 
 typedef struct tagOemDataRsp {
-	uint8_t rsp_len;
+	uint32_t rsp_len;
 	uint8_t *oem_data_rsp;
 } tOemDataRsp;
 

+ 55 - 21
core/wma/src/wma_features.c

@@ -1254,7 +1254,7 @@ int wma_oem_capability_event_callback(void *handle,
 	}
 
 	/*
-	 *  wma puts 4 bytes prefix for msg subtype, so length
+	 * wma puts 4 bytes prefix for msg subtype, so length
 	 * of data received from target should be 4 bytes less
 	 * then max allowed
 	 */
@@ -1269,12 +1269,21 @@ int wma_oem_capability_event_callback(void *handle,
 		WMA_LOGE("%s: Failed to alloc pStartOemDataRsp", __func__);
 		return -ENOMEM;
 	}
+
 	pStartOemDataRsp->rsp_len = datalen + OEM_MESSAGE_SUBTYPE_LEN;
-	pStartOemDataRsp->oem_data_rsp = qdf_mem_malloc(datalen);
-	if (!pStartOemDataRsp->oem_data_rsp) {
-		WMA_LOGE(FL("malloc failed for oem_data_rsp"));
+	if (pStartOemDataRsp->rsp_len) {
+		pStartOemDataRsp->oem_data_rsp =
+				qdf_mem_malloc(pStartOemDataRsp->rsp_len);
+		if (!pStartOemDataRsp->oem_data_rsp) {
+			WMA_LOGE(FL("malloc failed for oem_data_rsp"));
+			qdf_mem_free(pStartOemDataRsp);
+			return -ENOMEM;
+		}
+	} else {
+		WMA_LOGE(FL("Invalid rsp length: %d"),
+			 pStartOemDataRsp->rsp_len);
 		qdf_mem_free(pStartOemDataRsp);
-		return -ENOMEM;
+		return -EINVAL;
 	}
 
 	pStartOemDataRsp->target_rsp = true;
@@ -1340,12 +1349,21 @@ int wma_oem_measurement_report_event_callback(void *handle,
 		WMA_LOGE("%s: Failed to alloc pStartOemDataRsp", __func__);
 		return -ENOMEM;
 	}
+
 	pStartOemDataRsp->rsp_len = datalen + OEM_MESSAGE_SUBTYPE_LEN;
-	pStartOemDataRsp->oem_data_rsp = qdf_mem_malloc(datalen);
-	if (!pStartOemDataRsp->oem_data_rsp) {
-		WMA_LOGE(FL("malloc failed for oem_data_rsp"));
+	if (pStartOemDataRsp->rsp_len) {
+		pStartOemDataRsp->oem_data_rsp =
+				qdf_mem_malloc(pStartOemDataRsp->rsp_len);
+		if (!pStartOemDataRsp->oem_data_rsp) {
+			WMA_LOGE(FL("malloc failed for oem_data_rsp"));
+			qdf_mem_free(pStartOemDataRsp);
+			return -ENOMEM;
+		}
+	} else {
+		WMA_LOGE(FL("Invalid rsp length: %d"),
+			 pStartOemDataRsp->rsp_len);
 		qdf_mem_free(pStartOemDataRsp);
-		return -ENOMEM;
+		return -EINVAL;
 	}
 
 	pStartOemDataRsp->target_rsp = true;
@@ -1353,10 +1371,10 @@ int wma_oem_measurement_report_event_callback(void *handle,
 	*msg_subtype = WMI_OEM_MEASUREMENT_RSP;
 	/* copy data after msg sub type */
 	qdf_mem_copy(pStartOemDataRsp->oem_data_rsp + OEM_MESSAGE_SUBTYPE_LEN,
-		     data, pStartOemDataRsp->rsp_len);
+		     data, datalen);
 
 	WMA_LOGI("%s: Sending WMA_START_OEM_DATA_RSP, data len (%d)",
-		 __func__, datalen);
+		 __func__, pStartOemDataRsp->rsp_len);
 
 	wma_send_msg(wma, WMA_START_OEM_DATA_RSP, (void *)pStartOemDataRsp, 0);
 	return 0;
@@ -1410,12 +1428,21 @@ int wma_oem_error_report_event_callback(void *handle,
 		WMA_LOGE("%s: Failed to alloc pStartOemDataRsp", __func__);
 		return -ENOMEM;
 	}
+
 	pStartOemDataRsp->rsp_len = datalen + OEM_MESSAGE_SUBTYPE_LEN;
-	pStartOemDataRsp->oem_data_rsp = qdf_mem_malloc(datalen);
-	if (!pStartOemDataRsp->oem_data_rsp) {
-		WMA_LOGE(FL("malloc failed for oem_data_rsp"));
+	if (pStartOemDataRsp->rsp_len) {
+		pStartOemDataRsp->oem_data_rsp =
+				qdf_mem_malloc(pStartOemDataRsp->rsp_len);
+		if (!pStartOemDataRsp->oem_data_rsp) {
+			WMA_LOGE(FL("malloc failed for oem_data_rsp"));
+			qdf_mem_free(pStartOemDataRsp);
+			return -ENOMEM;
+		}
+	} else {
+		WMA_LOGE(FL("Invalid rsp length: %d"),
+			 pStartOemDataRsp->rsp_len);
 		qdf_mem_free(pStartOemDataRsp);
-		return -ENOMEM;
+		return -EINVAL;
 	}
 
 	pStartOemDataRsp->target_rsp = true;
@@ -1423,10 +1450,10 @@ int wma_oem_error_report_event_callback(void *handle,
 	*msg_subtype = WMI_OEM_ERROR_REPORT_RSP;
 	/* copy data after msg sub type */
 	qdf_mem_copy(pStartOemDataRsp->oem_data_rsp + OEM_MESSAGE_SUBTYPE_LEN,
-		     data, pStartOemDataRsp->rsp_len);
+		     data, datalen);
 
 	WMA_LOGI("%s: Sending WMA_START_OEM_DATA_RSP, data len (%d)",
-		 __func__, datalen);
+		 __func__, pStartOemDataRsp->rsp_len);
 
 	wma_send_msg(wma, WMA_START_OEM_DATA_RSP, (void *)pStartOemDataRsp, 0);
 	return 0;
@@ -1475,11 +1502,18 @@ int wma_oem_data_response_handler(void *handle,
 		return -ENOMEM;
 	}
 	oem_rsp->rsp_len = datalen;
-	oem_rsp->oem_data_rsp = qdf_mem_malloc(datalen);
-	if (!oem_rsp->rsp_len) {
-		WMA_LOGE(FL("malloc failed for oem_data_rsp"));
+	if (oem_rsp->rsp_len) {
+		oem_rsp->oem_data_rsp = qdf_mem_malloc(oem_rsp->rsp_len);
+		if (!oem_rsp->oem_data_rsp) {
+			WMA_LOGE(FL("malloc failed for oem_data_rsp"));
+			qdf_mem_free(oem_rsp);
+			return -ENOMEM;
+		}
+	} else {
+		WMA_LOGE(FL("Invalid rsp length: %d"),
+			 oem_rsp->rsp_len);
 		qdf_mem_free(oem_rsp);
-		return -ENOMEM;
+		return -EINVAL;
 	}
 
 	oem_rsp->target_rsp = true;