Commit b89e0100 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge tag 'wireless-2026-05-06' of...

Merge tag 'wireless-2026-05-06' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless

Johannes Berg says:

====================
Quite a number of fixes now:
 - mac80211
   - remove HT NSS validation to work with broken APs
     (with a kunit fix now)
   - remove 'static' that could cause races
   - check station link lookup before further processing
   - fix use-after-free due to delete in list iteration
   - remove AP station on assoc failures to fix crashes
 - ath12k
   - fix OF node refcount imbalance
   - fix queue flush ("REO update") in MLO
   - fix RCU assert
 - ath12k:
   - fix Kconfig with POWER_SEQUENCING
   - fix WMI buffer leaks on error conditions
   - don't use uninitialized stack data when processing RSSI events
   - fix logic for determining the peer ID in the RX path
 - ath5k: fix a potential stack buffer overwrite
 - rsi: fix thread lifetime race
 - brcmfmac: fix potential UAF
 - nl80211:
   - stricter permissions/checks for PMK and netns
   - fix netlink policy vs. code type confusion
 - cw1200: revert a broken locking change
 - various fixes to not trust values from firmware

* tag 'wireless-2026-05-06' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless: (25 commits)
  wifi: nl80211: re-check wiphy netns in nl80211_prepare_wdev_dump() continuation
  wifi: nl80211: require CAP_NET_ADMIN over the target netns in SET_WIPHY_NETNS
  wifi: nl80211: fix NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST usage
  wifi: mac80211: remove station if connection prep fails
  wifi: mac80211: use safe list iteration in radar detect work
  wifi: libertas: notify firmware load wait on disconnect
  wifi: ath5k: do not access array OOB
  wifi: ath12k: fix peer_id usage in normal RX path
  wifi: ath12k: initialize RSSI dBm conversion event state
  wifi: ath12k: fix leak in some ath12k_wmi_xxx() functions
  wifi: cw1200: Revert "Fix locking in error paths"
  wifi: mac80211: tests: mark HT check strict
  wifi: rsi: fix kthread lifetime race between self-exit and external-stop
  wifi: mac80211: drop stray 'static' from fast-RX rx_result
  wifi: mac80211: check ieee80211_rx_data_set_link return in pubsta MLO path
  wifi: nl80211: require admin perm on SET_PMK / DEL_PMK
  wifi: libertas: fix integer underflow in process_cmdrequest()
  wifi: b43legacy: enforce bounds check on firmware key index in RX path
  wifi: b43: enforce bounds check on firmware key index in b43_rx()
  wifi: brcmfmac: Fix potential use-after-free issue when stopping watchdog task
  ...
====================

Link: https://patch.msgid.link/20260506110325.219675-3-johannes@sipsolutions.net


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 3e8ec344 79240f3f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ config ATH10K_SNOC
	depends on ARCH_QCOM || COMPILE_TEST
	depends on QCOM_SMEM
	depends on QCOM_RPROC_COMMON || QCOM_RPROC_COMMON=n
	select POWER_SEQUENCING
	select QCOM_SCM
	select QCOM_QMI_HELPERS
	help
+48 −29
Original line number Diff line number Diff line
@@ -1838,10 +1838,22 @@ static struct ath12k_hw_group *ath12k_core_hw_group_alloc(struct ath12k_base *ab
	return ag;
}

static void ath12k_core_free_wsi_info(struct ath12k_hw_group *ag)
{
	int i;

	for (i = 0; i < ag->num_devices; i++) {
		of_node_put(ag->wsi_node[i]);
		ag->wsi_node[i] = NULL;
	}
	ag->num_devices = 0;
}

static void ath12k_core_hw_group_free(struct ath12k_hw_group *ag)
{
	mutex_lock(&ath12k_hw_group_mutex);

	ath12k_core_free_wsi_info(ag);
	list_del(&ag->list);
	kfree(ag);

@@ -1867,52 +1879,59 @@ static struct ath12k_hw_group *ath12k_core_hw_group_find_by_dt(struct ath12k_bas
static int ath12k_core_get_wsi_info(struct ath12k_hw_group *ag,
				    struct ath12k_base *ab)
{
	struct device_node *wsi_dev = ab->dev->of_node, *next_wsi_dev;
	struct device_node *tx_endpoint, *next_rx_endpoint;
	int device_count = 0;

	next_wsi_dev = wsi_dev;
	struct device_node *next_wsi_dev;
	int device_count = 0, ret = 0;
	struct device_node *wsi_dev;

	if (!next_wsi_dev)
	wsi_dev = of_node_get(ab->dev->of_node);
	if (!wsi_dev)
		return -ENODEV;

	do {
		ag->wsi_node[device_count] = next_wsi_dev;
		if (device_count >= ATH12K_MAX_DEVICES) {
			ath12k_warn(ab, "device count in DT %d is more than limit %d\n",
				    device_count, ATH12K_MAX_DEVICES);
			ret = -EINVAL;
			break;
		}

		ag->wsi_node[device_count++] = of_node_get(wsi_dev);

		tx_endpoint = of_graph_get_endpoint_by_regs(next_wsi_dev, 0, -1);
		struct device_node *tx_endpoint __free(device_node) =
					of_graph_get_endpoint_by_regs(wsi_dev, 0, -1);
		if (!tx_endpoint) {
			of_node_put(next_wsi_dev);
			return -ENODEV;
			ret = -ENODEV;
			break;
		}

		next_rx_endpoint = of_graph_get_remote_endpoint(tx_endpoint);
		struct device_node *next_rx_endpoint __free(device_node) =
					of_graph_get_remote_endpoint(tx_endpoint);
		if (!next_rx_endpoint) {
			of_node_put(next_wsi_dev);
			of_node_put(tx_endpoint);
			return -ENODEV;
			ret = -ENODEV;
			break;
		}

		of_node_put(tx_endpoint);
		of_node_put(next_wsi_dev);

		next_wsi_dev = of_graph_get_port_parent(next_rx_endpoint);
		if (!next_wsi_dev) {
			of_node_put(next_rx_endpoint);
			return -ENODEV;
			ret = -ENODEV;
			break;
		}

		of_node_put(next_rx_endpoint);
		of_node_put(wsi_dev);
		wsi_dev = next_wsi_dev;
	} while (ab->dev->of_node != wsi_dev);

		device_count++;
		if (device_count > ATH12K_MAX_DEVICES) {
			ath12k_warn(ab, "device count in DT %d is more than limit %d\n",
				    device_count, ATH12K_MAX_DEVICES);
			of_node_put(next_wsi_dev);
			return -EINVAL;
	if (ret) {
		while (--device_count >= 0) {
			of_node_put(ag->wsi_node[device_count]);
			ag->wsi_node[device_count] = NULL;
		}

		of_node_put(wsi_dev);
		return ret;
	}
	} while (wsi_dev != next_wsi_dev);

	of_node_put(next_wsi_dev);
	of_node_put(wsi_dev);
	ag->num_devices = device_count;

	return 0;
@@ -1983,9 +2002,9 @@ static struct ath12k_hw_group *ath12k_core_hw_group_assign(struct ath12k_base *a
		    ath12k_core_get_wsi_index(ag, ab)) {
			ath12k_dbg(ab, ATH12K_DBG_BOOT,
				   "unable to get wsi info from dt, grouping single device");
			ath12k_core_free_wsi_info(ag);
			ag->id = ATH12K_INVALID_GROUP_ID;
			ag->num_devices = 1;
			memset(ag->wsi_node, 0, sizeof(ag->wsi_node));
			wsi->index = 0;
		}

+4 −1
Original line number Diff line number Diff line
@@ -565,6 +565,9 @@ static int ath12k_dp_prepare_reo_update_elem(struct ath12k_dp *dp,

	lockdep_assert_held(&dp->dp_lock);

	if (!peer->primary_link)
		return 0;

	elem = kzalloc_obj(*elem, GFP_ATOMIC);
	if (!elem)
		return -ENOMEM;
@@ -1337,7 +1340,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc
	bool is_mcbc = rxcb->is_mcbc;
	bool is_eapol = rxcb->is_eapol;

	peer = ath12k_dp_peer_find_by_peerid(dp_pdev, rx_info->peer_id);
	peer = ath12k_dp_peer_find_by_peerid(dp_pdev, rxcb->peer_id);

	pubsta = peer ? peer->sta : NULL;

+1 −1
Original line number Diff line number Diff line
@@ -788,7 +788,7 @@ struct ath12k_link_vif *ath12k_mac_get_arvif(struct ath12k *ar, u32 vdev_id)

	/* To use the arvif returned, caller must have held rcu read lock.
	 */
	WARN_ON(!rcu_read_lock_any_held());
	lockdep_assert_in_rcu_read_lock();
	arvif_iter.vdev_id = vdev_id;
	arvif_iter.ar = ar;

+1 −1
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ static void ath12k_p2p_noa_update_vdev_iter(void *data, u8 *mac,
	struct ath12k_p2p_noa_arg *arg = data;
	struct ath12k_link_vif *arvif;

	WARN_ON(!rcu_read_lock_any_held());
	lockdep_assert_in_rcu_read_lock();
	arvif = &ahvif->deflink;
	if (!arvif->is_created || arvif->ar != arg->ar || arvif->vdev_id != arg->vdev_id)
		return;
Loading