[PATCH v2] wifi: nxpwifi: fix multiple static analysis errors and warnings

Jeff Chen <[email protected]> Tue, 4 Aug 2026 00:27:41 +0800
Newsgroups org.kernel.vger.linux-wireless
Message-ID <[email protected]>
From: Jeff Chen <[email protected]>

Fix various development-phase bugs, code quality, and logical issues
reported by the kernel test robot (using the Smatch static analysis tool).

The following addressable fixes are included:

- 11n.c & 11ax.c: Fix potential NULL pointer dereferences by correcting
  logical operators (&& to ||) in 11n.c and hoisting the bss_desc
  verification to the top of the function in 11ax.c.
- 11n.c: Fix a severe Use-After-Free (UAF) memory corruption during RCU
  list traversal. Restore the proper list_for_each_entry_safe() loop
  structure along with the required array index [i] within the locked
  writer path.
- sdio.c: Fix a missing unwind resource cleanup pathway where a protocol
  error branch returned directly via -EINVAL instead of using
  'goto term_cmd', leaving the SDIO hardware state machine out of sync.
- main.h: Fix a signedness mismatch bug where nxpwifi_get_unused_bss_num()
  could return -2 as an unsigned integer fallback.
- util.c: Remove a redundant and dead condition check (position <= 15)
  which was always true for a 4-bit unsigned bit-field member variable.
- cfg80211.c: Clean up a dead unreachable 'return 0' at the bottom of the
  switch-case logic.
- uap_txrx.c: Clean up mismatched and inconsistent indentations within the
  handling of multicast RX forward paths.

Reported-by: kernel test robot <[email protected]>
Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
Assisted-by: Gemini:unknown-model
Signed-off-by: Jeff Chen <[email protected]>
---
 drivers/net/wireless/nxp/nxpwifi/11ax.c     |  5 ++-
 drivers/net/wireless/nxp/nxpwifi/11n.c      |  7 +--
 drivers/net/wireless/nxp/nxpwifi/cfg80211.c | 14 ++++--
 drivers/net/wireless/nxp/nxpwifi/main.c     |  2 +-
 drivers/net/wireless/nxp/nxpwifi/main.h     | 21 ++++++---
 drivers/net/wireless/nxp/nxpwifi/sdio.c     |  3 +-
 drivers/net/wireless/nxp/nxpwifi/uap_txrx.c |  4 +-
 drivers/net/wireless/nxp/nxpwifi/util.c     | 47 ++++++++++-----------
 8 files changed, 60 insertions(+), 43 deletions(-)

diff --git a/drivers/net/wireless/nxp/nxpwifi/11ax.c b/drivers/net/wireless/nxp/nxpwifi/11ax.c
index cc47c435eb70..96540914f3cf 100644
--- a/drivers/net/wireless/nxp/nxpwifi/11ax.c
+++ b/drivers/net/wireless/nxp/nxpwifi/11ax.c
@@ -413,7 +413,10 @@ bool nxpwifi_is_11ax_twt_supported(struct nxpwifi_private *priv,
 	struct nxpwifi_ie_types_he_cap *user_he_cap;
 	struct nxpwifi_ie_types_he_cap *hw_he_cap;
 
-	if (bss_desc && (!nxpwifi_is_ap_11ax_twt_supported(bss_desc))) {
+	if (!bss_desc)
+		return false;
+
+	if (!nxpwifi_is_ap_11ax_twt_supported(bss_desc)) {
 		nxpwifi_dbg(priv->adapter, MSG,
 			    "AP don't support twt feature\n");
 		return false;
diff --git a/drivers/net/wireless/nxp/nxpwifi/11n.c b/drivers/net/wireless/nxp/nxpwifi/11n.c
index e46c5053d509..c2a54d781b42 100644
--- a/drivers/net/wireless/nxp/nxpwifi/11n.c
+++ b/drivers/net/wireless/nxp/nxpwifi/11n.c
@@ -451,7 +451,7 @@ void
 nxpwifi_11n_delete_tx_ba_stream_tbl_entry(struct nxpwifi_private *priv,
 					  struct nxpwifi_tx_ba_stream_tbl *tbl)
 {
-	if (!tbl && nxpwifi_is_tx_ba_stream_ptr_valid(priv, tbl))
+	if (!tbl || nxpwifi_is_tx_ba_stream_ptr_valid(priv, tbl))
 		return;
 
 	nxpwifi_dbg(priv->adapter, INFO,
@@ -694,7 +694,7 @@ int nxpwifi_get_tx_ba_stream_tbl(struct nxpwifi_private *priv,
 /* Delete Tx BA stream entry by RA. */
 void nxpwifi_del_tx_ba_stream_tbl_by_ra(struct nxpwifi_private *priv, u8 *ra)
 {
-	struct nxpwifi_tx_ba_stream_tbl *tbl;
+	struct nxpwifi_tx_ba_stream_tbl *tbl, *tmp;
 	int i;
 
 	if (!ra)
@@ -702,7 +702,8 @@ void nxpwifi_del_tx_ba_stream_tbl_by_ra(struct nxpwifi_private *priv, u8 *ra)
 
 	for (i = 0; i < MAX_NUM_TID; i++) {
 		spin_lock_bh(&priv->tx_ba_stream_tbl_lock[i]);
-		list_for_each_entry_rcu(tbl, &priv->tx_ba_stream_tbl_ptr[i], list)
+		list_for_each_entry_safe(tbl, tmp,
+					 &priv->tx_ba_stream_tbl_ptr[i], list)
 			if (!memcmp(tbl->ra, ra, ETH_ALEN))
 				nxpwifi_11n_delete_tx_ba_stream_tbl_entry(priv, tbl);
 
diff --git a/drivers/net/wireless/nxp/nxpwifi/cfg80211.c b/drivers/net/wireless/nxp/nxpwifi/cfg80211.c
index c820f08d2835..5cc8cdf594d3 100644
--- a/drivers/net/wireless/nxp/nxpwifi/cfg80211.c
+++ b/drivers/net/wireless/nxp/nxpwifi/cfg80211.c
@@ -717,6 +717,7 @@ nxpwifi_init_new_priv_params(struct nxpwifi_private *priv,
 			     enum nl80211_iftype type)
 {
 	struct nxpwifi_adapter *adapter = priv->adapter;
+	int ret;
 
 	nxpwifi_init_priv(priv);
 
@@ -740,7 +741,15 @@ nxpwifi_init_new_priv_params(struct nxpwifi_private *priv,
 		return -EOPNOTSUPP;
 	}
 
-	priv->bss_num = nxpwifi_get_unused_bss_num(adapter, priv->bss_type);
+	ret = nxpwifi_get_unused_bss_num(adapter, priv->bss_type,
+					 &priv->bss_num);
+
+	if (ret) {
+		nxpwifi_dbg(adapter, ERROR,
+			    "%s: no unused bss_num for type %d\n",
+			    dev->name, priv->bss_type);
+		return ret;
+	}
 
 	flush_workqueue(adapter->workqueue);
 	atomic_set(&adapter->iface_changing, 0);
@@ -943,7 +952,6 @@ nxpwifi_cfg80211_change_virtual_intf(struct wiphy *wiphy,
 		case NL80211_IFTYPE_STATION:
 			return nxpwifi_change_vif_to_sta(dev, curr_iftype,
 							 type, params);
-			break;
 		default:
 			goto errnotsupp;
 		}
@@ -952,8 +960,6 @@ nxpwifi_cfg80211_change_virtual_intf(struct wiphy *wiphy,
 		goto errnotsupp;
 	}
 
-	return 0;
-
 errnotsupp:
 	nxpwifi_dbg(priv->adapter, ERROR,
 		    "unsupported interface type transition: %d to %d\n",
diff --git a/drivers/net/wireless/nxp/nxpwifi/main.c b/drivers/net/wireless/nxp/nxpwifi/main.c
index 4e01f45f3a00..b4c63829024a 100644
--- a/drivers/net/wireless/nxp/nxpwifi/main.c
+++ b/drivers/net/wireless/nxp/nxpwifi/main.c
@@ -204,7 +204,7 @@ static bool nxpwifi_drain_tx(struct nxpwifi_adapter *adapter)
 					  NXPWIFI_ASYNC_CMD);
 			adapter->hs_activated_manually = false;
 		}
-			nxpwifi_process_bypass_tx(adapter);
+		nxpwifi_process_bypass_tx(adapter);
 		if (adapter->hs_activated) {
 			clear_bit(NXPWIFI_IS_HS_CONFIGURED,
 				  &adapter->work_flags);
diff --git a/drivers/net/wireless/nxp/nxpwifi/main.h b/drivers/net/wireless/nxp/nxpwifi/main.h
index 349dfa4d3f85..b25a6a4f2936 100644
--- a/drivers/net/wireless/nxp/nxpwifi/main.h
+++ b/drivers/net/wireless/nxp/nxpwifi/main.h
@@ -1166,8 +1166,9 @@ nxpwifi_get_priv(struct nxpwifi_adapter *adapter,
 }
 
 /* find unused BSS number for new interface */
-static inline u8
-nxpwifi_get_unused_bss_num(struct nxpwifi_adapter *adapter, u8 bss_type)
+static inline int
+nxpwifi_get_unused_bss_num(struct nxpwifi_adapter *adapter, u8 bss_type,
+			   u8 *bss_num)
 {
 	u8 i, j;
 	int index[NXPWIFI_MAX_BSS_NUM];
@@ -1179,9 +1180,14 @@ nxpwifi_get_unused_bss_num(struct nxpwifi_adapter *adapter, u8 bss_type)
 		      NL80211_IFTYPE_UNSPECIFIED)) {
 			index[adapter->priv[i]->bss_num] = 1;
 		}
-	for (j = 0; j < NXPWIFI_MAX_BSS_NUM; j++)
-		if (!index[j])
-			return j;
+
+	for (j = 0; j < NXPWIFI_MAX_BSS_NUM; j++) {
+		if (!index[j]) {
+			*bss_num = j;
+			return 0;
+		}
+	}
+
 	return -ENOENT;
 }
 
@@ -1195,8 +1201,9 @@ nxpwifi_get_unused_priv_by_bss_type(struct nxpwifi_adapter *adapter,
 	for (i = 0; i < adapter->priv_num; i++)
 		if (adapter->priv[i]->bss_mode ==
 		   NL80211_IFTYPE_UNSPECIFIED) {
-			adapter->priv[i]->bss_num =
-				nxpwifi_get_unused_bss_num(adapter, bss_type);
+			if (nxpwifi_get_unused_bss_num(adapter, bss_type,
+						       &adapter->priv[i]->bss_num))
+				return NULL;
 			break;
 		}
 
diff --git a/drivers/net/wireless/nxp/nxpwifi/sdio.c b/drivers/net/wireless/nxp/nxpwifi/sdio.c
index d8536354f093..8ef0f6eb49e2 100644
--- a/drivers/net/wireless/nxp/nxpwifi/sdio.c
+++ b/drivers/net/wireless/nxp/nxpwifi/sdio.c
@@ -1347,7 +1347,8 @@ static int nxpwifi_process_int_status(struct nxpwifi_adapter *adapter, u8 sdio_i
 			     ((rx_blocks * NXPWIFI_SDIO_BLOCK_SIZE) >
 			      card->mpa_rx.buf_size))) {
 				nxpwifi_dbg(adapter, ERROR, "invalid rx_len=%d\n", rx_len);
-				return -EINVAL;
+				ret = -EINVAL;
+				goto term_cmd;
 			}
 
 			rx_len = (u16)(rx_blocks * NXPWIFI_SDIO_BLOCK_SIZE);
diff --git a/drivers/net/wireless/nxp/nxpwifi/uap_txrx.c b/drivers/net/wireless/nxp/nxpwifi/uap_txrx.c
index f3d24bf861ca..840dddfc4f5a 100644
--- a/drivers/net/wireless/nxp/nxpwifi/uap_txrx.c
+++ b/drivers/net/wireless/nxp/nxpwifi/uap_txrx.c
@@ -246,8 +246,8 @@ int nxpwifi_handle_uap_rx_forward(struct nxpwifi_private *priv,
 		} else {
 			nxpwifi_dbg(adapter, ERROR,
 				    "failed to copy skb for uAP\n");
-				    priv->stats.rx_dropped++;
-				    dev_kfree_skb_any(skb);
+			priv->stats.rx_dropped++;
+			dev_kfree_skb_any(skb);
 			return -ENOMEM;
 		}
 	} else {
diff --git a/drivers/net/wireless/nxp/nxpwifi/util.c b/drivers/net/wireless/nxp/nxpwifi/util.c
index 29ef031f8ec9..bbfefb81d8d3 100644
--- a/drivers/net/wireless/nxp/nxpwifi/util.c
+++ b/drivers/net/wireless/nxp/nxpwifi/util.c
@@ -799,34 +799,33 @@ int nxpwifi_recv_packet_to_monif(struct nxpwifi_private *priv,
 		__le16 acc_le;
 		u8 flags = 0;
 
-		if (ext.timestamp.position <= 15) {
-			hdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_TIMESTAMP));
-			off = ALIGN(off, 8);
-
-			if (ext.timestamp.flags & 0x01) {
-				flags |= IEEE80211_RADIOTAP_TIMESTAMP_FLAG_32BIT;
-				ts = (u32)ext.timestamp.device_timestamp;
-			} else {
-				flags |= IEEE80211_RADIOTAP_TIMESTAMP_FLAG_64BIT;
-				ts = ext.timestamp.device_timestamp;
-			}
+		hdr->it_present |=
+			cpu_to_le32(BIT(IEEE80211_RADIOTAP_TIMESTAMP));
+		off = ALIGN(off, 8);
 
-			ts_le = cpu_to_le64(ts);
-			memcpy(rthdr + off, &ts_le, sizeof(ts_le));
-			off += sizeof(ts_le);
+		if (ext.timestamp.flags & 0x01) {
+			flags |= IEEE80211_RADIOTAP_TIMESTAMP_FLAG_32BIT;
+			ts = (u32)ext.timestamp.device_timestamp;
+		} else {
+			flags |= IEEE80211_RADIOTAP_TIMESTAMP_FLAG_64BIT;
+			ts = ext.timestamp.device_timestamp;
+		}
 
-			if (ext.timestamp.flags & 0x02) {
-				accuracy = ext.timestamp.accuracy;
-				flags |= IEEE80211_RADIOTAP_TIMESTAMP_FLAG_ACCURACY;
-			}
+		ts_le = cpu_to_le64(ts);
+		memcpy(rthdr + off, &ts_le, sizeof(ts_le));
+		off += sizeof(ts_le);
 
-			acc_le = cpu_to_le16(accuracy);
-			memcpy(rthdr + off, &acc_le, sizeof(acc_le));
-			off += sizeof(acc_le);
-			rthdr[off++] = (ext.timestamp.unit & 0x0f) |
-					((ext.timestamp.position & 0x0f) << 4);
-			rthdr[off++] = flags;
+		if (ext.timestamp.flags & 0x02) {
+			accuracy = ext.timestamp.accuracy;
+			flags |= IEEE80211_RADIOTAP_TIMESTAMP_FLAG_ACCURACY;
 		}
+
+		acc_le = cpu_to_le16(accuracy);
+		memcpy(rthdr + off, &acc_le, sizeof(acc_le));
+		off += sizeof(acc_le);
+		rthdr[off++] = (ext.timestamp.unit & 0x0f) |
+				((ext.timestamp.position & 0x0f) << 4);
+		rthdr[off++] = flags;
 	}
 
 	if (format == NXPWIFI_RATE_FORMAT_HE && has_ext) {

base-commit: 6c5fc504d0d6934132637aa3db4b9b58148eaa78
-- 
2.34.1