* [PATCH ath-next 1/2] wifi: ath12k: fix inconsistent arvif state in vdev_create error paths
2026-05-12 4:49 [PATCH ath-next 0/2] wifi: ath12k: fix NULL deref when MLO link activation fails Wei Zhang
@ 2026-05-12 4:49 ` Wei Zhang
2026-05-12 4:49 ` [PATCH ath-next 2/2] wifi: ath12k: fix NULL deref in change_sta_links for unready link Wei Zhang
1 sibling, 0 replies; 3+ messages in thread
From: Wei Zhang @ 2026-05-12 4:49 UTC (permalink / raw)
To: jeff.johnson; +Cc: ath12k, linux-wireless, linux-kernel, wei.zhang
ath12k_mac_vdev_create() has three error path issues that leave arvif
in an inconsistent state:
1. When ath12k_wmi_vdev_create() fails, the function returns directly
without clearing arvif->ar, which was already set before the WMI
call. Subsequent code checking arvif->ar to determine vdev readiness
will see a non-NULL value despite no vdev existing in firmware.
2. When ath12k_wmi_send_peer_delete_cmd() fails in err_peer_del, the
code jumped to err: skipping the DP peer cleanup and vdev rollback,
leaving num_created_vdevs, vdev maps and arvif list membership live.
3. When ath12k_wait_for_peer_delete_done() fails, the code jumped to
err_vdev_del: skipping the DP peer cleanup.
Fix by changing the ath12k_wmi_vdev_create() failure to goto err instead
of returning directly, routing both err_peer_del failure paths through
err_dp_peer_del: for proper DP peer and vdev rollback, and consolidating
the arvif state cleanup at err:.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3
Fixes: 477cabfdb776 ("wifi: ath12k: modify link arvif creation and removal for MLO")
Signed-off-by: Wei Zhang <wei.zhang@oss.qualcomm.com>
---
drivers/net/wireless/ath/ath12k/mac.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 2dc7dba53ec8..8f8456509468 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -10290,7 +10290,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
if (ret) {
ath12k_warn(ab, "failed to create WMI vdev %d: %d\n",
arvif->vdev_id, ret);
- return ret;
+ goto err;
}
ar->num_created_vdevs++;
@@ -10437,13 +10437,13 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
if (ret) {
ath12k_warn(ar->ab, "failed to delete peer vdev_id %d addr %pM\n",
arvif->vdev_id, arvif->bssid);
- goto err;
+ goto err_dp_peer_del;
}
ret = ath12k_wait_for_peer_delete_done(ar, arvif->vdev_id,
arvif->bssid);
if (ret)
- goto err_vdev_del;
+ goto err_dp_peer_del;
ar->num_peers--;
}
@@ -10460,8 +10460,6 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
ath12k_wmi_vdev_delete(ar, arvif->vdev_id);
ar->num_created_vdevs--;
- arvif->is_created = false;
- arvif->ar = NULL;
ar->allocated_vdev_map &= ~(1LL << arvif->vdev_id);
ab->free_vdev_map |= 1LL << arvif->vdev_id;
ab->free_vdev_stats_id_map &= ~(1LL << arvif->vdev_stats_id);
@@ -10470,6 +10468,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
spin_unlock_bh(&ar->data_lock);
err:
+ arvif->is_created = false;
arvif->ar = NULL;
return ret;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH ath-next 2/2] wifi: ath12k: fix NULL deref in change_sta_links for unready link
2026-05-12 4:49 [PATCH ath-next 0/2] wifi: ath12k: fix NULL deref when MLO link activation fails Wei Zhang
2026-05-12 4:49 ` [PATCH ath-next 1/2] wifi: ath12k: fix inconsistent arvif state in vdev_create error paths Wei Zhang
@ 2026-05-12 4:49 ` Wei Zhang
1 sibling, 0 replies; 3+ messages in thread
From: Wei Zhang @ 2026-05-12 4:49 UTC (permalink / raw)
To: jeff.johnson; +Cc: ath12k, linux-wireless, linux-kernel, wei.zhang
_ieee80211_set_active_links() calls _ieee80211_link_use_channel() for
each newly-added link and WARN_ON_ONCE()s if it fails. The call uses
assign_on_failure=true, which allows mac80211 to continue despite
driver failures, but when a mac80211-level channel validation fails
(e.g., combinations check, DFS, or no available radio),
drv_assign_vif_chanctx() is never reached. Since ath12k_mac_vdev_create()
is only called from that path, arvif->is_created remains false and
arvif->ar remains NULL for the failed link.
The subsequent drv_change_sta_links() call reaches
ath12k_mac_op_change_sta_links(), which allocates an arsta and sets
ahsta->links_map |= BIT(link_id) for the broken link before checking
whether the link is ready. When the vdev was never created, only
station_add() is skipped, but the link remains in links_map.
Any subsequent operation iterating links_map and dereferencing arvif->ar
without a NULL check will crash. Two observed examples are NULL deref in
ath12k_mac_ml_station_remove() on disconnect and in ath12k_mac_op_set_key()
when wpa_supplicant installs PTK keys.
BUG: Unable to handle kernel NULL pointer dereference at 0x00000000
pc : ath12k_mac_station_post_remove+0x40/0xe8 [ath12k]
Call trace:
ath12k_mac_station_post_remove+0x40/0xe8 [ath12k]
ath12k_mac_op_sta_state+0xb60/0x1720 [ath12k]
drv_sta_state+0x100/0xbd8 [mac80211]
__sta_info_destroy_part2+0x148/0x178 [mac80211]
ieee80211_set_disassoc+0x500/0x678 [mac80211]
BUG: Unable to handle kernel NULL pointer dereference at 0x00000000
pc : ath12k_mac_op_set_key+0x1f8/0x2c0 [ath12k]
Call trace:
ath12k_mac_op_set_key+0x1f8/0x2c0 [ath12k]
drv_set_key+0x70/0x100 [mac80211]
ieee80211_key_enable_hw_accel+0x78/0x260 [mac80211]
ieee80211_add_key+0x16c/0x2ac [mac80211]
nl80211_new_key+0x138/0x280 [cfg80211]
Fix this by checking arvif->is_created before calling
ath12k_mac_alloc_assign_link_sta(). This prevents the broken link from
entering links_map, so all subsequent operations iterating the bitmap
are protected. The reliability of arvif->is_created across all error
paths is ensured by the preceding patch.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3
Fixes: a27fa6148dac ("wifi: ath12k: support change_sta_links() mac80211 op")
Signed-off-by: Wei Zhang <wei.zhang@oss.qualcomm.com>
---
drivers/net/wireless/ath/ath12k/mac.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 8f8456509468..529a693fdd28 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -8045,16 +8045,16 @@ int ath12k_mac_op_change_sta_links(struct ieee80211_hw *hw,
continue;
arvif = wiphy_dereference(hw->wiphy, ahvif->link[link_id]);
- arsta = ath12k_mac_alloc_assign_link_sta(ah, ahsta, ahvif, link_id);
+ if (!arvif || !arvif->is_created)
+ continue;
- if (!arvif || !arsta) {
+ arsta = ath12k_mac_alloc_assign_link_sta(ah, ahsta, ahvif, link_id);
+ if (!arsta) {
ath12k_hw_warn(ah, "Failed to alloc/assign link sta");
continue;
}
ar = arvif->ar;
- if (!ar)
- continue;
ret = ath12k_mac_station_add(ar, arvif, arsta);
if (ret) {
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread