summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAjit Vaishya <ajitv@codeaurora.org>2019-04-04 15:25:50 +0530
committerLes Lee <lesl@google.com>2019-06-13 07:44:15 +0000
commit320302d00197eadab68b46448551bb06a7a6d17a (patch)
treef9db646b7bf3e50059ba48b63c146fdaa0d4ac0e
parent1b30bee31528c40d72cd9d762a8391dca498f675 (diff)
downloadwlan-320302d00197eadab68b46448551bb06a7a6d17a.tar.gz
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
-rw-r--r--qcwcn/wifi_hal/wifi_hal.cpp2
-rw-r--r--qcwcn/wifi_hal/wifilogger_diag.cpp62
2 files changed, 37 insertions, 27 deletions
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;