diff options
| author | Weigang He <geoffreyhe2@gmail.com> | 2026-10-22 01:58:07 +1100 |
|---|---|---|
| committer | Johannes Berg <johannes.berg@intel.com> | 2026-10-22 11:59:31 +0200 |
| commit | 35c5a5ea4418571997a7e7af3e7e8922b136f6e6 (patch) | |
| tree | 864a9897e762766d33e950576246e55e9febd28b /include | |
| parent | 045958acaa75205b31578cb22c4345e28dd2e4bf (diff) | |
wifi: mac80211: reload TDLS header pointer after skb_linearize()
ieee80211_process_tdls_channel_switch() sets tf = skb->data before it
calls skb_linearize(), and reads tf->action_code afterwards.
ieee80211_rx_h_data() queues TDLS channel switch requests and
responses to the interface after pulling only
offsetof(struct ieee80211_tdls_data, u) bytes, so the skb can still be
non-linear when the interface work handles it. Drivers that build
paged RX skbs do this for every frame that does not fit into the skb
head, e.g. iwlwifi (mvm), which is also the only mac80211 driver
that sets NL80211_FEATURE_TDLS_CHANNEL_SWITCH. If the remaining data
does not fit into the tailroom, skb_linearize() moves the data to a
new head and frees the old one, and the action code is then read from
freed memory. Depending on what that memory holds by then, the frame
is handled as before or ends in the WARN_ON_ONCE() of the default
case.
The frame only has to be a data frame with the TDLS ethertype from an
authorized peer, e.g. relayed by the AP from another station in the
BSS; the read happens before the sender is checked to be a TDLS peer.
Load tf after skb_linearize(), as the request and response handlers
already do.
Found by static analysis tool CodeQL.
Fixes: 8a4d32f30d11 ("mac80211: add TDLS channel-switch Rx flow")
Cc: stable@vger.kernel.org
Assisted-by: LLM codeql
Signed-off-by: Weigang He <geoffreyhe2@gmail.com>
Link: https://patch.msgid.link/20261021145807.3018338-1-geoffreyhe2@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'include')
0 files changed, 0 insertions, 0 deletions
