diff options
author | Hu Wang <huw@codeaurora.org> | 2021-01-27 10:53:17 +0800 |
---|---|---|
committer | Hu Wang <huw@codeaurora.org> | 2021-01-27 12:36:17 +0800 |
commit | 53f19fc64f5e8a17980637f6cd49902c362112ef (patch) | |
tree | b65771b98ac916634a0e988c119e97a79d3818be | |
parent | 3e54543bdac9698ae1f0d5eca01380e7bee28269 (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.cpp | 13 | ||||
-rw-r--r-- | qcwcn/wifi_hal/llstatscommand.h | 3 |
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); |