[PATCH ath-next] wifi: ath12k: Guard dp_peer dereference in ath12k_mac_peer_cleanup_all()

Jeff Johnson jeff.johnson at oss.qualcomm.com
Tue Jun 30 08:58:24 PDT 2026


On 6/25/2026 12:35 AM, Harsh Kumar Bijlani wrote:
> From: Harsh Kumar Bijlani <harsh.bijlani at oss.qualcomm.com>
> 
> In ath12k_mac_peer_cleanup_all(), the code iterates over all
> ath12k_dp_link_peer entries in the dp->peers list and performs
> datapath peer cleanup. For each peer, it accesses peer->dp_peer
> to clear the link_peers[] and dp_peers[] RCU pointers.
> 
> However, peer->dp_peer can legitimately be NULL. The
> ath12k_dp_link_peer structure is allocated and added to dp->peers
> during peer creation (ath12k_peer_create()), but the dp_peer
> assignment happens later via ath12k_dp_link_peer_assign(), which
> is called only when a valid dp_peer is found or created. If the
> peer creation sequence is interrupted, for example, due to a
> firmware crash, a race during interface teardown, or a failure
> in the HTT peer-map event processing, then a link peer entry can
> exist in dp->peers with dp_peer still NULL.
> 
> Accessing peer->dp_peer without a NULL check in this path leads
> to a NULL pointer dereference kernel crash during the mac cleanup
> path, which is invoked on radio stop or firmware recovery.
> 
> This is consistent with how the rest of the driver handles this
> field: ath12k_dp_link_peer_unassign(), ath12k_dp_peer_cleanup(),
> and several other paths all guard access to peer->dp_peer with
> an explicit NULL check before dereferencing it.
> 
> Fix this by wrapping the dp_peer dereference block inside a
> NULL check, mirroring the pattern already used in the same
> function for the Rx TID cleanup:
> 
>     if (peer->sta && peer->dp_peer)
>         ath12k_dp_rx_peer_tid_cleanup(ar, peer);
> 
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3
> 
> Signed-off-by: Harsh Kumar Bijlani <harsh.bijlani at oss.qualcomm.com>
> ---
>  drivers/net/wireless/ath/ath12k/mac.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
> index af354bef5c0d..caf274ee064e 100644
> --- a/drivers/net/wireless/ath/ath12k/mac.c
> +++ b/drivers/net/wireless/ath/ath12k/mac.c
> @@ -1237,10 +1237,12 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar)
>  
>  		/* cleanup dp peer */
>  		spin_lock_bh(&dp_hw->peer_lock);
> -		dp_peer = peer->dp_peer;
> -		peerid_index = ath12k_dp_peer_get_peerid_index(dp, peer->peer_id);
> -		rcu_assign_pointer(dp_peer->link_peers[peer->link_id], NULL);
> -		rcu_assign_pointer(dp_hw->dp_peers[peerid_index], NULL);
> +		if (peer->dp_peer) {
> +			dp_peer = peer->dp_peer;
> +			peerid_index = ath12k_dp_peer_get_peerid_index(dp, peer->peer_id);
> +			rcu_assign_pointer(dp_peer->link_peers[peer->link_id], NULL);
> +			rcu_assign_pointer(dp_hw->dp_peers[peerid_index], NULL);
> +		}
>  		spin_unlock_bh(&dp_hw->peer_lock);
>  
>  		ath12k_dp_link_peer_rhash_delete(dp, peer);
> 
> base-commit: 972c4dd19cb92e03d75b66c426cfade07582a1ba

FYI this was not submitted properly since you did not use 'b4' or the
get_maintainer.pl script to properly address all necessary recipients.
In particular this is not being tracked in patchwork since the linux-wireless
list was not specified.

Please send a REPOST with all necessary recipients specified.

/jeff



More information about the ath12k mailing list