mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
wifi: iwlwifi: mvm: validate TX_CMD response layout
TX_CMD parsing uses frame_count to walk status entries and then read the trailing SCD SSN. Make the minimum-length check follow that exact runtime layout calculation before parsing the payload. For new TX API, reject TX_CMD responses with frame_count != 1 and warn/return in the aggregation handler to document that aggregated accounting is expected via BA notifications. Assisted-by: GitHubCopilot:gpt-5.3-codex Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://patch.msgid.link/20260715215523.0474ee89bab9.I84f151aabecb8921b587da092f29f78c47128f0f@changeid
This commit is contained in:
parent
7786233bff
commit
8d70881707
|
|
@ -1544,6 +1544,17 @@ static inline u32 iwl_mvm_get_scd_ssn(struct iwl_mvm *mvm,
|
|||
return val & 0xFFF;
|
||||
}
|
||||
|
||||
static inline size_t iwl_mvm_tx_resp_min_len(struct iwl_mvm *mvm,
|
||||
struct iwl_tx_resp *tx_resp)
|
||||
{
|
||||
struct agg_tx_status *agg_status =
|
||||
iwl_mvm_get_agg_status(mvm, tx_resp);
|
||||
|
||||
/* The aggregate response ends with a trailing SCD SSN __le32 word. */
|
||||
return (u8 *)(agg_status + tx_resp->frame_count) - (u8 *)tx_resp +
|
||||
sizeof(__le32);
|
||||
}
|
||||
|
||||
static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_packet *pkt)
|
||||
{
|
||||
|
|
@ -1847,6 +1858,9 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
|
|||
int queue = SEQ_TO_QUEUE(sequence);
|
||||
struct ieee80211_sta *sta;
|
||||
|
||||
if (WARN_ON_ONCE(iwl_mvm_has_new_tx_api(mvm)))
|
||||
return;
|
||||
|
||||
if (WARN_ON_ONCE(queue < IWL_MVM_DQA_MIN_DATA_QUEUE &&
|
||||
(queue != IWL_MVM_DQA_BSS_CLIENT_QUEUE)))
|
||||
return;
|
||||
|
|
@ -1881,6 +1895,26 @@ void iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
|
|||
{
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
struct iwl_tx_resp *tx_resp = (void *)pkt->data;
|
||||
size_t min_len;
|
||||
|
||||
if (IWL_FW_CHECK(mvm, !tx_resp->frame_count,
|
||||
"invalid TX_CMD frame_count %u\n",
|
||||
tx_resp->frame_count))
|
||||
return;
|
||||
|
||||
if (IWL_FW_CHECK(mvm,
|
||||
iwl_mvm_has_new_tx_api(mvm) &&
|
||||
tx_resp->frame_count != 1,
|
||||
"invalid TX_CMD frame_count %u for new TX API\n",
|
||||
tx_resp->frame_count))
|
||||
return;
|
||||
|
||||
min_len = iwl_mvm_tx_resp_min_len(mvm, tx_resp);
|
||||
if (IWL_FW_CHECK(mvm, iwl_rx_packet_payload_len(pkt) < min_len,
|
||||
"invalid TX_CMD len %u (frame_count %u, min %zu)\n",
|
||||
iwl_rx_packet_payload_len(pkt), tx_resp->frame_count,
|
||||
min_len))
|
||||
return;
|
||||
|
||||
if (tx_resp->frame_count == 1)
|
||||
iwl_mvm_rx_tx_cmd_single(mvm, pkt);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user