diff options
| author | Tiger Yu <tfyu@codeaurora.org> | 2017-12-07 10:54:31 +0800 |
|---|---|---|
| committer | snandini <snandini@codeaurora.org> | 2017-12-10 22:26:17 -0800 |
| commit | dae8afd8fb75df42507449751bd323ae32a1de77 (patch) | |
| tree | bf808c4f2e2d664bbdbf2d69012249a6f42bdf08 | |
| parent | 1719b20ec34202f6319934cec2e1e3da385f93ff (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.c | 49 |
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( |
