summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTiger Yu <tfyu@codeaurora.org>2017-12-07 10:54:31 +0800
committersnandini <snandini@codeaurora.org>2017-12-10 22:26:17 -0800
commitdae8afd8fb75df42507449751bd323ae32a1de77 (patch)
treebf808c4f2e2d664bbdbf2d69012249a6f42bdf08
parent1719b20ec34202f6319934cec2e1e3da385f93ff (diff)
qcacld-2.0: Fix potential integer overflow when TX_CREDIT_UPDATE
Check for the validity of credits when received the htt message of HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND or HTT_T2H_MSG_TYPE_TX_COMPL_IND from firmware to ensure the integer overflow does not happen if these messages invoked many times. Change-Id: I01386b88f1b677153f3e51e055b7fbac073cd6b3 CRs-Fixed: 2147127
-rw-r--r--CORE/CLD_TXRX/HTT/htt_t2h.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/CORE/CLD_TXRX/HTT/htt_t2h.c b/CORE/CLD_TXRX/HTT/htt_t2h.c
index 315fdf79cff5..acdf900adeb3 100644
--- a/CORE/CLD_TXRX/HTT/htt_t2h.c
+++ b/CORE/CLD_TXRX/HTT/htt_t2h.c
@@ -141,6 +141,8 @@ static void HTT_RX_FRAG_SET_LAST_MSDU(
#define HTT_FAIL_NOTIFY_BREAK_CHECK(status) 0
#endif /* CONFIG_HL_SUPPORT */
+#define MAX_TARGET_TX_CREDIT 204800
+
/* Target to host Msg/event handler for low priority messages*/
void
htt_t2h_lp_msg_handler(void *context, adf_nbuf_t htt_t2h_msg )
@@ -414,12 +416,23 @@ htt_t2h_lp_msg_handler(void *context, adf_nbuf_t htt_t2h_msg )
{
u_int32_t htt_credit_delta_abs;
int32_t htt_credit_delta;
- int sign;
+ int sign, old_credit;
htt_credit_delta_abs = HTT_TX_CREDIT_DELTA_ABS_GET(*msg_word);
sign = HTT_TX_CREDIT_SIGN_BIT_GET(*msg_word) ? -1 : 1;
htt_credit_delta = sign * htt_credit_delta_abs;
+ old_credit = adf_os_atomic_read(&pdev->htt_tx_credit.target_delta);
+ if (((old_credit + htt_credit_delta) > MAX_TARGET_TX_CREDIT) ||
+ ((old_credit + htt_credit_delta) < -MAX_TARGET_TX_CREDIT)) {
+ adf_os_print("%s: invalid credit update,old_credit=%d,"
+ "htt_credit_delta=%d\n",
+ __FUNCTION__,
+ old_credit,
+ htt_credit_delta);
+ break;
+ }
+
if (pdev->cfg.is_high_latency &&
!pdev->cfg.default_tx_comp_req) {
HTT_TX_MUTEX_ACQUIRE(&pdev->credit_mutex);
@@ -654,6 +667,7 @@ if (adf_os_unlikely(pdev->rx_ring.rx_reset)) {
}
case HTT_T2H_MSG_TYPE_TX_COMPL_IND:
{
+ int old_credit;
int num_msdus;
enum htt_tx_status status;
int msg_len = adf_nbuf_len(htt_t2h_msg);
@@ -711,19 +725,30 @@ if (adf_os_unlikely(pdev->rx_ring.rx_reset)) {
break;
}
- if (!pdev->cfg.default_tx_comp_req) {
- int credit_delta;
- HTT_TX_MUTEX_ACQUIRE(&pdev->credit_mutex);
- adf_os_atomic_add(num_msdus,
- &pdev->htt_tx_credit.target_delta);
- credit_delta = htt_tx_credit_update(pdev);
- HTT_TX_MUTEX_RELEASE(&pdev->credit_mutex);
- if (credit_delta) {
+ old_credit = adf_os_atomic_read(&pdev->htt_tx_credit.target_delta);
+ if (((old_credit + num_msdus) > MAX_TARGET_TX_CREDIT) ||
+ ((old_credit + num_msdus) < -MAX_TARGET_TX_CREDIT)) {
+ adf_os_print("%s: invalid credit update,old_credit=%d,"
+ "num_msdus=%d\n",
+ __FUNCTION__,
+ old_credit,
+ num_msdus);
+ } else {
+ if (!pdev->cfg.default_tx_comp_req) {
+ int credit_delta;
+ HTT_TX_MUTEX_ACQUIRE(&pdev->credit_mutex);
+ adf_os_atomic_add(num_msdus,
+ &pdev->htt_tx_credit.target_delta);
+ credit_delta = htt_tx_credit_update(pdev);
+ HTT_TX_MUTEX_RELEASE(&pdev->credit_mutex);
+ if (credit_delta) {
+ ol_tx_target_credit_update(pdev->txrx_pdev,
+ credit_delta);
+ }
+ } else {
ol_tx_target_credit_update(pdev->txrx_pdev,
- credit_delta);
+ num_msdus);
}
- } else {
- ol_tx_target_credit_update(pdev->txrx_pdev, num_msdus);
}
}
ol_tx_completion_handler(