summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKabilan Kannan <kabilank@codeaurora.org>2016-06-28 23:46:51 -0700
committerNandini Suresh <snandini@codeaurora.org>2016-07-08 17:26:54 -0700
commit44f6586a20157da2ef9ecd1d201a38eac59a5de0 (patch)
treed719417133e66fe23b6e66c480064430c3deec7e
parent07f95f30986a351c4b6f762e8f1c97695cbf7636 (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.c48
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;
}