From 448e07a99ee03dc5b2987e4018c8ffa645e7b6f0 Mon Sep 17 00:00:00 2001 From: Rajeev Kumar Sirasanagandla Date: Wed, 28 Feb 2018 12:21:47 +0530 Subject: 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 --- utils/fwlog/dbglog_host.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'utils') diff --git a/utils/fwlog/dbglog_host.c b/utils/fwlog/dbglog_host.c index dc8b0f595..bf4006b85 100644 --- a/utils/fwlog/dbglog_host.c +++ b/utils/fwlog/dbglog_host.c @@ -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. * @@ -1483,7 +1483,7 @@ static int dbglog_print_raw_data(A_UINT32 *buffer, A_UINT32 length) char parseArgsString[DBGLOG_PARSE_ARGS_STRING_LENGTH]; char *dbgidString; - while (count < length) { + while ((count + 1) < length) { debugid = DBGLOG_GET_DBGID(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)); totalWriteLen = 0; + if (!numargs || (count + numargs + 2 > length)) + goto skip_args_processing; + for (curArgs = 0; curArgs < numargs; curArgs++) { /* * 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]); totalWriteLen += writeLen; } - +skip_args_processing: if (debugid < MAX_DBG_MSGS) { dbgidString = DBG_MSG_ARR[moduleid][debugid]; 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; } + if (len < sizeof(dropped)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid length\n")); + return A_ERROR; + } + dropped = *((A_UINT32 *) datap); if (dropped > 0) { AR_DEBUG_PRINTF(ATH_DEBUG_TRC, -- cgit v1.2.3