ath11k: Drop MSDU with length error in DP rx path
authorBaochen Qiang <bqiang@codeaurora.org>
Tue, 28 Sep 2021 11:00:43 +0000 (14:00 +0300)
committerKalle Valo <kvalo@codeaurora.org>
Tue, 28 Sep 2021 13:33:40 +0000 (16:33 +0300)
There are MSDUs whose length are invalid. For example,
attackers may inject on purpose truncated A-MSDUs with
invalid MSDU length.

Such MSDUs are marked with an err bit set in rx attention
tlvs, so we can check and drop them.

Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1

Signed-off-by: Baochen Qiang <bqiang@codeaurora.org>
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210913180246.193388-2-jouni@codeaurora.org
drivers/net/wireless/ath/ath11k/dp_rx.c

index f08eb9e..b145ea5 100644 (file)
@@ -142,6 +142,18 @@ static u32 ath11k_dp_rx_h_attn_mpdu_err(struct rx_attention *attn)
        return errmap;
 }
 
+static bool ath11k_dp_rx_h_attn_msdu_len_err(struct ath11k_base *ab,
+                                            struct hal_rx_desc *desc)
+{
+       struct rx_attention *rx_attention;
+       u32 errmap;
+
+       rx_attention = ath11k_dp_rx_get_attention(ab, desc);
+       errmap = ath11k_dp_rx_h_attn_mpdu_err(rx_attention);
+
+       return errmap & DP_RX_MPDU_ERR_MSDU_LEN;
+}
+
 static u16 ath11k_dp_rx_h_msdu_start_msdu_len(struct ath11k_base *ab,
                                              struct hal_rx_desc *desc)
 {
@@ -2525,6 +2537,12 @@ static int ath11k_dp_rx_process_msdu(struct ath11k *ar,
        }
 
        rx_desc = (struct hal_rx_desc *)msdu->data;
+       if (ath11k_dp_rx_h_attn_msdu_len_err(ab, rx_desc)) {
+               ath11k_warn(ar->ab, "msdu len not valid\n");
+               ret = -EIO;
+               goto free_out;
+       }
+
        lrx_desc = (struct hal_rx_desc *)last_buf->data;
        rx_attention = ath11k_dp_rx_get_attention(ab, lrx_desc);
        if (!ath11k_dp_rx_h_attn_msdu_done(rx_attention)) {