Skip to content

Commit 9a0dddf

Browse files
Manish Dharanenthiranjeff-t-johnson
authored andcommitted
wifi: ath12k: Fix invalid data access in ath12k_dp_rx_h_undecap_nwifi
In certain cases, hardware might provide packets with a length greater than the maximum native Wi-Fi header length. This can lead to accessing and modifying fields in the header within the ath12k_dp_rx_h_undecap_nwifi function for DP_RX_DECAP_TYPE_NATIVE_WIFI decap type and potentially resulting in invalid data access and memory corruption. Add a sanity check before processing the SKB to prevent invalid data access in the undecap native Wi-Fi function for the DP_RX_DECAP_TYPE_NATIVE_WIFI decap type. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Signed-off-by: Manish Dharanenthiran <[email protected]> Signed-off-by: Tamizh Chelvam Raja <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jeff Johnson <[email protected]>
1 parent d2d9c9b commit 9a0dddf

File tree

1 file changed

+40
-2
lines changed
  • drivers/net/wireless/ath/ath12k

1 file changed

+40
-2
lines changed

drivers/net/wireless/ath/ath12k/dp_rx.c

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2548,6 +2548,29 @@ static void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *nap
25482548
ieee80211_rx_napi(ath12k_ar_to_hw(ar), pubsta, msdu, napi);
25492549
}
25502550

2551+
static bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab,
2552+
struct hal_rx_desc *rx_desc,
2553+
struct sk_buff *msdu)
2554+
{
2555+
struct ieee80211_hdr *hdr;
2556+
u8 decap_type;
2557+
u32 hdr_len;
2558+
2559+
decap_type = ath12k_dp_rx_h_decap_type(ab, rx_desc);
2560+
if (decap_type != DP_RX_DECAP_TYPE_NATIVE_WIFI)
2561+
return true;
2562+
2563+
hdr = (struct ieee80211_hdr *)msdu->data;
2564+
hdr_len = ieee80211_hdrlen(hdr->frame_control);
2565+
2566+
if ((likely(hdr_len <= DP_MAX_NWIFI_HDR_LEN)))
2567+
return true;
2568+
2569+
ab->soc_stats.invalid_rbm++;
2570+
WARN_ON_ONCE(1);
2571+
return false;
2572+
}
2573+
25512574
static int ath12k_dp_rx_process_msdu(struct ath12k *ar,
25522575
struct sk_buff *msdu,
25532576
struct sk_buff_head *msdu_list,
@@ -2606,6 +2629,11 @@ static int ath12k_dp_rx_process_msdu(struct ath12k *ar,
26062629
}
26072630
}
26082631

2632+
if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu))) {
2633+
ret = -EINVAL;
2634+
goto free_out;
2635+
}
2636+
26092637
ath12k_dp_rx_h_ppdu(ar, rx_desc, rx_status);
26102638
ath12k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_status);
26112639

@@ -2996,6 +3024,9 @@ static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer
29963024
RX_FLAG_IV_STRIPPED | RX_FLAG_DECRYPTED;
29973025
skb_pull(msdu, hal_rx_desc_sz);
29983026

3027+
if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu)))
3028+
return -EINVAL;
3029+
29993030
ath12k_dp_rx_h_ppdu(ar, rx_desc, rxs);
30003031
ath12k_dp_rx_h_undecap(ar, msdu, rx_desc,
30013032
HAL_ENCRYPT_TYPE_TKIP_MIC, rxs, true);
@@ -3738,6 +3769,9 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu,
37383769
skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len);
37393770
skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes);
37403771
}
3772+
if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu)))
3773+
return -EINVAL;
3774+
37413775
ath12k_dp_rx_h_ppdu(ar, desc, status);
37423776

37433777
ath12k_dp_rx_h_mpdu(ar, msdu, desc, status);
@@ -3782,7 +3816,7 @@ static bool ath12k_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu,
37823816
return drop;
37833817
}
37843818

3785-
static void ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu,
3819+
static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu,
37863820
struct ieee80211_rx_status *status)
37873821
{
37883822
struct ath12k_base *ab = ar->ab;
@@ -3800,13 +3834,17 @@ static void ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu,
38003834
skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len);
38013835
skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes);
38023836

3837+
if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu)))
3838+
return true;
3839+
38033840
ath12k_dp_rx_h_ppdu(ar, desc, status);
38043841

38053842
status->flag |= (RX_FLAG_MMIC_STRIPPED | RX_FLAG_MMIC_ERROR |
38063843
RX_FLAG_DECRYPTED);
38073844

38083845
ath12k_dp_rx_h_undecap(ar, msdu, desc,
38093846
HAL_ENCRYPT_TYPE_TKIP_MIC, status, false);
3847+
return false;
38103848
}
38113849

38123850
static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu,
@@ -3825,7 +3863,7 @@ static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu,
38253863
case HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR:
38263864
err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc);
38273865
if (err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) {
3828-
ath12k_dp_rx_h_tkip_mic_err(ar, msdu, status);
3866+
drop = ath12k_dp_rx_h_tkip_mic_err(ar, msdu, status);
38293867
break;
38303868
}
38313869
fallthrough;

0 commit comments

Comments
 (0)