diff options
| author | gbian <gbian@qti.qualcomm.com> | 2016-07-11 13:49:27 +0800 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-07-12 16:41:22 +0530 |
| commit | 9dffd0e1910b43eafe3e4b02c1f67880be3fe90f (patch) | |
| tree | a5bf3b4aa07098070fb37d88dad78b52b0038de0 | |
| parent | e6596d488894e07acb66769d15dd8a975dfd9922 (diff) | |
qcacld-2.0: Fix skb corruption in fragment RX handling
Add packet length check for HTT_T2H_MSG_TYPE_RX_FRAG_IND message.
Do not clone the RX frag buffer in the ol_rx_fraglist_insert, and all
buffer will be freed by ol_rx_frag_indication_handler or upper layer to
avoid double free issue.
Change-Id: I977ed9109a476a092dfb298386625a707bc98191
CRs-Fixed: 1039135
| -rw-r--r-- | CORE/CLD_TXRX/HTT/htt_t2h.c | 35 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_rx_defrag.c | 8 |
2 files changed, 35 insertions, 8 deletions
diff --git a/CORE/CLD_TXRX/HTT/htt_t2h.c b/CORE/CLD_TXRX/HTT/htt_t2h.c index aa8c43cafa42..b736a970c575 100644 --- a/CORE/CLD_TXRX/HTT/htt_t2h.c +++ b/CORE/CLD_TXRX/HTT/htt_t2h.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -214,11 +214,44 @@ htt_t2h_lp_msg_handler(void *context, adf_nbuf_t htt_t2h_msg ) tid = HTT_RX_FRAG_IND_EXT_TID_GET(*msg_word); HTT_RX_FRAG_SET_LAST_MSDU(pdev, htt_t2h_msg); + /* If packet len is invalid, will discard this frame. */ + if (pdev->cfg.is_high_latency) { + u_int32_t rx_pkt_len = 0; + + rx_pkt_len = adf_nbuf_len(htt_t2h_msg); + + if (rx_pkt_len < (HTT_RX_FRAG_IND_BYTES + + sizeof(struct hl_htt_rx_ind_base)+ + sizeof(struct ieee80211_frame))) { + + adf_os_print("%s: invalid packet len, %u\n", + __FUNCTION__, + rx_pkt_len); + /* + * This buf will be freed before + * exiting this function. + */ + break; + } + } + ol_rx_frag_indication_handler( pdev->txrx_pdev, htt_t2h_msg, peer_id, tid); + + if (pdev->cfg.is_high_latency) { + /* + * For high latency solution, HTT_T2H_MSG_TYPE_RX_FRAG_IND + * message and RX packet share the same buffer. All buffer will + * be freed by ol_rx_frag_indication_handler or upper layer to + * avoid double free issue. + * + */ + return; + } + break; } case HTT_T2H_MSG_TYPE_RX_ADDBA: diff --git a/CORE/CLD_TXRX/TXRX/ol_rx_defrag.c b/CORE/CLD_TXRX/TXRX/ol_rx_defrag.c index cdbcc7667d07..b084889eb040 100644 --- a/CORE/CLD_TXRX/TXRX/ol_rx_defrag.c +++ b/CORE/CLD_TXRX/TXRX/ol_rx_defrag.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2014, 2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -128,14 +128,11 @@ static inline void OL_RX_FRAG_PULL_HDR(htt_pdev_handle htt_pdev, rx_desc_len = htt_rx_msdu_rx_desc_size_hl(htt_pdev, rx_desc); adf_nbuf_pull_head(frag, rx_desc_len + hdrsize); } -#define OL_RX_FRAG_CLONE(frag) \ - adf_nbuf_clone(frag) #else #define OL_RX_FRAG_GET_MAC_HDR(pdev, frag) \ (struct ieee80211_frame *) adf_nbuf_data(frag) #define OL_RX_FRAG_PULL_HDR(pdev, frag, hdrsize) \ adf_nbuf_pull_head(frag, hdrsize); -#define OL_RX_FRAG_CLONE(frag) NULL/* no-op */ #endif /* CONFIG_HL_SUPPORT */ static inline void @@ -353,11 +350,8 @@ ol_rx_fraglist_insert( struct ieee80211_frame *mac_hdr, *cmac_hdr, *next_hdr, *lmac_hdr; u_int8_t fragno, cur_fragno, lfragno, next_fragno; u_int8_t last_morefrag = 1, count = 0; - adf_nbuf_t frag_clone; adf_os_assert(frag); - frag_clone = OL_RX_FRAG_CLONE(frag); - frag = frag_clone ? frag_clone : frag; mac_hdr = (struct ieee80211_frame *) OL_RX_FRAG_GET_MAC_HDR(htt_pdev, frag); fragno = adf_os_le16_to_cpu(*(u_int16_t *) mac_hdr->i_seq) & |
