Skip to content

Commit a284820

Browse files
P Praneeshgregkh
authored andcommitted
wifi: ath12k: Fix invalid memory access while forming 802.11 header
[ Upstream commit be908d2 ] While forming the 802.11 header from the rx descriptor, skb_push() is performed for the 802.11 header length and then calls ath12k_dp_rx_desc_get_dot11_hdr(). Since skb_push() moves the skb->data pointer backwards by the 802.11 header length, the rx descriptor points to a different memory area than intended, causing invalid information to be fetched from the rx descriptor. Also, when IV and ICV are not stripped from the given MSDU, mac80211 performs PN validation for these MSDUs, which requires the crypto header. Before forming the crypto header from the given rx descriptor, skb_push() is performed for the crypto header length, which overwrites the memory pointed to by the rx descriptor, causing invalid information to form the 802.11 header. Fix these issues by moving all rx descriptor accesses before the skb_push() operation which ensures the proper 802.11 headers are generated from the given rx descriptor and removing ath12k_dp_rxdesc_get_mpdu_frame_ctrl() for filling frame control, as this information is already fetched by ath12k_dp_rx_desc_get_dot11_hdr(). Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Fixes: d889913 ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") Co-developed-by: Karthikeyan Periyasamy <karthikeyan.periyasamy@oss.qualcomm.com> Signed-off-by: Karthikeyan Periyasamy <karthikeyan.periyasamy@oss.qualcomm.com> Signed-off-by: P Praneesh <praneesh.p@oss.qualcomm.com> Link: https://patch.msgid.link/20250402180543.2670947-1-praneesh.p@oss.qualcomm.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 5a1210a commit a284820

File tree

3 files changed

+9
-38
lines changed

3 files changed

+9
-38
lines changed

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

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -228,12 +228,6 @@ static void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab,
228228
ab->hal_rx_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype);
229229
}
230230

231-
static u16 ath12k_dp_rxdesc_get_mpdu_frame_ctrl(struct ath12k_base *ab,
232-
struct hal_rx_desc *desc)
233-
{
234-
return ab->hal_rx_ops->rx_desc_get_mpdu_frame_ctl(desc);
235-
}
236-
237231
static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_base *ab,
238232
struct hal_rx_desc *desc)
239233
{
@@ -2067,33 +2061,30 @@ static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k *ar,
20672061
struct hal_rx_desc *rx_desc = rxcb->rx_desc;
20682062
struct ath12k_base *ab = ar->ab;
20692063
size_t hdr_len, crypto_len;
2070-
struct ieee80211_hdr *hdr;
2064+
struct ieee80211_hdr hdr;
20712065
u16 qos_ctl;
2072-
__le16 fc;
2073-
u8 *crypto_hdr;
2066+
u8 *crypto_hdr, mesh_ctrl;
2067+
2068+
ath12k_dp_rx_desc_get_dot11_hdr(ab, rx_desc, &hdr);
2069+
hdr_len = ieee80211_hdrlen(hdr.frame_control);
2070+
mesh_ctrl = ath12k_dp_rx_h_mesh_ctl_present(ab, rx_desc);
20742071

20752072
if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
20762073
crypto_len = ath12k_dp_rx_crypto_param_len(ar, enctype);
20772074
crypto_hdr = skb_push(msdu, crypto_len);
20782075
ath12k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype);
20792076
}
20802077

2081-
fc = cpu_to_le16(ath12k_dp_rxdesc_get_mpdu_frame_ctrl(ab, rx_desc));
2082-
hdr_len = ieee80211_hdrlen(fc);
20832078
skb_push(msdu, hdr_len);
2084-
hdr = (struct ieee80211_hdr *)msdu->data;
2085-
hdr->frame_control = fc;
2086-
2087-
/* Get wifi header from rx_desc */
2088-
ath12k_dp_rx_desc_get_dot11_hdr(ab, rx_desc, hdr);
2079+
memcpy(msdu->data, &hdr, min(hdr_len, sizeof(hdr)));
20892080

20902081
if (rxcb->is_mcbc)
20912082
status->flag &= ~RX_FLAG_PN_VALIDATED;
20922083

20932084
/* Add QOS header */
2094-
if (ieee80211_is_data_qos(hdr->frame_control)) {
2085+
if (ieee80211_is_data_qos(hdr.frame_control)) {
20952086
qos_ctl = rxcb->tid;
2096-
if (ath12k_dp_rx_h_mesh_ctl_present(ab, rx_desc))
2087+
if (mesh_ctrl)
20972088
qos_ctl |= IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT;
20982089

20992090
/* TODO: Add other QoS ctl fields when required */

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

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -511,11 +511,6 @@ static void ath12k_hw_qcn9274_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc,
511511
crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274.mpdu_start.pn[1]);
512512
}
513513

514-
static u16 ath12k_hw_qcn9274_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc)
515-
{
516-
return __le16_to_cpu(desc->u.qcn9274.mpdu_start.frame_ctrl);
517-
}
518-
519514
static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab)
520515
{
521516
struct ath12k_hal *hal = &ab->hal;
@@ -736,7 +731,6 @@ const struct hal_rx_ops hal_rx_qcn9274_ops = {
736731
.rx_desc_is_da_mcbc = ath12k_hw_qcn9274_rx_desc_is_da_mcbc,
737732
.rx_desc_get_dot11_hdr = ath12k_hw_qcn9274_rx_desc_get_dot11_hdr,
738733
.rx_desc_get_crypto_header = ath12k_hw_qcn9274_rx_desc_get_crypto_hdr,
739-
.rx_desc_get_mpdu_frame_ctl = ath12k_hw_qcn9274_rx_desc_get_mpdu_frame_ctl,
740734
.dp_rx_h_msdu_done = ath12k_hw_qcn9274_dp_rx_h_msdu_done,
741735
.dp_rx_h_l4_cksum_fail = ath12k_hw_qcn9274_dp_rx_h_l4_cksum_fail,
742736
.dp_rx_h_ip_cksum_fail = ath12k_hw_qcn9274_dp_rx_h_ip_cksum_fail,
@@ -975,11 +969,6 @@ ath12k_hw_qcn9274_compact_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc,
975969
HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274_compact.mpdu_start.pn[1]);
976970
}
977971

978-
static u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc)
979-
{
980-
return __le16_to_cpu(desc->u.qcn9274_compact.mpdu_start.frame_ctrl);
981-
}
982-
983972
static bool ath12k_hw_qcn9274_compact_dp_rx_h_msdu_done(struct hal_rx_desc *desc)
984973
{
985974
return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info14,
@@ -1080,8 +1069,6 @@ const struct hal_rx_ops hal_rx_qcn9274_compact_ops = {
10801069
.rx_desc_is_da_mcbc = ath12k_hw_qcn9274_compact_rx_desc_is_da_mcbc,
10811070
.rx_desc_get_dot11_hdr = ath12k_hw_qcn9274_compact_rx_desc_get_dot11_hdr,
10821071
.rx_desc_get_crypto_header = ath12k_hw_qcn9274_compact_rx_desc_get_crypto_hdr,
1083-
.rx_desc_get_mpdu_frame_ctl =
1084-
ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_frame_ctl,
10851072
.dp_rx_h_msdu_done = ath12k_hw_qcn9274_compact_dp_rx_h_msdu_done,
10861073
.dp_rx_h_l4_cksum_fail = ath12k_hw_qcn9274_compact_dp_rx_h_l4_cksum_fail,
10871074
.dp_rx_h_ip_cksum_fail = ath12k_hw_qcn9274_compact_dp_rx_h_ip_cksum_fail,
@@ -1330,11 +1317,6 @@ static void ath12k_hw_wcn7850_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc,
13301317
crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[1]);
13311318
}
13321319

1333-
static u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc)
1334-
{
1335-
return __le16_to_cpu(desc->u.wcn7850.mpdu_start.frame_ctrl);
1336-
}
1337-
13381320
static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab)
13391321
{
13401322
struct ath12k_hal *hal = &ab->hal;
@@ -1555,7 +1537,6 @@ const struct hal_rx_ops hal_rx_wcn7850_ops = {
15551537
.rx_desc_is_da_mcbc = ath12k_hw_wcn7850_rx_desc_is_da_mcbc,
15561538
.rx_desc_get_dot11_hdr = ath12k_hw_wcn7850_rx_desc_get_dot11_hdr,
15571539
.rx_desc_get_crypto_header = ath12k_hw_wcn7850_rx_desc_get_crypto_hdr,
1558-
.rx_desc_get_mpdu_frame_ctl = ath12k_hw_wcn7850_rx_desc_get_mpdu_frame_ctl,
15591540
.dp_rx_h_msdu_done = ath12k_hw_wcn7850_dp_rx_h_msdu_done,
15601541
.dp_rx_h_l4_cksum_fail = ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail,
15611542
.dp_rx_h_ip_cksum_fail = ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail,

drivers/net/wireless/ath/ath12k/hal.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1068,7 +1068,6 @@ struct hal_rx_ops {
10681068
bool (*rx_desc_is_da_mcbc)(struct hal_rx_desc *desc);
10691069
void (*rx_desc_get_dot11_hdr)(struct hal_rx_desc *desc,
10701070
struct ieee80211_hdr *hdr);
1071-
u16 (*rx_desc_get_mpdu_frame_ctl)(struct hal_rx_desc *desc);
10721071
void (*rx_desc_get_crypto_header)(struct hal_rx_desc *desc,
10731072
u8 *crypto_hdr,
10741073
enum hal_encrypt_type enctype);

0 commit comments

Comments
 (0)