wifi: nxpwifi: fix multiple static analysis errors and warnings

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 <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202608020855.QwN5n7i5-lkp@intel.com/
Assisted-by: Gemini:unknown-model
Signed-off-by: Jeff Chen <jeff.chen_1@nxp.com>
Link: https://patch.msgid.link/20260803162741.438820-1-chunfan.chen@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Jeff Chen 2026-08-04 00:27:41 +08:00 committed by Johannes Berg
parent ea21b21ca0
commit 00c786a758
8 changed files with 62 additions and 45 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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",

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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 {

View File

@ -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);
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;
}
ts_le = cpu_to_le64(ts);
memcpy(rthdr + off, &ts_le, sizeof(ts_le));
off += sizeof(ts_le);
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 (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;
}
ts_le = cpu_to_le64(ts);
memcpy(rthdr + off, &ts_le, sizeof(ts_le));
off += sizeof(ts_le);
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) {