Explorar el Código

qcacld-3.0: Fix OOB write in wma_unified_debug_print_event_handler

The routine wma_unified_debug_print_event_handler logs the data from debug
print event handler. The param event data from firmware is copied to a
destination buffer .If the maximum size of the data exceeds or equals
BIG_ENDIAN_MAX_DEBUG_BUF for big endian hosts then possible OOB write will
occur in wma_unified_debug_print_event_handler. For other hosts, OOB read
could occur if datalen exceeds maximum firmware message size
WMI_SVC_MAX_SIZE.

Add check to validate datalen doesnot exceed the maximum firmware msg size
WMI_SVC_MAX_SIZE. Return failure if it exceeds.
Add check to ensure datalen doesnot exceed or equal the maximum buffer
length value for big endian hosts BIG_ENDIAN_MAX_DEBUG_BUF.
Add null termination at the end of the data recieved from the firmware.

Change-Id: Ibb662cb8e17ef8be8b7591308c422a78b71e331a
CRs-Fixed: 2222533
Pragaspathi Thilagaraj hace 7 años
padre
commit
d9888ce77f
Se han modificado 1 ficheros con 9 adiciones y 3 borrados
  1. 9 3
      core/wma/src/wma_utils.c

+ 9 - 3
core/wma/src/wma_utils.c

@@ -3527,19 +3527,25 @@ int wma_unified_debug_print_event_handler(void *handle, uint8_t *datap,
 	uint32_t datalen;
 
 	param_buf = (WMI_DEBUG_PRINT_EVENTID_param_tlvs *) datap;
-	if (!param_buf) {
+	if (!param_buf || !param_buf->data) {
 		WMA_LOGE("Get NULL point message from FW");
 		return -ENOMEM;
 	}
 	data = param_buf->data;
 	datalen = param_buf->num_data;
+	if (datalen > WMI_SVC_MSG_MAX_SIZE) {
+		WMA_LOGE("Received data len %d exceeds max value %d",
+				datalen, WMI_SVC_MSG_MAX_SIZE);
+		return QDF_STATUS_E_FAILURE;
+	}
+	data[datalen - 1] = '\0';
 
 #ifdef BIG_ENDIAN_HOST
 	{
-		if (datalen > BIG_ENDIAN_MAX_DEBUG_BUF) {
+		if (datalen >= BIG_ENDIAN_MAX_DEBUG_BUF) {
 			WMA_LOGE("%s Invalid data len %d, limiting to max",
 				 __func__, datalen);
-			datalen = BIG_ENDIAN_MAX_DEBUG_BUF;
+			datalen = BIG_ENDIAN_MAX_DEBUG_BUF - 1;
 		}
 		char dbgbuf[BIG_ENDIAN_MAX_DEBUG_BUF] = { 0 };