From 320302d00197eadab68b46448551bb06a7a6d17a Mon Sep 17 00:00:00 2001 From: Ajit Vaishya Date: Thu, 4 Apr 2019 15:25:50 +0530 Subject: Wifi-Hal: Avoid accessing invalid memory while parsing pkt stats Current implementation of packet stats parsing isn't validating remaining buflen, which might lead to accessing invalid memory location while parsing. To address this issue, we need to check whether received buflen is sufficient to parse the stat before reading the stats from nlmsg. While parsing pkt stats, the bufflen shall be decremented for all versions of packet log records. Add logic to decrement buflen for the missed versions also. Change-Id: I573a5158b97f2c2b1b59026a8ae14e23ffc8135f CRs-Fixed: 2422931 Bug: 130226017 Test: Manual Test, turn verbose logging and check pkt log --- qcwcn/wifi_hal/wifi_hal.cpp | 2 +- qcwcn/wifi_hal/wifilogger_diag.cpp | 62 ++++++++++++++++++++++---------------- 2 files changed, 37 insertions(+), 27 deletions(-) (limited to 'qcwcn/wifi_hal') diff --git a/qcwcn/wifi_hal/wifi_hal.cpp b/qcwcn/wifi_hal/wifi_hal.cpp index 5fc3007..462f1fa 100644 --- a/qcwcn/wifi_hal/wifi_hal.cpp +++ b/qcwcn/wifi_hal/wifi_hal.cpp @@ -818,7 +818,7 @@ wifi_error wifi_initialize(wifi_handle *handle) } ALOGV("%s: hardware version type %d", __func__, info->pkt_log_ver); } else { - ALOGE("Failed to get supported logger feature set: %d", ret); + ALOGE("Failed to get firmware version: %d", ret); } ret = get_firmware_bus_max_size_supported(iface_handle); diff --git a/qcwcn/wifi_hal/wifilogger_diag.cpp b/qcwcn/wifi_hal/wifilogger_diag.cpp index 1bcece4..436a42b 100644 --- a/qcwcn/wifi_hal/wifilogger_diag.cpp +++ b/qcwcn/wifi_hal/wifilogger_diag.cpp @@ -2465,52 +2465,62 @@ static wifi_error parse_stats_record_v1(hal_info *info, static wifi_error parse_stats(hal_info *info, u8 *data, u32 buflen) { wh_pktlog_hdr_t *pkt_stats_header; - wh_pktlog_hdr_v2_t *pkt_stats_header_t; + wh_pktlog_hdr_v2_t *pkt_stats_header_v2_t; wifi_error status = WIFI_SUCCESS; do { + u32 record_len; + if (buflen < sizeof(wh_pktlog_hdr_t)) { status = WIFI_ERROR_INVALID_ARGS; break; } pkt_stats_header = (wh_pktlog_hdr_t *)data; + pkt_stats_header_v2_t = (wh_pktlog_hdr_v2_t *)data; + + if (info->pkt_log_ver == PKT_LOG_V2) { + if (buflen < sizeof(wh_pktlog_hdr_v2_t)) { + status = WIFI_ERROR_INVALID_ARGS; + break; + } + record_len = (sizeof(wh_pktlog_hdr_v2_t) + pkt_stats_header_v2_t->size); + } else { + if (pkt_stats_header->flags & PKT_INFO_FLG_PKT_DUMP_V2){ + if (buflen < sizeof(wh_pktlog_hdr_v2_t)) { + status = WIFI_ERROR_INVALID_ARGS; + break; + } + record_len = (sizeof(wh_pktlog_hdr_v2_t) + pkt_stats_header_v2_t->size); + } else { + record_len = (sizeof(wh_pktlog_hdr_t) + pkt_stats_header->size); + } + } - if (buflen < (sizeof(wh_pktlog_hdr_t) + pkt_stats_header->size)) { + if (buflen < record_len) { status = WIFI_ERROR_INVALID_ARGS; break; } /* Pkt_log_V2 based packet parsing */ if (info->pkt_log_ver == PKT_LOG_V2) { - pkt_stats_header_t = (wh_pktlog_hdr_v2_t *)data; - status = parse_stats_record_v2(info, pkt_stats_header_t); - if (status != WIFI_SUCCESS) { - ALOGE("Failed to parse the stats type : %d", - pkt_stats_header_t->log_type); - return status; - } + status = parse_stats_record_v2(info, pkt_stats_header_v2_t); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to parse the stats type : %d", + pkt_stats_header_v2_t->log_type); + return status; + } /* Pkt_log_V1 based packet parsing */ } else { - status = parse_stats_record_v1(info, pkt_stats_header); - if (status != WIFI_SUCCESS) { - ALOGE("Failed to parse the stats type : %d", + status = parse_stats_record_v1(info, pkt_stats_header); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to parse the stats type : %d", pkt_stats_header->log_type); - return status; - } + return status; + } } + data += record_len; + buflen -= record_len; - if (info->pkt_log_ver == PKT_LOG_V1) { - if (pkt_stats_header->flags & PKT_INFO_FLG_PKT_DUMP_V2){ - data += (sizeof(wh_pktlog_hdr_v2_t) + pkt_stats_header->size); - buflen -= (sizeof(wh_pktlog_hdr_v2_t) + pkt_stats_header->size); - } else { - data += (sizeof(wh_pktlog_hdr_t) + pkt_stats_header->size); - buflen -= (sizeof(wh_pktlog_hdr_t) + pkt_stats_header->size); - } - } else if (info->pkt_log_ver == PKT_LOG_V2) { - data += (sizeof(wh_pktlog_hdr_v2_t) + pkt_stats_header->size); - buflen -= (sizeof(wh_pktlog_hdr_v2_t) + pkt_stats_header->size); - } } while (buflen > 0); return status; -- cgit v1.2.3