qcacmn: Fix integer underflow and buffer over-read in fwlog
Currently, there is no check of: 1) Firmware event parameters in dbglog_parse_debug_logs(), which can result in integer underflow. 2) Number of dbg log args against the total length, which can result in buffer over-read. To fix this, compare size of firmware event parameters and number of dbg log args with total buffer length. Change-Id: I7fbc684ec9e80cfc66220755a1ad6b9394194735 CRs-Fixed: 2197246
This commit is contained in:

committed by
nshrivas

parent
deeaf6e9b2
commit
448e07a99e
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
|
* Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
|
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
|
||||||
*
|
*
|
||||||
@@ -1483,7 +1483,7 @@ static int dbglog_print_raw_data(A_UINT32 *buffer, A_UINT32 length)
|
|||||||
char parseArgsString[DBGLOG_PARSE_ARGS_STRING_LENGTH];
|
char parseArgsString[DBGLOG_PARSE_ARGS_STRING_LENGTH];
|
||||||
char *dbgidString;
|
char *dbgidString;
|
||||||
|
|
||||||
while (count < length) {
|
while ((count + 1) < length) {
|
||||||
|
|
||||||
debugid = DBGLOG_GET_DBGID(buffer[count + 1]);
|
debugid = DBGLOG_GET_DBGID(buffer[count + 1]);
|
||||||
moduleid = DBGLOG_GET_MODULEID(buffer[count + 1]);
|
moduleid = DBGLOG_GET_MODULEID(buffer[count + 1]);
|
||||||
@@ -1496,6 +1496,9 @@ static int dbglog_print_raw_data(A_UINT32 *buffer, A_UINT32 length)
|
|||||||
OS_MEMZERO(parseArgsString, sizeof(parseArgsString));
|
OS_MEMZERO(parseArgsString, sizeof(parseArgsString));
|
||||||
totalWriteLen = 0;
|
totalWriteLen = 0;
|
||||||
|
|
||||||
|
if (!numargs || (count + numargs + 2 > length))
|
||||||
|
goto skip_args_processing;
|
||||||
|
|
||||||
for (curArgs = 0; curArgs < numargs; curArgs++) {
|
for (curArgs = 0; curArgs < numargs; curArgs++) {
|
||||||
/*
|
/*
|
||||||
* Using sprintf_s instead of sprintf,
|
* Using sprintf_s instead of sprintf,
|
||||||
@@ -1508,7 +1511,7 @@ static int dbglog_print_raw_data(A_UINT32 *buffer, A_UINT32 length)
|
|||||||
buffer[count + 2 + curArgs]);
|
buffer[count + 2 + curArgs]);
|
||||||
totalWriteLen += writeLen;
|
totalWriteLen += writeLen;
|
||||||
}
|
}
|
||||||
|
skip_args_processing:
|
||||||
if (debugid < MAX_DBG_MSGS) {
|
if (debugid < MAX_DBG_MSGS) {
|
||||||
dbgidString = DBG_MSG_ARR[moduleid][debugid];
|
dbgidString = DBG_MSG_ARR[moduleid][debugid];
|
||||||
if (dbgidString != NULL) {
|
if (dbgidString != NULL) {
|
||||||
@@ -2000,6 +2003,11 @@ int dbglog_parse_debug_logs(ol_scn_t scn, uint8_t *data, uint32_t datalen)
|
|||||||
len = param_buf->num_bufp;
|
len = param_buf->num_bufp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (len < sizeof(dropped)) {
|
||||||
|
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid length\n"));
|
||||||
|
return A_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
dropped = *((A_UINT32 *) datap);
|
dropped = *((A_UINT32 *) datap);
|
||||||
if (dropped > 0) {
|
if (dropped > 0) {
|
||||||
AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
|
AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
|
||||||
|
Reference in New Issue
Block a user