When max virtual ap interfaces are configured in all the bands
with ACS and hostapd restart is done every 60s,
a crash is observed at random times in dp_rx path.
This patch series handles the following:
1. Ignore the fragments of the peer which does not have its
datapath initialized.
2. Fix the undefined behavior of __fls which was found during
this crash.
Harshitha Prem (2):
wifi: ath12k: Ignore fragments from uninitialized peer in dp
wifi: ath12k: fix undefined behavior with __fls in dp
drivers/net/wireless/ath/ath12k/dp.c | 1 +
drivers/net/wireless/ath/ath12k/dp_rx.c | 11 ++++++++++-
drivers/net/wireless/ath/ath12k/peer.h | 3 +++
3 files changed, 14 insertions(+), 1 deletion(-)
base-commit: 3f257461ab0ab19806bae2bfde4c3cd88dbf050e
--
2.17.1
When max virtual ap interfaces are configured in all the bands
with ACS and hostapd restart is done every 60s,
a crash is observed at random times.
In the above scenario, a fragmented packet is received for self peer,
for which rx_tid and rx_frags are not initialized in datapath.
While handling this fragment, crash is observed as the rx_frag list
is uninitialised and when we walk in ath12k_dp_rx_h_sort_frags,
skb null leads to exception.
To address this, before processing received fragments we check
dp_setup_done flag is set to ensure that peer has completed its
dp peer setup for fragment queue, else ignore processing the
fragments.
Call trace:
PC points to "ath12k_dp_process_rx_err+0x4e8/0xfcc [ath12k]"
LR points to "ath12k_dp_process_rx_err+0x480/0xfcc [ath12k]".
The Backtrace obtained is as follows:
ath12k_dp_process_rx_err+0x4e8/0xfcc [ath12k]
ath12k_dp_service_srng+0x78/0x260 [ath12k]
ath12k_pci_write32+0x990/0xb0c [ath12k]
__napi_poll+0x30/0xa4
net_rx_action+0x118/0x270
__do_softirq+0x10c/0x244
irq_exit+0x64/0xb4
__handle_domain_irq+0x88/0xac
gic_handle_irq+0x74/0xbc
el1_irq+0xf0/0x1c0
arch_cpu_idle+0x10/0x18
do_idle+0x104/0x248
cpu_startup_entry+0x20/0x64
rest_init+0xd0/0xdc
arch_call_rest_init+0xc/0x14
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Signed-off-by: Harshitha Prem <[email protected]>
---
drivers/net/wireless/ath/ath12k/dp.c | 1 +
drivers/net/wireless/ath/ath12k/dp_rx.c | 9 +++++++++
drivers/net/wireless/ath/ath12k/peer.h | 3 +++
3 files changed, 13 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c
index ae1645d0f42a..d825e08d820a 100644
--- a/drivers/net/wireless/ath/ath12k/dp.c
+++ b/drivers/net/wireless/ath/ath12k/dp.c
@@ -38,6 +38,7 @@ void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr)
ath12k_dp_rx_peer_tid_cleanup(ar, peer);
crypto_free_shash(peer->tfm_mmic);
+ peer->dp_setup_done = false;
spin_unlock_bh(&ab->base_lock);
}
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index 67f8c140840f..5923c7c9eaff 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -2748,6 +2748,7 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev
}
peer->tfm_mmic = tfm;
+ peer->dp_setup_done = true;
spin_unlock_bh(&ab->base_lock);
return 0;
@@ -3214,6 +3215,14 @@ static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar,
ret = -ENOENT;
goto out_unlock;
}
+
+ if (!peer->dp_setup_done) {
+ ath12k_warn(ab, "The peer %pM [%d] has uninitialized datapath\n",
+ peer->addr, peer_id);
+ ret = -ENOENT;
+ goto out_unlock;
+ }
+
rx_tid = &peer->rx_tid[tid];
if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) ||
diff --git a/drivers/net/wireless/ath/ath12k/peer.h b/drivers/net/wireless/ath/ath12k/peer.h
index b296dc0e2f67..c6edb24cbedd 100644
--- a/drivers/net/wireless/ath/ath12k/peer.h
+++ b/drivers/net/wireless/ath/ath12k/peer.h
@@ -44,6 +44,9 @@ struct ath12k_peer {
struct ppdu_user_delayba ppdu_stats_delayba;
bool delayba_flag;
bool is_authorized;
+
+ /* protected by ab->data_lock */
+ bool dp_setup_done;
};
void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id);
--
2.17.1
On 8/8/2023 9:27 PM, Harshitha Prem wrote:
> When max virtual ap interfaces are configured in all the bands
> with ACS and hostapd restart is done every 60s,
> a crash is observed at random times.
nit: please fill the paragraph to 70+ columns
>
> In the above scenario, a fragmented packet is received for self peer,
> for which rx_tid and rx_frags are not initialized in datapath.
> While handling this fragment, crash is observed as the rx_frag list
> is uninitialised and when we walk in ath12k_dp_rx_h_sort_frags,
nit: s/uninitialised /uninitialized/
> skb null leads to exception.
>
> To address this, before processing received fragments we check
> dp_setup_done flag is set to ensure that peer has completed its
> dp peer setup for fragment queue, else ignore processing the
> fragments.
>
> Call trace:
> PC points to "ath12k_dp_process_rx_err+0x4e8/0xfcc [ath12k]"
> LR points to "ath12k_dp_process_rx_err+0x480/0xfcc [ath12k]".
> The Backtrace obtained is as follows:
> ath12k_dp_process_rx_err+0x4e8/0xfcc [ath12k]
> ath12k_dp_service_srng+0x78/0x260 [ath12k]
> ath12k_pci_write32+0x990/0xb0c [ath12k]
> __napi_poll+0x30/0xa4
> net_rx_action+0x118/0x270
> __do_softirq+0x10c/0x244
> irq_exit+0x64/0xb4
> __handle_domain_irq+0x88/0xac
> gic_handle_irq+0x74/0xbc
> el1_irq+0xf0/0x1c0
> arch_cpu_idle+0x10/0x18
> do_idle+0x104/0x248
> cpu_startup_entry+0x20/0x64
> rest_init+0xd0/0xdc
> arch_call_rest_init+0xc/0x14
>
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Harshitha Prem <[email protected]>
> ---
actual code patch LGTM
On 8/9/2023 11:41 PM, Jeff Johnson wrote:
> On 8/8/2023 9:27 PM, Harshitha Prem wrote:
>> When max virtual ap interfaces are configured in all the bands
>> with ACS and hostapd restart is done every 60s,
>> a crash is observed at random times.
>
> nit: please fill the paragraph to 70+ columns
>
>>
>> In the above scenario, a fragmented packet is received for self peer,
>> for which rx_tid and rx_frags are not initialized in datapath.
>> While handling this fragment, crash is observed as the rx_frag list
>> is uninitialised and when we walk in ath12k_dp_rx_h_sort_frags,
>
> nit: s/uninitialised /uninitialized/
>
>> skb null leads to exception.
>>
>> To address this, before processing received fragments we check
>> dp_setup_done flag is set to ensure that peer has completed its
>> dp peer setup for fragment queue, else ignore processing the
>> fragments.
>>
>> Call trace:
>> PC points to "ath12k_dp_process_rx_err+0x4e8/0xfcc [ath12k]"
>> LR points to "ath12k_dp_process_rx_err+0x480/0xfcc [ath12k]".
>> The Backtrace obtained is as follows:
>> ath12k_dp_process_rx_err+0x4e8/0xfcc [ath12k]
>> ath12k_dp_service_srng+0x78/0x260 [ath12k]
>> ath12k_pci_write32+0x990/0xb0c [ath12k]
>> __napi_poll+0x30/0xa4
>> net_rx_action+0x118/0x270
>> __do_softirq+0x10c/0x244
>> irq_exit+0x64/0xb4
>> __handle_domain_irq+0x88/0xac
>> gic_handle_irq+0x74/0xbc
>> el1_irq+0xf0/0x1c0
>> arch_cpu_idle+0x10/0x18
>> do_idle+0x104/0x248
>> cpu_startup_entry+0x20/0x64
>> rest_init+0xd0/0xdc
>> arch_call_rest_init+0xc/0x14
>>
>> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>>
>> Signed-off-by: Harshitha Prem <[email protected]>
>> ---
>
> actual code patch LGTM
>
Thank you Jeff. Sure, will update the commit message.
Thanks,
Harshitha