AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/11/03 18:31 flow patch-triage
33m Args:
null

Results:
{
  "EnableConfigs": [
    "CFG80211",
    "MAC80211",
    "MAC80211_RC_MINSTREL",
    "MAC80211_HWSIM"
  ],
  "FocusSymbols": [
    "ieee80211_start_tx_ba_session",
    "ieee80211_stop_tx_ba_session",
    "ieee80211_calc_expected_tx_airtime",
    "drv_change_sta_links",
    "ieee80211_sta_ps_transition",
    "ieee80211_sta_pspoll",
    "ieee80211_sta_uapsd_trigger",
    "ieee80211_tx_dequeue",
    "ieee80211_reserve_tid",
    "ieee80211_unreserve_tid"
  ],
  "KMSANReasoning": "The patch is a pure code refactoring that introduces the helper function sta_from_pub() (which wraps container_of(sta, struct sta_info, sta)) and replaces direct container_of invocations throughout the mac80211 subsystem. It does not introduce any memory allocations, data copying to userspace, modifications to struct layouts or initializations, or changes to control flow/bounds checking. Consequently, it introduces no risks of uninitialized memory access or info-leaks, and a dedicated KMSAN fuzzing session is not warranted.",
  "NeedsKMSAN": false,
  "Reasoning": "The patch introduces the inline helper sta_from_pub() and replaces container_of() invocations across multiple mac80211 modules (TX aggregation, airtime calculation, RX handling, power save management, rate control, and TX scheduling). These changes modify reachable wireless core networking code that is actively fuzzed via mac80211_hwsim in virtualized environments. Fuzzing is warranted to test station pointer retrieval and prevent regressions across station operations.",
  "WorthFuzzing": true
}

1/1 2026/11/03 18:31 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit f9f8ce30187cb82d1fa215d85e4c819431376082\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Tue Nov 3 18:31:15 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c\nindex f3ecdd8601a042..f9285ff081fc01 100644\n--- a/net/mac80211/agg-tx.c\n+++ b/net/mac80211/agg-tx.c\n@@ -555,7 +555,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)\n void ieee80211_refresh_tx_agg_session_timer(struct ieee80211_sta *pubsta,\n \t\t\t\t\t    u16 tid)\n {\n-\tstruct sta_info *sta = container_of(pubsta, struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(pubsta);\n \tstruct tid_ampdu_tx *tid_tx;\n \n \tif (WARN_ON_ONCE(tid \u003e= IEEE80211_NUM_TIDS))\n@@ -600,7 +600,7 @@ static void sta_tx_agg_session_timer_expired(struct timer_list *t)\n int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,\n \t\t\t\t  u16 timeout)\n {\n-\tstruct sta_info *sta = container_of(pubsta, struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(pubsta);\n \tstruct ieee80211_sub_if_data *sdata = sta-\u003esdata;\n \tstruct ieee80211_local *local = sdata-\u003elocal;\n \tstruct tid_ampdu_tx *tid_tx;\n@@ -868,7 +868,7 @@ EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);\n \n int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)\n {\n-\tstruct sta_info *sta = container_of(pubsta, struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(pubsta);\n \tstruct ieee80211_sub_if_data *sdata = sta-\u003esdata;\n \tstruct ieee80211_local *local = sdata-\u003elocal;\n \tstruct tid_ampdu_tx *tid_tx;\ndiff --git a/net/mac80211/airtime.c b/net/mac80211/airtime.c\nindex a4e1f33c037797..53a455b6425fb6 100644\n--- a/net/mac80211/airtime.c\n+++ b/net/mac80211/airtime.c\n@@ -1,7 +1,7 @@\n // SPDX-License-Identifier: ISC\n /*\n  * Copyright (C) 2019 Felix Fietkau \u003cnbd@nbd.name\u003e\n- * Copyright (C) 2021-2022 Intel Corporation\n+ * Copyright (C) 2021-2022, 2026 Intel Corporation\n  */\n \n #include \u003cnet/mac80211.h\u003e\n@@ -838,8 +838,7 @@ u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw,\n \t\tband = conf-\u003edef.chan-\u003eband;\n \n \tif (pubsta) {\n-\t\tstruct sta_info *sta = container_of(pubsta, struct sta_info,\n-\t\t\t\t\t\t    sta);\n+\t\tstruct sta_info *sta = sta_from_pub(pubsta);\n \t\tstruct ieee80211_tx_rate *tx_rate = \u0026sta-\u003edeflink.tx_stats.last_rate;\n \t\tstruct rate_info *ri = \u0026sta-\u003edeflink.tx_stats.last_rate_info;\n \t\tu32 duration;\ndiff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c\nindex 1f3e0765a8ab2e..12ea71036e4a08 100644\n--- a/net/mac80211/driver-ops.c\n+++ b/net/mac80211/driver-ops.c\n@@ -583,7 +583,7 @@ int drv_change_sta_links(struct ieee80211_local *local,\n \t\t\t struct ieee80211_sta *sta,\n \t\t\t u16 old_links, u16 new_links)\n {\n-\tstruct sta_info *info = container_of(sta, struct sta_info, sta);\n+\tstruct sta_info *info = sta_from_pub(sta);\n \tstruct link_sta_info *link_sta;\n \tunsigned long links_to_add;\n \tunsigned long links_to_rem;\ndiff --git a/net/mac80211/he.c b/net/mac80211/he.c\nindex 5acf482c177a7e..0278892ae91f38 100644\n--- a/net/mac80211/he.c\n+++ b/net/mac80211/he.c\n@@ -265,8 +265,7 @@ ieee80211_he_spr_ie_to_bss_conf(struct ieee80211_vif *vif,\n bool ieee80211_prepare_rx_omi_bw(struct ieee80211_link_sta *pub_link_sta,\n \t\t\t\t enum ieee80211_sta_rx_bandwidth bw)\n {\n-\tstruct sta_info *sta = container_of(pub_link_sta-\u003esta,\n-\t\t\t\t\t    struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(pub_link_sta-\u003esta);\n \tstruct ieee80211_local *local = sta-\u003esdata-\u003elocal;\n \tstruct link_sta_info *link_sta =\n \t\tsdata_dereference(sta-\u003elink[pub_link_sta-\u003elink_id], sta-\u003esdata);\n@@ -318,8 +317,7 @@ EXPORT_SYMBOL_GPL(ieee80211_prepare_rx_omi_bw);\n \n void ieee80211_finalize_rx_omi_bw(struct ieee80211_link_sta *pub_link_sta)\n {\n-\tstruct sta_info *sta = container_of(pub_link_sta-\u003esta,\n-\t\t\t\t\t    struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(pub_link_sta-\u003esta);\n \tstruct ieee80211_local *local = sta-\u003esdata-\u003elocal;\n \tstruct link_sta_info *link_sta =\n \t\tsdata_dereference(sta-\u003elink[pub_link_sta-\u003elink_id], sta-\u003esdata);\ndiff --git a/net/mac80211/rate.c b/net/mac80211/rate.c\nindex 10e6ad53726140..d74413fdaf0675 100644\n--- a/net/mac80211/rate.c\n+++ b/net/mac80211/rate.c\n@@ -88,7 +88,7 @@ void rate_control_tx_status(struct ieee80211_local *local,\n \t\t\t    struct ieee80211_tx_status *st)\n {\n \tstruct rate_control_ref *ref = local-\u003erate_ctrl;\n-\tstruct sta_info *sta = container_of(st-\u003esta, struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(st-\u003esta);\n \tvoid *priv_sta = sta-\u003erate_ctrl_priv;\n \tstruct ieee80211_supported_band *sband;\n \n@@ -442,7 +442,7 @@ static bool rate_control_send_low(struct ieee80211_sta *pubsta,\n \t\t\t}\n \t\t\tuse_basicrate = true;\n \t\t} else if (pubsta) {\n-\t\t\tsta = container_of(pubsta, struct sta_info, sta);\n+\t\t\tsta = sta_from_pub(pubsta);\n \t\t\tif (ieee80211_vif_is_mesh(\u0026sta-\u003esdata-\u003evif))\n \t\t\t\tuse_basicrate = true;\n \t\t}\n@@ -970,7 +970,7 @@ int rate_control_set_rates(struct ieee80211_hw *hw,\n \t\t\t   struct ieee80211_sta *pubsta,\n \t\t\t   struct ieee80211_sta_rates *rates)\n {\n-\tstruct sta_info *sta = container_of(pubsta, struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(pubsta);\n \tstruct ieee80211_sta_rates *old;\n \tstruct ieee80211_supported_band *sband;\n \ndiff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c\nindex 45e7a7ea769008..d46b6780bfdb3a 100644\n--- a/net/mac80211/rc80211_minstrel_ht.c\n+++ b/net/mac80211/rc80211_minstrel_ht.c\n@@ -1,7 +1,7 @@\n // SPDX-License-Identifier: GPL-2.0-only\n /*\n  * Copyright (C) 2010-2013 Felix Fietkau \u003cnbd@openwrt.org\u003e\n- * Copyright (C) 2019-2022 Intel Corporation\n+ * Copyright (C) 2019-2022, 2026 Intel Corporation\n  */\n #include \u003clinux/netdevice.h\u003e\n #include \u003clinux/types.h\u003e\n@@ -1865,7 +1865,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,\n \t\t\t\tvht_cap-\u003evht_mcs.tx_mcs_map);\n \t}\n \n-\tsta_info = container_of(sta, struct sta_info, sta);\n+\tsta_info = sta_from_pub(sta);\n \tmi-\u003euse_short_preamble = test_sta_flag(sta_info, WLAN_STA_SHORT_PREAMBLE) \u0026\u0026\n \t\t\t\t sta_info-\u003esdata-\u003evif.bss_conf.use_short_preamble;\n \ndiff --git a/net/mac80211/rx.c b/net/mac80211/rx.c\nindex ee1f33178d2670..acf1188ff42688 100644\n--- a/net/mac80211/rx.c\n+++ b/net/mac80211/rx.c\n@@ -1724,7 +1724,7 @@ static void sta_ps_end(struct sta_info *sta)\n \n void ieee80211_sta_ps_transition(struct ieee80211_sta *pubsta, bool start)\n {\n-\tstruct sta_info *sta = container_of(pubsta, struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(pubsta);\n \tbool in_ps;\n \n \tWARN_ON(!ieee80211_hw_check(\u0026sta-\u003elocal-\u003ehw, AP_LINK_PS));\n@@ -1743,7 +1743,7 @@ EXPORT_SYMBOL(ieee80211_sta_ps_transition);\n \n void ieee80211_sta_pspoll(struct ieee80211_sta *pubsta)\n {\n-\tstruct sta_info *sta = container_of(pubsta, struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(pubsta);\n \n \tif (test_sta_flag(sta, WLAN_STA_SP))\n \t\treturn;\n@@ -1757,7 +1757,7 @@ EXPORT_SYMBOL(ieee80211_sta_pspoll);\n \n void ieee80211_sta_uapsd_trigger(struct ieee80211_sta *pubsta, u8 tid)\n {\n-\tstruct sta_info *sta = container_of(pubsta, struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(pubsta);\n \tint ac = ieee80211_ac_from_tid(tid);\n \n \t/*\n@@ -4439,7 +4439,7 @@ void ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *pubsta, u8 tid,\n \n \t__skb_queue_head_init(\u0026frames);\n \n-\tsta = container_of(pubsta, struct sta_info, sta);\n+\tsta = sta_from_pub(pubsta);\n \n \tlocal = sta-\u003esdata-\u003elocal;\n \tWARN_ONCE(local-\u003ehw.max_rx_aggregation_subframes \u003e 64,\n@@ -5289,7 +5289,7 @@ static void __ieee80211_rx_handle_8023(struct ieee80211_hw *hw,\n \tif (!link_pubsta)\n \t\tgoto drop;\n \n-\tsta = container_of(link_pubsta-\u003esta, struct sta_info, sta);\n+\tsta = sta_from_pub(link_pubsta-\u003esta);\n \tif (sta-\u003esta.valid_links)\n \t\tlink_id = link_pubsta-\u003elink_id;\n \tif (!ieee80211_rx_data_set_sta(\u0026rx, sta, link_id))\n@@ -5398,8 +5398,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,\n \t */\n \tif (ieee80211_is_data(fc)) {\n \t\tif (link_pubsta) {\n-\t\t\tsta = container_of(link_pubsta-\u003esta, struct sta_info,\n-\t\t\t\t\t   sta);\n+\t\t\tsta = sta_from_pub(link_pubsta-\u003esta);\n \t\t\tlink_sta = rcu_dereference(sta-\u003elink[link_pubsta-\u003elink_id]);\n \n \t\t\trx.sdata = sta-\u003esdata;\ndiff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c\nindex 23166fc3972913..6e9c06f3e4db5e 100644\n--- a/net/mac80211/sta_info.c\n+++ b/net/mac80211/sta_info.c\n@@ -2349,7 +2349,7 @@ void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta)\n void ieee80211_sta_block_awake(struct ieee80211_hw *hw,\n \t\t\t       struct ieee80211_sta *pubsta, bool block)\n {\n-\tstruct sta_info *sta = container_of(pubsta, struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(pubsta);\n \n \ttrace_api_sta_block_awake(sta-\u003elocal, pubsta, block);\n \n@@ -2380,7 +2380,7 @@ EXPORT_SYMBOL(ieee80211_sta_block_awake);\n \n void ieee80211_sta_eosp(struct ieee80211_sta *pubsta)\n {\n-\tstruct sta_info *sta = container_of(pubsta, struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(pubsta);\n \tstruct ieee80211_local *local = sta-\u003elocal;\n \n \ttrace_api_eosp(local, pubsta);\n@@ -2391,7 +2391,7 @@ EXPORT_SYMBOL(ieee80211_sta_eosp);\n \n void ieee80211_send_eosp_nullfunc(struct ieee80211_sta *pubsta, int tid)\n {\n-\tstruct sta_info *sta = container_of(pubsta, struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(pubsta);\n \tenum ieee80211_frame_release_type reason;\n \tbool more_data;\n \n@@ -2408,7 +2408,7 @@ EXPORT_SYMBOL(ieee80211_send_eosp_nullfunc);\n void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta,\n \t\t\t\tu8 tid, bool buffered)\n {\n-\tstruct sta_info *sta = container_of(pubsta, struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(pubsta);\n \n \tif (WARN_ON(tid \u003e= IEEE80211_NUM_TIDS))\n \t\treturn;\n@@ -2427,7 +2427,7 @@ EXPORT_SYMBOL(ieee80211_sta_set_buffered);\n void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,\n \t\t\t\t    u32 tx_airtime, u32 rx_airtime)\n {\n-\tstruct sta_info *sta = container_of(pubsta, struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(pubsta);\n \tstruct ieee80211_local *local = sta-\u003esdata-\u003elocal;\n \tu8 ac = ieee80211_ac_from_tid(tid);\n \tu32 airtime = 0;\n@@ -2495,7 +2495,7 @@ void __ieee80211_sta_recalc_aggregates(struct sta_info *sta, u16 active_links)\n \n void ieee80211_sta_recalc_aggregates(struct ieee80211_sta *pubsta)\n {\n-\tstruct sta_info *sta = container_of(pubsta, struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(pubsta);\n \n \t__ieee80211_sta_recalc_aggregates(sta, sta-\u003esdata-\u003evif.active_links);\n }\n@@ -3683,7 +3683,7 @@ void ieee80211_sta_set_max_amsdu_subframes(struct sta_info *sta,\n #ifdef CONFIG_LOCKDEP\n bool lockdep_sta_mutex_held(struct ieee80211_sta *pubsta)\n {\n-\tstruct sta_info *sta = container_of(pubsta, struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(pubsta);\n \n \treturn lockdep_is_held(\u0026sta-\u003elocal-\u003ehw.wiphy-\u003emtx);\n }\ndiff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h\nindex 8c6a9fee6b29b0..0e8f7794fd01b7 100644\n--- a/net/mac80211/sta_info.h\n+++ b/net/mac80211/sta_info.h\n@@ -793,6 +793,11 @@ struct sta_info {\n \tstruct ieee80211_sta sta;\n };\n \n+static inline struct sta_info *sta_from_pub(struct ieee80211_sta *sta)\n+{\n+\treturn container_of(sta, struct sta_info, sta);\n+}\n+\n static inline int ieee80211_tdls_sta_link_id(struct sta_info *sta)\n {\n \t/* TDLS STA can only have a single link */\ndiff --git a/net/mac80211/status.c b/net/mac80211/status.c\nindex 414979e2a1d930..5d1807ab46ef5c 100644\n--- a/net/mac80211/status.c\n+++ b/net/mac80211/status.c\n@@ -1013,7 +1013,7 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw,\n \tfc = hdr-\u003eframe_control;\n \n \tif (status-\u003esta) {\n-\t\tsta = container_of(status-\u003esta, struct sta_info, sta);\n+\t\tsta = sta_from_pub(status-\u003esta);\n \n \t\tif (info-\u003eflags \u0026 IEEE80211_TX_STATUS_EOSP)\n \t\t\tclear_sta_flag(sta, WLAN_STA_SP);\n@@ -1246,7 +1246,7 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,\n \tieee80211_tx_status_drop_invalid_rates(status);\n \n \tif (pubsta) {\n-\t\tsta = container_of(pubsta, struct sta_info, sta);\n+\t\tsta = sta_from_pub(pubsta);\n \n \t\tif (status-\u003en_rates)\n \t\t\tsta-\u003edeflink.tx_stats.last_rate_info =\n@@ -1363,7 +1363,7 @@ void ieee80211_tx_rate_update(struct ieee80211_hw *hw,\n \t\t\t      struct ieee80211_tx_info *info)\n {\n \tstruct ieee80211_local *local = hw_to_local(hw);\n-\tstruct sta_info *sta = container_of(pubsta, struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(pubsta);\n \tstruct ieee80211_tx_status status = {\n \t\t.info = info,\n \t\t.sta = pubsta,\n@@ -1379,7 +1379,7 @@ EXPORT_SYMBOL(ieee80211_tx_rate_update);\n \n void ieee80211_report_low_ack(struct ieee80211_sta *pubsta, u32 num_packets)\n {\n-\tstruct sta_info *sta = container_of(pubsta, struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(pubsta);\n \tcfg80211_cqm_pktloss_notify(sta-\u003esdata-\u003edev, sta-\u003esta.addr,\n \t\t\t\t    num_packets, GFP_ATOMIC);\n }\ndiff --git a/net/mac80211/tx.c b/net/mac80211/tx.c\nindex e9b6a0415d6a94..22335ea362aa7d 100644\n--- a/net/mac80211/tx.c\n+++ b/net/mac80211/tx.c\n@@ -4031,7 +4031,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,\n \ttx.sdata = vif_to_sdata(info-\u003econtrol.vif);\n \n \tif (txq-\u003esta) {\n-\t\ttx.sta = container_of(txq-\u003esta, struct sta_info, sta);\n+\t\ttx.sta = sta_from_pub(txq-\u003esta);\n \n \t\tif (unlikely(ieee80211_drop_unauth_port(\u0026tx))) {\n \t\t\tI802_DEBUG_INC(local-\u003etx_handlers_drop_unauth_port);\n@@ -4067,8 +4067,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,\n \t}\n \n \tif (info-\u003econtrol.flags \u0026 IEEE80211_TX_CTRL_FAST_XMIT) {\n-\t\tstruct sta_info *sta = container_of(txq-\u003esta, struct sta_info,\n-\t\t\t\t\t\t    sta);\n+\t\tstruct sta_info *sta = sta_from_pub(txq-\u003esta);\n \t\tu8 pn_offs = 0;\n \n \t\tif (tx.key \u0026\u0026\n@@ -4176,7 +4175,7 @@ ieee80211_txq_set_active(struct txq_info *txqi)\n \tif (!txqi-\u003etxq.sta)\n \t\treturn;\n \n-\tsta = container_of(txqi-\u003etxq.sta, struct sta_info, sta);\n+\tsta = sta_from_pub(txqi-\u003etxq.sta);\n \tsta-\u003eairtime[txqi-\u003etxq.ac].last_active = jiffies;\n }\n \n@@ -4188,7 +4187,7 @@ ieee80211_txq_keep_active(struct txq_info *txqi)\n \tif (!txqi-\u003etxq.sta)\n \t\treturn false;\n \n-\tsta = container_of(txqi-\u003etxq.sta, struct sta_info, sta);\n+\tsta = sta_from_pub(txqi-\u003etxq.sta);\n \tif (ieee80211_sta_deficit(sta, txqi-\u003etxq.ac) \u003e= 0)\n \t\treturn false;\n \n@@ -4230,8 +4229,7 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)\n \t\tfound_eligible_txq = true;\n \n \tif (txqi-\u003etxq.sta) {\n-\t\tstruct sta_info *sta = container_of(txqi-\u003etxq.sta,\n-\t\t\t\t\t\t    struct sta_info, sta);\n+\t\tstruct sta_info *sta = sta_from_pub(txqi-\u003etxq.sta);\n \n \t\tif (ieee80211_sta_deficit(sta, txqi-\u003etxq.ac) \u003c 0) {\n \t\t\tsta-\u003eairtime[txqi-\u003etxq.ac].deficit +=\n@@ -4319,7 +4317,7 @@ bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw,\n \tif (unlikely(txq-\u003etid == IEEE80211_NUM_TIDS))\n \t\treturn true;\n \n-\tsta = container_of(txq-\u003esta, struct sta_info, sta);\n+\tsta = sta_from_pub(txq-\u003esta);\n \tif (atomic_read(\u0026sta-\u003eairtime[txq-\u003eac].aql_tx_pending) \u003c\n \t    sta-\u003eairtime[txq-\u003eac].aql_limit_low)\n \t\treturn true;\n@@ -4346,7 +4344,7 @@ u32 ieee80211_txq_aql_pending(struct ieee80211_hw *hw,\n \tif (!txq-\u003esta)\n \t\treturn atomic_read(\u0026local-\u003eaql_mc_pending_airtime);\n \n-\tsta = container_of(txq-\u003esta, struct sta_info, sta);\n+\tsta = sta_from_pub(txq-\u003esta);\n \n \treturn atomic_read(\u0026sta-\u003eairtime[txq-\u003eac].aql_tx_pending);\n }\n@@ -4400,13 +4398,13 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,\n \t\t\t\t       \u0026local-\u003eactive_txqs[ac]);\n \t\t\tcontinue;\n \t\t}\n-\t\tsta = container_of(iter-\u003etxq.sta, struct sta_info, sta);\n+\t\tsta = sta_from_pub(iter-\u003etxq.sta);\n \t\tif (ieee80211_sta_deficit(sta, ac) \u003c 0)\n \t\t\tsta-\u003eairtime[ac].deficit += sta-\u003eairtime_weight;\n \t\tlist_move_tail(\u0026iter-\u003eschedule_order, \u0026local-\u003eactive_txqs[ac]);\n \t}\n \n-\tsta = container_of(txqi-\u003etxq.sta, struct sta_info, sta);\n+\tsta = sta_from_pub(txqi-\u003etxq.sta);\n \tif (sta-\u003eairtime[ac].deficit \u003e= 0)\n \t\tgoto out;\n \n@@ -6446,7 +6444,7 @@ EXPORT_SYMBOL(ieee80211_get_buffered_bc);\n \n int ieee80211_reserve_tid(struct ieee80211_sta *pubsta, u8 tid)\n {\n-\tstruct sta_info *sta = container_of(pubsta, struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(pubsta);\n \tstruct ieee80211_sub_if_data *sdata = sta-\u003esdata;\n \tstruct ieee80211_local *local = sdata-\u003elocal;\n \tint ret;\n@@ -6510,7 +6508,7 @@ EXPORT_SYMBOL(ieee80211_reserve_tid);\n \n void ieee80211_unreserve_tid(struct ieee80211_sta *pubsta, u8 tid)\n {\n-\tstruct sta_info *sta = container_of(pubsta, struct sta_info, sta);\n+\tstruct sta_info *sta = sta_from_pub(pubsta);\n \tstruct ieee80211_sub_if_data *sdata = sta-\u003esdata;\n \n \tlockdep_assert_wiphy(sdata-\u003elocal-\u003ehw.wiphy);\ndiff --git a/net/mac80211/util.c b/net/mac80211/util.c\nindex 44feb80274c61c..2706f6a5a8fbbe 100644\n--- a/net/mac80211/util.c\n+++ b/net/mac80211/util.c\n@@ -904,7 +904,7 @@ __ieee80211_iterate_stations(struct ieee80211_hw *hw,\n \tlockdep_assert_wiphy(local-\u003ehw.wiphy);\n \n \tif (prev)\n-\t\tsta = container_of(prev, struct sta_info, sta);\n+\t\tsta = sta_from_pub(prev);\n \n \tsta = list_prepare_entry(sta, \u0026local-\u003esta_list, list);\n \tlist_for_each_entry_continue(sta, \u0026local-\u003esta_list, list) {\n"
}

2/1 2026/11/03 18:31 agent patch-evaluator
30m Model:
core

Args:
null

Results:
{
  "EnableConfigs": [
    "CFG80211",
    "MAC80211",
    "MAC80211_RC_MINSTREL",
    "MAC80211_HWSIM"
  ],
  "FocusSymbols": [
    "ieee80211_start_tx_ba_session",
    "ieee80211_stop_tx_ba_session",
    "ieee80211_calc_expected_tx_airtime",
    "drv_change_sta_links",
    "ieee80211_sta_ps_transition",
    "ieee80211_sta_pspoll",
    "ieee80211_sta_uapsd_trigger",
    "ieee80211_tx_dequeue",
    "ieee80211_reserve_tid",
    "ieee80211_unreserve_tid"
  ],
  "Reasoning": "The patch introduces the inline helper sta_from_pub() and replaces container_of() invocations across multiple mac80211 modules (TX aggregation, airtime calculation, RX handling, power save management, rate control, and TX scheduling). These changes modify reachable wireless core networking code that is actively fuzzed via mac80211_hwsim in virtualized environments. Fuzzing is warranted to test station pointer retrieval and prevent regressions across station operations.",
  "WorthFuzzing": true
}

Instruction:
You are an expert Linux kernel maintainer and security engineer.
Your job is to review a provided patch series and evaluate whether it warrants fuzzing with syzkaller.

IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on internal assumptions. You must actively use your code access
tools to inspect the actual source code, callers, and surrounding context.

================================================================================
1. CORE TRIAGE PHILOSOPHY
================================================================================
The goal of patch fuzzing is to discover crashes, regressions, exposed latent bugs,
and newly triggered assertions introduced by the patch series.

- REACHABILITY IS THE PRIMARY GATE:
  Fuzzing can only discover bugs in code that can actually execute in standard virtualized
  environments (GCE or QEMU, utilizing software-emulated devices like USB gadgets, netdev, tun/tap).
  If the modified code is structurally unreachable (see Section 2), it MUST NOT be fuzzed,
  regardless of whether it adds assertions or complex logic.

- DO NOT BLINDLY TRUST "NO FUNCTIONAL CHANGE" (NFCI) OR "REFACTORING" CLAIMS:
  Patch authors routinely label changes as "cleanups", "refactorings", or state
  "No functional change intended". Do NOT take these claims at face value.
  Code refactorings that rearrange logic, introduce helper functions, or alter state management
  in core subsystems frequently introduce subtle semantic shifts or uncover latent kernel bugs.
  If reachable executable code is modified or refactored, it MUST be fuzzed.

- NEW OR MODIFIED ASSERTIONS IN REACHABLE CODE MUST BE FUZZED:
  When a patch introduces or modifies runtime checks or assertions (e.g., WARN_ON*, VM_WARN_ON*,
  BUG_ON*, lockdep_assert*) in reachable code paths, it enforces new or stricter invariants.
  Even if the author believes the invariant always holds, fuzzing is essential to verify whether
  an unusual sequence of operations can violate it.

================================================================================
2. WHEN TO RETURN WorthFuzzing=false (NEGATIVE CRITERIA)
================================================================================
Return WorthFuzzing=false ONLY IF all modified code falls strictly into one or more of these categories:

- Non-kernel and non-executable changes:
  * Modifications to Documentation/, comments, or spelling fixes.
  * User-space directories, self-tests, samples, or scripts (e.g., tools/, samples/, scripts/, usr/)
    that do not affect the compiled kernel image (vmlinux) or kernel modules.
  * Purely decorative logging (e.g., message strings in pr_err, printk, dev_info) or tracepoints
    that do not alter control flow or data structures.
  * Build system or Kconfig changes that do not alter compiled C logic.
- Structurally unreachable hardware:
  * Vendor-specific PCIe switches, SmartNICs, or GPU drivers (e.g., mlxsw, pds_core, qed,
    ionic, amdgpu) requiring physical ASIC/PCIe cards not emulated in standard QEMU.
- Unreachable execution paths:
  * Driver teardown callbacks (.remove, .shutdown, pci_unregister_driver) executed only during
    physical PCI hot-unplug or manual sysfs driver unbinding.
  * Code paths exclusive to architectures other than the target architecture.

================================================================================
3. WHEN TO RETURN WorthFuzzing=true (POSITIVE CRITERIA)
================================================================================
Return WorthFuzzing=true whenever the patch touches reachable executable code, including:
- Core Subsystems:
  * Any logic modifications in memory management (mm/), synchronization/locking (kernel/locking/),
    BPF, scheduler, core networking, VFS, or syscall handling.
- Refactorings and Code Cleanups:
  * Any restructuring of reachable data structures, helper abstractions, or algorithm flows.
- Runtime Assertions and Defensive Checks:
  * Any introduction or alteration of assertions (WARN_ON*, VM_WARN_ON*, BUG_ON*, etc.) in reachable paths.
- Reachable Drivers and Protocols:
  * Drivers accessible via virtual buses (virtio, USB gadget, loopback, netlink, binder, sockets, etc.).

================================================================================
4. EXTRACTING FocusSymbols (PREVENTING DILUTION)
================================================================================
When WorthFuzzing=true, you must extract specific kernel functions into FocusSymbols to guide the fuzzer:

- AVOID UBIQUITOUS LIFECYCLE HOT-PATHS:
  Do NOT list generic, ubiquitous functions called by almost every program in the corpus
  (including, but not limited to: general memory allocators and deallocators, page fault
  and trap handlers, or core synchronization primitives; this is not an exhaustive list).
  Listing ubiquitous functions causes the fuzzer to classify thousands of unrelated tests as "focused",
  which severely dilutes fuzzing effort away from the actual changes.

- TARGET SPECIFIC FEATURE LOGIC AND ENTRYPOINTS:
  List functions that specifically implement the logic being added or altered, or direct API entrypoints
  for the subsystem feature under review.

- HANDLING STATIC INLINE FUNCTIONS IN HEADERS (.h):
  Compiler-inlined static functions (such as static inlines in mm/*.h or include/linux/*.h) lack
  distinct symbol addresses in vmlinux and cannot be targeted directly by symbol coverage filters.
  If the changes are primarily in static inline helpers, identify non-static, feature-specific caller
  functions in .c files that exercise them (avoiding ubiquitous lifecycle wrappers).

================================================================================
5. IDENTIFYING EnableConfigs
================================================================================
Identify any specific CONFIG_ options required to properly compile and reach the modified code:
- Inspect Kconfig files and #ifdef guards; do not make assumptions.
- Check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed.
- Strip any 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
Target architecture: amd64

For your convenience, here is the diff of the changes:
commit f9f8ce30187cb82d1fa215d85e4c819431376082
Author: syz-cluster <triage@syzkaller.com>
Date:   Tue Nov 3 18:31:15 2026 +0000

    syz-cluster: applied patch under review

diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index f3ecdd8601a042..f9285ff081fc01 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -555,7 +555,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
 void ieee80211_refresh_tx_agg_session_timer(struct ieee80211_sta *pubsta,
 					    u16 tid)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	struct tid_ampdu_tx *tid_tx;
 
 	if (WARN_ON_ONCE(tid >= IEEE80211_NUM_TIDS))
@@ -600,7 +600,7 @@ static void sta_tx_agg_session_timer_expired(struct timer_list *t)
 int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
 				  u16 timeout)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
 	struct ieee80211_local *local = sdata->local;
 	struct tid_ampdu_tx *tid_tx;
@@ -868,7 +868,7 @@ EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
 
 int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
 	struct ieee80211_local *local = sdata->local;
 	struct tid_ampdu_tx *tid_tx;
diff --git a/net/mac80211/airtime.c b/net/mac80211/airtime.c
index a4e1f33c037797..53a455b6425fb6 100644
--- a/net/mac80211/airtime.c
+++ b/net/mac80211/airtime.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: ISC
 /*
  * Copyright (C) 2019 Felix Fietkau <nbd@nbd.name>
- * Copyright (C) 2021-2022 Intel Corporation
+ * Copyright (C) 2021-2022, 2026 Intel Corporation
  */
 
 #include <net/mac80211.h>
@@ -838,8 +838,7 @@ u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw,
 		band = conf->def.chan->band;
 
 	if (pubsta) {
-		struct sta_info *sta = container_of(pubsta, struct sta_info,
-						    sta);
+		struct sta_info *sta = sta_from_pub(pubsta);
 		struct ieee80211_tx_rate *tx_rate = &sta->deflink.tx_stats.last_rate;
 		struct rate_info *ri = &sta->deflink.tx_stats.last_rate_info;
 		u32 duration;
diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c
index 1f3e0765a8ab2e..12ea71036e4a08 100644
--- a/net/mac80211/driver-ops.c
+++ b/net/mac80211/driver-ops.c
@@ -583,7 +583,7 @@ int drv_change_sta_links(struct ieee80211_local *local,
 			 struct ieee80211_sta *sta,
 			 u16 old_links, u16 new_links)
 {
-	struct sta_info *info = container_of(sta, struct sta_info, sta);
+	struct sta_info *info = sta_from_pub(sta);
 	struct link_sta_info *link_sta;
 	unsigned long links_to_add;
 	unsigned long links_to_rem;
diff --git a/net/mac80211/he.c b/net/mac80211/he.c
index 5acf482c177a7e..0278892ae91f38 100644
--- a/net/mac80211/he.c
+++ b/net/mac80211/he.c
@@ -265,8 +265,7 @@ ieee80211_he_spr_ie_to_bss_conf(struct ieee80211_vif *vif,
 bool ieee80211_prepare_rx_omi_bw(struct ieee80211_link_sta *pub_link_sta,
 				 enum ieee80211_sta_rx_bandwidth bw)
 {
-	struct sta_info *sta = container_of(pub_link_sta->sta,
-					    struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pub_link_sta->sta);
 	struct ieee80211_local *local = sta->sdata->local;
 	struct link_sta_info *link_sta =
 		sdata_dereference(sta->link[pub_link_sta->link_id], sta->sdata);
@@ -318,8 +317,7 @@ EXPORT_SYMBOL_GPL(ieee80211_prepare_rx_omi_bw);
 
 void ieee80211_finalize_rx_omi_bw(struct ieee80211_link_sta *pub_link_sta)
 {
-	struct sta_info *sta = container_of(pub_link_sta->sta,
-					    struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pub_link_sta->sta);
 	struct ieee80211_local *local = sta->sdata->local;
 	struct link_sta_info *link_sta =
 		sdata_dereference(sta->link[pub_link_sta->link_id], sta->sdata);
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 10e6ad53726140..d74413fdaf0675 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -88,7 +88,7 @@ void rate_control_tx_status(struct ieee80211_local *local,
 			    struct ieee80211_tx_status *st)
 {
 	struct rate_control_ref *ref = local->rate_ctrl;
-	struct sta_info *sta = container_of(st->sta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(st->sta);
 	void *priv_sta = sta->rate_ctrl_priv;
 	struct ieee80211_supported_band *sband;
 
@@ -442,7 +442,7 @@ static bool rate_control_send_low(struct ieee80211_sta *pubsta,
 			}
 			use_basicrate = true;
 		} else if (pubsta) {
-			sta = container_of(pubsta, struct sta_info, sta);
+			sta = sta_from_pub(pubsta);
 			if (ieee80211_vif_is_mesh(&sta->sdata->vif))
 				use_basicrate = true;
 		}
@@ -970,7 +970,7 @@ int rate_control_set_rates(struct ieee80211_hw *hw,
 			   struct ieee80211_sta *pubsta,
 			   struct ieee80211_sta_rates *rates)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	struct ieee80211_sta_rates *old;
 	struct ieee80211_supported_band *sband;
 
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 45e7a7ea769008..d46b6780bfdb3a 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (C) 2010-2013 Felix Fietkau <nbd@openwrt.org>
- * Copyright (C) 2019-2022 Intel Corporation
+ * Copyright (C) 2019-2022, 2026 Intel Corporation
  */
 #include <linux/netdevice.h>
 #include <linux/types.h>
@@ -1865,7 +1865,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
 				vht_cap->vht_mcs.tx_mcs_map);
 	}
 
-	sta_info = container_of(sta, struct sta_info, sta);
+	sta_info = sta_from_pub(sta);
 	mi->use_short_preamble = test_sta_flag(sta_info, WLAN_STA_SHORT_PREAMBLE) &&
 				 sta_info->sdata->vif.bss_conf.use_short_preamble;
 
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index ee1f33178d2670..acf1188ff42688 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1724,7 +1724,7 @@ static void sta_ps_end(struct sta_info *sta)
 
 void ieee80211_sta_ps_transition(struct ieee80211_sta *pubsta, bool start)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	bool in_ps;
 
 	WARN_ON(!ieee80211_hw_check(&sta->local->hw, AP_LINK_PS));
@@ -1743,7 +1743,7 @@ EXPORT_SYMBOL(ieee80211_sta_ps_transition);
 
 void ieee80211_sta_pspoll(struct ieee80211_sta *pubsta)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 
 	if (test_sta_flag(sta, WLAN_STA_SP))
 		return;
@@ -1757,7 +1757,7 @@ EXPORT_SYMBOL(ieee80211_sta_pspoll);
 
 void ieee80211_sta_uapsd_trigger(struct ieee80211_sta *pubsta, u8 tid)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	int ac = ieee80211_ac_from_tid(tid);
 
 	/*
@@ -4439,7 +4439,7 @@ void ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *pubsta, u8 tid,
 
 	__skb_queue_head_init(&frames);
 
-	sta = container_of(pubsta, struct sta_info, sta);
+	sta = sta_from_pub(pubsta);
 
 	local = sta->sdata->local;
 	WARN_ONCE(local->hw.max_rx_aggregation_subframes > 64,
@@ -5289,7 +5289,7 @@ static void __ieee80211_rx_handle_8023(struct ieee80211_hw *hw,
 	if (!link_pubsta)
 		goto drop;
 
-	sta = container_of(link_pubsta->sta, struct sta_info, sta);
+	sta = sta_from_pub(link_pubsta->sta);
 	if (sta->sta.valid_links)
 		link_id = link_pubsta->link_id;
 	if (!ieee80211_rx_data_set_sta(&rx, sta, link_id))
@@ -5398,8 +5398,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
 	 */
 	if (ieee80211_is_data(fc)) {
 		if (link_pubsta) {
-			sta = container_of(link_pubsta->sta, struct sta_info,
-					   sta);
+			sta = sta_from_pub(link_pubsta->sta);
 			link_sta = rcu_dereference(sta->link[link_pubsta->link_id]);
 
 			rx.sdata = sta->sdata;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 23166fc3972913..6e9c06f3e4db5e 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -2349,7 +2349,7 @@ void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta)
 void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
 			       struct ieee80211_sta *pubsta, bool block)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 
 	trace_api_sta_block_awake(sta->local, pubsta, block);
 
@@ -2380,7 +2380,7 @@ EXPORT_SYMBOL(ieee80211_sta_block_awake);
 
 void ieee80211_sta_eosp(struct ieee80211_sta *pubsta)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	struct ieee80211_local *local = sta->local;
 
 	trace_api_eosp(local, pubsta);
@@ -2391,7 +2391,7 @@ EXPORT_SYMBOL(ieee80211_sta_eosp);
 
 void ieee80211_send_eosp_nullfunc(struct ieee80211_sta *pubsta, int tid)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	enum ieee80211_frame_release_type reason;
 	bool more_data;
 
@@ -2408,7 +2408,7 @@ EXPORT_SYMBOL(ieee80211_send_eosp_nullfunc);
 void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta,
 				u8 tid, bool buffered)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 
 	if (WARN_ON(tid >= IEEE80211_NUM_TIDS))
 		return;
@@ -2427,7 +2427,7 @@ EXPORT_SYMBOL(ieee80211_sta_set_buffered);
 void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,
 				    u32 tx_airtime, u32 rx_airtime)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	struct ieee80211_local *local = sta->sdata->local;
 	u8 ac = ieee80211_ac_from_tid(tid);
 	u32 airtime = 0;
@@ -2495,7 +2495,7 @@ void __ieee80211_sta_recalc_aggregates(struct sta_info *sta, u16 active_links)
 
 void ieee80211_sta_recalc_aggregates(struct ieee80211_sta *pubsta)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 
 	__ieee80211_sta_recalc_aggregates(sta, sta->sdata->vif.active_links);
 }
@@ -3683,7 +3683,7 @@ void ieee80211_sta_set_max_amsdu_subframes(struct sta_info *sta,
 #ifdef CONFIG_LOCKDEP
 bool lockdep_sta_mutex_held(struct ieee80211_sta *pubsta)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 
 	return lockdep_is_held(&sta->local->hw.wiphy->mtx);
 }
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 8c6a9fee6b29b0..0e8f7794fd01b7 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -793,6 +793,11 @@ struct sta_info {
 	struct ieee80211_sta sta;
 };
 
+static inline struct sta_info *sta_from_pub(struct ieee80211_sta *sta)
+{
+	return container_of(sta, struct sta_info, sta);
+}
+
 static inline int ieee80211_tdls_sta_link_id(struct sta_info *sta)
 {
 	/* TDLS STA can only have a single link */
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 414979e2a1d930..5d1807ab46ef5c 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -1013,7 +1013,7 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw,
 	fc = hdr->frame_control;
 
 	if (status->sta) {
-		sta = container_of(status->sta, struct sta_info, sta);
+		sta = sta_from_pub(status->sta);
 
 		if (info->flags & IEEE80211_TX_STATUS_EOSP)
 			clear_sta_flag(sta, WLAN_STA_SP);
@@ -1246,7 +1246,7 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
 	ieee80211_tx_status_drop_invalid_rates(status);
 
 	if (pubsta) {
-		sta = container_of(pubsta, struct sta_info, sta);
+		sta = sta_from_pub(pubsta);
 
 		if (status->n_rates)
 			sta->deflink.tx_stats.last_rate_info =
@@ -1363,7 +1363,7 @@ void ieee80211_tx_rate_update(struct ieee80211_hw *hw,
 			      struct ieee80211_tx_info *info)
 {
 	struct ieee80211_local *local = hw_to_local(hw);
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	struct ieee80211_tx_status status = {
 		.info = info,
 		.sta = pubsta,
@@ -1379,7 +1379,7 @@ EXPORT_SYMBOL(ieee80211_tx_rate_update);
 
 void ieee80211_report_low_ack(struct ieee80211_sta *pubsta, u32 num_packets)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	cfg80211_cqm_pktloss_notify(sta->sdata->dev, sta->sta.addr,
 				    num_packets, GFP_ATOMIC);
 }
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e9b6a0415d6a94..22335ea362aa7d 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -4031,7 +4031,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
 	tx.sdata = vif_to_sdata(info->control.vif);
 
 	if (txq->sta) {
-		tx.sta = container_of(txq->sta, struct sta_info, sta);
+		tx.sta = sta_from_pub(txq->sta);
 
 		if (unlikely(ieee80211_drop_unauth_port(&tx))) {
 			I802_DEBUG_INC(local->tx_handlers_drop_unauth_port);
@@ -4067,8 +4067,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
 	}
 
 	if (info->control.flags & IEEE80211_TX_CTRL_FAST_XMIT) {
-		struct sta_info *sta = container_of(txq->sta, struct sta_info,
-						    sta);
+		struct sta_info *sta = sta_from_pub(txq->sta);
 		u8 pn_offs = 0;
 
 		if (tx.key &&
@@ -4176,7 +4175,7 @@ ieee80211_txq_set_active(struct txq_info *txqi)
 	if (!txqi->txq.sta)
 		return;
 
-	sta = container_of(txqi->txq.sta, struct sta_info, sta);
+	sta = sta_from_pub(txqi->txq.sta);
 	sta->airtime[txqi->txq.ac].last_active = jiffies;
 }
 
@@ -4188,7 +4187,7 @@ ieee80211_txq_keep_active(struct txq_info *txqi)
 	if (!txqi->txq.sta)
 		return false;
 
-	sta = container_of(txqi->txq.sta, struct sta_info, sta);
+	sta = sta_from_pub(txqi->txq.sta);
 	if (ieee80211_sta_deficit(sta, txqi->txq.ac) >= 0)
 		return false;
 
@@ -4230,8 +4229,7 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)
 		found_eligible_txq = true;
 
 	if (txqi->txq.sta) {
-		struct sta_info *sta = container_of(txqi->txq.sta,
-						    struct sta_info, sta);
+		struct sta_info *sta = sta_from_pub(txqi->txq.sta);
 
 		if (ieee80211_sta_deficit(sta, txqi->txq.ac) < 0) {
 			sta->airtime[txqi->txq.ac].deficit +=
@@ -4319,7 +4317,7 @@ bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw,
 	if (unlikely(txq->tid == IEEE80211_NUM_TIDS))
 		return true;
 
-	sta = container_of(txq->sta, struct sta_info, sta);
+	sta = sta_from_pub(txq->sta);
 	if (atomic_read(&sta->airtime[txq->ac].aql_tx_pending) <
 	    sta->airtime[txq->ac].aql_limit_low)
 		return true;
@@ -4346,7 +4344,7 @@ u32 ieee80211_txq_aql_pending(struct ieee80211_hw *hw,
 	if (!txq->sta)
 		return atomic_read(&local->aql_mc_pending_airtime);
 
-	sta = container_of(txq->sta, struct sta_info, sta);
+	sta = sta_from_pub(txq->sta);
 
 	return atomic_read(&sta->airtime[txq->ac].aql_tx_pending);
 }
@@ -4400,13 +4398,13 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
 				       &local->active_txqs[ac]);
 			continue;
 		}
-		sta = container_of(iter->txq.sta, struct sta_info, sta);
+		sta = sta_from_pub(iter->txq.sta);
 		if (ieee80211_sta_deficit(sta, ac) < 0)
 			sta->airtime[ac].deficit += sta->airtime_weight;
 		list_move_tail(&iter->schedule_order, &local->active_txqs[ac]);
 	}
 
-	sta = container_of(txqi->txq.sta, struct sta_info, sta);
+	sta = sta_from_pub(txqi->txq.sta);
 	if (sta->airtime[ac].deficit >= 0)
 		goto out;
 
@@ -6446,7 +6444,7 @@ EXPORT_SYMBOL(ieee80211_get_buffered_bc);
 
 int ieee80211_reserve_tid(struct ieee80211_sta *pubsta, u8 tid)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
 	struct ieee80211_local *local = sdata->local;
 	int ret;
@@ -6510,7 +6508,7 @@ EXPORT_SYMBOL(ieee80211_reserve_tid);
 
 void ieee80211_unreserve_tid(struct ieee80211_sta *pubsta, u8 tid)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
 
 	lockdep_assert_wiphy(sdata->local->hw.wiphy);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 44feb80274c61c..2706f6a5a8fbbe 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -904,7 +904,7 @@ __ieee80211_iterate_stations(struct ieee80211_hw *hw,
 	lockdep_assert_wiphy(local->hw.wiphy);
 
 	if (prev)
-		sta = container_of(prev, struct sta_info, sta);
+		sta = sta_from_pub(prev);
 
 	sta = list_prepare_entry(sta, &local->sta_list, list);
 	list_for_each_entry_continue(sta, &local->sta_list, list) {

3/2 2026/11/03 18:31 llm patch-evaluator
4m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 10901
							output: 34
							thoughts: 1423
						

Thoughts:
**Patch Analysis: mac80211 Refactor - Worthy of Fuzzing**

Okay, let's break this down. It looks like we have a patch introducing a helper function, `sta_from_pub`, to replace direct use of `container_of` within the `net/mac80211` subsystem. The diff clearly shows the introduction of the inline function and the subsequent replacement of instances of `container_of(pubsta, struct sta_info, sta)` with `sta_from_pub(pubsta)` across multiple files, including `agg-tx.c`, `sta_info.h`, and several others within mac80211.

Initially, my thought was, "Purely syntactic refactoring, probably a no-op." However, I need to be *very* cautious and follow the guidelines. I can't just take the "refactoring" label at face value. The instructions are clear: even seemingly benign refactors can introduce subtle bugs. My expert instinct tells me to dig deeper.

So, `sta_from_pub` is literally a `container_of`. The crucial point is whether the *reachability* of modified code. I need to ask myself whether the change affects code execution paths. The code *is* modified, and it's within a core subsystem.

The key question: Does this fall under the "WorthFuzzing=true" criteria? Section 3 states "WorthFuzzing=true whenever the patch touches reachable executable code" and lists "Refactorings and Code Cleanups... Any restructuring of reachable data structures, helper abstractions, or algorithm flows." This is exactly what we have here. Also, Section 3 includes "Core Subsystems" in general, and networking fits that!

The final piece of the puzzle is mac80211's reachability. And the answer is YES! mac80211 is a core wireless networking stack, and it's readily accessible via virtual buses like nl80211. In fact, `mac80211_hwsim` is a key target for fuzzing. Thus this is executable code, and therefore worth fuzzing. I can verify this is a refactor and not a functional change, but must treat this as executable and requiring fuzzing because it is refactoring a core subsystem.

Therefore, despite the apparent simplicity, this change warrants fuzzing. I'll need to double check the git log and associated context just to be thorough and look for any other hidden details, or commits that might give more info.



4/2 2026/11/03 18:35 tool grepper
0m Args:
{
  "Expression": "sta_from_pub",
  "PathPrefixes": [
    "net/mac80211"
  ]
}

Results:
{
  "Output": "\nFull output is too long, showing 200 out of 229 lines.\nUse more precise expression or PathPrefixes if possible.\n\nNumber of matching lines per file (12 files in total):\nnet/mac80211/agg-tx.c:3\nnet/mac80211/airtime.c:1\nnet/mac80211/driver-ops.c:1\nnet/mac80211/he.c:2\nnet/mac80211/rate.c:3\nnet/mac80211/rc80211_minstrel_ht.c:1\nnet/mac80211/rx.c:6\nnet/mac80211/sta_info.c:7\nnet/mac80211/sta_info.h:1\nnet/mac80211/status.c:4\nnet/mac80211/tx.c:11\nnet/mac80211/util.c:1\n\nnet/mac80211/agg-tx.c=555=void ieee80211_refresh_tx_agg_session_timer(struct ieee80211_sta *pubsta,\n--\nnet/mac80211/agg-tx.c-557-{\nnet/mac80211/agg-tx.c:558:\tstruct sta_info *sta = sta_from_pub(pubsta);\nnet/mac80211/agg-tx.c-559-\tstruct tid_ampdu_tx *tid_tx;\n--\nnet/mac80211/agg-tx.c=600=int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,\n--\nnet/mac80211/agg-tx.c-602-{\nnet/mac80211/agg-tx.c:603:\tstruct sta_info *sta = sta_from_pub(pubsta);\nnet/mac80211/agg-tx.c-604-\tstruct ieee80211_sub_if_data *sdata = sta-\u003esdata;\n--\nnet/mac80211/agg-tx.c=869=int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)\nnet/mac80211/agg-tx.c-870-{\nnet/mac80211/agg-tx.c:871:\tstruct sta_info *sta = sta_from_pub(pubsta);\nnet/mac80211/agg-tx.c-872-\tstruct ieee80211_sub_if_data *sdata = sta-\u003esdata;\n--\nnet/mac80211/airtime.c=821=u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw,\n--\nnet/mac80211/airtime.c-840-\tif (pubsta) {\nnet/mac80211/airtime.c:841:\t\tstruct sta_info *sta = sta_from_pub(pubsta);\nnet/mac80211/airtime.c-842-\t\tstruct ieee80211_tx_rate *tx_rate = \u0026sta-\u003edeflink.tx_stats.last_rate;\n--\nnet/mac80211/driver-ops.c=581=int drv_change_sta_links(struct ieee80211_local *local,\n--\nnet/mac80211/driver-ops.c-585-{\nnet/mac80211/driver-ops.c:586:\tstruct sta_info *info = sta_from_pub(sta);\nnet/mac80211/driver-ops.c-587-\tstruct link_sta_info *link_sta;\n--\nnet/mac80211/he.c=265=bool ieee80211_prepare_rx_omi_bw(struct ieee80211_link_sta *pub_link_sta,\n--\nnet/mac80211/he.c-267-{\nnet/mac80211/he.c:268:\tstruct sta_info *sta = sta_from_pub(pub_link_sta-\u003esta);\nnet/mac80211/he.c-269-\tstruct ieee80211_local *local = sta-\u003esdata-\u003elocal;\n--\nnet/mac80211/he.c=318=void ieee80211_finalize_rx_omi_bw(struct ieee80211_link_sta *pub_link_sta)\nnet/mac80211/he.c-319-{\nnet/mac80211/he.c:320:\tstruct sta_info *sta = sta_from_pub(pub_link_sta-\u003esta);\nnet/mac80211/he.c-321-\tstruct ieee80211_local *local = sta-\u003esdata-\u003elocal;\n--\nnet/mac80211/rate.c=87=void rate_control_tx_status(struct ieee80211_local *local,\n--\nnet/mac80211/rate.c-90-\tstruct rate_control_ref *ref = local-\u003erate_ctrl;\nnet/mac80211/rate.c:91:\tstruct sta_info *sta = sta_from_pub(st-\u003esta);\nnet/mac80211/rate.c-92-\tvoid *priv_sta = sta-\u003erate_ctrl_priv;\n--\nnet/mac80211/rate.c=421=static bool rate_control_send_low(struct ieee80211_sta *pubsta,\n--\nnet/mac80211/rate.c-444-\t\t} else if (pubsta) {\nnet/mac80211/rate.c:445:\t\t\tsta = sta_from_pub(pubsta);\nnet/mac80211/rate.c-446-\t\t\tif (ieee80211_vif_is_mesh(\u0026sta-\u003esdata-\u003evif))\n--\nnet/mac80211/rate.c=969=int rate_control_set_rates(struct ieee80211_hw *hw,\n--\nnet/mac80211/rate.c-972-{\nnet/mac80211/rate.c:973:\tstruct sta_info *sta = sta_from_pub(pubsta);\nnet/mac80211/rate.c-974-\tstruct ieee80211_sta_rates *old;\n--\nnet/mac80211/rc80211_minstrel_ht.c=1746=minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,\n--\nnet/mac80211/rc80211_minstrel_ht.c-1867-\nnet/mac80211/rc80211_minstrel_ht.c:1868:\tsta_info = sta_from_pub(sta);\nnet/mac80211/rc80211_minstrel_ht.c-1869-\tmi-\u003euse_short_preamble = test_sta_flag(sta_info, WLAN_STA_SHORT_PREAMBLE) \u0026\u0026\n--\nnet/mac80211/rx.c=1725=void ieee80211_sta_ps_transition(struct ieee80211_sta *pubsta, bool start)\nnet/mac80211/rx.c-1726-{\nnet/mac80211/rx.c:1727:\tstruct sta_info *sta = sta_from_pub(pubsta);\nnet/mac80211/rx.c-1728-\tbool in_ps;\n--\nnet/mac80211/rx.c=1744=void ieee80211_sta_pspoll(struct ieee80211_sta *pubsta)\nnet/mac80211/rx.c-1745-{\nnet/mac80211/rx.c:1746:\tstruct sta_info *sta = sta_from_pub(pubsta);\nnet/mac80211/rx.c-1747-\n--\nnet/mac80211/rx.c=1758=void ieee80211_sta_uapsd_trigger(struct ieee80211_sta *pubsta, u8 tid)\nnet/mac80211/rx.c-1759-{\nnet/mac80211/rx.c:1760:\tstruct sta_info *sta = sta_from_pub(pubsta);\nnet/mac80211/rx.c-1761-\tint ac = ieee80211_ac_from_tid(tid);\n--\nnet/mac80211/rx.c=4422=void ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *pubsta, u8 tid,\n--\nnet/mac80211/rx.c-4441-\nnet/mac80211/rx.c:4442:\tsta = sta_from_pub(pubsta);\nnet/mac80211/rx.c-4443-\n--\nnet/mac80211/rx.c=5267=static void __ieee80211_rx_handle_8023(struct ieee80211_hw *hw,\n--\nnet/mac80211/rx.c-5291-\nnet/mac80211/rx.c:5292:\tsta = sta_from_pub(link_pubsta-\u003esta);\nnet/mac80211/rx.c-5293-\tif (sta-\u003esta.valid_links)\n--\nnet/mac80211/rx.c=5330=static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,\n--\nnet/mac80211/rx.c-5400-\t\tif (link_pubsta) {\nnet/mac80211/rx.c:5401:\t\t\tsta = sta_from_pub(link_pubsta-\u003esta);\nnet/mac80211/rx.c-5402-\t\t\tlink_sta = rcu_dereference(sta-\u003elink[link_pubsta-\u003elink_id]);\n--\nnet/mac80211/sta_info.c=2349=void ieee80211_sta_block_awake(struct ieee80211_hw *hw,\n--\nnet/mac80211/sta_info.c-2351-{\nnet/mac80211/sta_info.c:2352:\tstruct sta_info *sta = sta_from_pub(pubsta);\nnet/mac80211/sta_info.c-2353-\n--\nnet/mac80211/sta_info.c=2381=void ieee80211_sta_eosp(struct ieee80211_sta *pubsta)\nnet/mac80211/sta_info.c-2382-{\nnet/mac80211/sta_info.c:2383:\tstruct sta_info *sta = sta_from_pub(pubsta);\nnet/mac80211/sta_info.c-2384-\tstruct ieee80211_local *local = sta-\u003elocal;\n--\nnet/mac80211/sta_info.c=2392=void ieee80211_send_eosp_nullfunc(struct ieee80211_sta *pubsta, int tid)\nnet/mac80211/sta_info.c-2393-{\nnet/mac80211/sta_info.c:2394:\tstruct sta_info *sta = sta_from_pub(pubsta);\nnet/mac80211/sta_info.c-2395-\tenum ieee80211_frame_release_type reason;\n--\nnet/mac80211/sta_info.c=2408=void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta,\n--\nnet/mac80211/sta_info.c-2410-{\nnet/mac80211/sta_info.c:2411:\tstruct sta_info *sta = sta_from_pub(pubsta);\nnet/mac80211/sta_info.c-2412-\n--\nnet/mac80211/sta_info.c=2427=void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,\n--\nnet/mac80211/sta_info.c-2429-{\nnet/mac80211/sta_info.c:2430:\tstruct sta_info *sta = sta_from_pub(pubsta);\nnet/mac80211/sta_info.c-2431-\tstruct ieee80211_local *local = sta-\u003esdata-\u003elocal;\n--\nnet/mac80211/sta_info.c=2496=void ieee80211_sta_recalc_aggregates(struct ieee80211_sta *pubsta)\nnet/mac80211/sta_info.c-2497-{\nnet/mac80211/sta_info.c:2498:\tstruct sta_info *sta = sta_from_pub(pubsta);\nnet/mac80211/sta_info.c-2499-\n--\nnet/mac80211/sta_info.c=3684=bool lockdep_sta_mutex_held(struct ieee80211_sta *pubsta)\nnet/mac80211/sta_info.c-3685-{\nnet/mac80211/sta_info.c:3686:\tstruct sta_info *sta = sta_from_pub(pubsta);\nnet/mac80211/sta_info.c-3687-\n--\nnet/mac80211/sta_info.h=717=struct sta_info {\n--\nnet/mac80211/sta_info.h-795-\nnet/mac80211/sta_info.h:796:static inline struct sta_info *sta_from_pub(struct ieee80211_sta *sta)\nnet/mac80211/sta_info.h-797-{\n--\nnet/mac80211/status.c=998=static void __ieee80211_tx_status(struct ieee80211_hw *hw,\n--\nnet/mac80211/status.c-1015-\tif (status-\u003esta) {\nnet/mac80211/status.c:1016:\t\tsta = sta_from_pub(status-\u003esta);\nnet/mac80211/status.c-1017-\n--\nnet/mac80211/status.c=1234=void ieee80211_tx_status_ext(struct ieee80211_hw *hw,\n--\nnet/mac80211/status.c-1248-\tif (pubsta) {\nnet/mac80211/status.c:1249:\t\tsta = sta_from_pub(pubsta);\nnet/mac80211/status.c-1250-\n--\nnet/mac80211/status.c=1361=void ieee80211_tx_rate_update(struct ieee80211_hw *hw,\n--\nnet/mac80211/status.c-1365-\tstruct ieee80211_local *local = hw_to_local(hw);\nnet/mac80211/status.c:1366:\tstruct sta_info *sta = sta_from_pub(pubsta);\nnet/mac80211/status.c-1367-\tstruct ieee80211_tx_status status = {\n--\nnet/mac80211/status.c=1380=void ieee80211_report_low_ack(struct ieee80211_sta *pubsta, u32 num_packets)\nnet/mac80211/status.c-1381-{\nnet/mac80211/status.c:1382:\tstruct sta_info *sta = sta_from_pub(pubsta);\nnet/mac80211/status.c-1383-\tcfg80211_cqm_pktloss_notify(sta-\u003esdata-\u003edev, sta-\u003esta.addr,\n--\nnet/mac80211/tx.c=3969=struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,\n--\nnet/mac80211/tx.c-4033-\tif (txq-\u003esta) {\nnet/mac80211/tx.c:4034:\t\ttx.sta = sta_from_pub(txq-\u003esta);\nnet/mac80211/tx.c-4035-\n--\nnet/mac80211/tx.c-4069-\tif (info-\u003econtrol.flags \u0026 IEEE80211_TX_CTRL_FAST_XMIT) {\nnet/mac80211/tx.c:4070:\t\tstruct sta_info *sta = sta_from_pub(txq-\u003esta);\nnet/mac80211/tx.c-4071-\t\tu8 pn_offs = 0;\n--\nnet/mac80211/tx.c=4171=ieee80211_txq_set_active(struct txq_info *txqi)\n--\nnet/mac80211/tx.c-4177-\nnet/mac80211/tx.c:4178:\tsta = sta_from_pub(txqi-\u003etxq.sta);\nnet/mac80211/tx.c-4179-\tsta-\u003eairtime[txqi-\u003etxq.ac].last_active = jiffies;\n--\nnet/mac80211/tx.c=4183=ieee80211_txq_keep_active(struct txq_info *txqi)\n--\nnet/mac80211/tx.c-4189-\nnet/mac80211/tx.c:4190:\tsta = sta_from_pub(txqi-\u003etxq.sta);\nnet/mac80211/tx.c-4191-\tif (ieee80211_sta_deficit(sta, txqi-\u003etxq.ac) \u003e= 0)\n--\nnet/mac80211/tx.c=4197=struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)\n--\nnet/mac80211/tx.c-4231-\tif (txqi-\u003etxq.sta) {\nnet/mac80211/tx.c:4232:\t\tstruct sta_info *sta = sta_from_pub(txqi-\u003etxq.sta);\nnet/mac80211/tx.c-4233-\n--\nnet/mac80211/tx.c=4301=bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw,\n--\nnet/mac80211/tx.c-4319-\nnet/mac80211/tx.c:4320:\tsta = sta_from_pub(txq-\u003esta);\nnet/mac80211/tx.c-4321-\tif (atomic_read(\u0026sta-\u003eairtime[txq-\u003eac].aql_tx_pending) \u003c\n--\nnet/mac80211/tx.c=4335=u32 ieee80211_txq_aql_pending(struct ieee80211_hw *hw,\n--\n\n"
}

5/2 2026/11/03 18:35 llm patch-evaluator
5m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 18271
							output: 53
							thoughts: 22
						

Thoughts:
Here's my take on those files.

**Remaining Matches in tx.c and util.c**

Alright, let's take a quick look through `tx.c` and `util.c` and get a handle on what those remaining matches are. I'm just curious to see what we're dealing with, if any of the outstanding items look urgent or if they are simple refactors or optimizations. Context is key, so I'm hoping this quick scan will help me understand the overall state of things better and prioritize accordingly. I'm especially interested to see if there are any obvious discrepancies, performance bottlenecks, or potential security vulnerabilities I can spot with a fresh pair of eyes. Time to dive in!



6/2 2026/11/03 18:40 tool grepper
0m Args:
{
  "Expression": "sta_from_pub",
  "PathPrefixes": [
    "net/mac80211/tx.c",
    "net/mac80211/util.c"
  ]
}

Results:
{
  "Output": "net/mac80211/tx.c=3969=struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,\n--\nnet/mac80211/tx.c-4033-\tif (txq-\u003esta) {\nnet/mac80211/tx.c:4034:\t\ttx.sta = sta_from_pub(txq-\u003esta);\nnet/mac80211/tx.c-4035-\n--\nnet/mac80211/tx.c-4069-\tif (info-\u003econtrol.flags \u0026 IEEE80211_TX_CTRL_FAST_XMIT) {\nnet/mac80211/tx.c:4070:\t\tstruct sta_info *sta = sta_from_pub(txq-\u003esta);\nnet/mac80211/tx.c-4071-\t\tu8 pn_offs = 0;\n--\nnet/mac80211/tx.c=4171=ieee80211_txq_set_active(struct txq_info *txqi)\n--\nnet/mac80211/tx.c-4177-\nnet/mac80211/tx.c:4178:\tsta = sta_from_pub(txqi-\u003etxq.sta);\nnet/mac80211/tx.c-4179-\tsta-\u003eairtime[txqi-\u003etxq.ac].last_active = jiffies;\n--\nnet/mac80211/tx.c=4183=ieee80211_txq_keep_active(struct txq_info *txqi)\n--\nnet/mac80211/tx.c-4189-\nnet/mac80211/tx.c:4190:\tsta = sta_from_pub(txqi-\u003etxq.sta);\nnet/mac80211/tx.c-4191-\tif (ieee80211_sta_deficit(sta, txqi-\u003etxq.ac) \u003e= 0)\n--\nnet/mac80211/tx.c=4197=struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)\n--\nnet/mac80211/tx.c-4231-\tif (txqi-\u003etxq.sta) {\nnet/mac80211/tx.c:4232:\t\tstruct sta_info *sta = sta_from_pub(txqi-\u003etxq.sta);\nnet/mac80211/tx.c-4233-\n--\nnet/mac80211/tx.c=4301=bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw,\n--\nnet/mac80211/tx.c-4319-\nnet/mac80211/tx.c:4320:\tsta = sta_from_pub(txq-\u003esta);\nnet/mac80211/tx.c-4321-\tif (atomic_read(\u0026sta-\u003eairtime[txq-\u003eac].aql_tx_pending) \u003c\n--\nnet/mac80211/tx.c=4335=u32 ieee80211_txq_aql_pending(struct ieee80211_hw *hw,\n--\nnet/mac80211/tx.c-4346-\nnet/mac80211/tx.c:4347:\tsta = sta_from_pub(txq-\u003esta);\nnet/mac80211/tx.c-4348-\n--\nnet/mac80211/tx.c=4372=bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,\n--\nnet/mac80211/tx.c-4400-\t\t}\nnet/mac80211/tx.c:4401:\t\tsta = sta_from_pub(iter-\u003etxq.sta);\nnet/mac80211/tx.c-4402-\t\tif (ieee80211_sta_deficit(sta, ac) \u003c 0)\n--\nnet/mac80211/tx.c-4406-\nnet/mac80211/tx.c:4407:\tsta = sta_from_pub(txqi-\u003etxq.sta);\nnet/mac80211/tx.c-4408-\tif (sta-\u003eairtime[ac].deficit \u003e= 0)\n--\nnet/mac80211/tx.c=6445=int ieee80211_reserve_tid(struct ieee80211_sta *pubsta, u8 tid)\nnet/mac80211/tx.c-6446-{\nnet/mac80211/tx.c:6447:\tstruct sta_info *sta = sta_from_pub(pubsta);\nnet/mac80211/tx.c-6448-\tstruct ieee80211_sub_if_data *sdata = sta-\u003esdata;\n--\nnet/mac80211/tx.c=6509=void ieee80211_unreserve_tid(struct ieee80211_sta *pubsta, u8 tid)\nnet/mac80211/tx.c-6510-{\nnet/mac80211/tx.c:6511:\tstruct sta_info *sta = sta_from_pub(pubsta);\nnet/mac80211/tx.c-6512-\tstruct ieee80211_sub_if_data *sdata = sta-\u003esdata;\n--\nnet/mac80211/util.c=898=__ieee80211_iterate_stations(struct ieee80211_hw *hw,\n--\nnet/mac80211/util.c-906-\tif (prev)\nnet/mac80211/util.c:907:\t\tsta = sta_from_pub(prev);\nnet/mac80211/util.c-908-\n"
}

7/2 2026/11/03 18:40 llm patch-evaluator
1m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 20139
							output: 42
							thoughts: 317
						

Thoughts:
**Analyzing This Commit**

Okay, first things first, let's understand what this commit is doing. The commit message itself might be informative, but since I only have `grepper` and `read-file` available, let's try a quick inspection. I wonder if I can use those to simulate a `git log -1`? No, forget that, how about we just go straight to the code.

Alright, the code changes look straightforward. It seems they've introduced a new inline function, `sta_from_pub`. It's a simple macro replacement, effectively substituting instances of `container_of(sta, struct sta_info, sta)` with `sta_from_pub(sta)`. Clever, but I need to understand *why*. Let's see if there's anything else in this patch to give clues.

Hang on... there are copyright notice updates in `airtime.c` and `rc80211_minstrel_ht.c`. Interesting. The copyright now includes 2026. This doesn't seem directly related to the `sta_from_pub` change, but it's worth noting.

Back to the primary question: why the `sta_from_pub` function? To understand the motivation behind this change, I should probably check `net/mac80211/sta_info.h` to see how `sta` is used around line 793. Are they trying to improve readability? Optimization? Avoiding potential issues with the `container_of` macro? I'll bet it's something around those lines.



8/2 2026/11/03 18:41 tool read-file
0m Args:
{
  "File": "net/mac80211/sta_info.h",
  "FirstLine": 785,
  "LineCount": 30
}

Results:
{
  "Contents": " 785:\t\tstruct ieee80211_fragment_cache frags;\n 786:\t\n 787:\t\tstruct ieee80211_sta_aggregates cur;\n 788:\t\tstruct link_sta_info deflink;\n 789:\t\tstruct link_sta_info __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS];\n 790:\t\tstruct ieee80211_sta_removed_link_stats rem_link_stats;\n 791:\t\n 792:\t\t/* keep last! */\n 793:\t\tstruct ieee80211_sta sta;\n 794:\t};\n 795:\t\n 796:\tstatic inline struct sta_info *sta_from_pub(struct ieee80211_sta *sta)\n 797:\t{\n 798:\t\treturn container_of(sta, struct sta_info, sta);\n 799:\t}\n 800:\t\n 801:\tstatic inline int ieee80211_tdls_sta_link_id(struct sta_info *sta)\n 802:\t{\n 803:\t\t/* TDLS STA can only have a single link */\n 804:\t\treturn sta-\u003esta.valid_links ? __ffs(sta-\u003esta.valid_links) : 0;\n 805:\t}\n 806:\t\n 807:\tstatic inline enum nl80211_plink_state sta_plink_state(struct sta_info *sta)\n 808:\t{\n 809:\t#ifdef CONFIG_MAC80211_MESH\n 810:\t\treturn sta-\u003emesh-\u003eplink_state;\n 811:\t#endif\n 812:\t\treturn NL80211_PLINK_LISTEN;\n 813:\t}\n 814:\t\n"
}

9/2 2026/11/03 18:41 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 21345
							output: 41
							thoughts: 32
						

Thoughts:
Okay, here's my attempt at summarizing that thought process, tailored for an expert audience:

**Investigating Potential STA Information Quirks**

Alright, let me quickly run through this `net/mac80211` code... I'm particularly interested in anything that might be using the `container_of` macro to get at a `struct sta_info` from a `struct sta`. I know it's a common pattern, but it's *critical* to ensuring pointer arithmetic is correct and doesn't introduce vulnerabilities or unexpected behaviors, especially within this area of the wireless stack. I need to be absolutely certain there aren't any sneaky spots I've missed. It's too easy to make subtle errors in these kinds of structures, and those errors could cause stability or security issues. So, the question then becomes: besides what's already known, has any of the recent code been refactored, or is there a new addition I haven't seen that utilizes that specific `container_of` usage? Gotta be thorough. Time to dive back in and grep that code base.



10/2 2026/11/03 18:42 tool grepper
0m Args:
{
  "Expression": "container_of\\(.*struct sta_info, sta\\)",
  "PathPrefixes": [
    "net/mac80211"
  ]
}

Results:
{
  "Output": "net/mac80211/sta_info.h=796=static inline struct sta_info *sta_from_pub(struct ieee80211_sta *sta)\nnet/mac80211/sta_info.h-797-{\nnet/mac80211/sta_info.h:798:\treturn container_of(sta, struct sta_info, sta);\nnet/mac80211/sta_info.h-799-}\n"
}

11/2 2026/11/03 18:42 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 21782
							output: 37
							thoughts: 2930
						

Thoughts:
**Fuzzing Recommendation: WorthFuzzing = True**

Okay, here's the breakdown. After carefully reviewing the instructions, my conclusion is that this patch *absolutely* warrants fuzzing. The key here is the subtle but significant change – the introduction of the helper function `sta_from_pub()`. While seemingly a "refactoring," the guidelines are clear: any modification to reachable executable code, including helper function introductions, requires fuzzing. Let's walk through my reasoning:

First, I eliminated the negative criteria (when to *not* fuzz). This patch doesn't involve:

*   Non-kernel and non-executable changes: It modifies core kernel files (`net/mac80211/*.c`, `*.h`) that are compiled into the kernel image and module.
*   Structurally unreachable hardware: mac80211 is fully reachable through the `mac80211_hwsim` virtual device in standard QEMU.
*   Unreachable execution paths: The code changes impact standard packet handling and mac80211 operations (receive, transmit, rate control, etc.).

Now, looking at the positive criteria, Section 3 states "WorthFuzzing=true whenever the patch touches reachable executable code, including: ... Refactorings and Code Cleanups: Any restructuring of reachable data structures, helper abstractions, or algorithm flows." The `sta_from_pub()` function *directly* falls under "helper abstractions," specifically a restructuring of how station information is accessed.

The guidelines explicitly highlight that refactoring can introduce subtle semantic shifts or uncover latent kernel bugs. The substitution of `container_of` with `sta_from_pub` introduces a new function, making it critical to test for unexpected side effects.

Finally, regarding `FocusSymbols` (Section 4), I've identified the key functions in the .c files that *use* the new `static inline` `sta_from_pub()` helper:
*   `net/mac80211/agg-tx.c`:
    *   `ieee80211_refresh_tx_agg_session_timer`
    *   `ieee80211_start_tx_ba_session`
    *   `ieee80211_stop_tx_ba_session`

*   `net/mac80211/airtime.c`:
    *   `ieee80211_calc_expected_tx_airtime`

*   `net/mac80211/driver-ops.c`:
    *   `drv_change_sta_links`

*   `net/mac80211/he.c`:
    *   `ieee80211_prepare_rx_omi_bw`
    *   `ieee80211_finalize_rx_omi_bw`

*   `net/mac80211/rate.c`:
    *   `rate_control_tx_status`
    *   `rate_control_send_low` (static)
    *   `rate_control_set_rates`

*   `net/mac80211/rc80211_minstrel_ht.c`:
    *   `minstrel_ht_update_caps` (static or exported ops?)

*   `net/mac80211/rx.c`:
    *   `ieee80211_sta_ps_transition`
    *   `ieee80211_sta_pspoll`
    *   `ieee80211_sta_uapsd_trigger`
    *   `ieee80211_mark_rx_ba_filtered_frames`
    *   `__ieee80211_rx_handle_8023` (static)
    *   `__ieee80211_rx_handle_packet` (static)

*   `net/mac80211/sta_info.c`:
    *   `ieee80211_sta_block_awake`
    *   `ieee80211_sta_eosp`
    *   `ieee80211_send_eosp_nullfunc`
    *   `ieee80211_sta_set_buffered`
    *   `ieee80211_sta_register_airtime`
    *   `ieee80211_sta_recalc_aggregates`
    *   `lock


12/2 2026/11/03 18:42 tool grepper
0m Args:
{
  "Expression": "MAC80211",
  "PathPrefixes": [
    "net/mac80211/Makefile"
  ]
}

Results:
{
  "Output": "net/mac80211/Makefile-1-# SPDX-License-Identifier: GPL-2.0\nnet/mac80211/Makefile:2:obj-$(CONFIG_MAC80211) += mac80211.o\nnet/mac80211/Makefile-3-\n--\nnet/mac80211/Makefile=5=mac80211-y := \\\n--\nnet/mac80211/Makefile-39-\nnet/mac80211/Makefile:40:mac80211-$(CONFIG_MAC80211_LEDS) += led.o\nnet/mac80211/Makefile:41:mac80211-$(CONFIG_MAC80211_DEBUGFS) += \\\nnet/mac80211/Makefile-42-\tdebugfs.o \\\n--\nnet/mac80211/Makefile-46-\nnet/mac80211/Makefile:47:mac80211-$(CONFIG_MAC80211_MESH) += \\\nnet/mac80211/Makefile-48-\tmesh.o \\\n--\nnet/mac80211/Makefile=59=rc80211_minstrel-y := \\\n--\nnet/mac80211/Makefile-61-\nnet/mac80211/Makefile:62:rc80211_minstrel-$(CONFIG_MAC80211_DEBUGFS) += \\\nnet/mac80211/Makefile-63-\trc80211_minstrel_ht_debugfs.o\nnet/mac80211/Makefile-64-\nnet/mac80211/Makefile:65:mac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y)\nnet/mac80211/Makefile-66-\n"
}

13/2 2026/11/03 18:42 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 26272
							output: 36
							thoughts: 29
						

Thoughts:
Okay, here's my interpretation of that request, formatted for a technically proficient user:

**Diving into the net/mac80211 Makefile**

Alright, let's take a look at the `net/mac80211/Makefile`. I need to understand the initial setup, so I'm focusing on the first 40 lines. I'll use `read-file` to get the content of those lines, and then I'll start mentally parsing the makefile syntax. I'll be looking for any hints about core definitions, includes, or initial variable assignments that set the stage for how this specific build process is structured for this wireless network subsystem. It is important to know the very beginning of a file, in order to more quickly understand later, more complex code. I'll be expecting to see some target definitions, perhaps some dependency specifications, and probably the inclusion of other relevant makefiles or configuration files. I'm hoping to get a quick grasp of the build environment's initial state before it gets too complex.



14/2 2026/11/03 18:43 tool read-file
0m Args:
{
  "File": "net/mac80211/Makefile",
  "FirstLine": 1,
  "LineCount": 40
}

Results:
{
  "Contents": "   1:\t# SPDX-License-Identifier: GPL-2.0\n   2:\tobj-$(CONFIG_MAC80211) += mac80211.o\n   3:\t\n   4:\t# mac80211 objects\n   5:\tmac80211-y := \\\n   6:\t\tmain.o status.o \\\n   7:\t\tdriver-ops.o \\\n   8:\t\tsta_info.o \\\n   9:\t\twep.o \\\n  10:\t\taead_api.o \\\n  11:\t\twpa.o \\\n  12:\t\tscan.o offchannel.o \\\n  13:\t\tht.o agg-tx.o agg-rx.o \\\n  14:\t\tvht.o \\\n  15:\t\the.o \\\n  16:\t\ts1g.o \\\n  17:\t\tibss.o \\\n  18:\t\tiface.o \\\n  19:\t\tlink.o \\\n  20:\t\trate.o \\\n  21:\t\ttkip.o \\\n  22:\t\taes_cmac.o \\\n  23:\t\taes_gmac.o \\\n  24:\t\tfils_aead.o \\\n  25:\t\tcfg.o \\\n  26:\t\tethtool.o \\\n  27:\t\trx.o \\\n  28:\t\tspectmgmt.o \\\n  29:\t\ttx.o \\\n  30:\t\tkey.o \\\n  31:\t\tutil.o parse.o \\\n  32:\t\twme.o \\\n  33:\t\tchan.o ap.o \\\n  34:\t\ttrace.o mlme.o \\\n  35:\t\ttdls.o \\\n  36:\t\tocb.o \\\n  37:\t\tairtime.o \\\n  38:\t\teht.o uhr.o nan.o\n  39:\t\n  40:\tmac80211-$(CONFIG_MAC80211_LEDS) += led.o\n"
}

15/2 2026/11/03 18:43 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 27074
							output: 37
							thoughts: 199
						

Thoughts:
Okay, let's break this down.

**Analyzing MAC80211 Compilation Dependencies**

Right, so I see these object files: `main.o status.o driver-ops.o sta_info.o ht.o agg-tx.o he.o rate.o rx.o tx.o util.o airtime.o`. And the compiler unconditionally generates them whenever `CONFIG_MAC80211` is set. That's good to know, a solid foundational set. Now, I'm curious about how `rc80211_minstrel_ht.o` fits into the picture, because that looks important to rate control, and I want to understand exactly what triggers it to be included.

Aha, line 55-70 of `net/mac80211/Makefile` seems to hold the key here. It looks like the inclusion of that specific object file, `rc80211_minstrel_ht.o`, is controlled by `CONFIG_MAC80211_RC_MINSTREL`. The variable assignment `rc80211_minstrel-y := rc80211_minstrel.o net/mac80211/rc80211_minstrel_ht.o` shows the exact objects which will be compiled if that configuration option is enabled. That helps clarify the dependency chain. I need to keep an eye on how that gets set within the broader build configuration.



16/2 2026/11/03 18:44 tool read-file
0m Args:
{
  "File": "net/mac80211/Makefile",
  "FirstLine": 50,
  "LineCount": 25
}

Results:
{
  "Contents": "  50:\t\tmesh_plink.o \\\n  51:\t\tmesh_hwmp.o \\\n  52:\t\tmesh_sync.o \\\n  53:\t\tmesh_ps.o\n  54:\t\n  55:\tmac80211-$(CONFIG_PM) += pm.o\n  56:\t\n  57:\tCFLAGS_trace.o := -I$(src)\n  58:\t\n  59:\trc80211_minstrel-y := \\\n  60:\t\trc80211_minstrel_ht.o\n  61:\t\n  62:\trc80211_minstrel-$(CONFIG_MAC80211_DEBUGFS) += \\\n  63:\t\trc80211_minstrel_ht_debugfs.o\n  64:\t\n  65:\tmac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y)\n  66:\t\n  67:\tobj-y += tests/\n  68:\t\n  69:\tmac80211-y += wbrf.o\n  70:\t\n  71:\tccflags-y += -DDEBUG\n"
}

17/2 2026/11/03 18:44 llm patch-evaluator
1m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 27961
							output: 41
							thoughts: 31
						

Thoughts:
Here's my thought process, as requested:

**Navigating the Linux Kernel Configuration for mac80211**

Okay, so I need to understand the dependencies for `CONFIG_MAC80211`. Given that it's a core networking component, my first instinct is to dive into the Kconfig file within the mac80211 subtree. That's usually where all the build-time configuration options, their dependencies, and descriptions are defined. So, let's head over to `net/mac80211/Kconfig` and see what we can find. It's the most logical place to start untangling this configuration puzzle. I expect to see conditionals, potentially involving other kernel modules or hardware support, that determine when `CONFIG_MAC80211` is enabled or disabled. This will give me a clear picture of what needs to be enabled or in place for mac80211 to be active in the build.



18/2 2026/11/03 18:45 tool grepper
0m Args:
{
  "Expression": "config MAC80211\\b",
  "PathPrefixes": [
    "net/mac80211/Kconfig"
  ]
}

Results:
{
  "Output": "net/mac80211/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\nnet/mac80211/Kconfig:2:config MAC80211\nnet/mac80211/Kconfig-3-\ttristate \"Generic IEEE 802.11 Networking Stack (mac80211)\"\n"
}

19/2 2026/11/03 18:45 llm patch-evaluator
1m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 28340
							output: 37
							thoughts: 25
						

Thoughts:
Okay, here's my interpretation of reading those lines of `net/mac80211/Kconfig`, summarized as my own thought process:

**Diving into the MAC80211 Configuration Landscape**

Alright, let's get started. I'm going to jump into the `Kconfig` file for `net/mac80211`. This is where the core configuration options for the 802.11 wireless stack are defined, so it's essential for understanding how features are enabled and customized. I need to get a grip on the fundamentals, which means reading these first 40 lines. I'm expecting to see definitions for the top-level configuration symbols, the high-level options that form the basis for everything else. I'll be looking for things like whether we're enabling the core MAC80211 functionality itself, or if we're setting up for specific drivers or features. I'm also anticipating that these lines will include dependencies or prerequisites for other options – the things that *must* be enabled before other features even become available. It will be very telling of the overall architecture and which building blocks the designers wanted to make optional. I want to see how they've structured the dependencies; what's considered absolutely core, and what's more specialized. Based on that information, I'll build my mental map of how this whole wireless stack is built, and what the key decision points are.



20/2 2026/11/03 18:47 tool read-file
0m Args:
{
  "File": "net/mac80211/Kconfig",
  "FirstLine": 1,
  "LineCount": 40
}

Results:
{
  "Contents": "   1:\t# SPDX-License-Identifier: GPL-2.0-only\n   2:\tconfig MAC80211\n   3:\t\ttristate \"Generic IEEE 802.11 Networking Stack (mac80211)\"\n   4:\t\tdepends on CFG80211\n   5:\t\tselect CRYPTO\n   6:\t\tselect CRYPTO_LIB_AES_CBC_MACS\n   7:\t\tselect CRYPTO_LIB_ARC4\n   8:\t\tselect CRYPTO_AES\n   9:\t\tselect CRYPTO_CCM\n  10:\t\tselect CRYPTO_GCM\n  11:\t\tselect CRC32\n  12:\t\thelp\n  13:\t\t  This option enables the hardware independent IEEE 802.11\n  14:\t\t  networking stack.\n  15:\t\n  16:\tcomment \"CFG80211 needs to be enabled for MAC80211\"\n  17:\t\tdepends on CFG80211=n\n  18:\t\n  19:\tif MAC80211 != n\n  20:\t\n  21:\tconfig MAC80211_HAS_RC\n  22:\t\tbool\n  23:\t\n  24:\tconfig MAC80211_RC_MINSTREL\n  25:\t\tbool \"Minstrel\" if EXPERT\n  26:\t\tselect MAC80211_HAS_RC\n  27:\t\tdefault y\n  28:\t\thelp\n  29:\t\t  This option enables the 'minstrel' TX rate control algorithm\n  30:\t\n  31:\tchoice\n  32:\t\tprompt \"Default rate control algorithm\"\n  33:\t\tdepends on MAC80211_HAS_RC\n  34:\t\tdefault MAC80211_RC_DEFAULT_MINSTREL\n  35:\t\thelp\n  36:\t\t  This option selects the default rate control algorithm\n  37:\t\t  mac80211 will use. Note that this default can still be\n  38:\t\t  overridden through the ieee80211_default_rc_algo module\n  39:\t\t  parameter if different algorithms are available.\n  40:\t\n"
}

21/2 2026/11/03 18:47 llm patch-evaluator
4m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 29262
							output: 37
							thoughts: 76
						

Thoughts:
Okay, let's dive into this.

**Investigating the MAC80211 HWSIM**

Right, I need to understand the emulation and testing environment for `mac80211`. I'm thinking, let's specifically look at `MAC80211_HWSIM` and see how it works. Where is that actually implemented? Ah, okay, it's under `drivers/net/wireless/virtual/mac80211_hwsim.c`. That makes sense. Now, let me quickly glance at its `Kconfig` file. I'll need to understand how it's configured to truly grasp the setup. I always find Kconfig gives the basic information to contextualize the code itself.



22/2 2026/11/03 18:51 tool grepper
0m Args:
{
  "Expression": "config MAC80211_HWSIM",
  "PathPrefixes": [
    "drivers/net/wireless"
  ]
}

Results:
{
  "Output": "drivers/net/wireless/virtual/Kconfig:1:config MAC80211_HWSIM\ndrivers/net/wireless/virtual/Kconfig-2-\ttristate \"Simulated radio testing tool for mac80211\"\n"
}

23/2 2026/11/03 18:51 llm patch-evaluator
4m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 29605
							output: 36
							thoughts: 16
						

Thoughts:
Here's a summary of my thought process, as requested:

**Kconfig Dive**

Alright, time to dive in. My immediate thought is to check the `drivers/net/wireless/virtual/Kconfig` file. That's the logical starting point for understanding the configuration options related to virtual wireless interfaces within this kernel tree. I'm going to want to understand what features are enabled, what dependencies exist, and how the various virtual wireless functionalities are controlled via the build system. This Kconfig file should be the central point to begin untangling all of that.



24/2 2026/11/03 18:56 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/virtual/Kconfig",
  "FirstLine": 1,
  "LineCount": 20
}

Results:
{
  "Contents": "   1:\tconfig MAC80211_HWSIM\n   2:\t\ttristate \"Simulated radio testing tool for mac80211\"\n   3:\t\tdepends on MAC80211\n   4:\t\thelp\n   5:\t\t  This driver is a developer testing tool that can be used to test\n   6:\t\t  IEEE 802.11 networking stack (mac80211) functionality. This is not\n   7:\t\t  needed for normal wireless LAN usage and is only for testing. See\n   8:\t\t  Documentation/networking/mac80211_hwsim for more information on how\n   9:\t\t  to use this tool.\n  10:\t\n  11:\t\t  To compile this driver as a module, choose M here: the module will be\n  12:\t\t  called mac80211_hwsim.  If unsure, say N.\n  13:\t\n  14:\tconfig VIRT_WIFI\n  15:\t\ttristate \"Wifi wrapper for ethernet drivers\"\n  16:\t\tdepends on CFG80211\n  17:\t\thelp\n  18:\t\t  This option adds support for ethernet connections to appear as if they\n  19:\t\t  are wifi connections through a special rtnetlink device.\n  20:\t\n"
}

25/2 2026/11/03 18:56 llm patch-evaluator
5m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 30101
							output: 330
							thoughts: 1624
						

Thoughts:
**Focussing on the Relevant Symbols for Fuzzing**

Okay, so I need to identify the key configurations and functions to focus on for fuzzing this `mac80211` patch. First things first, `MAC80211` depends on `CFG80211`, so those are obviously primary. `MAC80211_HWSIM` is also crucial as it enables the software-simulated radio, which is essential for testing. `MAC80211_RC_MINSTREL` seems to be enabled by default, so I'll keep that in mind.

Now, let's zero in on the specific functions. I need to make sure I'm following the guidelines in Section 4: Avoid ubiquitous functions, target specific feature logic, and handle inline functions properly.

I've got a list of modified functions in the `.c` files: `ieee80211_start_tx_ba_session`, `ieee80211_stop_tx_ba_session`, `ieee80211_calc_expected_tx_airtime`, `drv_change_sta_links`, and so on.

Next, I checked the exported symbols in `mac80211.ko`. Most of these modified functions are exported! Perfect. They're not generic memory allocators or page fault handlers; they're very specific to station management, aggregation, power-saving, and TX queue operations – exactly what I want.

So, I'm going to choose a representative set of specific functions directly modified in this patch:
- `ieee80211_start_tx_ba_session`
- `ieee80211_stop_tx_ba_session`
- `ieee80211_calc_expected_tx_airtime`
- `drv_change_sta_links`
- `ieee80211_sta_ps_transition`
- `ieee80211_sta_pspoll`
- `ieee80211_sta_uapsd_trigger`
- `ieee80211_reserve_tid`
- `ieee80211_unreserve_tid`
- `ieee80211_tx_dequeue`

I double-checked for any relevant configurations within these functions. I found a few conditional compilations with `CONFIG_LOCKDEP` and `CONFIG_MAC80211_RC_MINSTREL`. The bulk of the code is compiled under `CONFIG_MAC80211`.

So, `CFG80211`, `MAC80211`, `MAC80211_RC_MINSTREL`, and `MAC80211_HWSIM` enable the compilation of the modified files and testability in QEMU.

In summary, this patch is refactoring `mac80211` station pointer access using an inline helper macro. It touches core station management, aggregation, power saving, and TX queue operations. It's definitely worth fuzzing because it's reachable executable code and core subsystem refactoring. The chosen symbols are all very appropriate. Time to set-results.



26/2 2026/11/03 19:01 tool set-results
0m Args:
{
  "EnableConfigs": [
    "CFG80211",
    "MAC80211",
    "MAC80211_RC_MINSTREL",
    "MAC80211_HWSIM"
  ],
  "FocusSymbols": [
    "ieee80211_start_tx_ba_session",
    "ieee80211_stop_tx_ba_session",
    "ieee80211_calc_expected_tx_airtime",
    "drv_change_sta_links",
    "ieee80211_sta_ps_transition",
    "ieee80211_sta_pspoll",
    "ieee80211_sta_uapsd_trigger",
    "ieee80211_tx_dequeue",
    "ieee80211_reserve_tid",
    "ieee80211_unreserve_tid"
  ],
  "Reasoning": "The patch introduces the inline helper sta_from_pub() and replaces container_of() invocations across multiple mac80211 modules (TX aggregation, airtime calculation, RX handling, power save management, rate control, and TX scheduling). These changes modify reachable wireless core networking code that is actively fuzzed via mac80211_hwsim in virtualized environments. Fuzzing is warranted to test station pointer retrieval and prevent regressions across station operations.",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "CFG80211",
    "MAC80211",
    "MAC80211_RC_MINSTREL",
    "MAC80211_HWSIM"
  ],
  "FocusSymbols": [
    "ieee80211_start_tx_ba_session",
    "ieee80211_stop_tx_ba_session",
    "ieee80211_calc_expected_tx_airtime",
    "drv_change_sta_links",
    "ieee80211_sta_ps_transition",
    "ieee80211_sta_pspoll",
    "ieee80211_sta_uapsd_trigger",
    "ieee80211_tx_dequeue",
    "ieee80211_reserve_tid",
    "ieee80211_unreserve_tid"
  ],
  "Reasoning": "The patch introduces the inline helper sta_from_pub() and replaces container_of() invocations across multiple mac80211 modules (TX aggregation, airtime calculation, RX handling, power save management, rate control, and TX scheduling). These changes modify reachable wireless core networking code that is actively fuzzed via mac80211_hwsim in virtualized environments. Fuzzing is warranted to test station pointer retrieval and prevent regressions across station operations.",
  "WorthFuzzing": true
}

27/1 2026/11/03 19:01 action If
3m Args:
{
  "WorthFuzzing": true
}

Results:
null

28/2 2026/11/03 19:01 agent kmsan-evaluator
3m Model:
core

Args:
null

Results:
{
  "KMSANReasoning": "The patch is a pure code refactoring that introduces the helper function sta_from_pub() (which wraps container_of(sta, struct sta_info, sta)) and replaces direct container_of invocations throughout the mac80211 subsystem. It does not introduce any memory allocations, data copying to userspace, modifications to struct layouts or initializations, or changes to control flow/bounds checking. Consequently, it introduces no risks of uninitialized memory access or info-leaks, and a dedicated KMSAN fuzzing session is not warranted.",
  "NeedsKMSAN": false
}

Instruction:
You are an expert Linux kernel security engineer specializing in kernel memory
error detectors (KASAN and KMSAN). Your job is to review the provided patch series and
determine if the code changes justify spawning a dedicated KMSAN (KernelMemorySanitizer)
fuzzing session in addition to standard KASAN fuzzing.

CRITICAL DISTINCTION BETWEEN KASAN AND KMSAN:
- Standard KASAN kernel builds (upstream-apparmor-kasan.config) already enable
  a comprehensive suite of debugging tools and sanitizers, including KASAN
  (out-of-bounds accesses, use-after-free, double free, invalid free), LOCKDEP
  (locking bugs and deadlocks), UB-sanitizers, and memory corruption checks.
- KMSAN (KernelMemorySanitizer) detects reads of UNINITIALIZED memory (stack, heap,
  or page allocations) and kernel-to-user memory info-leaks.

Rule: THERE IS NO SENSE IN RUNNING A KMSAN SESSION IF A BUG CAN BE CAUGHT BY KASAN,
LOCKDEP, OR OTHER STANDARD BUG DETECTORS.
A dedicated KMSAN fuzzing session incurs significant resource costs. You must ONLY
set NeedsKMSAN=true if the code changes introduce or expose UNINITIALIZED MEMORY risks
that are detected ONLY by KMSAN.

Look holistically at the patch series and surrounding code. Even if no direct
uninitialized field accesses or new buffer allocations are added in the diff itself,
a patch may alter control flow, bounds checking, or data length calculations in ways
that change how the rest of the code operates on existing buffers (e.g. allowing
uninitialized stack/heap memory to be read, copied to user space, or used in control
flow). Do not hesitate to use your code access tools to inspect the surrounding code,
called functions, and callers.

Set NeedsKMSAN=true ONLY IF the patch introduces or modifies:
1. Kernel structures sent to user space (via copy_to_user, put_user, netlink skb
   attributes, ioctl output arguments, socket options, or BPF buffers) where fields
   or structure padding might not be fully initialized/zeroed.
2. Conditional logic or branching that depends on potentially uninitialized variables
   or struct fields.
3. Allocation or initialization of complex data structures where uninitialized fields
   could be read later in reachable code paths.
4. Bounds checks, lengths, or logic in a way that allows surrounding code to access
   uninitialized bytes of existing buffers.

Set NeedsKMSAN=false IF:
- The code changes primarily risk out-of-bounds access, array overflows, NULL pointer
  dereferences, locking deadlocks, or use-after-free bugs (these are already caught
  by KASAN, LOCKDEP, or standard bug detectors).
- All stack/heap structures touched or introduced by the patch are fully zeroed
  or initialized (e.g. using = {0}, memset, kzalloc) before being read or copied.
- The patch does not introduce any risk of uninitialized memory usage or info-leaks.

Use your code access tools to inspect the surrounding code if necessary, then provide
detailed KMSANReasoning contrasting KASAN vs KMSAN applicability for this patch.
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
Target architecture: amd64

For your convenience, here is the diff of the changes:
commit f9f8ce30187cb82d1fa215d85e4c819431376082
Author: syz-cluster <triage@syzkaller.com>
Date:   Tue Nov 3 18:31:15 2026 +0000

    syz-cluster: applied patch under review

diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index f3ecdd8601a042..f9285ff081fc01 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -555,7 +555,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
 void ieee80211_refresh_tx_agg_session_timer(struct ieee80211_sta *pubsta,
 					    u16 tid)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	struct tid_ampdu_tx *tid_tx;
 
 	if (WARN_ON_ONCE(tid >= IEEE80211_NUM_TIDS))
@@ -600,7 +600,7 @@ static void sta_tx_agg_session_timer_expired(struct timer_list *t)
 int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
 				  u16 timeout)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
 	struct ieee80211_local *local = sdata->local;
 	struct tid_ampdu_tx *tid_tx;
@@ -868,7 +868,7 @@ EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
 
 int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
 	struct ieee80211_local *local = sdata->local;
 	struct tid_ampdu_tx *tid_tx;
diff --git a/net/mac80211/airtime.c b/net/mac80211/airtime.c
index a4e1f33c037797..53a455b6425fb6 100644
--- a/net/mac80211/airtime.c
+++ b/net/mac80211/airtime.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: ISC
 /*
  * Copyright (C) 2019 Felix Fietkau <nbd@nbd.name>
- * Copyright (C) 2021-2022 Intel Corporation
+ * Copyright (C) 2021-2022, 2026 Intel Corporation
  */
 
 #include <net/mac80211.h>
@@ -838,8 +838,7 @@ u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw,
 		band = conf->def.chan->band;
 
 	if (pubsta) {
-		struct sta_info *sta = container_of(pubsta, struct sta_info,
-						    sta);
+		struct sta_info *sta = sta_from_pub(pubsta);
 		struct ieee80211_tx_rate *tx_rate = &sta->deflink.tx_stats.last_rate;
 		struct rate_info *ri = &sta->deflink.tx_stats.last_rate_info;
 		u32 duration;
diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c
index 1f3e0765a8ab2e..12ea71036e4a08 100644
--- a/net/mac80211/driver-ops.c
+++ b/net/mac80211/driver-ops.c
@@ -583,7 +583,7 @@ int drv_change_sta_links(struct ieee80211_local *local,
 			 struct ieee80211_sta *sta,
 			 u16 old_links, u16 new_links)
 {
-	struct sta_info *info = container_of(sta, struct sta_info, sta);
+	struct sta_info *info = sta_from_pub(sta);
 	struct link_sta_info *link_sta;
 	unsigned long links_to_add;
 	unsigned long links_to_rem;
diff --git a/net/mac80211/he.c b/net/mac80211/he.c
index 5acf482c177a7e..0278892ae91f38 100644
--- a/net/mac80211/he.c
+++ b/net/mac80211/he.c
@@ -265,8 +265,7 @@ ieee80211_he_spr_ie_to_bss_conf(struct ieee80211_vif *vif,
 bool ieee80211_prepare_rx_omi_bw(struct ieee80211_link_sta *pub_link_sta,
 				 enum ieee80211_sta_rx_bandwidth bw)
 {
-	struct sta_info *sta = container_of(pub_link_sta->sta,
-					    struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pub_link_sta->sta);
 	struct ieee80211_local *local = sta->sdata->local;
 	struct link_sta_info *link_sta =
 		sdata_dereference(sta->link[pub_link_sta->link_id], sta->sdata);
@@ -318,8 +317,7 @@ EXPORT_SYMBOL_GPL(ieee80211_prepare_rx_omi_bw);
 
 void ieee80211_finalize_rx_omi_bw(struct ieee80211_link_sta *pub_link_sta)
 {
-	struct sta_info *sta = container_of(pub_link_sta->sta,
-					    struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pub_link_sta->sta);
 	struct ieee80211_local *local = sta->sdata->local;
 	struct link_sta_info *link_sta =
 		sdata_dereference(sta->link[pub_link_sta->link_id], sta->sdata);
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 10e6ad53726140..d74413fdaf0675 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -88,7 +88,7 @@ void rate_control_tx_status(struct ieee80211_local *local,
 			    struct ieee80211_tx_status *st)
 {
 	struct rate_control_ref *ref = local->rate_ctrl;
-	struct sta_info *sta = container_of(st->sta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(st->sta);
 	void *priv_sta = sta->rate_ctrl_priv;
 	struct ieee80211_supported_band *sband;
 
@@ -442,7 +442,7 @@ static bool rate_control_send_low(struct ieee80211_sta *pubsta,
 			}
 			use_basicrate = true;
 		} else if (pubsta) {
-			sta = container_of(pubsta, struct sta_info, sta);
+			sta = sta_from_pub(pubsta);
 			if (ieee80211_vif_is_mesh(&sta->sdata->vif))
 				use_basicrate = true;
 		}
@@ -970,7 +970,7 @@ int rate_control_set_rates(struct ieee80211_hw *hw,
 			   struct ieee80211_sta *pubsta,
 			   struct ieee80211_sta_rates *rates)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	struct ieee80211_sta_rates *old;
 	struct ieee80211_supported_band *sband;
 
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 45e7a7ea769008..d46b6780bfdb3a 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (C) 2010-2013 Felix Fietkau <nbd@openwrt.org>
- * Copyright (C) 2019-2022 Intel Corporation
+ * Copyright (C) 2019-2022, 2026 Intel Corporation
  */
 #include <linux/netdevice.h>
 #include <linux/types.h>
@@ -1865,7 +1865,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
 				vht_cap->vht_mcs.tx_mcs_map);
 	}
 
-	sta_info = container_of(sta, struct sta_info, sta);
+	sta_info = sta_from_pub(sta);
 	mi->use_short_preamble = test_sta_flag(sta_info, WLAN_STA_SHORT_PREAMBLE) &&
 				 sta_info->sdata->vif.bss_conf.use_short_preamble;
 
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index ee1f33178d2670..acf1188ff42688 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1724,7 +1724,7 @@ static void sta_ps_end(struct sta_info *sta)
 
 void ieee80211_sta_ps_transition(struct ieee80211_sta *pubsta, bool start)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	bool in_ps;
 
 	WARN_ON(!ieee80211_hw_check(&sta->local->hw, AP_LINK_PS));
@@ -1743,7 +1743,7 @@ EXPORT_SYMBOL(ieee80211_sta_ps_transition);
 
 void ieee80211_sta_pspoll(struct ieee80211_sta *pubsta)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 
 	if (test_sta_flag(sta, WLAN_STA_SP))
 		return;
@@ -1757,7 +1757,7 @@ EXPORT_SYMBOL(ieee80211_sta_pspoll);
 
 void ieee80211_sta_uapsd_trigger(struct ieee80211_sta *pubsta, u8 tid)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	int ac = ieee80211_ac_from_tid(tid);
 
 	/*
@@ -4439,7 +4439,7 @@ void ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *pubsta, u8 tid,
 
 	__skb_queue_head_init(&frames);
 
-	sta = container_of(pubsta, struct sta_info, sta);
+	sta = sta_from_pub(pubsta);
 
 	local = sta->sdata->local;
 	WARN_ONCE(local->hw.max_rx_aggregation_subframes > 64,
@@ -5289,7 +5289,7 @@ static void __ieee80211_rx_handle_8023(struct ieee80211_hw *hw,
 	if (!link_pubsta)
 		goto drop;
 
-	sta = container_of(link_pubsta->sta, struct sta_info, sta);
+	sta = sta_from_pub(link_pubsta->sta);
 	if (sta->sta.valid_links)
 		link_id = link_pubsta->link_id;
 	if (!ieee80211_rx_data_set_sta(&rx, sta, link_id))
@@ -5398,8 +5398,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
 	 */
 	if (ieee80211_is_data(fc)) {
 		if (link_pubsta) {
-			sta = container_of(link_pubsta->sta, struct sta_info,
-					   sta);
+			sta = sta_from_pub(link_pubsta->sta);
 			link_sta = rcu_dereference(sta->link[link_pubsta->link_id]);
 
 			rx.sdata = sta->sdata;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 23166fc3972913..6e9c06f3e4db5e 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -2349,7 +2349,7 @@ void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta)
 void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
 			       struct ieee80211_sta *pubsta, bool block)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 
 	trace_api_sta_block_awake(sta->local, pubsta, block);
 
@@ -2380,7 +2380,7 @@ EXPORT_SYMBOL(ieee80211_sta_block_awake);
 
 void ieee80211_sta_eosp(struct ieee80211_sta *pubsta)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	struct ieee80211_local *local = sta->local;
 
 	trace_api_eosp(local, pubsta);
@@ -2391,7 +2391,7 @@ EXPORT_SYMBOL(ieee80211_sta_eosp);
 
 void ieee80211_send_eosp_nullfunc(struct ieee80211_sta *pubsta, int tid)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	enum ieee80211_frame_release_type reason;
 	bool more_data;
 
@@ -2408,7 +2408,7 @@ EXPORT_SYMBOL(ieee80211_send_eosp_nullfunc);
 void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta,
 				u8 tid, bool buffered)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 
 	if (WARN_ON(tid >= IEEE80211_NUM_TIDS))
 		return;
@@ -2427,7 +2427,7 @@ EXPORT_SYMBOL(ieee80211_sta_set_buffered);
 void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,
 				    u32 tx_airtime, u32 rx_airtime)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	struct ieee80211_local *local = sta->sdata->local;
 	u8 ac = ieee80211_ac_from_tid(tid);
 	u32 airtime = 0;
@@ -2495,7 +2495,7 @@ void __ieee80211_sta_recalc_aggregates(struct sta_info *sta, u16 active_links)
 
 void ieee80211_sta_recalc_aggregates(struct ieee80211_sta *pubsta)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 
 	__ieee80211_sta_recalc_aggregates(sta, sta->sdata->vif.active_links);
 }
@@ -3683,7 +3683,7 @@ void ieee80211_sta_set_max_amsdu_subframes(struct sta_info *sta,
 #ifdef CONFIG_LOCKDEP
 bool lockdep_sta_mutex_held(struct ieee80211_sta *pubsta)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 
 	return lockdep_is_held(&sta->local->hw.wiphy->mtx);
 }
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 8c6a9fee6b29b0..0e8f7794fd01b7 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -793,6 +793,11 @@ struct sta_info {
 	struct ieee80211_sta sta;
 };
 
+static inline struct sta_info *sta_from_pub(struct ieee80211_sta *sta)
+{
+	return container_of(sta, struct sta_info, sta);
+}
+
 static inline int ieee80211_tdls_sta_link_id(struct sta_info *sta)
 {
 	/* TDLS STA can only have a single link */
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 414979e2a1d930..5d1807ab46ef5c 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -1013,7 +1013,7 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw,
 	fc = hdr->frame_control;
 
 	if (status->sta) {
-		sta = container_of(status->sta, struct sta_info, sta);
+		sta = sta_from_pub(status->sta);
 
 		if (info->flags & IEEE80211_TX_STATUS_EOSP)
 			clear_sta_flag(sta, WLAN_STA_SP);
@@ -1246,7 +1246,7 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
 	ieee80211_tx_status_drop_invalid_rates(status);
 
 	if (pubsta) {
-		sta = container_of(pubsta, struct sta_info, sta);
+		sta = sta_from_pub(pubsta);
 
 		if (status->n_rates)
 			sta->deflink.tx_stats.last_rate_info =
@@ -1363,7 +1363,7 @@ void ieee80211_tx_rate_update(struct ieee80211_hw *hw,
 			      struct ieee80211_tx_info *info)
 {
 	struct ieee80211_local *local = hw_to_local(hw);
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	struct ieee80211_tx_status status = {
 		.info = info,
 		.sta = pubsta,
@@ -1379,7 +1379,7 @@ EXPORT_SYMBOL(ieee80211_tx_rate_update);
 
 void ieee80211_report_low_ack(struct ieee80211_sta *pubsta, u32 num_packets)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	cfg80211_cqm_pktloss_notify(sta->sdata->dev, sta->sta.addr,
 				    num_packets, GFP_ATOMIC);
 }
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e9b6a0415d6a94..22335ea362aa7d 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -4031,7 +4031,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
 	tx.sdata = vif_to_sdata(info->control.vif);
 
 	if (txq->sta) {
-		tx.sta = container_of(txq->sta, struct sta_info, sta);
+		tx.sta = sta_from_pub(txq->sta);
 
 		if (unlikely(ieee80211_drop_unauth_port(&tx))) {
 			I802_DEBUG_INC(local->tx_handlers_drop_unauth_port);
@@ -4067,8 +4067,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
 	}
 
 	if (info->control.flags & IEEE80211_TX_CTRL_FAST_XMIT) {
-		struct sta_info *sta = container_of(txq->sta, struct sta_info,
-						    sta);
+		struct sta_info *sta = sta_from_pub(txq->sta);
 		u8 pn_offs = 0;
 
 		if (tx.key &&
@@ -4176,7 +4175,7 @@ ieee80211_txq_set_active(struct txq_info *txqi)
 	if (!txqi->txq.sta)
 		return;
 
-	sta = container_of(txqi->txq.sta, struct sta_info, sta);
+	sta = sta_from_pub(txqi->txq.sta);
 	sta->airtime[txqi->txq.ac].last_active = jiffies;
 }
 
@@ -4188,7 +4187,7 @@ ieee80211_txq_keep_active(struct txq_info *txqi)
 	if (!txqi->txq.sta)
 		return false;
 
-	sta = container_of(txqi->txq.sta, struct sta_info, sta);
+	sta = sta_from_pub(txqi->txq.sta);
 	if (ieee80211_sta_deficit(sta, txqi->txq.ac) >= 0)
 		return false;
 
@@ -4230,8 +4229,7 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)
 		found_eligible_txq = true;
 
 	if (txqi->txq.sta) {
-		struct sta_info *sta = container_of(txqi->txq.sta,
-						    struct sta_info, sta);
+		struct sta_info *sta = sta_from_pub(txqi->txq.sta);
 
 		if (ieee80211_sta_deficit(sta, txqi->txq.ac) < 0) {
 			sta->airtime[txqi->txq.ac].deficit +=
@@ -4319,7 +4317,7 @@ bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw,
 	if (unlikely(txq->tid == IEEE80211_NUM_TIDS))
 		return true;
 
-	sta = container_of(txq->sta, struct sta_info, sta);
+	sta = sta_from_pub(txq->sta);
 	if (atomic_read(&sta->airtime[txq->ac].aql_tx_pending) <
 	    sta->airtime[txq->ac].aql_limit_low)
 		return true;
@@ -4346,7 +4344,7 @@ u32 ieee80211_txq_aql_pending(struct ieee80211_hw *hw,
 	if (!txq->sta)
 		return atomic_read(&local->aql_mc_pending_airtime);
 
-	sta = container_of(txq->sta, struct sta_info, sta);
+	sta = sta_from_pub(txq->sta);
 
 	return atomic_read(&sta->airtime[txq->ac].aql_tx_pending);
 }
@@ -4400,13 +4398,13 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
 				       &local->active_txqs[ac]);
 			continue;
 		}
-		sta = container_of(iter->txq.sta, struct sta_info, sta);
+		sta = sta_from_pub(iter->txq.sta);
 		if (ieee80211_sta_deficit(sta, ac) < 0)
 			sta->airtime[ac].deficit += sta->airtime_weight;
 		list_move_tail(&iter->schedule_order, &local->active_txqs[ac]);
 	}
 
-	sta = container_of(txqi->txq.sta, struct sta_info, sta);
+	sta = sta_from_pub(txqi->txq.sta);
 	if (sta->airtime[ac].deficit >= 0)
 		goto out;
 
@@ -6446,7 +6444,7 @@ EXPORT_SYMBOL(ieee80211_get_buffered_bc);
 
 int ieee80211_reserve_tid(struct ieee80211_sta *pubsta, u8 tid)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
 	struct ieee80211_local *local = sdata->local;
 	int ret;
@@ -6510,7 +6508,7 @@ EXPORT_SYMBOL(ieee80211_reserve_tid);
 
 void ieee80211_unreserve_tid(struct ieee80211_sta *pubsta, u8 tid)
 {
-	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+	struct sta_info *sta = sta_from_pub(pubsta);
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
 
 	lockdep_assert_wiphy(sdata->local->hw.wiphy);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 44feb80274c61c..2706f6a5a8fbbe 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -904,7 +904,7 @@ __ieee80211_iterate_stations(struct ieee80211_hw *hw,
 	lockdep_assert_wiphy(local->hw.wiphy);
 
 	if (prev)
-		sta = container_of(prev, struct sta_info, sta);
+		sta = sta_from_pub(prev);
 
 	sta = list_prepare_entry(sta, &local->sta_list, list);
 	list_for_each_entry_continue(sta, &local->sta_list, list) {

29/3 2026/11/03 19:01 llm kmsan-evaluator
3m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 10113
							output: 139
							thoughts: 594
						

Thoughts:
**Analyzing the MAC80211 Refactoring Patch**

Alright, let's break this down. The patch introduces a simple inline helper function, `sta_from_pub`, within `net/mac80211/sta_info.h`.  My initial thought is that this is straightforward refactoring, and my experience tells me to approach this with due diligence, but also, to look for the obvious.

It essentially wraps `container_of(sta, struct sta_info, sta)`, and systematically substitutes all the direct invocations of `container_of` with this new helper. I see the replacements across several `.c` files within the `net/mac80211` directory. This seems to primarily be about code readability and maintainability.

The key question, as always, is whether this introduces any regressions or potential security issues. My assessment boils down to looking for any sort of:

1.  Exposure of uninitialized kernel structures to userspace. Not here.
2.  Uninitialized variable usage within conditional branches. Doesn't appear to be a factor.
3.  Complex data structure initialization with potentially uninitialized fields that might be read later. I'm not seeing any new allocations or complex initializations here that would raise a red flag.
4.  Bounds check issues or changes to buffer lengths that could lead to reading outside of allocated memory. Not present.

Since `sta_from_pub(sta)` is a direct equivalent of the original `container_of` usage, I'm confident there are no semantic changes. No new memory is being allocated, copied, or initialized in a way that would require KMSAN's scrutiny. Therefore, **NeedsKMSAN = false**. The change is purely syntactic.

In short, it's a clean refactoring, and I'm prepared to articulate this reasoning. Now let's wrap this up with a call to `set-results`.



30/3 2026/11/03 19:05 tool set-results
0m Args:
{
  "KMSANReasoning": "The patch is a pure code refactoring that introduces the helper function sta_from_pub() (which wraps container_of(sta, struct sta_info, sta)) and replaces direct container_of invocations throughout the mac80211 subsystem. It does not introduce any memory allocations, data copying to userspace, modifications to struct layouts or initializations, or changes to control flow/bounds checking. Consequently, it introduces no risks of uninitialized memory access or info-leaks, and a dedicated KMSAN fuzzing session is not warranted.",
  "NeedsKMSAN": false
}

Results:
{
  "KMSANReasoning": "The patch is a pure code refactoring that introduces the helper function sta_from_pub() (which wraps container_of(sta, struct sta_info, sta)) and replaces direct container_of invocations throughout the mac80211 subsystem. It does not introduce any memory allocations, data copying to userspace, modifications to struct layouts or initializations, or changes to control flow/bounds checking. Consequently, it introduces no risks of uninitialized memory access or info-leaks, and a dedicated KMSAN fuzzing session is not warranted.",
  "NeedsKMSAN": false
}

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)