Skip to content

Commit 4ce72eb

Browse files
Sriram Rgregkh
authored andcommitted
ath11k: Avoid NULL ptr access during mgmt tx cleanup
[ Upstream commit a93789a ] Currently 'ar' reference is not added in skb_cb during WMI mgmt tx. Though this is generally not used during tx completion callbacks, on interface removal the remaining idr cleanup callback uses the ar ptr from skb_cb from mgmt txmgmt_idr. Hence fill them during tx call for proper usage. Also free the skb which is missing currently in these callbacks. Crash_info: [19282.489476] Unable to handle kernel NULL pointer dereference at virtual address 00000000 [19282.489515] pgd = 91eb8000 [19282.496702] [00000000] *pgd=00000000 [19282.502524] Internal error: Oops: 5 [#1] PREEMPT SMP ARM [19282.783728] PC is at ath11k_mac_vif_txmgmt_idr_remove+0x28/0xd8 [ath11k] [19282.789170] LR is at idr_for_each+0xa0/0xc8 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-00729-QCAHKSWPL_SILICONZ-3 v2 Signed-off-by: Sriram R <quic_srirrama@quicinc.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Link: https://lore.kernel.org/r/1637832614-13831-1-git-send-email-quic_srirrama@quicinc.com Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent bd2b526 commit 4ce72eb

File tree

1 file changed

+20
-15
lines changed
  • drivers/net/wireless/ath/ath11k

1 file changed

+20
-15
lines changed

drivers/net/wireless/ath/ath11k/mac.c

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-License-Identifier: BSD-3-Clause-Clear
22
/*
33
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4+
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
45
*/
56

67
#include <net/mac80211.h>
@@ -4935,23 +4936,32 @@ static int __ath11k_set_antenna(struct ath11k *ar, u32 tx_ant, u32 rx_ant)
49354936
return 0;
49364937
}
49374938

4938-
int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx)
4939+
static void ath11k_mac_tx_mgmt_free(struct ath11k *ar, int buf_id)
49394940
{
4940-
struct sk_buff *msdu = skb;
4941+
struct sk_buff *msdu;
49414942
struct ieee80211_tx_info *info;
4942-
struct ath11k *ar = ctx;
4943-
struct ath11k_base *ab = ar->ab;
49444943

49454944
spin_lock_bh(&ar->txmgmt_idr_lock);
4946-
idr_remove(&ar->txmgmt_idr, buf_id);
4945+
msdu = idr_remove(&ar->txmgmt_idr, buf_id);
49474946
spin_unlock_bh(&ar->txmgmt_idr_lock);
4948-
dma_unmap_single(ab->dev, ATH11K_SKB_CB(msdu)->paddr, msdu->len,
4947+
4948+
if (!msdu)
4949+
return;
4950+
4951+
dma_unmap_single(ar->ab->dev, ATH11K_SKB_CB(msdu)->paddr, msdu->len,
49494952
DMA_TO_DEVICE);
49504953

49514954
info = IEEE80211_SKB_CB(msdu);
49524955
memset(&info->status, 0, sizeof(info->status));
49534956

49544957
ieee80211_free_txskb(ar->hw, msdu);
4958+
}
4959+
4960+
int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx)
4961+
{
4962+
struct ath11k *ar = ctx;
4963+
4964+
ath11k_mac_tx_mgmt_free(ar, buf_id);
49554965

49564966
return 0;
49574967
}
@@ -4960,17 +4970,10 @@ static int ath11k_mac_vif_txmgmt_idr_remove(int buf_id, void *skb, void *ctx)
49604970
{
49614971
struct ieee80211_vif *vif = ctx;
49624972
struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB((struct sk_buff *)skb);
4963-
struct sk_buff *msdu = skb;
49644973
struct ath11k *ar = skb_cb->ar;
4965-
struct ath11k_base *ab = ar->ab;
49664974

4967-
if (skb_cb->vif == vif) {
4968-
spin_lock_bh(&ar->txmgmt_idr_lock);
4969-
idr_remove(&ar->txmgmt_idr, buf_id);
4970-
spin_unlock_bh(&ar->txmgmt_idr_lock);
4971-
dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len,
4972-
DMA_TO_DEVICE);
4973-
}
4975+
if (skb_cb->vif == vif)
4976+
ath11k_mac_tx_mgmt_free(ar, buf_id);
49744977

49754978
return 0;
49764979
}
@@ -4985,6 +4988,8 @@ static int ath11k_mac_mgmt_tx_wmi(struct ath11k *ar, struct ath11k_vif *arvif,
49854988
int buf_id;
49864989
int ret;
49874990

4991+
ATH11K_SKB_CB(skb)->ar = ar;
4992+
49884993
spin_lock_bh(&ar->txmgmt_idr_lock);
49894994
buf_id = idr_alloc(&ar->txmgmt_idr, skb, 0,
49904995
ATH11K_TX_MGMT_NUM_PENDING_MAX, GFP_ATOMIC);

0 commit comments

Comments
 (0)