From: Tamizh Chelvam <[email protected]>

[ Upstream commit d7d43782d541edb8596d2f4fc7f41b0734948ec5 ]

In certain scenario host receives the packets with invalid length
which causes below kernel panic. Free up those msdus to avoid
this kernel panic.

 2270.028121:   <6> task: ffffffc0008306d0 ti: ffffffc0008306d0 task.ti: 
ffffffc0008306d0
 2270.035247:   <2> PC is at skb_panic+0x40/0x44
 2270.042784:   <2> LR is at skb_panic+0x40/0x44
 2270.521775:   <2> [<ffffffc0004a06e0>] skb_panic+0x40/0x44
 2270.524039:   <2> [<ffffffc0004a1278>] skb_put+0x54/0x5c
 2270.529264:   <2> [<ffffffbffcc373a8>] ath11k_dp_process_rx_err+0x320/0x5b0 
[ath11k]
 2270.533860:   <2> [<ffffffbffcc30b68>] ath11k_dp_service_srng+0x80/0x268 
[ath11k]
 2270.541063:   <2> [<ffffffbffcc1d554>] 
ath11k_hal_rx_reo_ent_buf_paddr_get+0x200/0xb64 [ath11k]
 2270.547917:   <2> [<ffffffc0004b1f74>] net_rx_action+0xf8/0x274
 2270.556247:   <2> [<ffffffc000099df4>] __do_softirq+0x128/0x228
 2270.561625:   <2> [<ffffffc00009a130>] irq_exit+0x84/0xcc
 2270.567008:   <2> [<ffffffc0000cfb28>] __handle_domain_irq+0x8c/0xb0
 2270.571695:   <2> [<ffffffc000082484>] gic_handle_irq+0x6c/0xbc

Signed-off-by: Tamizh Chelvam <[email protected]>
Signed-off-by: Kalle Valo <[email protected]>
Link: 
https://lore.kernel.org/r/[email protected]
Signed-off-by: Sasha Levin <[email protected]>
---
 drivers/net/wireless/ath/ath11k/dp_rx.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c 
b/drivers/net/wireless/ath/ath11k/dp_rx.c
index 34b1e8e6a7fb..007bb73d6c61 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -2265,6 +2265,7 @@ static int ath11k_dp_rx_process_msdu(struct ath11k *ar,
        struct ieee80211_hdr *hdr;
        struct sk_buff *last_buf;
        u8 l3_pad_bytes;
+       u8 *hdr_status;
        u16 msdu_len;
        int ret;
 
@@ -2293,8 +2294,13 @@ static int ath11k_dp_rx_process_msdu(struct ath11k *ar,
                skb_pull(msdu, HAL_RX_DESC_SIZE);
        } else if (!rxcb->is_continuation) {
                if ((msdu_len + HAL_RX_DESC_SIZE) > DP_RX_BUFFER_SIZE) {
+                       hdr_status = ath11k_dp_rx_h_80211_hdr(rx_desc);
                        ret = -EINVAL;
                        ath11k_warn(ar->ab, "invalid msdu len %u\n", msdu_len);
+                       ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", 
hdr_status,
+                                       sizeof(struct ieee80211_hdr));
+                       ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", 
rx_desc,
+                                       sizeof(struct hal_rx_desc));
                        goto free_out;
                }
                skb_put(msdu, HAL_RX_DESC_SIZE + l3_pad_bytes + msdu_len);
@@ -3389,6 +3395,7 @@ ath11k_dp_process_rx_err_buf(struct ath11k *ar, u32 
*ring_desc, int buf_id, bool
        struct sk_buff *msdu;
        struct ath11k_skb_rxcb *rxcb;
        struct hal_rx_desc *rx_desc;
+       u8 *hdr_status;
        u16 msdu_len;
 
        spin_lock_bh(&rx_ring->idr_lock);
@@ -3426,6 +3433,17 @@ ath11k_dp_process_rx_err_buf(struct ath11k *ar, u32 
*ring_desc, int buf_id, bool
 
        rx_desc = (struct hal_rx_desc *)msdu->data;
        msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(rx_desc);
+       if ((msdu_len + HAL_RX_DESC_SIZE) > DP_RX_BUFFER_SIZE) {
+               hdr_status = ath11k_dp_rx_h_80211_hdr(rx_desc);
+               ath11k_warn(ar->ab, "invalid msdu leng %u", msdu_len);
+               ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status,
+                               sizeof(struct ieee80211_hdr));
+               ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", rx_desc,
+                               sizeof(struct hal_rx_desc));
+               dev_kfree_skb_any(msdu);
+               goto exit;
+       }
+
        skb_put(msdu, HAL_RX_DESC_SIZE + msdu_len);
 
        if (ath11k_dp_rx_frag_h_mpdu(ar, msdu, ring_desc)) {
-- 
2.25.1

Reply via email to