diff options
| author | Kabilan Kannan <kabilank@codeaurora.org> | 2016-06-28 23:46:51 -0700 |
|---|---|---|
| committer | Nandini Suresh <snandini@codeaurora.org> | 2016-07-08 17:26:54 -0700 |
| commit | 44f6586a20157da2ef9ecd1d201a38eac59a5de0 (patch) | |
| tree | d719417133e66fe23b6e66c480064430c3deec7e | |
| parent | 07f95f30986a351c4b6f762e8f1c97695cbf7636 (diff) | |
qcacld-3.0: Add validation to avoid buffer overflow
Buffer overflow condition is not validated correctly in function
sme_update_tdls_peer_state(). This may result in erratic program
behavior.
Add buffer over flow validation to avoid memory access errors,
incorrect results, a crash, or a breach of system security.
Change-Id: I793bd056b32924b484ce7cb264b22c74c8c4cca4
CRs-Fixed: 1035656
| -rw-r--r-- | core/sme/src/common/sme_api.c | 48 |
1 files changed, 33 insertions, 15 deletions
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 493def9ac410..60bd6c9600fb 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -10095,6 +10095,7 @@ QDF_STATUS sme_update_tdls_peer_state(tHalHandle hHal, tTdlsPeerCapParams *peer_cap = NULL; cds_msg_t cds_message; uint8_t num; + uint8_t peer_chan_len; uint8_t chanId; uint8_t i; @@ -10143,9 +10144,7 @@ QDF_STATUS sme_update_tdls_peer_state(tHalHandle hHal, QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, FL("invalid peer state param (%d)"), peerStateParams->peerState); - qdf_mem_free(pTdlsPeerStateParams); - sme_release_global_lock(&pMac->sme); - return QDF_STATUS_E_FAILURE; + goto error_return; } peer_cap = &(pTdlsPeerStateParams->peerCap); peer_cap->isPeerResponder = @@ -10164,19 +10163,30 @@ QDF_STATUS sme_update_tdls_peer_state(tHalHandle hHal, peerStateParams->peerCap.selfCurrOperClass; num = 0; - for (i = 0; i < peerStateParams->peerCap.peerChanLen; i++) { - chanId = peerStateParams->peerCap.peerChan[i]; - if (csr_roam_is_channel_valid(pMac, chanId) && - !(cds_get_channel_state(chanId) == - CHANNEL_STATE_DFS) && - !cds_is_dsrc_channel(cds_chan_to_freq(chanId))) { - peer_cap->peerChan[num].chanId = chanId; - peer_cap->peerChan[num].pwr = - csr_get_cfg_max_tx_power(pMac, chanId); - peer_cap->peerChan[num].dfsSet = false; + peer_chan_len = peerStateParams->peerCap.peerChanLen; + + if (peer_chan_len >= 0 && + peer_chan_len <= SME_TDLS_MAX_SUPP_CHANNELS) { + for (i = 0; i < peerStateParams->peerCap.peerChanLen; i++) { + chanId = peerStateParams->peerCap.peerChan[i]; + if (csr_roam_is_channel_valid(pMac, chanId) && + !(cds_get_channel_state(chanId) == + CHANNEL_STATE_DFS) && + !cds_is_dsrc_channel(cds_chan_to_freq(chanId))) { + peer_cap->peerChan[num].chanId = chanId; + peer_cap->peerChan[num].pwr = + csr_get_cfg_max_tx_power(pMac, chanId); + peer_cap->peerChan[num].dfsSet = false; num++; + } } + } else { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("invalid peer channel len (%d)"), + peer_chan_len); + goto error_return; } + peer_cap->peerChanLen = num; peer_cap->peerOperClassLen = peerStateParams->peerCap.peerOperClassLen; @@ -10198,9 +10208,17 @@ QDF_STATUS sme_update_tdls_peer_state(tHalHandle hHal, qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { - qdf_mem_free(pTdlsPeerStateParams); - status = QDF_STATUS_E_FAILURE; + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("cds_mq_post_message failed ")); + goto error_return; + } else { + goto success_return; } + +error_return: + status = QDF_STATUS_E_FAILURE; + qdf_mem_free(pTdlsPeerStateParams); +success_return: sme_release_global_lock(&pMac->sme); return status; } |
