[PATCH wireless] wifi: mac80211_hwsim: avoid division by zero in mac80211_hwsim_write_tsf()

From: Serhat Kumral

Date: Fri Jun 26 2026 - 07:12:37 EST


mac80211_hwsim_write_tsf() adjusts the timestamp of beacon, probe
response and S1G beacon frames by dividing a constant by the legacy
bitrate of the selected tx rate, e.g.:

mgmt->u.probe_resp.timestamp =
cpu_to_le64(sim_time + data->tsf_offset +
24 * 8 * 10 / bitrate);

bitrate is taken from ieee80211_get_tx_rate(), which indexes the band's
legacy bitrates[] table by control.rates[0].idx without checking the
HT/VHT/S1G MCS flags or the table bounds. For an MCS rate the idx is not
a legacy-rate index, so the returned rate can have a bitrate of 0. The
code only guarded against a NULL rate, not a zero bitrate, so the
division can divide by zero. As the call trace shows, this is reachable
from user space by injecting a frame on a monitor interface:

divide error: 0000 [#1] SMP KASAN NOPTI
RIP: 0010:mac80211_hwsim_write_tsf+0x3a3/0x590
Call Trace:
mac80211_hwsim_tx_frame_no_nl+0x16b/0x1760
mac80211_hwsim_tx+0x1784/0x2500
ieee80211_tx_frags+0x3df/0x890
ieee80211_monitor_start_xmit+0xb33/0x1280
__dev_queue_xmit+0x1435/0x37f0
packet_sendmsg+0x3d95/0x5040

Fixing this in ieee80211_get_tx_rate() is not viable: callers such as
ath5k and adm8211 dereference its return value without a NULL check, so
making it return NULL for MCS rates would only move the crash elsewhere.
Keep the fix local and fall back to the existing default of 100 whenever
the reported bitrate is zero, in line with the existing "/* TODO: get
MCS */" note above.

Fixes: e75129031f1c ("wifi: mac80211_hwsim: move timestamp writing later in the datapath")
Reported-by: syzbot+21629c14aa749636db9d@xxxxxxxxxxxxxxxxxxxxxxxxx
Closes: https://syzkaller.appspot.com/bug?extid=21629c14aa749636db9d
Signed-off-by: Serhat Kumral <serhatkumral1@xxxxxxxxx>
---
drivers/net/wireless/virtual/mac80211_hwsim_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_main.c b/drivers/net/wireless/virtual/mac80211_hwsim_main.c
index 0dd8a6c85953..c745395d2042 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim_main.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim_main.c
@@ -1604,7 +1604,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);
- if (txrate)
+ if (txrate && txrate->bitrate)
bitrate = txrate->bitrate;

if (skb->len >= offsetofend(typeof(*mgmt), u.probe_resp.timestamp) &&
--
2.54.0