diff options
| author | gaolez <gaolez@codeaurora.org> | 2018-07-06 13:35:32 +0800 |
|---|---|---|
| committer | gaolez <gaolez@codeaurora.org> | 2018-07-06 13:35:32 +0800 |
| commit | c6b9f11a0a7dbacb9fad659d7ebe7cb64f25d1c4 (patch) | |
| tree | b39387faab44802d3e3598851538cda823f45b77 | |
| parent | dcff449ac780849c2eae8704f153c1c7671def54 (diff) | |
qcacld-2.0: Fix OOB write in wma_unified_debug_print_event_handler
propagation from qcacld-3.0 to qcacld-2.0
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: 2273985
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 399faf764831..3f69182fca10 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -1508,19 +1508,24 @@ static int wma_unified_debug_print_event_handler(void *handle, u_int8_t *datap, u_int32_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 > WMA_SVC_MSG_MAX_SIZE ) { + WMA_LOGE("Received data len %d exceeds max value %d", + datalen, WMA_SVC_MSG_MAX_SIZE); + return -EINVAL; + } + 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 }; |
