]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: mac80211_hwsim: avoid treating MCS as legacy rate index
authorYousef Alhouseen <alhouseenyousef@gmail.com>
Sun, 28 Jun 2026 00:25:37 +0000 (02:25 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 6 Jul 2026 12:11:07 +0000 (14:11 +0200)
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>
drivers/net/wireless/virtual/mac80211_hwsim_main.c

index 5c17182775990c2441beda7a77ec97761b5d2adf..956ff9b94526daa04bcb93997f47e07aa517630f 100644 (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;