diff options
| author | Tiger Yu <tfyu@codeaurora.org> | 2017-12-08 15:41:29 +0800 |
|---|---|---|
| committer | snandini <snandini@codeaurora.org> | 2017-12-10 22:26:07 -0800 |
| commit | 5c4f3c4a5ac8b1fa61bbb06f0f51fce8328d9ca3 (patch) | |
| tree | f4b432e2ef55ac9968f564badf5e68db2d39cb95 | |
| parent | 8af8f6e745cde3e5c1e7dc88e96a27343f38aa37 (diff) | |
qcacld-2.0: Fix potential BUG_ON in the htt_rx_offload_msdu_pop_ll
For HTT_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND, the msdu_cnt is a signed
integer coming from firmware. If set the msdu_cnt to a negative value,
or be greater than the number of current elements in the queue, the loop
will execute lots of times in ol_rx_offload_deliver_ind_handler, the
htt_rx_netbuf_pop will cause the BUG_ON issue sooner or later if it is
low latency solution.
Change the msdu_cnt type from signed to unsigned and add the validity
msdu_cnt checking will fix this issue.
Change-Id: I436557a124074f59ab11fd937dfdc975b9caebe8
CRs-Fixed: 2149461
| -rw-r--r-- | CORE/CLD_TXRX/HTT/htt_rx.c | 20 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/HTT/htt_t2h.c | 2 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_rx.c | 13 | ||||
| -rw-r--r-- | CORE/SERVICES/COMMON/ol_htt_rx_api.h | 9 | ||||
| -rw-r--r-- | CORE/SERVICES/COMMON/ol_txrx_htt_api.h | 2 |
5 files changed, 43 insertions, 3 deletions
diff --git a/CORE/CLD_TXRX/HTT/htt_rx.c b/CORE/CLD_TXRX/HTT/htt_rx.c index b38043d6110c..57762e08c550 100644 --- a/CORE/CLD_TXRX/HTT/htt_rx.c +++ b/CORE/CLD_TXRX/HTT/htt_rx.c @@ -1291,6 +1291,13 @@ htt_rx_frag_pop_hl( } int +htt_rx_offload_msdu_cnt_ll( + htt_pdev_handle pdev) +{ + return htt_rx_ring_elems(pdev); +} + +int htt_rx_offload_msdu_pop_ll( htt_pdev_handle pdev, adf_nbuf_t offload_deliver_msg, @@ -1914,6 +1921,13 @@ htt_rx_mon_amsdu_pop_hl( return 0; } +int +htt_rx_offload_msdu_cnt_hl( + htt_pdev_handle pdev) +{ + return 1; +} + /* Return values: 1 - success, 0 - failure */ int htt_rx_offload_msdu_pop_hl( @@ -2577,6 +2591,10 @@ int (*htt_rx_frag_pop)( adf_nbuf_t *tail_msdu); int +(*htt_rx_offload_msdu_cnt)( + htt_pdev_handle pdev); + +int (*htt_rx_offload_msdu_pop)( htt_pdev_handle pdev, adf_nbuf_t offload_deliver_msg, @@ -3404,6 +3422,7 @@ htt_rx_attach(struct htt_pdev_t *pdev) if (VOS_MONITOR_MODE == vos_get_conparam()) htt_rx_amsdu_pop = htt_rx_mon_amsdu_rx_in_order_pop_ll; + htt_rx_offload_msdu_cnt = htt_rx_offload_msdu_cnt_ll; htt_rx_offload_msdu_pop = htt_rx_offload_msdu_pop_ll; htt_rx_mpdu_desc_retry = htt_rx_mpdu_desc_retry_ll; htt_rx_mpdu_desc_seq_num = htt_rx_mpdu_desc_seq_num_ll; @@ -3430,6 +3449,7 @@ htt_rx_attach(struct htt_pdev_t *pdev) if (VOS_MONITOR_MODE == vos_get_conparam()) htt_rx_amsdu_pop = htt_rx_mon_amsdu_pop_hl; htt_rx_frag_pop = htt_rx_frag_pop_hl; + htt_rx_offload_msdu_cnt = htt_rx_offload_msdu_cnt_hl; htt_rx_offload_msdu_pop = htt_rx_offload_msdu_pop_hl; htt_rx_mpdu_desc_list_next = htt_rx_mpdu_desc_list_next_hl; htt_rx_mpdu_desc_retry = htt_rx_mpdu_desc_retry_hl; diff --git a/CORE/CLD_TXRX/HTT/htt_t2h.c b/CORE/CLD_TXRX/HTT/htt_t2h.c index 4467ca70489c..6dedfb9d9b8b 100644 --- a/CORE/CLD_TXRX/HTT/htt_t2h.c +++ b/CORE/CLD_TXRX/HTT/htt_t2h.c @@ -196,7 +196,7 @@ htt_t2h_lp_msg_handler(void *context, adf_nbuf_t htt_t2h_msg ) } case HTT_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND: { - int msdu_cnt; + u_int16_t msdu_cnt; msdu_cnt = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_CNT_GET(*msg_word); ol_rx_offload_deliver_ind_handler( pdev->txrx_pdev, diff --git a/CORE/CLD_TXRX/TXRX/ol_rx.c b/CORE/CLD_TXRX/TXRX/ol_rx.c index 22fab039187e..6e8ced2cd9ac 100644 --- a/CORE/CLD_TXRX/TXRX/ol_rx.c +++ b/CORE/CLD_TXRX/TXRX/ol_rx.c @@ -815,7 +815,7 @@ void ol_rx_offload_deliver_ind_handler( ol_txrx_pdev_handle pdev, adf_nbuf_t msg, - int msdu_cnt) + u_int16_t msdu_cnt) { int vdev_id, peer_id, tid; adf_nbuf_t head_buf, tail_buf, buf; @@ -824,6 +824,17 @@ ol_rx_offload_deliver_ind_handler( u_int8_t fw_desc; htt_pdev_handle htt_pdev = pdev->htt_pdev; + if (msdu_cnt > htt_rx_offload_msdu_cnt(htt_pdev)) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s: invalid msdu_cnt=%u\n", + __func__, + msdu_cnt); + if (pdev->cfg.is_high_latency) + htt_rx_desc_frame_free(htt_pdev, msg); + + return; + } + while (msdu_cnt) { if (!htt_rx_offload_msdu_pop( htt_pdev, msg, &vdev_id, &peer_id, diff --git a/CORE/SERVICES/COMMON/ol_htt_rx_api.h b/CORE/SERVICES/COMMON/ol_htt_rx_api.h index 34a209c11117..3ac1aff57577 100644 --- a/CORE/SERVICES/COMMON/ol_htt_rx_api.h +++ b/CORE/SERVICES/COMMON/ol_htt_rx_api.h @@ -671,6 +671,15 @@ extern int adf_nbuf_t *tail_msdu); /** + * @brief Return the maximum number of available msdus currently + * + * @param pdev - the HTT instance the rx data was received on + */ +extern int +(*htt_rx_offload_msdu_cnt)( + htt_pdev_handle pdev); + +/** * @brief Return a linked list of buffers holding one MSDU * In some systems the buffers are delivered along with offload delivery * indication message itself, while in other systems the buffers are uploaded diff --git a/CORE/SERVICES/COMMON/ol_txrx_htt_api.h b/CORE/SERVICES/COMMON/ol_txrx_htt_api.h index cb6b828b9f51..6918a6d5ca1c 100644 --- a/CORE/SERVICES/COMMON/ol_txrx_htt_api.h +++ b/CORE/SERVICES/COMMON/ol_txrx_htt_api.h @@ -448,7 +448,7 @@ void ol_rx_offload_deliver_ind_handler( ol_txrx_pdev_handle pdev, adf_nbuf_t msg, - int msdu_cnt); + u_int16_t msdu_cnt); /** * @brief Process a peer map message sent by the target. |
