nxpwifi_wait_queue_complete() detaches the caller-owned data buffer from the still-current command when the wait is interrupted or times out: spin_lock_bh(&adapter->nxpwifi_cmd_lock); if (adapter->curr_cmd == cmd_queued) adapter->curr_cmd->data_buf = NULL; spin_unlock_bh(&adapter->nxpwifi_cmd_lock); nxpwifi_cancel_all_pending_cmd() keeps the current command -- "no recycle probably wait for response" -- so a late response still reaches nxpwifi_process_cmdresp(), which passes that now-NULL pointer to the command's cmd_resp callback. Commit 068986fd6f2a5 ("wifi: nxpwifi: detach sync command buffer on interrupted wait") introduced that detached state and swept the response handlers that dereference the buffer unconditionally, adding a "return 0" to nxpwifi_ret_sta_get_chan_info(), nxpwifi_ret_sta_hs_wakeup_reason() and nxpwifi_ret_sta_robust_coex(). The sweep did not cover 11ax.c. mwifiex, which the detachment was ported from, has no 11ax or TWT support, so there was no counterpart there to compare against. All three handlers in 11ax.c dereference the buffer with no check: nxpwifi_ret_11ax_cfg() takes &ax_cfg->he_cap_cfg and stores through it at "he_cap->id = tlv_type". nxpwifi_set_11ax_status() declares the struct nxpwifi_11ax_he_cfg on the stack and issues HOST_CMD_11AX_CFG synchronously while bringing an AP up, so this one is reachable. nxpwifi_ret_twt_cfg() stores at "twt_cfg->sub_id = ...". The twt_setup, twt_teardown, twt_report and twt_information debugfs files each pass a stack struct nxpwifi_twt_cfg to a synchronous HOST_CMD_TWT_CFG, so this one is reachable too. nxpwifi_ret_11ax_cmd() stores at "ax_cmd->sub_id = ...". Nothing in the tree sends HOST_CMD_11AX_CMD, so this one is guarded for symmetry only. Return 0 and drop the response, the way the three handlers the original sweep covered already do. Fixes: 73b01e57ed3e ("wifi: nxp: add nxpwifi driver for IW61x") Signed-off-by: Yehyeong Lee --- drivers/net/wireless/nxp/nxpwifi/11ax.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/nxp/nxpwifi/11ax.c b/drivers/net/wireless/nxp/nxpwifi/11ax.c index 96540914f3cf6..d15495a85d2ba 100644 --- a/drivers/net/wireless/nxp/nxpwifi/11ax.c +++ b/drivers/net/wireless/nxp/nxpwifi/11ax.c @@ -205,9 +205,13 @@ int nxpwifi_ret_11ax_cfg(struct nxpwifi_private *priv, struct host_cmd_11ax_cfg *he_cfg = &resp->params.ax_cfg; struct nxpwifi_ie_types_header *header; u16 left_len, tlv_type, tlv_len; + struct nxpwifi_11ax_he_cap_cfg *he_cap; u8 ext_id; - struct nxpwifi_11ax_he_cap_cfg *he_cap = &ax_cfg->he_cap_cfg; + if (!ax_cfg) + return 0; + + he_cap = &ax_cfg->he_cap_cfg; left_len = le16_to_cpu(resp->size) - sizeof(*he_cfg) - S_DS_GEN; header = (struct nxpwifi_ie_types_header *)he_cfg->tlv; @@ -346,6 +350,9 @@ int nxpwifi_ret_11ax_cmd(struct nxpwifi_private *priv, struct host_cmd_11ax_cmd *he_cmd = &resp->params.ax_cmd; struct nxpwifi_ie_types_data *tlv; + if (!ax_cmd) + return 0; + ax_cmd->sub_id = le16_to_cpu(he_cmd->sub_id); switch (ax_cmd->sub_command) { @@ -582,6 +589,9 @@ int nxpwifi_ret_twt_cfg(struct nxpwifi_private *priv, struct host_cmd_twt_cfg *twt_cfg_cmd = &resp->params.twt_cfg; u16 action; + if (!twt_cfg) + return 0; + action = le16_to_cpu(twt_cfg_cmd->action); twt_cfg->sub_id = le16_to_cpu(twt_cfg_cmd->sub_id); -- 2.43.0