# Patch Review **Patch:** `wifi: mac80211_hwsim: fix divide-by-zero on zero beacon interval` **Report:** `69efb8dd.050a0220.18b4f.0006.GAE@google.com` **Reviewer:** Patch Reviewer Agent --- ## Verdict: PASS ### Checklist | # | Item | Result | Notes | |---|------|--------|-------| | 1 | Resource leaks | ✅ Clean | No allocations introduced; no new object lifecycle. | | 2 | Lock imbalance | ✅ Clean | No locks acquired in the function before the new `return`; the wiphy mutex is held by the caller and is not affected. | | 3 | NULL / uninitialized dereference | ✅ Clean | Patch adds a guard, not a dereference. | | 4 | Error path coverage | ✅ Clean | No new fallible operations introduced. | | 5 | Caller contract changes | ✅ Clean | `void` function; no return-value or locking-precondition change. The callback is looked up by `.link_info_changed`; no callers inspect a return value. | | 6 | Obviousness | ✅ Correct | Fix directly matches the root cause. | ### Analysis **Crash:** `do_div(tsf, bcn_int)` at `mac80211_hwsim.c:2734` with `bcn_int = 0` (loaded from `link_data->beacon_int = info->beacon_int * 1024` where `info->beacon_int = 0`). **Fix:** Insert `if (!bcn_int) return;` immediately after `bcn_int` is loaded, before the division. **Correctness of `return` vs. other strategies:** The early `return` exits `mac80211_hwsim_link_info_changed()` before processing any remaining `if (changed & ...)` blocks (lines 2753–2778). However, **all** of those blocks are pure `wiphy_dbg()` debug-log statements — no state is mutated, no timers are touched, no data structures are updated. Skipping them is functionally harmless regardless of which other flags `changed` carries. The concern that a combined `changed` bitmask (e.g., `BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_HT`) could cause silent skips is therefore not a correctness problem in this driver: `mac80211_hwsim` only logs those flag-changes, it does not act on them. **Consistency with existing guard (`mac80211_hwsim_config()` line 2630):** ```c if (!data->started || !link_data->beacon_int) { hrtimer_cancel(&link_data->beacon_timer); } else if (!hrtimer_active(&link_data->beacon_timer)) { u32 bcn_int = link_data->beacon_int; u64 until_tbtt = bcn_int - do_div(tsf, bcn_int); // protected ``` The existing guard cancels the timer when `beacon_int == 0`. The new guard in `link_info_changed` does not cancel (the timer is already inactive — verified by the `!hrtimer_active()` check at line 2727 that gates entry into this block), so a cancel would be a no-op. Returning early is correct. **No beacon timer misuse:** Because the timer is never started (the `return` bypasses `hrtimer_start()`), `mac80211_hwsim_beacon()` will not fire with `link_data->beacon_int = 0`, eliminating any follow-on divide-by-zero in the callback. **`Fixes:` tag:** Points to `c51f878379b1` ("mac80211_hwsim: fix beacon timing"), the commit that introduced the unguarded `do_div`. Correct. --- *Reviewed by patchreviewer:linux-kernel-oops-x86*