2023-04-03 19:18:29

by Nagarajan Maran

[permalink] [raw]
Subject: [PATCH 1/2] wifi: ath11k: Ignore frags from uninitialized peer in dp.

From: Harshitha Prem <[email protected]>

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 this certain 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
ath11k_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:
ath11k_dp_process_rx_err+0x550/0x1084 [ath11k]
ath11k_dp_service_srng+0x70/0x370 [ath11k]
0xffffffc009693a04
__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
start_kernel+0x480/0x4b8
Code: f9400281 f94066a2 91405021 b94a0023 (f9406401)

Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1

Signed-off-by: Harshitha Prem <[email protected]>
Signed-off-by: Nagarajan Maran <[email protected]>
---
drivers/net/wireless/ath/ath11k/dp.c | 4 +++-
drivers/net/wireless/ath/ath11k/dp_rx.c | 8 ++++++++
drivers/net/wireless/ath/ath11k/peer.h | 1 +
3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c
index f5156a7fbdd7..d070bcb3fe24 100644
--- a/drivers/net/wireless/ath/ath11k/dp.c
+++ b/drivers/net/wireless/ath/ath11k/dp.c
@@ -36,6 +36,7 @@ void ath11k_dp_peer_cleanup(struct ath11k *ar, int vdev_id, const u8 *addr)
}

ath11k_peer_rx_tid_cleanup(ar, peer);
+ peer->dp_setup_done = false;
crypto_free_shash(peer->tfm_mmic);
spin_unlock_bh(&ab->base_lock);
}
@@ -72,7 +73,8 @@ int ath11k_dp_peer_setup(struct ath11k *ar, int vdev_id, const u8 *addr)
ret = ath11k_peer_rx_frag_setup(ar, addr, vdev_id);
if (ret) {
ath11k_warn(ab, "failed to setup rx defrag context\n");
- return ret;
+ tid--;
+ goto peer_clean;
}

/* TODO: Setup other peer specific resource used in data path */
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
index 99859b59138e..2893f6757e3e 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -3127,6 +3127,7 @@ int ath11k_peer_rx_frag_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id
}

peer->tfm_mmic = tfm;
+ peer->dp_setup_done = true;
spin_unlock_bh(&ab->base_lock);

return 0;
@@ -3572,6 +3573,13 @@ static int ath11k_dp_rx_frag_h_mpdu(struct ath11k *ar,
ret = -ENOENT;
goto out_unlock;
}
+ if (!peer->dp_setup_done) {
+ ath11k_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/ath11k/peer.h b/drivers/net/wireless/ath/ath11k/peer.h
index 6dd17bafe3a0..9bd385d0a38c 100644
--- a/drivers/net/wireless/ath/ath11k/peer.h
+++ b/drivers/net/wireless/ath/ath11k/peer.h
@@ -35,6 +35,7 @@ struct ath11k_peer {
u16 sec_type;
u16 sec_type_grp;
bool is_authorized;
+ bool dp_setup_done;
};

void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id);
--
2.17.1


2023-04-17 10:33:37

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 1/2] wifi: ath11k: Ignore frags from uninitialized peer in dp.

Nagarajan Maran <[email protected]> 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.
> In this certain 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
> ath11k_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:
> ath11k_dp_process_rx_err+0x550/0x1084 [ath11k]
> ath11k_dp_service_srng+0x70/0x370 [ath11k]
> 0xffffffc009693a04
> __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
> start_kernel+0x480/0x4b8
> Code: f9400281 f94066a2 91405021 b94a0023 (f9406401)
>
> Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Harshitha Prem <[email protected]>
> Signed-off-by: Nagarajan Maran <[email protected]>
> Signed-off-by: Kalle Valo <[email protected]>

2 patches applied to ath-next branch of ath.git, thanks.

a06bfb3c9f69 wifi: ath11k: Ignore frags from uninitialized peer in dp.
41e02bf4ae32 wifi: ath11k: fix undefined behavior with __fls in dp

--
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches