diff options
author | Hu Wang <huw@codeaurora.org> | 2021-01-27 10:53:17 +0800 |
---|---|---|
committer | Hsiu-Chang Chen <hsiuchangchen@google.com> | 2021-06-28 15:16:59 +0800 |
commit | 9fe3a9f3484fff09fe7d28e1250ffa2d12f1b0ed (patch) | |
tree | 3ff6a6f17723a3a45c7aa744e4547db988b72381 | |
parent | d3d0a6c0adb9e9ba466132c6961824318e437b8c (diff) | |
download | wlan-9fe3a9f3484fff09fe7d28e1250ffa2d12f1b0ed.tar.gz |
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.
Bug: 190878523
Test: Regression test
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 50b8149..d9e2441 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() @@ -863,6 +864,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); @@ -881,6 +887,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); @@ -894,6 +905,7 @@ void LLStatsCommand::clearStats() mResultsParams.radio_stat = NULL; mRadioStatsSize = 0; mNumRadios = 0; + mNumRadiosAllocated = 0; } if(mResultsParams.iface_stat) { @@ -978,6 +990,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); |