wifi: mac80211_hwsim: avoid treating MCS as legacy rate index

Injected HT and VHT rates store an MCS value in rates[0].idx rather
than an index into the legacy bitrate table. hwsim nevertheless passes
these rates to ieee80211_get_tx_rate() while generating monitor frames
and timestamps.

A crafted injected frame can therefore read beyond the bitrate table.
If the resulting bitrate is zero, mac80211_hwsim_write_tsf() also
divides by zero, as observed by syzbot.

Use ieee80211_get_tx_rate() only for legacy rates. The existing fallback
continues to supply a conservative bitrate where hwsim does not yet
calculate MCS rates.

Reported-by: syzbot+21629c14aa749636db9d@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=21629c14aa749636db9d
Signed-off-by: Yousef Alhouseen <alhouseenyousef@gmail.com>
Link: https://patch.msgid.link/20260628002537.23550-1-alhouseenyousef@gmail.com
[drop wrong Fixes tag]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Yousef Alhouseen 2026-06-28 02:25:37 +02:00 committed by Johannes Berg
parent 63c2391dee
commit 23b493d9dc

View File

@ -1324,6 +1324,17 @@ static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw,
}
}
static struct ieee80211_rate *
mac80211_hwsim_get_tx_rate(struct ieee80211_hw *hw,
struct ieee80211_tx_info *info)
{
if (info->control.rates[0].flags &
(IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_VHT_MCS))
return NULL;
return ieee80211_get_tx_rate(hw, info);
}
static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
struct sk_buff *tx_skb,
struct ieee80211_channel *chan)
@ -1333,7 +1344,7 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
struct hwsim_radiotap_hdr *hdr;
u16 flags, bitrate;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_skb);
struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info);
struct ieee80211_rate *txrate = mac80211_hwsim_get_tx_rate(hw, info);
if (!txrate)
bitrate = 0;
@ -1603,7 +1614,7 @@ static void mac80211_hwsim_write_tsf(struct mac80211_hwsim_data *data,
spin_lock_bh(&data->tsf_offset_lock);
txrate = ieee80211_get_tx_rate(data->hw, info);
txrate = mac80211_hwsim_get_tx_rate(data->hw, info);
if (txrate)
bitrate = txrate->bitrate;