summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHu Wang <huw@codeaurora.org>2021-01-27 10:53:17 +0800
committerHu Wang <huw@codeaurora.org>2021-01-27 12:36:17 +0800
commit53f19fc64f5e8a17980637f6cd49902c362112ef (patch)
treeb65771b98ac916634a0e988c119e97a79d3818be
parent3e54543bdac9698ae1f0d5eca01380e7bee28269 (diff)
llstats: Use mNumRadioAllocated for real radio stats recevied
Wifihal uses mNumRadio from QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS, but it shall use mNumRadioAllocated which is based on the real radio stats received. This avoids memory out-of-bound access. CRs-Fixed: 2863682 Change-Id: Ia1c8484307182a3fab8fbfbde2a9be9047eade61
-rw-r--r--qcwcn/wifi_hal/llstats.cpp13
-rw-r--r--qcwcn/wifi_hal/llstatscommand.h3
2 files changed, 16 insertions, 0 deletions
diff --git a/qcwcn/wifi_hal/llstats.cpp b/qcwcn/wifi_hal/llstats.cpp
index b02da62..bf28d2a 100644
--- a/qcwcn/wifi_hal/llstats.cpp
+++ b/qcwcn/wifi_hal/llstats.cpp
@@ -54,6 +54,7 @@ LLStatsCommand::LLStatsCommand(wifi_handle handle, int id, u32 vendor_id, u32 su
memset(&mHandler, 0,sizeof(mHandler));
mRadioStatsSize = 0;
mNumRadios = 0;
+ mNumRadiosAllocated = 0;
}
LLStatsCommand::~LLStatsCommand()
@@ -864,6 +865,11 @@ wifi_error LLStatsCommand::notifyResponse()
/* Indicate stats to framework only if both radio and iface stats
* are present */
if (mResultsParams.radio_stat && mResultsParams.iface_stat) {
+ if (mNumRadios > mNumRadiosAllocated) {
+ ALOGE("%s: Force reset mNumRadios=%d to allocated=%d",
+ __FUNCTION__, mNumRadios, mNumRadiosAllocated);
+ mNumRadios = mNumRadiosAllocated;
+ }
mHandler.on_link_stats_results(mRequestId,
mResultsParams.iface_stat, mNumRadios,
mResultsParams.radio_stat);
@@ -882,6 +888,11 @@ void LLStatsCommand::clearStats()
if(mResultsParams.radio_stat)
{
wifi_radio_stat *radioStat = mResultsParams.radio_stat;
+ if (mNumRadios > mNumRadiosAllocated) {
+ ALOGE("%s: Force reset mNumRadios=%d to allocated=%d",
+ __FUNCTION__, mNumRadios, mNumRadiosAllocated);
+ mNumRadios = mNumRadiosAllocated;
+ }
for (u8 radio = 0; radio < mNumRadios; radio++) {
if (radioStat->tx_time_per_levels) {
free(radioStat->tx_time_per_levels);
@@ -895,6 +906,7 @@ void LLStatsCommand::clearStats()
mResultsParams.radio_stat = NULL;
mRadioStatsSize = 0;
mNumRadios = 0;
+ mNumRadiosAllocated = 0;
}
if(mResultsParams.iface_stat)
{
@@ -979,6 +991,7 @@ int LLStatsCommand::handleResponse(WifiEvent &reply)
+ mRadioStatsSize);
memset(radioStatsBuf, 0, resultsBufSize);
mRadioStatsSize += resultsBufSize;
+ mNumRadiosAllocated ++;
if (tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_TX_LEVELS])
radioStatsBuf->num_tx_levels = nla_get_u32(tb_vendor[
diff --git a/qcwcn/wifi_hal/llstatscommand.h b/qcwcn/wifi_hal/llstatscommand.h
index 5d4c480..86b9672 100644
--- a/qcwcn/wifi_hal/llstatscommand.h
+++ b/qcwcn/wifi_hal/llstatscommand.h
@@ -83,7 +83,10 @@ private:
u32 mRadioStatsSize;
+ // mNumRadios is decoded from tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS]
+ // nNumRadiosAllocated is the actual radio stats received.
u8 mNumRadios;
+ u8 mNumRadiosAllocated;
LLStatsCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd);