| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/09/11 14:26 | flow | patch-triage |
3mArgs:null Results: {
"EnableConfigs": [
"MAC80211_HWSIM",
"MAC80211",
"CFG80211"
],
"FocusSymbols": [
"hwsim_cloned_frame_received_nl",
"hwsim_tx_info_frame_received_nl",
"mac80211_hwsim_tx_frame_nl",
"mac80211_hwsim_monitor_rx",
"mac80211_hwsim_monitor_ack",
"mac80211_hwsim_tx"
],
"KMSANReasoning": "The patch modifies `mac80211_hwsim` to add the `HWSIM_ATTR_NO_MONITOR` netlink flag attribute for skipping monitor reports, preserves the transmission channel frequency in `rate_driver_data[1]`, and updates the pending transmitted skb in `hwsim_cloned_frame_received_nl` when matching cookie and transmitter attributes are provided.\n\nAll local variables (`freq`, `no_monitor`, `cookie`, etc.) and structure members (`rate_driver_data[1]`, `hdr-\u003ert_channel`) introduced or modified in this patch are explicitly assigned and initialized before access. SKB modifications use `skb_put_data` with verified payload lengths from validated netlink attributes. There are no uninitialized memory reads, uninitialized structure paddings, or info-leaks to userspace. Potential risks relating to SKB manipulation, queue locking, or reference handling are covered by standard KASAN and LOCKDEP detectors. Dedicated KMSAN fuzzing is not needed.",
"NeedsKMSAN": false,
"Reasoning": "The patch modifies mac80211_hwsim, a software-emulated 802.11 radio testing tool fully accessible in standard virtualized fuzzing environments via generic netlink. The changes introduce handling for HWSIM_ATTR_NO_MONITOR, modify center frequency tracking across TX monitor reporting, and add logic in hwsim_cloned_frame_received_nl to search the pending transmission queue by cookie and modify the original skb data (via pskb_expand_head, skb_trim, and skb_put_data). Fuzzing is warranted to test for potential buffer manipulation issues, race conditions, or state inconsistencies in the simulated radio TX/RX paths.",
"WorthFuzzing": true
} |
| 1/1 | 2026/09/11 14:26 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 5b75af513ae1af87792a20b5aba41416353f9998\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Fri Sep 11 14:26:46 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/wireless/virtual/mac80211_hwsim.h b/drivers/net/wireless/virtual/mac80211_hwsim.h\nindex a022cd5c0f1c7..1d2fd06c585a9 100644\n--- a/drivers/net/wireless/virtual/mac80211_hwsim.h\n+++ b/drivers/net/wireless/virtual/mac80211_hwsim.h\n@@ -3,7 +3,7 @@\n * mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211\n * Copyright (c) 2008, Jouni Malinen \u003cj@w1.fi\u003e\n * Copyright (c) 2011, Javier Lopez \u003cjlopex@gmail.com\u003e\n- * Copyright (C) 2020, 2022-2025 Intel Corporation\n+ * Copyright (C) 2020, 2022-2026 Intel Corporation\n */\n \n #ifndef __MAC80211_HWSIM_H\n@@ -162,6 +162,8 @@ enum hwsim_commands {\n *\teach radio instead of for the wiphy.\n * @HWSIM_ATTR_SUPPORT_NAN_DEVICE: support NAN Device virtual interface (flag)\n * @HWSIM_ATTR_SUPPORT_BACKGROUND_RADAR: background radar/CAC support (flag)\n+ * @HWSIM_ATTR_NO_MONITOR: skip monitor report for this TX status, e.g. in case\n+ *\tthe frame was never reported to any receiver (flag)\n * @__HWSIM_ATTR_MAX: enum limit\n */\n enum hwsim_attrs {\n@@ -197,6 +199,7 @@ enum hwsim_attrs {\n \tHWSIM_ATTR_MULTI_RADIO,\n \tHWSIM_ATTR_SUPPORT_NAN_DEVICE,\n \tHWSIM_ATTR_SUPPORT_BACKGROUND_RADAR,\n+\tHWSIM_ATTR_NO_MONITOR,\n \t__HWSIM_ATTR_MAX,\n };\n #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)\ndiff --git a/drivers/net/wireless/virtual/mac80211_hwsim_main.c b/drivers/net/wireless/virtual/mac80211_hwsim_main.c\nindex 02b6d81cccd11..fca4bf823ef4e 100644\n--- a/drivers/net/wireless/virtual/mac80211_hwsim_main.c\n+++ b/drivers/net/wireless/virtual/mac80211_hwsim_main.c\n@@ -895,6 +895,7 @@ static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {\n \t[HWSIM_ATTR_MULTI_RADIO] = { .type = NLA_FLAG },\n \t[HWSIM_ATTR_SUPPORT_NAN_DEVICE] = { .type = NLA_FLAG },\n \t[HWSIM_ATTR_SUPPORT_BACKGROUND_RADAR] = { .type = NLA_FLAG },\n+\t[HWSIM_ATTR_NO_MONITOR] = { .type = NLA_FLAG },\n };\n \n #if IS_REACHABLE(CONFIG_VIRTIO)\n@@ -1337,7 +1338,7 @@ mac80211_hwsim_get_tx_rate(struct ieee80211_hw *hw,\n \n static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,\n \t\t\t\t struct sk_buff *tx_skb,\n-\t\t\t\t struct ieee80211_channel *chan)\n+\t\t\t\t u32 freq)\n {\n \tstruct mac80211_hwsim_data *data = hw-\u003epriv;\n \tstruct sk_buff *skb;\n@@ -1369,7 +1370,7 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,\n \thdr-\u003ert_tsft = __mac80211_hwsim_get_tsf(data);\n \thdr-\u003ert_flags = 0;\n \thdr-\u003ert_rate = bitrate / 5;\n-\thdr-\u003ert_channel = cpu_to_le16(chan-\u003ecenter_freq);\n+\thdr-\u003ert_channel = cpu_to_le16(freq);\n \tflags = IEEE80211_CHAN_2GHZ;\n \tif (txrate \u0026\u0026 txrate-\u003eflags \u0026 IEEE80211_RATE_ERP_G)\n \t\tflags |= IEEE80211_CHAN_OFDM;\n@@ -1387,8 +1388,7 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,\n }\n \n \n-static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan,\n-\t\t\t\t const u8 *addr)\n+static void mac80211_hwsim_monitor_ack(u32 freq, const u8 *addr)\n {\n \tstruct sk_buff *skb;\n \tstruct hwsim_radiotap_ack_hdr *hdr;\n@@ -1410,7 +1410,7 @@ static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan,\n \t\t\t\t\t (1 \u003c\u003c IEEE80211_RADIOTAP_CHANNEL));\n \thdr-\u003ert_flags = 0;\n \thdr-\u003epad = 0;\n-\thdr-\u003ert_channel = cpu_to_le16(chan-\u003ecenter_freq);\n+\thdr-\u003ert_channel = cpu_to_le16(freq);\n \tflags = IEEE80211_CHAN_2GHZ;\n \thdr-\u003ert_chbitmask = cpu_to_le16(flags);\n \n@@ -1735,6 +1735,9 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,\n \tif (nla_put_u64_64bit(skb, HWSIM_ATTR_COOKIE, cookie, HWSIM_ATTR_PAD))\n \t\tgoto nla_put_failure;\n \n+\t/* track the frequency */\n+\tinfo-\u003erate_driver_data[1] = (void *)(uintptr_t)channel-\u003ecenter_freq;\n+\n \tgenlmsg_end(skb, msg_head);\n \n \tif (hwsim_virtio_enabled) {\n@@ -1912,7 +1915,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,\n \n \tmac80211_hwsim_write_tsf(data, skb, sim_tsf);\n \n-\tmac80211_hwsim_monitor_rx(hw, skb, chan);\n+\tmac80211_hwsim_monitor_rx(hw, skb, chan-\u003ecenter_freq);\n \n \tmemset(\u0026rx_status, 0, sizeof(rx_status));\n \trx_status.flag |= RX_FLAG_MACTIME_START;\n@@ -2276,7 +2279,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,\n \tack = mac80211_hwsim_tx_frame_no_nl(hw, skb, channel);\n \n \tif (ack \u0026\u0026 skb-\u003elen \u003e= 16)\n-\t\tmac80211_hwsim_monitor_ack(channel, hdr-\u003eaddr2);\n+\t\tmac80211_hwsim_monitor_ack(channel-\u003ecenter_freq, hdr-\u003eaddr2);\n \n \tieee80211_tx_info_clear_status(txi);\n \n@@ -6391,6 +6394,8 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,\n \tint i;\n \tunsigned long flags;\n \tbool found = false;\n+\tbool no_monitor;\n+\tu32 freq;\n \n \tif (!info-\u003eattrs[HWSIM_ATTR_ADDR_TRANSMITTER] ||\n \t !info-\u003eattrs[HWSIM_ATTR_FLAGS] ||\n@@ -6402,6 +6407,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,\n \tsrc = (void *)nla_data(info-\u003eattrs[HWSIM_ATTR_ADDR_TRANSMITTER]);\n \thwsim_flags = nla_get_u32(info-\u003eattrs[HWSIM_ATTR_FLAGS]);\n \tret_skb_cookie = nla_get_u64(info-\u003eattrs[HWSIM_ATTR_COOKIE]);\n+\tno_monitor = nla_get_flag(info-\u003eattrs[HWSIM_ATTR_NO_MONITOR]);\n \n \tdata2 = get_hwsim_data_ref_from_addr(src);\n \tif (!data2)\n@@ -6436,7 +6442,11 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,\n \tif (!found)\n \t\tgoto out;\n \n-\tmac80211_hwsim_monitor_rx(data2-\u003ehw, skb, data2-\u003echannel);\n+\ttxi = IEEE80211_SKB_CB(skb);\n+\tfreq = (uintptr_t)txi-\u003erate_driver_data[1];\n+\n+\tif (!no_monitor)\n+\t\tmac80211_hwsim_monitor_rx(data2-\u003ehw, skb, freq);\n \n \t/* Tx info received because the frame was broadcasted on user space,\n \t so we get all the necessary info: tx attempts and skb control buff */\n@@ -6445,8 +6455,6 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,\n \t\t info-\u003eattrs[HWSIM_ATTR_TX_INFO]);\n \n \t/* now send back TX status */\n-\ttxi = IEEE80211_SKB_CB(skb);\n-\n \tieee80211_tx_info_clear_status(txi);\n \n \tfor (i = 0; i \u003c IEEE80211_TX_MAX_RATES; i++) {\n@@ -6466,8 +6474,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,\n \tif (!(hwsim_flags \u0026 HWSIM_TX_CTL_NO_ACK) \u0026\u0026\n \t (hwsim_flags \u0026 HWSIM_TX_STAT_ACK)) {\n \t\tif (skb-\u003elen \u003e= 16)\n-\t\t\tmac80211_hwsim_monitor_ack(data2-\u003echannel,\n-\t\t\t\t\t\t hdr-\u003eaddr2);\n+\t\t\tmac80211_hwsim_monitor_ack(freq, hdr-\u003eaddr2);\n \t\ttxi-\u003eflags |= IEEE80211_TX_STAT_ACK;\n \t}\n \n@@ -6535,6 +6542,51 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,\n \t\t\tgoto out;\n \t}\n \n+\t/* look for the skb matching the cookie passed back from user */\n+\tif (info-\u003eattrs[HWSIM_ATTR_COOKIE] \u0026\u0026\n+\t info-\u003eattrs[HWSIM_ATTR_ADDR_TRANSMITTER]) {\n+\t\tu64 cookie = nla_get_u64(info-\u003eattrs[HWSIM_ATTR_COOKIE]);\n+\t\tstruct sk_buff *orig_skb, *found = NULL;\n+\t\tstruct mac80211_hwsim_data *txdata;\n+\t\tstruct ieee80211_tx_info *txi;\n+\t\tconst u8 *transmitter;\n+\t\tunsigned long flags;\n+\n+\t\ttransmitter = nla_data(info-\u003eattrs[HWSIM_ATTR_ADDR_TRANSMITTER]);\n+\t\ttxdata = get_hwsim_data_ref_from_addr(transmitter);\n+\t\tif (!txdata || txdata-\u003enetgroup != data2-\u003enetgroup)\n+\t\t\tgoto out;\n+\n+\t\tspin_lock_irqsave(\u0026txdata-\u003epending.lock, flags);\n+\t\tskb_queue_walk(\u0026txdata-\u003epending, orig_skb) {\n+\t\t\tuintptr_t skb_cookie;\n+\n+\t\t\ttxi = IEEE80211_SKB_CB(orig_skb);\n+\t\t\tskb_cookie = (uintptr_t)txi-\u003erate_driver_data[0];\n+\n+\t\t\tif (skb_cookie == cookie) {\n+\t\t\t\tfound = orig_skb;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\n+\t\t/* that's weird */\n+\t\tif (!found) {\n+\t\t\tspin_unlock_irqrestore(\u0026txdata-\u003epending.lock, flags);\n+\t\t\tgoto out;\n+\t\t}\n+\n+\t\tif (frame_data_len \u003e found-\u003elen \u0026\u0026\n+\t\t pskb_expand_head(found, 0, frame_data_len - found-\u003elen,\n+\t\t\t\t GFP_ATOMIC)) {\n+\t\t\tspin_unlock_irqrestore(\u0026txdata-\u003epending.lock, flags);\n+\t\t\tgoto out;\n+\t\t}\n+\t\tskb_trim(found, 0);\n+\t\tskb_put_data(found, frame_data, frame_data_len);\n+\t\tspin_unlock_irqrestore(\u0026txdata-\u003epending.lock, flags);\n+\t}\n+\n \t/* check if radio is configured properly */\n \n \tif ((data2-\u003eidle \u0026\u0026 !data2-\u003etmp_chan) || !data2-\u003estarted)\n"
} |
| 2/1 | 2026/09/11 14:26 | agent | patch-evaluator |
2mModel:core Args: null Results: {
"EnableConfigs": [
"MAC80211_HWSIM",
"MAC80211",
"CFG80211"
],
"FocusSymbols": [
"hwsim_cloned_frame_received_nl",
"hwsim_tx_info_frame_received_nl",
"mac80211_hwsim_tx_frame_nl",
"mac80211_hwsim_monitor_rx",
"mac80211_hwsim_monitor_ack",
"mac80211_hwsim_tx"
],
"Reasoning": "The patch modifies mac80211_hwsim, a software-emulated 802.11 radio testing tool fully accessible in standard virtualized fuzzing environments via generic netlink. The changes introduce handling for HWSIM_ATTR_NO_MONITOR, modify center frequency tracking across TX monitor reporting, and add logic in hwsim_cloned_frame_received_nl to search the pending transmission queue by cookie and modify the original skb data (via pskb_expand_head, skb_trim, and skb_put_data). Fuzzing is warranted to test for potential buffer manipulation issues, race conditions, or state inconsistencies in the simulated radio TX/RX paths.",
"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 5b75af513ae1af87792a20b5aba41416353f9998
Author: syz-cluster <triage@syzkaller.com>
Date: Fri Sep 11 14:26:46 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.h b/drivers/net/wireless/virtual/mac80211_hwsim.h
index a022cd5c0f1c7..1d2fd06c585a9 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim.h
+++ b/drivers/net/wireless/virtual/mac80211_hwsim.h
@@ -3,7 +3,7 @@
* mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211
* Copyright (c) 2008, Jouni Malinen <j@w1.fi>
* Copyright (c) 2011, Javier Lopez <jlopex@gmail.com>
- * Copyright (C) 2020, 2022-2025 Intel Corporation
+ * Copyright (C) 2020, 2022-2026 Intel Corporation
*/
#ifndef __MAC80211_HWSIM_H
@@ -162,6 +162,8 @@ enum hwsim_commands {
* each radio instead of for the wiphy.
* @HWSIM_ATTR_SUPPORT_NAN_DEVICE: support NAN Device virtual interface (flag)
* @HWSIM_ATTR_SUPPORT_BACKGROUND_RADAR: background radar/CAC support (flag)
+ * @HWSIM_ATTR_NO_MONITOR: skip monitor report for this TX status, e.g. in case
+ * the frame was never reported to any receiver (flag)
* @__HWSIM_ATTR_MAX: enum limit
*/
enum hwsim_attrs {
@@ -197,6 +199,7 @@ enum hwsim_attrs {
HWSIM_ATTR_MULTI_RADIO,
HWSIM_ATTR_SUPPORT_NAN_DEVICE,
HWSIM_ATTR_SUPPORT_BACKGROUND_RADAR,
+ HWSIM_ATTR_NO_MONITOR,
__HWSIM_ATTR_MAX,
};
#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_main.c b/drivers/net/wireless/virtual/mac80211_hwsim_main.c
index 02b6d81cccd11..fca4bf823ef4e 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim_main.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim_main.c
@@ -895,6 +895,7 @@ static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {
[HWSIM_ATTR_MULTI_RADIO] = { .type = NLA_FLAG },
[HWSIM_ATTR_SUPPORT_NAN_DEVICE] = { .type = NLA_FLAG },
[HWSIM_ATTR_SUPPORT_BACKGROUND_RADAR] = { .type = NLA_FLAG },
+ [HWSIM_ATTR_NO_MONITOR] = { .type = NLA_FLAG },
};
#if IS_REACHABLE(CONFIG_VIRTIO)
@@ -1337,7 +1338,7 @@ mac80211_hwsim_get_tx_rate(struct ieee80211_hw *hw,
static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
struct sk_buff *tx_skb,
- struct ieee80211_channel *chan)
+ u32 freq)
{
struct mac80211_hwsim_data *data = hw->priv;
struct sk_buff *skb;
@@ -1369,7 +1370,7 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
hdr->rt_tsft = __mac80211_hwsim_get_tsf(data);
hdr->rt_flags = 0;
hdr->rt_rate = bitrate / 5;
- hdr->rt_channel = cpu_to_le16(chan->center_freq);
+ hdr->rt_channel = cpu_to_le16(freq);
flags = IEEE80211_CHAN_2GHZ;
if (txrate && txrate->flags & IEEE80211_RATE_ERP_G)
flags |= IEEE80211_CHAN_OFDM;
@@ -1387,8 +1388,7 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
}
-static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan,
- const u8 *addr)
+static void mac80211_hwsim_monitor_ack(u32 freq, const u8 *addr)
{
struct sk_buff *skb;
struct hwsim_radiotap_ack_hdr *hdr;
@@ -1410,7 +1410,7 @@ static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan,
(1 << IEEE80211_RADIOTAP_CHANNEL));
hdr->rt_flags = 0;
hdr->pad = 0;
- hdr->rt_channel = cpu_to_le16(chan->center_freq);
+ hdr->rt_channel = cpu_to_le16(freq);
flags = IEEE80211_CHAN_2GHZ;
hdr->rt_chbitmask = cpu_to_le16(flags);
@@ -1735,6 +1735,9 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
if (nla_put_u64_64bit(skb, HWSIM_ATTR_COOKIE, cookie, HWSIM_ATTR_PAD))
goto nla_put_failure;
+ /* track the frequency */
+ info->rate_driver_data[1] = (void *)(uintptr_t)channel->center_freq;
+
genlmsg_end(skb, msg_head);
if (hwsim_virtio_enabled) {
@@ -1912,7 +1915,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
mac80211_hwsim_write_tsf(data, skb, sim_tsf);
- mac80211_hwsim_monitor_rx(hw, skb, chan);
+ mac80211_hwsim_monitor_rx(hw, skb, chan->center_freq);
memset(&rx_status, 0, sizeof(rx_status));
rx_status.flag |= RX_FLAG_MACTIME_START;
@@ -2276,7 +2279,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
ack = mac80211_hwsim_tx_frame_no_nl(hw, skb, channel);
if (ack && skb->len >= 16)
- mac80211_hwsim_monitor_ack(channel, hdr->addr2);
+ mac80211_hwsim_monitor_ack(channel->center_freq, hdr->addr2);
ieee80211_tx_info_clear_status(txi);
@@ -6391,6 +6394,8 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
int i;
unsigned long flags;
bool found = false;
+ bool no_monitor;
+ u32 freq;
if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] ||
!info->attrs[HWSIM_ATTR_FLAGS] ||
@@ -6402,6 +6407,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
src = (void *)nla_data(info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER]);
hwsim_flags = nla_get_u32(info->attrs[HWSIM_ATTR_FLAGS]);
ret_skb_cookie = nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]);
+ no_monitor = nla_get_flag(info->attrs[HWSIM_ATTR_NO_MONITOR]);
data2 = get_hwsim_data_ref_from_addr(src);
if (!data2)
@@ -6436,7 +6442,11 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
if (!found)
goto out;
- mac80211_hwsim_monitor_rx(data2->hw, skb, data2->channel);
+ txi = IEEE80211_SKB_CB(skb);
+ freq = (uintptr_t)txi->rate_driver_data[1];
+
+ if (!no_monitor)
+ mac80211_hwsim_monitor_rx(data2->hw, skb, freq);
/* Tx info received because the frame was broadcasted on user space,
so we get all the necessary info: tx attempts and skb control buff */
@@ -6445,8 +6455,6 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
info->attrs[HWSIM_ATTR_TX_INFO]);
/* now send back TX status */
- txi = IEEE80211_SKB_CB(skb);
-
ieee80211_tx_info_clear_status(txi);
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
@@ -6466,8 +6474,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
if (!(hwsim_flags & HWSIM_TX_CTL_NO_ACK) &&
(hwsim_flags & HWSIM_TX_STAT_ACK)) {
if (skb->len >= 16)
- mac80211_hwsim_monitor_ack(data2->channel,
- hdr->addr2);
+ mac80211_hwsim_monitor_ack(freq, hdr->addr2);
txi->flags |= IEEE80211_TX_STAT_ACK;
}
@@ -6535,6 +6542,51 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
goto out;
}
+ /* look for the skb matching the cookie passed back from user */
+ if (info->attrs[HWSIM_ATTR_COOKIE] &&
+ info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER]) {
+ u64 cookie = nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]);
+ struct sk_buff *orig_skb, *found = NULL;
+ struct mac80211_hwsim_data *txdata;
+ struct ieee80211_tx_info *txi;
+ const u8 *transmitter;
+ unsigned long flags;
+
+ transmitter = nla_data(info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER]);
+ txdata = get_hwsim_data_ref_from_addr(transmitter);
+ if (!txdata || txdata->netgroup != data2->netgroup)
+ goto out;
+
+ spin_lock_irqsave(&txdata->pending.lock, flags);
+ skb_queue_walk(&txdata->pending, orig_skb) {
+ uintptr_t skb_cookie;
+
+ txi = IEEE80211_SKB_CB(orig_skb);
+ skb_cookie = (uintptr_t)txi->rate_driver_data[0];
+
+ if (skb_cookie == cookie) {
+ found = orig_skb;
+ break;
+ }
+ }
+
+ /* that's weird */
+ if (!found) {
+ spin_unlock_irqrestore(&txdata->pending.lock, flags);
+ goto out;
+ }
+
+ if (frame_data_len > found->len &&
+ pskb_expand_head(found, 0, frame_data_len - found->len,
+ GFP_ATOMIC)) {
+ spin_unlock_irqrestore(&txdata->pending.lock, flags);
+ goto out;
+ }
+ skb_trim(found, 0);
+ skb_put_data(found, frame_data, frame_data_len);
+ spin_unlock_irqrestore(&txdata->pending.lock, flags);
+ }
+
/* check if radio is configured properly */
if ((data2->idle && !data2->tmp_chan) || !data2->started)
|
| 3/2 | 2026/09/11 14:26 | llm | patch-evaluator |
1mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 6216 output: 52 thoughts: 563 Thoughts: **Analyzing the Potential for Fuzzing this Patch** Okay, let's dive into this patch and figure out if it's fuzz-worthy, what kind of configuration it might need, and what symbols we should be focusing on. First, the diff... it looks like we're touching `drivers/net/wireless/virtual/mac80211_hwsim.h` and `drivers/net/wireless/virtual/mac80211_hwsim_main.c`. Right, `mac80211_hwsim` is that handy software simulator for 802.11 radios within mac80211. Good. It's a virtual netdev/wireless driver, accessible through generic netlink, specifically the nl80211/hwsim genl interface. Knowing Syzkaller already exercises it via this very interface is a plus – means we have a known attack surface. Now, the changes themselves...let me break this down. * We've got a new enum `hwsim_attrs` entry: `HWSIM_ATTR_NO_MONITOR`. This is interesting. * The `hwsim_genl_policy` is updated to include that new attribute as a flag. Okay. * Functions `mac80211_hwsim_monitor_rx` and `mac80211_hwsim_monitor_ack` have had their channel pointer arguments replaced with a `u32 freq` – using `info->rate_driver_data[1]` to store the center frequency. This seems like a potential area for fuzzing input values. * In `mac80211_hwsim_tx_frame_nl`, we're setting `info->rate_driver_data[1] = (void *)(uintptr_t)channel->center_freq;`. * Then in `hwsim_tx_info_frame_received_nl`, we are handling `HWSIM_ATTR_NO_MONITOR` and using that frequency from `rate_driver_data[1]`. * And finally, in `hwsim_cloned_frame_received_nl`... this is where things get interesting. We've got a new code block. If certain attributes are present (`HWSIM_ATTR_COOKIE` and `HWSIM_ATTR_ADDR_TRANSMITTER`), it looks up the transmitter hwsim\_data, checks the pending queue for a matching cookie, expands the head if necessary (`pskb_expand_head`), trims, and replaces the skb data with `frame_data` using `skb_put_data`. That `pskb_expand_head` call is often a good place to look. The focus here seems to be the interactions between cloned frames, transmitter data, and the manipulation of skbs. I need to understand the context of `hwsim_cloned_frame_received_nl` and `hwsim_tx_info_frame_received_nl` a bit better. This looks ripe for some directed fuzzing. |
| 4/2 | 2026/09/11 14:27 | tool | grepper |
0mArgs:{
"Expression": "hwsim_cloned_frame_received_nl",
"PathPrefix": "drivers/net/wireless/virtual/mac80211_hwsim_main.c"
}Results: {
"Output": "drivers/net/wireless/virtual/mac80211_hwsim_main.c=6382=static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-6490-\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:6491:static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-6492-\t\t\t\t\t struct genl_info *info)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=7157=static const struct genl_small_ops hwsim_ops[] = {\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-7166-\t\t.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:7167:\t\t.doit = hwsim_cloned_frame_received_nl,\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-7168-\t},\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=7348=static int hwsim_virtio_handle_cmd(struct sk_buff *skb)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-7372-\tcase HWSIM_CMD_FRAME:\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:7373:\t\thwsim_cloned_frame_received_nl(skb, \u0026info);\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-7374-\t\tbreak;\n"
} |
| 5/2 | 2026/09/11 14:27 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 8024 output: 38 thoughts: 44 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience: **Analyzing Kconfig Dependencies for mac80211_hwsim_main.c and mac80211_hwsim** Alright, let's dive in. My immediate thought is, before I start poking around with `mac80211_hwsim_main.c` and `mac80211_hwsim`, I *need* to verify the Kconfig dependencies. No point wasting time if a necessary option isn't enabled, or if something else is conflicting. I'm going to quickly check what's guarding those specific files and the core `mac80211_hwsim` functionality. I'll need to know: are we dependent on specific networking features, debug options, or perhaps even a particular wireless standard? Are there any obvious conflicts, like potentially a dependency on a platform that doesn't fully support all the test features in those files? I'll probably start with the immediate file, `mac80211_hwsim_main.c` and the associated Kconfig entry to see if there are any obvious preconditions. Then I'll expand outwards to anything that depends on `mac80211_hwsim`. I'm also thinking this is probably a good time to double-check that the modules themselves are configured correctly from a dependency point of view. Just a quick sanity check before I go any further. |
| 6/2 | 2026/09/11 14:28 | tool | grepper |
0mArgs:{
"Expression": "MAC80211_HWSIM",
"PathPrefix": "drivers/net/wireless/virtual/"
}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--\ndrivers/net/wireless/virtual/Makefile:1:obj-$(CONFIG_MAC80211_HWSIM)\t+= mac80211_hwsim.o\ndrivers/net/wireless/virtual/Makefile-2-mac80211_hwsim-objs\t\t+= mac80211_hwsim_main.o\n--\ndrivers/net/wireless/virtual/mac80211_hwsim.h-8-\ndrivers/net/wireless/virtual/mac80211_hwsim.h:9:#ifndef __MAC80211_HWSIM_H\ndrivers/net/wireless/virtual/mac80211_hwsim.h:10:#define __MAC80211_HWSIM_H\ndrivers/net/wireless/virtual/mac80211_hwsim.h-11-\n--\ndrivers/net/wireless/virtual/mac80211_hwsim.h=220=struct hwsim_tx_rate {\n--\ndrivers/net/wireless/virtual/mac80211_hwsim.h-233- *\ndrivers/net/wireless/virtual/mac80211_hwsim.h:234: * @MAC80211_HWSIM_TX_RC_USE_RTS_CTS: Use RTS/CTS exchange for this rate.\ndrivers/net/wireless/virtual/mac80211_hwsim.h:235: * @MAC80211_HWSIM_TX_RC_USE_CTS_PROTECT: CTS-to-self protection is required.\ndrivers/net/wireless/virtual/mac80211_hwsim.h-236- *\tThis is set if the current BSS requires ERP protection.\ndrivers/net/wireless/virtual/mac80211_hwsim.h:237: * @MAC80211_HWSIM_TX_RC_USE_SHORT_PREAMBLE: Use short preamble.\ndrivers/net/wireless/virtual/mac80211_hwsim.h:238: * @MAC80211_HWSIM_TX_RC_MCS: HT rate.\ndrivers/net/wireless/virtual/mac80211_hwsim.h:239: * @MAC80211_HWSIM_TX_RC_VHT_MCS: VHT MCS rate, in this case the idx field is\ndrivers/net/wireless/virtual/mac80211_hwsim.h-240- *\tsplit into a higher 4 bits (Nss) and lower 4 bits (MCS number)\ndrivers/net/wireless/virtual/mac80211_hwsim.h:241: * @MAC80211_HWSIM_TX_RC_GREEN_FIELD: Indicates whether this rate should be used\ndrivers/net/wireless/virtual/mac80211_hwsim.h-242- *\tin Greenfield mode.\ndrivers/net/wireless/virtual/mac80211_hwsim.h:243: * @MAC80211_HWSIM_TX_RC_40_MHZ_WIDTH: Indicates if the Channel Width should be\ndrivers/net/wireless/virtual/mac80211_hwsim.h-244- *\t40 MHz.\ndrivers/net/wireless/virtual/mac80211_hwsim.h:245: * @MAC80211_HWSIM_TX_RC_80_MHZ_WIDTH: Indicates 80 MHz transmission\ndrivers/net/wireless/virtual/mac80211_hwsim.h:246: * @MAC80211_HWSIM_TX_RC_160_MHZ_WIDTH: Indicates 160 MHz transmission\ndrivers/net/wireless/virtual/mac80211_hwsim.h-247- *\t(80+80 isn't supported yet)\ndrivers/net/wireless/virtual/mac80211_hwsim.h:248: * @MAC80211_HWSIM_TX_RC_DUP_DATA: The frame should be transmitted on both of\ndrivers/net/wireless/virtual/mac80211_hwsim.h-249- *\tthe adjacent 20 MHz channels, if the current channel type is\ndrivers/net/wireless/virtual/mac80211_hwsim.h-250- *\tNL80211_CHAN_HT40MINUS or NL80211_CHAN_HT40PLUS.\ndrivers/net/wireless/virtual/mac80211_hwsim.h:251: * @MAC80211_HWSIM_TX_RC_SHORT_GI: Short Guard interval should be used for this\ndrivers/net/wireless/virtual/mac80211_hwsim.h-252- *\trate.\n--\ndrivers/net/wireless/virtual/mac80211_hwsim.h=254=enum hwsim_tx_rate_flags {\ndrivers/net/wireless/virtual/mac80211_hwsim.h:255:\tMAC80211_HWSIM_TX_RC_USE_RTS_CTS\t\t= BIT(0),\ndrivers/net/wireless/virtual/mac80211_hwsim.h:256:\tMAC80211_HWSIM_TX_RC_USE_CTS_PROTECT\t\t= BIT(1),\ndrivers/net/wireless/virtual/mac80211_hwsim.h:257:\tMAC80211_HWSIM_TX_RC_USE_SHORT_PREAMBLE\t= BIT(2),\ndrivers/net/wireless/virtual/mac80211_hwsim.h-258-\ndrivers/net/wireless/virtual/mac80211_hwsim.h-259-\t/* rate index is an HT/VHT MCS instead of an index */\ndrivers/net/wireless/virtual/mac80211_hwsim.h:260:\tMAC80211_HWSIM_TX_RC_MCS\t\t\t= BIT(3),\ndrivers/net/wireless/virtual/mac80211_hwsim.h:261:\tMAC80211_HWSIM_TX_RC_GREEN_FIELD\t\t= BIT(4),\ndrivers/net/wireless/virtual/mac80211_hwsim.h:262:\tMAC80211_HWSIM_TX_RC_40_MHZ_WIDTH\t\t= BIT(5),\ndrivers/net/wireless/virtual/mac80211_hwsim.h:263:\tMAC80211_HWSIM_TX_RC_DUP_DATA\t\t= BIT(6),\ndrivers/net/wireless/virtual/mac80211_hwsim.h:264:\tMAC80211_HWSIM_TX_RC_SHORT_GI\t\t= BIT(7),\ndrivers/net/wireless/virtual/mac80211_hwsim.h:265:\tMAC80211_HWSIM_TX_RC_VHT_MCS\t\t\t= BIT(8),\ndrivers/net/wireless/virtual/mac80211_hwsim.h:266:\tMAC80211_HWSIM_TX_RC_80_MHZ_WIDTH\t\t= BIT(9),\ndrivers/net/wireless/virtual/mac80211_hwsim.h:267:\tMAC80211_HWSIM_TX_RC_160_MHZ_WIDTH\t\t= BIT(10),\ndrivers/net/wireless/virtual/mac80211_hwsim.h-268-};\n--\ndrivers/net/wireless/virtual/mac80211_hwsim.h=331=enum hwsim_rate_info_attributes {\n--\ndrivers/net/wireless/virtual/mac80211_hwsim.h-350-\ndrivers/net/wireless/virtual/mac80211_hwsim.h:351:#endif /* __MAC80211_HWSIM_H */\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_i.h-9-\ndrivers/net/wireless/virtual/mac80211_hwsim_i.h:10:#ifndef __MAC80211_HWSIM_I_H\ndrivers/net/wireless/virtual/mac80211_hwsim_i.h:11:#define __MAC80211_HWSIM_I_H\ndrivers/net/wireless/virtual/mac80211_hwsim_i.h-12-\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_i.h=165=void ieee80211_hwsim_wake_tx_queue(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_i.h-167-\ndrivers/net/wireless/virtual/mac80211_hwsim_i.h:168:#endif /* __MAC80211_HWSIM_I_H */\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=712=static struct mac80211_hwsim_data *get_hwsim_data_ref_from_addr(const u8 *addr)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-716-\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:717:/* MAC80211_HWSIM netlink family */\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-718-static struct genl_family hwsim_genl_family;\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=724=static const struct genl_multicast_group hwsim_mcgrps[] = {\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-727-\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:728:/* MAC80211_HWSIM netlink policy */\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-729-\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=865=static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-902-\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:903:/* MAC80211_HWSIM virtio queues */\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-904-static struct virtqueue *hwsim_vqs[HWSIM_NUM_VQS];\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=1575=static inline u16 trans_tx_rate_flags_ieee2hwsim(struct ieee80211_tx_rate *rate)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-1579-\tif (rate-\u003eflags \u0026 IEEE80211_TX_RC_USE_RTS_CTS)\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:1580:\t\tresult |= MAC80211_HWSIM_TX_RC_USE_RTS_CTS;\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-1581-\tif (rate-\u003eflags \u0026 IEEE80211_TX_RC_USE_CTS_PROTECT)\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:1582:\t\tresult |= MAC80211_HWSIM_TX_RC_USE_CTS_PROTECT;\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-1583-\tif (rate-\u003eflags \u0026 IEEE80211_TX_RC_USE_SHORT_PREAMBLE)\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:1584:\t\tresult |= MAC80211_HWSIM_TX_RC_USE_SHORT_PREAMBLE;\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-1585-\tif (rate-\u003eflags \u0026 IEEE80211_TX_RC_MCS)\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:1586:\t\tresult |= MAC80211_HWSIM_TX_RC_MCS;\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-1587-\tif (rate-\u003eflags \u0026 IEEE80211_TX_RC_GREEN_FIELD)\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:1588:\t\tresult |= MAC80211_HWSIM_TX_RC_GREEN_FIELD;\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-1589-\tif (rate-\u003eflags \u0026 IEEE80211_TX_RC_40_MHZ_WIDTH)\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:1590:\t\tresult |= MAC80211_HWSIM_TX_RC_40_MHZ_WIDTH;\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-1591-\tif (rate-\u003eflags \u0026 IEEE80211_TX_RC_DUP_DATA)\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:1592:\t\tresult |= MAC80211_HWSIM_TX_RC_DUP_DATA;\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-1593-\tif (rate-\u003eflags \u0026 IEEE80211_TX_RC_SHORT_GI)\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:1594:\t\tresult |= MAC80211_HWSIM_TX_RC_SHORT_GI;\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-1595-\tif (rate-\u003eflags \u0026 IEEE80211_TX_RC_VHT_MCS)\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:1596:\t\tresult |= MAC80211_HWSIM_TX_RC_VHT_MCS;\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-1597-\tif (rate-\u003eflags \u0026 IEEE80211_TX_RC_80_MHZ_WIDTH)\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:1598:\t\tresult |= MAC80211_HWSIM_TX_RC_80_MHZ_WIDTH;\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-1599-\tif (rate-\u003eflags \u0026 IEEE80211_TX_RC_160_MHZ_WIDTH)\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:1600:\t\tresult |= MAC80211_HWSIM_TX_RC_160_MHZ_WIDTH;\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-1601-\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=3487=static const char mac80211_hwsim_gstrings_stats[][ETH_GSTRING_LEN] = {\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-3497-\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:3498:#define MAC80211_HWSIM_SSTATS_LEN ARRAY_SIZE(mac80211_hwsim_gstrings_stats)\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-3499-\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=3509=static int mac80211_hwsim_get_et_sset_count(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-3512-\tif (sset == ETH_SS_STATS)\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:3513:\t\treturn MAC80211_HWSIM_SSTATS_LEN;\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-3514-\treturn 0;\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=3517=static void mac80211_hwsim_get_et_stats(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-3532-\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:3533:\tWARN_ON(i != MAC80211_HWSIM_SSTATS_LEN);\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-3534-}\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=5650=static const u8 iftypes_ext_capa_ap[] = {\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-5658-\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:5659:#define MAC80211_HWSIM_MLD_CAPA_OPS\t\t\t\t\\\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-5660-\tFIELD_PREP_CONST(IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP, \\\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=5665=static const struct wiphy_iftype_ext_capab mac80211_hwsim_iftypes_ext_capa[] = {\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-5672-\t\t\t\t IEEE80211_EML_CAP_EMLMR_SUPPORT,\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:5673:\t\t.mld_capa_and_ops = MAC80211_HWSIM_MLD_CAPA_OPS,\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-5674-\t},\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=7199=static struct genl_family hwsim_genl_family __ro_after_init = {\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:7200:\t.name = \"MAC80211_HWSIM\",\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-7201-\t.version = 1,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=7519=static void hwsim_virtio_remove(struct virtio_device *vdev)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-7527-\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:7528:/* MAC80211_HWSIM virtio device id table */\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-7529-static const struct virtio_device_id id_table[] = {\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:7530:\t{ VIRTIO_ID_MAC80211_HWSIM, VIRTIO_DEV_ANY_ID },\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-7531-\t{ 0 }\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=78=static u64 hwsim_nan_get_master_rank(struct mac80211_hwsim_data *data)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-82-\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:83:\tif (data-\u003enan.phase == MAC80211_HWSIM_NAN_PHASE_UP) {\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-84-\t\tmaster_pref = data-\u003enan.master_pref;\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=216=void mac80211_hwsim_nan_rx(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-273-\tif ((slot != SLOT_24GHZ_DW \u0026\u0026\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:274:\t data-\u003enan.phase != MAC80211_HWSIM_NAN_PHASE_SCAN) ||\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-275-\t rx_status.freq != 2437)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-436-\t\t (cg == own_cg \u0026\u0026 frame_amr \u003e curr_amr) ||\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:437:\t\t data-\u003enan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN) {\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-438-\t\t\t/* Avoid a state transition */\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-468-\t\t\t */\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:469:\t\t\tdata-\u003enan.phase = MAC80211_HWSIM_NAN_PHASE_UP;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-470-\t\t\tdata-\u003enan.random_factor_valid_dwst = 0;\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=612=mac80211_hwsim_nan_exec_state_transitions(struct mac80211_hwsim_data *data)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-625-\tif (data-\u003enan.master_transition_score \u003c 3)\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:626:\t\tdata-\u003enan.role = MAC80211_HWSIM_NAN_ROLE_MASTER;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:627:\telse if (data-\u003enan.role == MAC80211_HWSIM_NAN_ROLE_MASTER \u0026\u0026\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-628-\t\t data-\u003enan.master_transition_score \u003e= 3)\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:629:\t\tdata-\u003enan.role = MAC80211_HWSIM_NAN_ROLE_SYNC;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:630:\telse if (data-\u003enan.role == MAC80211_HWSIM_NAN_ROLE_SYNC \u0026\u0026\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-631-\t\t data-\u003enan.sync_transition_score \u003e= 3)\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:632:\t\tdata-\u003enan.role = MAC80211_HWSIM_NAN_ROLE_NON_SYNC;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:633:\telse if (data-\u003enan.role == MAC80211_HWSIM_NAN_ROLE_NON_SYNC \u0026\u0026\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-634-\t\t data-\u003enan.sync_transition_score \u003c 3)\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:635:\t\tdata-\u003enan.role = MAC80211_HWSIM_NAN_ROLE_SYNC;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-636-\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-641-\t */\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:642:\tif (data-\u003enan.role == MAC80211_HWSIM_NAN_ROLE_MASTER \u0026\u0026\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-643-\t !hrtimer_active(\u0026data-\u003enan.discovery_beacon_timer))\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-653-\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:654:\t\tif (data-\u003enan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN) {\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:655:\t\t\tdata-\u003enan.phase = MAC80211_HWSIM_NAN_PHASE_WARMUP;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-656-\t\t\tdata-\u003enan.random_factor_valid_dwst = NAN_WARMUP_DWST;\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-659-\t\t} else {\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:660:\t\t\tdata-\u003enan.phase = MAC80211_HWSIM_NAN_PHASE_UP;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-661-\t\t\tdata-\u003enan.random_factor_valid_dwst =\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=695=mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-750-\tnan_attr.length = cpu_to_le16(sizeof(master_indication));\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:751:\tif (data-\u003enan.phase == MAC80211_HWSIM_NAN_PHASE_UP) {\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-752-\t\tmaster_indication.master_pref = data-\u003enan.master_pref;\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=774=mac80211_hwsim_nan_slot_timer(struct hrtimer *timer)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-807-\t\ttx_sync_beacon =\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:808:\t\t\tdata-\u003enan.phase != MAC80211_HWSIM_NAN_PHASE_SCAN \u0026\u0026\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:809:\t\t\tdata-\u003enan.role != MAC80211_HWSIM_NAN_ROLE_NON_SYNC;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-810-\t}\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=867=mac80211_hwsim_nan_discovery_beacon_timer(struct hrtimer *timer)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-879-\tscoped_guard(spinlock, \u0026data-\u003enan.state_lock) {\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:880:\t\tif (data-\u003enan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN ||\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:881:\t\t data-\u003enan.role != MAC80211_HWSIM_NAN_ROLE_MASTER)\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-882-\t\t\treturn HRTIMER_NORESTART;\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=909=int mac80211_hwsim_nan_start(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-926-\t\t/* Start in the \"scan\" phase and stay there for a little bit */\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:927:\t\tdata-\u003enan.phase = MAC80211_HWSIM_NAN_PHASE_SCAN;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-928-\t\tdata-\u003enan.random_factor_valid_dwst = 1;\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-930-\t\tdata-\u003enan.master_pref = conf-\u003emaster_pref;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:931:\t\tdata-\u003enan.role = MAC80211_HWSIM_NAN_ROLE_MASTER;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-932-\t\tmemset(\u0026data-\u003enan.current_ami, 0,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=1226=bool mac80211_hwsim_nan_receive(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1235-\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:1236:\tif (data-\u003enan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN)\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1237-\t\treturn channel-\u003ecenter_freq == 2437;\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h-6-\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h:7:#ifndef __MAC80211_HWSIM_NAN_H\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h:8:#define __MAC80211_HWSIM_NAN_H\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h-9-\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h=10=enum mac80211_hwsim_nan_phase {\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h:11:\tMAC80211_HWSIM_NAN_PHASE_SCAN,\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h:12:\tMAC80211_HWSIM_NAN_PHASE_WARMUP,\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h:13:\tMAC80211_HWSIM_NAN_PHASE_UP,\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h-14-};\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h=16=enum mac80211_hwsim_nan_role {\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h:17:\tMAC80211_HWSIM_NAN_ROLE_MASTER,\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h:18:\tMAC80211_HWSIM_NAN_ROLE_SYNC,\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h:19:\tMAC80211_HWSIM_NAN_ROLE_NON_SYNC,\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h-20-};\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h=99=void mac80211_hwsim_nan_local_sched_changed(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h-101-\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h:102:#endif /* __MAC80211_HWSIM_NAN_H */\n"
} |
| 7/2 | 2026/09/11 14:28 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 17376 output: 36 thoughts: 16 Thoughts: Here's my take on the thought process, as if I were the one thinking it: **Diving into Virtual Wireless Configuration** Okay, time to get my hands dirty. I need to understand the configuration options available for the virtual wireless network driver. My first instinct, as always, is to head straight to the source. Specifically, I need to check the Kconfig file for that driver. Let's start with `drivers/net/wireless/virtual/Kconfig`. This is where all the juicy details about feature flags, dependencies, and default settings are kept. That's the first stop to understand how this module fits into the broader wireless landscape and what's configurable. Let's see what we can find. |
| 8/2 | 2026/09/11 14:28 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/virtual/Kconfig",
"FirstLine": 1,
"LineCount": 40
}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"
} |
| 9/2 | 2026/09/11 14:28 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 17904 output: 40 thoughts: 42 Thoughts: Here's my thought process, as if I were considering this issue: **Investigating MAC80211 Configuration** Okay, so I need to figure out the configuration dependencies for `MAC80211` and specifically `MAC80211_HWSIM`. My initial instinct is to dive into the Kconfig files – namely, `net/mac80211/Kconfig`. That's the logical place to start, as it should define the relevant options and their relationships. I should be able to trace the dependencies from there. I’ll need to understand if `MAC80211_HWSIM` has specific dependencies that need to be met before it can even be considered, or if it is just a suboption of the general `MAC80211` configuration. I might also need to look at parent Kconfig files or dependencies, just in case something is defined or conditioned higher up in the hierarchy. This is where the magic usually happens. I should quickly be able to see the relevant 'depends on' clauses and any potentially conflicting options. Understanding the full configuration context is the key to solving this. |
| 10/2 | 2026/09/11 14:28 | tool | grepper |
0mArgs:{
"Expression": "config MAC80211\\b",
"PathPrefix": "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"
} |
| 11/2 | 2026/09/11 14:28 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 18331 output: 37 thoughts: 25 Thoughts: Here's my take on the line of thought, reflecting as an expert: **Diving into the `net/mac80211/Kconfig` File** Alright, let's get down to brass tacks. I need to take a look at the `net/mac80211/Kconfig` file, specifically around line 2. Given that this is a configuration file, my immediate assumption is that this region likely defines some core, fundamental configurations related to the mac80211 wireless subsystem. Knowing that mac80211 is the heart of the Linux wireless stack, I'm expecting to find either a general module or a top-level macro. I'm going in with the expectation of getting a foundational overview. |
| 12/2 | 2026/09/11 14:28 | tool | read-file |
0mArgs:{
"File": "net/mac80211/Kconfig",
"FirstLine": 1,
"LineCount": 20
}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"
} |
| 13/2 | 2026/09/11 14:28 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 18837 output: 51 thoughts: 186 Thoughts: Okay, let's dive into these code changes. I need to make sure I understand the modifications fully, so I'll verify their reach, purpose, and identify any potential vulnerabilities or edge cases. **Code Review - Analyzing Recent Changes in mac80211_hwsim** First, I need to focus on these specific functions: `mac80211_hwsim_monitor_rx`, `mac80211_hwsim_monitor_ack`, `mac80211_hwsim_tx_frame_nl`, `mac80211_hwsim_tx_frame_no_nl`, `mac80211_hwsim_tx`, `hwsim_tx_info_frame_received_nl`, and `hwsim_cloned_frame_received_nl`. They're the core of the recent work. I will approach this systematically. To get a good understanding, I'll start by taking a close look at the code block in `drivers/net/wireless/virtual/mac80211_hwsim_main.c`, specifically around lines 6490 to 6590. This should provide the context for these functions. I will start by going through the code line by line and try to understand what's happening. |
| 14/2 | 2026/09/11 14:28 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/virtual/mac80211_hwsim_main.c",
"FirstLine": 6490,
"LineCount": 100
}Results: {
"Contents": "6490:\t\n6491:\tstatic int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,\n6492:\t\t\t\t\t\t struct genl_info *info)\n6493:\t{\n6494:\t\tstruct mac80211_hwsim_data *data2;\n6495:\t\tstruct ieee80211_rx_status rx_status;\n6496:\t\tstruct ieee80211_hdr *hdr;\n6497:\t\tconst u8 *dst;\n6498:\t\tint frame_data_len;\n6499:\t\tvoid *frame_data;\n6500:\t\tstruct sk_buff *skb = NULL;\n6501:\t\tstruct ieee80211_channel *channel = NULL;\n6502:\t\n6503:\t\tif (!info-\u003eattrs[HWSIM_ATTR_ADDR_RECEIVER] ||\n6504:\t\t !info-\u003eattrs[HWSIM_ATTR_FRAME] ||\n6505:\t\t !info-\u003eattrs[HWSIM_ATTR_RX_RATE] ||\n6506:\t\t !info-\u003eattrs[HWSIM_ATTR_SIGNAL])\n6507:\t\t\tgoto out;\n6508:\t\n6509:\t\tdst = (void *)nla_data(info-\u003eattrs[HWSIM_ATTR_ADDR_RECEIVER]);\n6510:\t\tframe_data_len = nla_len(info-\u003eattrs[HWSIM_ATTR_FRAME]);\n6511:\t\tframe_data = (void *)nla_data(info-\u003eattrs[HWSIM_ATTR_FRAME]);\n6512:\t\n6513:\t\tif (frame_data_len \u003c sizeof(struct ieee80211_hdr_3addr) ||\n6514:\t\t frame_data_len \u003e IEEE80211_MAX_DATA_LEN)\n6515:\t\t\tgoto err;\n6516:\t\n6517:\t\t/* Allocate new skb here */\n6518:\t\tskb = alloc_skb(frame_data_len, GFP_KERNEL);\n6519:\t\tif (skb == NULL)\n6520:\t\t\tgoto err;\n6521:\t\n6522:\t\t/* Copy the data */\n6523:\t\tskb_put_data(skb, frame_data, frame_data_len);\n6524:\t\n6525:\t\tdata2 = get_hwsim_data_ref_from_addr(dst);\n6526:\t\tif (!data2)\n6527:\t\t\tgoto out;\n6528:\t\n6529:\t\tif (data2-\u003euse_chanctx) {\n6530:\t\t\tif (data2-\u003etmp_chan)\n6531:\t\t\t\tchannel = data2-\u003etmp_chan;\n6532:\t\t} else {\n6533:\t\t\tchannel = data2-\u003echannel;\n6534:\t\t}\n6535:\t\n6536:\t\tif (!hwsim_virtio_enabled) {\n6537:\t\t\tif (hwsim_net_get_netgroup(genl_info_net(info)) !=\n6538:\t\t\t data2-\u003enetgroup)\n6539:\t\t\t\tgoto out;\n6540:\t\n6541:\t\t\tif (info-\u003esnd_portid != data2-\u003ewmediumd)\n6542:\t\t\t\tgoto out;\n6543:\t\t}\n6544:\t\n6545:\t\t/* look for the skb matching the cookie passed back from user */\n6546:\t\tif (info-\u003eattrs[HWSIM_ATTR_COOKIE] \u0026\u0026\n6547:\t\t info-\u003eattrs[HWSIM_ATTR_ADDR_TRANSMITTER]) {\n6548:\t\t\tu64 cookie = nla_get_u64(info-\u003eattrs[HWSIM_ATTR_COOKIE]);\n6549:\t\t\tstruct sk_buff *orig_skb, *found = NULL;\n6550:\t\t\tstruct mac80211_hwsim_data *txdata;\n6551:\t\t\tstruct ieee80211_tx_info *txi;\n6552:\t\t\tconst u8 *transmitter;\n6553:\t\t\tunsigned long flags;\n6554:\t\n6555:\t\t\ttransmitter = nla_data(info-\u003eattrs[HWSIM_ATTR_ADDR_TRANSMITTER]);\n6556:\t\t\ttxdata = get_hwsim_data_ref_from_addr(transmitter);\n6557:\t\t\tif (!txdata || txdata-\u003enetgroup != data2-\u003enetgroup)\n6558:\t\t\t\tgoto out;\n6559:\t\n6560:\t\t\tspin_lock_irqsave(\u0026txdata-\u003epending.lock, flags);\n6561:\t\t\tskb_queue_walk(\u0026txdata-\u003epending, orig_skb) {\n6562:\t\t\t\tuintptr_t skb_cookie;\n6563:\t\n6564:\t\t\t\ttxi = IEEE80211_SKB_CB(orig_skb);\n6565:\t\t\t\tskb_cookie = (uintptr_t)txi-\u003erate_driver_data[0];\n6566:\t\n6567:\t\t\t\tif (skb_cookie == cookie) {\n6568:\t\t\t\t\tfound = orig_skb;\n6569:\t\t\t\t\tbreak;\n6570:\t\t\t\t}\n6571:\t\t\t}\n6572:\t\n6573:\t\t\t/* that's weird */\n6574:\t\t\tif (!found) {\n6575:\t\t\t\tspin_unlock_irqrestore(\u0026txdata-\u003epending.lock, flags);\n6576:\t\t\t\tgoto out;\n6577:\t\t\t}\n6578:\t\n6579:\t\t\tif (frame_data_len \u003e found-\u003elen \u0026\u0026\n6580:\t\t\t pskb_expand_head(found, 0, frame_data_len - found-\u003elen,\n6581:\t\t\t\t\t GFP_ATOMIC)) {\n6582:\t\t\t\tspin_unlock_irqrestore(\u0026txdata-\u003epending.lock, flags);\n6583:\t\t\t\tgoto out;\n6584:\t\t\t}\n6585:\t\t\tskb_trim(found, 0);\n6586:\t\t\tskb_put_data(found, frame_data, frame_data_len);\n6587:\t\t\tspin_unlock_irqrestore(\u0026txdata-\u003epending.lock, flags);\n6588:\t\t}\n6589:\t\n"
} |
| 15/2 | 2026/09/11 14:28 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 21009 output: 50 thoughts: 64 Thoughts: Here's my summary, as if I were thinking these thoughts: **Analyzing Hardware Simulation for Frame Transmission** Okay, I need to dig into the hardware simulation aspects of this frame transmission process a bit deeper. I should probably focus on two specific areas in the code. I'm thinking I should really understand the flow from the point the hardware simulation receives some TX information; I'll focus on `hwsim_tx_info_frame_received_nl` (lines 6390-6490). It's crucial to understand how the simulation processes that input. Then, I need to see how the hardware simulation actually *sends* the frame, so I'll also be examining `mac80211_hwsim_tx_frame_nl` (lines 1720-1760). By examining these two functions, I'll build a much better picture of how the simulation handles TX frame data end-to-end. |
| 16/2 | 2026/09/11 14:28 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/virtual/mac80211_hwsim_main.c",
"FirstLine": 6390,
"LineCount": 90
}Results: {
"Contents": "6390:\t\tu64 ret_skb_cookie;\n6391:\t\tstruct sk_buff *skb, *tmp;\n6392:\t\tconst u8 *src;\n6393:\t\tunsigned int hwsim_flags;\n6394:\t\tint i;\n6395:\t\tunsigned long flags;\n6396:\t\tbool found = false;\n6397:\t\tbool no_monitor;\n6398:\t\tu32 freq;\n6399:\t\n6400:\t\tif (!info-\u003eattrs[HWSIM_ATTR_ADDR_TRANSMITTER] ||\n6401:\t\t !info-\u003eattrs[HWSIM_ATTR_FLAGS] ||\n6402:\t\t !info-\u003eattrs[HWSIM_ATTR_COOKIE] ||\n6403:\t\t !info-\u003eattrs[HWSIM_ATTR_SIGNAL] ||\n6404:\t\t !info-\u003eattrs[HWSIM_ATTR_TX_INFO])\n6405:\t\t\tgoto out;\n6406:\t\n6407:\t\tsrc = (void *)nla_data(info-\u003eattrs[HWSIM_ATTR_ADDR_TRANSMITTER]);\n6408:\t\thwsim_flags = nla_get_u32(info-\u003eattrs[HWSIM_ATTR_FLAGS]);\n6409:\t\tret_skb_cookie = nla_get_u64(info-\u003eattrs[HWSIM_ATTR_COOKIE]);\n6410:\t\tno_monitor = nla_get_flag(info-\u003eattrs[HWSIM_ATTR_NO_MONITOR]);\n6411:\t\n6412:\t\tdata2 = get_hwsim_data_ref_from_addr(src);\n6413:\t\tif (!data2)\n6414:\t\t\tgoto out;\n6415:\t\n6416:\t\tif (!hwsim_virtio_enabled) {\n6417:\t\t\tif (hwsim_net_get_netgroup(genl_info_net(info)) !=\n6418:\t\t\t data2-\u003enetgroup)\n6419:\t\t\t\tgoto out;\n6420:\t\n6421:\t\t\tif (info-\u003esnd_portid != data2-\u003ewmediumd)\n6422:\t\t\t\tgoto out;\n6423:\t\t}\n6424:\t\n6425:\t\t/* look for the skb matching the cookie passed back from user */\n6426:\t\tspin_lock_irqsave(\u0026data2-\u003epending.lock, flags);\n6427:\t\tskb_queue_walk_safe(\u0026data2-\u003epending, skb, tmp) {\n6428:\t\t\tuintptr_t skb_cookie;\n6429:\t\n6430:\t\t\ttxi = IEEE80211_SKB_CB(skb);\n6431:\t\t\tskb_cookie = (uintptr_t)txi-\u003erate_driver_data[0];\n6432:\t\n6433:\t\t\tif (skb_cookie == ret_skb_cookie) {\n6434:\t\t\t\t__skb_unlink(skb, \u0026data2-\u003epending);\n6435:\t\t\t\tfound = true;\n6436:\t\t\t\tbreak;\n6437:\t\t\t}\n6438:\t\t}\n6439:\t\tspin_unlock_irqrestore(\u0026data2-\u003epending.lock, flags);\n6440:\t\n6441:\t\t/* not found */\n6442:\t\tif (!found)\n6443:\t\t\tgoto out;\n6444:\t\n6445:\t\ttxi = IEEE80211_SKB_CB(skb);\n6446:\t\tfreq = (uintptr_t)txi-\u003erate_driver_data[1];\n6447:\t\n6448:\t\tif (!no_monitor)\n6449:\t\t\tmac80211_hwsim_monitor_rx(data2-\u003ehw, skb, freq);\n6450:\t\n6451:\t\t/* Tx info received because the frame was broadcasted on user space,\n6452:\t\t so we get all the necessary info: tx attempts and skb control buff */\n6453:\t\n6454:\t\ttx_attempts = (struct hwsim_tx_rate *)nla_data(\n6455:\t\t\t info-\u003eattrs[HWSIM_ATTR_TX_INFO]);\n6456:\t\n6457:\t\t/* now send back TX status */\n6458:\t\tieee80211_tx_info_clear_status(txi);\n6459:\t\n6460:\t\tfor (i = 0; i \u003c IEEE80211_TX_MAX_RATES; i++) {\n6461:\t\t\ttxi-\u003estatus.rates[i].idx = tx_attempts[i].idx;\n6462:\t\t\ttxi-\u003estatus.rates[i].count = tx_attempts[i].count;\n6463:\t\t}\n6464:\t\n6465:\t\ttxi-\u003estatus.ack_signal = nla_get_u32(info-\u003eattrs[HWSIM_ATTR_SIGNAL]);\n6466:\t\n6467:\t\thdr = (struct ieee80211_hdr *)skb-\u003edata;\n6468:\t\ti = mac80211_hwsim_get_link_id(txi-\u003econtrol.vif, hdr);\n6469:\t\tif (i \u003e= 0) {\n6470:\t\t\ttxi-\u003estatus.link_valid = 1;\n6471:\t\t\ttxi-\u003estatus.link_id = i;\n6472:\t\t}\n6473:\t\n6474:\t\tif (!(hwsim_flags \u0026 HWSIM_TX_CTL_NO_ACK) \u0026\u0026\n6475:\t\t (hwsim_flags \u0026 HWSIM_TX_STAT_ACK)) {\n6476:\t\t\tif (skb-\u003elen \u003e= 16)\n6477:\t\t\t\tmac80211_hwsim_monitor_ack(freq, hdr-\u003eaddr2);\n6478:\t\t\ttxi-\u003eflags |= IEEE80211_TX_STAT_ACK;\n6479:\t\t}\n"
} |
| 17/2 | 2026/09/11 14:28 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 22891 output: 50 thoughts: 36 Thoughts: Okay, let's dive into this. **Examining the `mac80211_hwsim_tx_frame_nl` Function** Right, so I need to examine the `mac80211_hwsim_tx_frame_nl` function, specifically focusing on lines 1720 through 1760. I immediately know the context here; this likely deals with the network layer interaction in the `mac80211_hwsim` module, specifically the transmission side of things given the "tx" in the function name. I'm expecting this is where network frames are processed, formatted, and ultimately handed off (or simulated as handed off) to the hardware abstraction layer for transmission – or, in this simulated case, handled within the hwsim environment. I'll need to see how the netlink attributes are parsed to know exactly how the frame characteristics are being presented, and then how the simulation handles that to proceed. There might be some interesting bits on frame serialization or simulation of transmission errors in this section, so that's something I'll be sure to look for. I'll be looking to see how it handles things like the rate control parameters, the queueing discipline, and any potential hardware-specific information that might be relevant in this simulation. |
| 18/2 | 2026/09/11 14:28 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/virtual/mac80211_hwsim_main.c",
"FirstLine": 1720,
"LineCount": 50
}Results: {
"Contents": "1720:\t\t}\n1721:\t\n1722:\t\tif (nla_put(skb, HWSIM_ATTR_TX_INFO,\n1723:\t\t\t sizeof(struct hwsim_tx_rate)*IEEE80211_TX_MAX_RATES,\n1724:\t\t\t tx_attempts))\n1725:\t\t\tgoto nla_put_failure;\n1726:\t\n1727:\t\tif (nla_put(skb, HWSIM_ATTR_TX_INFO_FLAGS,\n1728:\t\t\t sizeof(struct hwsim_tx_rate_flag) * IEEE80211_TX_MAX_RATES,\n1729:\t\t\t tx_attempts_flags))\n1730:\t\t\tgoto nla_put_failure;\n1731:\t\n1732:\t\t/* We create a cookie to identify this skb */\n1733:\t\tcookie = atomic_inc_return(\u0026data-\u003epending_cookie);\n1734:\t\tinfo-\u003erate_driver_data[0] = (void *)cookie;\n1735:\t\tif (nla_put_u64_64bit(skb, HWSIM_ATTR_COOKIE, cookie, HWSIM_ATTR_PAD))\n1736:\t\t\tgoto nla_put_failure;\n1737:\t\n1738:\t\t/* track the frequency */\n1739:\t\tinfo-\u003erate_driver_data[1] = (void *)(uintptr_t)channel-\u003ecenter_freq;\n1740:\t\n1741:\t\tgenlmsg_end(skb, msg_head);\n1742:\t\n1743:\t\tif (hwsim_virtio_enabled) {\n1744:\t\t\tif (hwsim_tx_virtio(data, skb))\n1745:\t\t\t\tgoto err_free_txskb;\n1746:\t\t} else {\n1747:\t\t\tif (hwsim_unicast_netgroup(data, skb, dst_portid))\n1748:\t\t\t\tgoto err_free_txskb;\n1749:\t\t}\n1750:\t\n1751:\t\t/* Enqueue the packet */\n1752:\t\tskb_queue_tail(\u0026data-\u003epending, my_skb);\n1753:\t\tdata-\u003etx_pkts++;\n1754:\t\tdata-\u003etx_bytes += my_skb-\u003elen;\n1755:\t\treturn;\n1756:\t\n1757:\tnla_put_failure:\n1758:\t\tnlmsg_free(skb);\n1759:\terr_free_txskb:\n1760:\t\tpr_debug(\"mac80211_hwsim: error occurred in %s\\n\", __func__);\n1761:\t\tieee80211_free_txskb(hw, my_skb);\n1762:\t\tdata-\u003etx_failed++;\n1763:\t}\n1764:\t\n1765:\tstatic bool hwsim_chans_compat(struct ieee80211_channel *c1,\n1766:\t\t\t\t struct ieee80211_channel *c2)\n1767:\t{\n1768:\t\tif (!c1 || !c2)\n1769:\t\t\treturn false;\n"
} |
| 19/2 | 2026/09/11 14:28 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 24107 output: 30 thoughts: 571 Thoughts: **Analyzing Potential Vulnerabilities in the mac80211_hwsim Driver** Okay, let's break this down. My initial focus is on the `hwsim_cloned_frame_received_nl` and `hwsim_tx_info_frame_received_nl` functions. It appears the flow involves a user-space process sending a frame back through Generic Netlink using `HWSIM_CMD_FRAME`. If `HWSIM_ATTR_COOKIE` and `HWSIM_ATTR_ADDR_TRANSMITTER` are present, the code retrieves the original socket buffer (`skb`) from the transmitter's "pending" queue. This caught my attention: it finds the original `skb`, modifies it *in place* using `pskb_expand_head`, `skb_trim`, and `skb_put_data`, but, importantly, the modified `skb` *remains* in the pending queue. Then, later, `hwsim_tx_info_frame_received_nl` handles `HWSIM_CMD_TX_INFO_FRAME`, dequeues *that same* `skb` from the "pending" queue, and processes it. This raises a red flag in terms of potential double frees, use-after-free, or other memory corruption issues if the modification is done in a way that is not synchronized, or properly accounted for later on. Furthermore, in `hwsim_tx_info_frame_received_nl`, I see the use of `HWSIM_ATTR_NO_MONITOR` to optionally skip `mac80211_hwsim_monitor_rx`, a typical target for fuzzing. Also I notice the use of `freq = (uintptr_t)txi->rate_driver_data[1]` instead of `data2->channel` which may lead to inconsistencies or assumptions. Given that `mac80211_hwsim` is a pure software simulated 802.11 driver, communicating via Generic Netlink, and considering that syzkaller actively targets nl80211 and hwsim netlink interfaces, I'm confident that these code paths are indeed reachable within QEMU or a standard fuzzing environment. That simplifies things a great deal. To expand the scope, I'll need to check the broader configuration landscape. I'll need to look at `net/mac80211` and `drivers/net/wireless/virtual`, specifically the `MAC80211_HWSIM`, `MAC80211`, `CFG80211`, `NET`, and `INET` config options to understand any dependencies or related functionality. Furthermore, I'll `grep` for `CONFIG_` in `drivers/net/wireless/virtual/mac80211_hwsim_main.c` and other files within the `virtual` directory to identify other potentially relevant configurations. The goal is to fully understand the context, especially how `skb`'s state is being manipulated across different Netlink commands, to get a clear attack surface. |
| 20/2 | 2026/09/11 14:29 | tool | grepper |
0mArgs:{
"Expression": "CONFIG_",
"PathPrefix": "drivers/net/wireless/virtual/"
}Results: {
"Output": "drivers/net/wireless/virtual/Makefile:1:obj-$(CONFIG_MAC80211_HWSIM)\t+= mac80211_hwsim.o\ndrivers/net/wireless/virtual/Makefile-2-mac80211_hwsim-objs\t\t+= mac80211_hwsim_main.o\ndrivers/net/wireless/virtual/Makefile=3=mac80211_hwsim-objs\t\t+= mac80211_hwsim_nan.o\ndrivers/net/wireless/virtual/Makefile-4-\ndrivers/net/wireless/virtual/Makefile:5:obj-$(CONFIG_VIRT_WIFI)\t+= virt_wifi.o\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=865=static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-900-\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:901:#if IS_REACHABLE(CONFIG_VIRTIO)\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-902-\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=2345=static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-2364-\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:2365:#ifdef CONFIG_MAC80211_DEBUGFS\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-2366-static void\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=2997=mac80211_hwsim_can_neg_ttlm(struct ieee80211_hw *hw, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-3013-\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:3014:#ifdef CONFIG_NL80211_TESTMODE\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-3015-/*\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=4277=static int mac80211_hwsim_set_radar_background(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-4294-\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:4295:#ifdef CONFIG_MAC80211_DEBUGFS\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-4296-#define HWSIM_DEBUGFS_OPS\t\t\t\t\t\\\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=4521=static const struct ieee80211_sband_iftype_data sband_capa_2ghz[] = {\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-4754-\t},\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:4755:#ifdef CONFIG_MAC80211_MESH\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-4756-\t{\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=4798=static const struct ieee80211_sband_iftype_data sband_capa_5ghz[] = {\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-5064-\t},\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:5065:#ifdef CONFIG_MAC80211_MESH\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-5066-\t{\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=5111=static const struct ieee80211_sband_iftype_data sband_capa_6ghz[] = {\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-5419-\t},\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:5420:#ifdef CONFIG_MAC80211_MESH\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-5421-\t{\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=5611=static void mac80211_hwsim_sband_capab(struct ieee80211_supported_band *sband)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-5627-\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:5628:#ifdef CONFIG_MAC80211_MESH\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-5629-#define HWSIM_MESH_BIT BIT(NL80211_IFTYPE_MESH_POINT)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=7327=static void hwsim_exit_netlink(void)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-7334-\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:7335:#if IS_REACHABLE(CONFIG_VIRTIO)\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-7336-static void hwsim_virtio_tx_done(struct virtqueue *vq)\n"
} |
| 21/2 | 2026/09/11 14:29 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 27028 output: 302 thoughts: 684 Thoughts: **Analysis of Modified mac80211_hwsim Functions** Okay, so I've been tasked with evaluating some changes to the `mac80211_hwsim` driver. My initial step is to identify the key functions that have been modified. I've got a list: `mac80211_hwsim_monitor_rx`, `mac80211_hwsim_monitor_ack`, `mac80211_hwsim_tx_frame_nl`, `mac80211_hwsim_tx_frame_no_nl`, `mac80211_hwsim_tx`, `hwsim_tx_info_frame_received_nl`, and `hwsim_cloned_frame_received_nl`. My immediate thought is to confirm that these functions are actually accessible, or if static, what their symbol visibility is within the kernel. I'll need to check if any of the static functions are exposed as symbols or called in the same compilation unit. Now, let's take a closer look at what *specifically* changed in each of these functions. I'm seeing significant alterations to how cloned frames are handled (`hwsim_cloned_frame_received_nl`), including manipulation of the pending queue and the use of `pskb_expand_head`, `skb_trim`, and `skb_put_data`. That's interesting; it indicates changes in memory management and data handling during frame cloning. Then, there's `hwsim_tx_info_frame_received_nl`, which now deals with `HWSIM_ATTR_NO_MONITOR` and keeps track of the center frequency. `mac80211_hwsim_tx_frame_nl` is storing channel frequency data as well, and `mac80211_hwsim_monitor_rx`, `mac80211_hwsim_monitor_ack`, and `mac80211_hwsim_tx` have signature and usage updates. This suggests enhancements or modifications to monitor capabilities, likely tied to the network protocol's lower levels. Next, I need to make sure the enabling configurations are in place. The dependencies seem to be `MAC80211_HWSIM`, `MAC80211`, and `CFG80211`. That's what I'd expect; it makes sense that the virtual hardware simulation, the mac80211 stack, and the configuration interface are all required. Finally, let's confirm the overall criteria for the assessment are met. First, the driver itself must be reachable in a standard QEMU environment without requiring any physical hardware; it sounds like that's the case. Second, the modified logic must be substantial, which it appears to be: frame cloning, pending `skb` replacement, monitor control are all modified. Third, we are focusing on the functions I enumerated in `drivers/net/wireless/virtual/mac80211_hwsim_main.c`. Fourth, the enabling configurations are in place. All criteria are met. Time to call `set-results`. |
| 22/2 | 2026/09/11 14:29 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"MAC80211_HWSIM",
"MAC80211",
"CFG80211"
],
"FocusSymbols": [
"hwsim_cloned_frame_received_nl",
"hwsim_tx_info_frame_received_nl",
"mac80211_hwsim_tx_frame_nl",
"mac80211_hwsim_monitor_rx",
"mac80211_hwsim_monitor_ack",
"mac80211_hwsim_tx"
],
"Reasoning": "The patch modifies mac80211_hwsim, a software-emulated 802.11 radio testing tool fully accessible in standard virtualized fuzzing environments via generic netlink. The changes introduce handling for HWSIM_ATTR_NO_MONITOR, modify center frequency tracking across TX monitor reporting, and add logic in hwsim_cloned_frame_received_nl to search the pending transmission queue by cookie and modify the original skb data (via pskb_expand_head, skb_trim, and skb_put_data). Fuzzing is warranted to test for potential buffer manipulation issues, race conditions, or state inconsistencies in the simulated radio TX/RX paths.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"MAC80211_HWSIM",
"MAC80211",
"CFG80211"
],
"FocusSymbols": [
"hwsim_cloned_frame_received_nl",
"hwsim_tx_info_frame_received_nl",
"mac80211_hwsim_tx_frame_nl",
"mac80211_hwsim_monitor_rx",
"mac80211_hwsim_monitor_ack",
"mac80211_hwsim_tx"
],
"Reasoning": "The patch modifies mac80211_hwsim, a software-emulated 802.11 radio testing tool fully accessible in standard virtualized fuzzing environments via generic netlink. The changes introduce handling for HWSIM_ATTR_NO_MONITOR, modify center frequency tracking across TX monitor reporting, and add logic in hwsim_cloned_frame_received_nl to search the pending transmission queue by cookie and modify the original skb data (via pskb_expand_head, skb_trim, and skb_put_data). Fuzzing is warranted to test for potential buffer manipulation issues, race conditions, or state inconsistencies in the simulated radio TX/RX paths.",
"WorthFuzzing": true
} |
| 23/1 | 2026/09/11 14:29 | action | If |
0mArgs:{
"WorthFuzzing": true
}Results: null |
| 24/2 | 2026/09/11 14:29 | agent | kmsan-evaluator |
0mModel:core Args: null Results: {
"KMSANReasoning": "The patch modifies `mac80211_hwsim` to add the `HWSIM_ATTR_NO_MONITOR` netlink flag attribute for skipping monitor reports, preserves the transmission channel frequency in `rate_driver_data[1]`, and updates the pending transmitted skb in `hwsim_cloned_frame_received_nl` when matching cookie and transmitter attributes are provided.\n\nAll local variables (`freq`, `no_monitor`, `cookie`, etc.) and structure members (`rate_driver_data[1]`, `hdr-\u003ert_channel`) introduced or modified in this patch are explicitly assigned and initialized before access. SKB modifications use `skb_put_data` with verified payload lengths from validated netlink attributes. There are no uninitialized memory reads, uninitialized structure paddings, or info-leaks to userspace. Potential risks relating to SKB manipulation, queue locking, or reference handling are covered by standard KASAN and LOCKDEP detectors. Dedicated KMSAN fuzzing is not needed.",
"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 5b75af513ae1af87792a20b5aba41416353f9998
Author: syz-cluster <triage@syzkaller.com>
Date: Fri Sep 11 14:26:46 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.h b/drivers/net/wireless/virtual/mac80211_hwsim.h
index a022cd5c0f1c7..1d2fd06c585a9 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim.h
+++ b/drivers/net/wireless/virtual/mac80211_hwsim.h
@@ -3,7 +3,7 @@
* mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211
* Copyright (c) 2008, Jouni Malinen <j@w1.fi>
* Copyright (c) 2011, Javier Lopez <jlopex@gmail.com>
- * Copyright (C) 2020, 2022-2025 Intel Corporation
+ * Copyright (C) 2020, 2022-2026 Intel Corporation
*/
#ifndef __MAC80211_HWSIM_H
@@ -162,6 +162,8 @@ enum hwsim_commands {
* each radio instead of for the wiphy.
* @HWSIM_ATTR_SUPPORT_NAN_DEVICE: support NAN Device virtual interface (flag)
* @HWSIM_ATTR_SUPPORT_BACKGROUND_RADAR: background radar/CAC support (flag)
+ * @HWSIM_ATTR_NO_MONITOR: skip monitor report for this TX status, e.g. in case
+ * the frame was never reported to any receiver (flag)
* @__HWSIM_ATTR_MAX: enum limit
*/
enum hwsim_attrs {
@@ -197,6 +199,7 @@ enum hwsim_attrs {
HWSIM_ATTR_MULTI_RADIO,
HWSIM_ATTR_SUPPORT_NAN_DEVICE,
HWSIM_ATTR_SUPPORT_BACKGROUND_RADAR,
+ HWSIM_ATTR_NO_MONITOR,
__HWSIM_ATTR_MAX,
};
#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_main.c b/drivers/net/wireless/virtual/mac80211_hwsim_main.c
index 02b6d81cccd11..fca4bf823ef4e 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim_main.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim_main.c
@@ -895,6 +895,7 @@ static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {
[HWSIM_ATTR_MULTI_RADIO] = { .type = NLA_FLAG },
[HWSIM_ATTR_SUPPORT_NAN_DEVICE] = { .type = NLA_FLAG },
[HWSIM_ATTR_SUPPORT_BACKGROUND_RADAR] = { .type = NLA_FLAG },
+ [HWSIM_ATTR_NO_MONITOR] = { .type = NLA_FLAG },
};
#if IS_REACHABLE(CONFIG_VIRTIO)
@@ -1337,7 +1338,7 @@ mac80211_hwsim_get_tx_rate(struct ieee80211_hw *hw,
static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
struct sk_buff *tx_skb,
- struct ieee80211_channel *chan)
+ u32 freq)
{
struct mac80211_hwsim_data *data = hw->priv;
struct sk_buff *skb;
@@ -1369,7 +1370,7 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
hdr->rt_tsft = __mac80211_hwsim_get_tsf(data);
hdr->rt_flags = 0;
hdr->rt_rate = bitrate / 5;
- hdr->rt_channel = cpu_to_le16(chan->center_freq);
+ hdr->rt_channel = cpu_to_le16(freq);
flags = IEEE80211_CHAN_2GHZ;
if (txrate && txrate->flags & IEEE80211_RATE_ERP_G)
flags |= IEEE80211_CHAN_OFDM;
@@ -1387,8 +1388,7 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
}
-static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan,
- const u8 *addr)
+static void mac80211_hwsim_monitor_ack(u32 freq, const u8 *addr)
{
struct sk_buff *skb;
struct hwsim_radiotap_ack_hdr *hdr;
@@ -1410,7 +1410,7 @@ static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan,
(1 << IEEE80211_RADIOTAP_CHANNEL));
hdr->rt_flags = 0;
hdr->pad = 0;
- hdr->rt_channel = cpu_to_le16(chan->center_freq);
+ hdr->rt_channel = cpu_to_le16(freq);
flags = IEEE80211_CHAN_2GHZ;
hdr->rt_chbitmask = cpu_to_le16(flags);
@@ -1735,6 +1735,9 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
if (nla_put_u64_64bit(skb, HWSIM_ATTR_COOKIE, cookie, HWSIM_ATTR_PAD))
goto nla_put_failure;
+ /* track the frequency */
+ info->rate_driver_data[1] = (void *)(uintptr_t)channel->center_freq;
+
genlmsg_end(skb, msg_head);
if (hwsim_virtio_enabled) {
@@ -1912,7 +1915,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
mac80211_hwsim_write_tsf(data, skb, sim_tsf);
- mac80211_hwsim_monitor_rx(hw, skb, chan);
+ mac80211_hwsim_monitor_rx(hw, skb, chan->center_freq);
memset(&rx_status, 0, sizeof(rx_status));
rx_status.flag |= RX_FLAG_MACTIME_START;
@@ -2276,7 +2279,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
ack = mac80211_hwsim_tx_frame_no_nl(hw, skb, channel);
if (ack && skb->len >= 16)
- mac80211_hwsim_monitor_ack(channel, hdr->addr2);
+ mac80211_hwsim_monitor_ack(channel->center_freq, hdr->addr2);
ieee80211_tx_info_clear_status(txi);
@@ -6391,6 +6394,8 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
int i;
unsigned long flags;
bool found = false;
+ bool no_monitor;
+ u32 freq;
if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] ||
!info->attrs[HWSIM_ATTR_FLAGS] ||
@@ -6402,6 +6407,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
src = (void *)nla_data(info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER]);
hwsim_flags = nla_get_u32(info->attrs[HWSIM_ATTR_FLAGS]);
ret_skb_cookie = nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]);
+ no_monitor = nla_get_flag(info->attrs[HWSIM_ATTR_NO_MONITOR]);
data2 = get_hwsim_data_ref_from_addr(src);
if (!data2)
@@ -6436,7 +6442,11 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
if (!found)
goto out;
- mac80211_hwsim_monitor_rx(data2->hw, skb, data2->channel);
+ txi = IEEE80211_SKB_CB(skb);
+ freq = (uintptr_t)txi->rate_driver_data[1];
+
+ if (!no_monitor)
+ mac80211_hwsim_monitor_rx(data2->hw, skb, freq);
/* Tx info received because the frame was broadcasted on user space,
so we get all the necessary info: tx attempts and skb control buff */
@@ -6445,8 +6455,6 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
info->attrs[HWSIM_ATTR_TX_INFO]);
/* now send back TX status */
- txi = IEEE80211_SKB_CB(skb);
-
ieee80211_tx_info_clear_status(txi);
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
@@ -6466,8 +6474,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
if (!(hwsim_flags & HWSIM_TX_CTL_NO_ACK) &&
(hwsim_flags & HWSIM_TX_STAT_ACK)) {
if (skb->len >= 16)
- mac80211_hwsim_monitor_ack(data2->channel,
- hdr->addr2);
+ mac80211_hwsim_monitor_ack(freq, hdr->addr2);
txi->flags |= IEEE80211_TX_STAT_ACK;
}
@@ -6535,6 +6542,51 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
goto out;
}
+ /* look for the skb matching the cookie passed back from user */
+ if (info->attrs[HWSIM_ATTR_COOKIE] &&
+ info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER]) {
+ u64 cookie = nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]);
+ struct sk_buff *orig_skb, *found = NULL;
+ struct mac80211_hwsim_data *txdata;
+ struct ieee80211_tx_info *txi;
+ const u8 *transmitter;
+ unsigned long flags;
+
+ transmitter = nla_data(info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER]);
+ txdata = get_hwsim_data_ref_from_addr(transmitter);
+ if (!txdata || txdata->netgroup != data2->netgroup)
+ goto out;
+
+ spin_lock_irqsave(&txdata->pending.lock, flags);
+ skb_queue_walk(&txdata->pending, orig_skb) {
+ uintptr_t skb_cookie;
+
+ txi = IEEE80211_SKB_CB(orig_skb);
+ skb_cookie = (uintptr_t)txi->rate_driver_data[0];
+
+ if (skb_cookie == cookie) {
+ found = orig_skb;
+ break;
+ }
+ }
+
+ /* that's weird */
+ if (!found) {
+ spin_unlock_irqrestore(&txdata->pending.lock, flags);
+ goto out;
+ }
+
+ if (frame_data_len > found->len &&
+ pskb_expand_head(found, 0, frame_data_len - found->len,
+ GFP_ATOMIC)) {
+ spin_unlock_irqrestore(&txdata->pending.lock, flags);
+ goto out;
+ }
+ skb_trim(found, 0);
+ skb_put_data(found, frame_data, frame_data_len);
+ spin_unlock_irqrestore(&txdata->pending.lock, flags);
+ }
+
/* check if radio is configured properly */
if ((data2->idle && !data2->tmp_chan) || !data2->started)
|
| 25/3 | 2026/09/11 14:29 | llm | kmsan-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 5428 output: 52 thoughts: 675 Thoughts: **Analyzing the mac80211_hwsim Patch**
Okay, let's dive into this patch and figure out if KMSAN is a concern here. My initial thought is to examine the touched files: `drivers/net/wireless/virtual/mac80211_hwsim.h` and `drivers/net/wireless/virtual/mac80211_hwsim_main.c`. It seems we're dealing with modifications related to the mac80211_hwsim virtual wireless driver, which is usually a good thing to pay attention to.
First, `mac80211_hwsim.h` adds `HWSIM_ATTR_NO_MONITOR` to the `hwsim_attrs` enum. A flag...interesting. Then, `mac80211_hwsim_main.c` is where things get more interesting. We're seeing `[HWSIM_ATTR_NO_MONITOR] = { .type = NLA_FLAG }` added to the `hwsim_genl_policy`. So, it looks like there's a new attribute exposed via Netlink.
The code modifies `mac80211_hwsim_monitor_rx` and `mac80211_hwsim_monitor_ack` to use a `u32 freq` instead of a `struct ieee80211_channel *chan`. That's a definite change in how frequency information is handled. We're also seeing the `channel->center_freq` being saved into `info->rate_driver_data[1]` in `mac80211_hwsim_tx_frame_nl` and passed directly in other functions.
Now, things get a bit more involved. In `hwsim_tx_info_frame_received_nl`, there's a check for `no_monitor` based on the new flag. If not set, it calls `mac80211_hwsim_monitor_rx` and `mac80211_hwsim_monitor_ack` with the frequency. That makes sense, we want to control the monitor function.
Here's the bit that really requires careful analysis: `hwsim_cloned_frame_received_nl`. It appears to be handling cloned SKBs within a pending TX queue. The code looks for an original SKB based on a cookie. If found, it checks if `frame_data_len` is greater than `found->len`, and expands the header if necessary. Then, it calls `skb_trim(found, 0)` and subsequently copies data using `skb_put_data(found, frame_data, frame_data_len)`. My immediate concern is with the copy. Is this copying into uninitialized memory? The potential for memory corruption always raises my hackles, so I need to check how `frame_data` and `frame_data_len` are initialized to know if we can have a KMSAN problem here. Let me check the definitions for those. I need to be sure that these are safe to use here.
|
| 26/3 | 2026/09/11 14:29 | tool | grepper |
0mArgs:{
"Expression": "hwsim_cloned_frame_received_nl",
"PathPrefix": "drivers/net/wireless/virtual/mac80211_hwsim_main.c"
}Results: {
"Output": "drivers/net/wireless/virtual/mac80211_hwsim_main.c=6382=static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-6490-\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:6491:static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-6492-\t\t\t\t\t struct genl_info *info)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=7157=static const struct genl_small_ops hwsim_ops[] = {\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-7166-\t\t.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:7167:\t\t.doit = hwsim_cloned_frame_received_nl,\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-7168-\t},\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=7348=static int hwsim_virtio_handle_cmd(struct sk_buff *skb)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-7372-\tcase HWSIM_CMD_FRAME:\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:7373:\t\thwsim_cloned_frame_received_nl(skb, \u0026info);\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-7374-\t\tbreak;\n"
} |
| 27/3 | 2026/09/11 14:29 | llm | kmsan-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 7362 output: 51 thoughts: 24 Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience: **Analyzing `hwsim_cloned_frame_received_nl` and its Context** Okay, let's dive into this `hwsim_cloned_frame_received_nl` function and its surrounding code in the hardware simulator. My initial focus is on understanding the data flow here – how cloned frames are injected into the Netlink path, specifically within the hardware simulation environment. I want to see how this function is triggered, what data it receives as input, and how that data is processed and potentially passed up the stack. I'll be looking for potential race conditions or synchronization issues, especially if this function is dealing with shared resources or state related to simulated hardware. Are there any locks involved, and if so, what's their scope and how are they acquired and released? I also expect to see some interesting interactions with the kernel's networking stack, and I'm keen to spot if any custom Netlink attributes or commands are being used for this simulated hardware. I'm hoping to uncover any optimizations or potential bottlenecks that might affect performance. |
| 28/3 | 2026/09/11 14:29 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/virtual/mac80211_hwsim_main.c",
"FirstLine": 6490,
"LineCount": 100
}Results: {
"Contents": "6490:\t\n6491:\tstatic int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,\n6492:\t\t\t\t\t\t struct genl_info *info)\n6493:\t{\n6494:\t\tstruct mac80211_hwsim_data *data2;\n6495:\t\tstruct ieee80211_rx_status rx_status;\n6496:\t\tstruct ieee80211_hdr *hdr;\n6497:\t\tconst u8 *dst;\n6498:\t\tint frame_data_len;\n6499:\t\tvoid *frame_data;\n6500:\t\tstruct sk_buff *skb = NULL;\n6501:\t\tstruct ieee80211_channel *channel = NULL;\n6502:\t\n6503:\t\tif (!info-\u003eattrs[HWSIM_ATTR_ADDR_RECEIVER] ||\n6504:\t\t !info-\u003eattrs[HWSIM_ATTR_FRAME] ||\n6505:\t\t !info-\u003eattrs[HWSIM_ATTR_RX_RATE] ||\n6506:\t\t !info-\u003eattrs[HWSIM_ATTR_SIGNAL])\n6507:\t\t\tgoto out;\n6508:\t\n6509:\t\tdst = (void *)nla_data(info-\u003eattrs[HWSIM_ATTR_ADDR_RECEIVER]);\n6510:\t\tframe_data_len = nla_len(info-\u003eattrs[HWSIM_ATTR_FRAME]);\n6511:\t\tframe_data = (void *)nla_data(info-\u003eattrs[HWSIM_ATTR_FRAME]);\n6512:\t\n6513:\t\tif (frame_data_len \u003c sizeof(struct ieee80211_hdr_3addr) ||\n6514:\t\t frame_data_len \u003e IEEE80211_MAX_DATA_LEN)\n6515:\t\t\tgoto err;\n6516:\t\n6517:\t\t/* Allocate new skb here */\n6518:\t\tskb = alloc_skb(frame_data_len, GFP_KERNEL);\n6519:\t\tif (skb == NULL)\n6520:\t\t\tgoto err;\n6521:\t\n6522:\t\t/* Copy the data */\n6523:\t\tskb_put_data(skb, frame_data, frame_data_len);\n6524:\t\n6525:\t\tdata2 = get_hwsim_data_ref_from_addr(dst);\n6526:\t\tif (!data2)\n6527:\t\t\tgoto out;\n6528:\t\n6529:\t\tif (data2-\u003euse_chanctx) {\n6530:\t\t\tif (data2-\u003etmp_chan)\n6531:\t\t\t\tchannel = data2-\u003etmp_chan;\n6532:\t\t} else {\n6533:\t\t\tchannel = data2-\u003echannel;\n6534:\t\t}\n6535:\t\n6536:\t\tif (!hwsim_virtio_enabled) {\n6537:\t\t\tif (hwsim_net_get_netgroup(genl_info_net(info)) !=\n6538:\t\t\t data2-\u003enetgroup)\n6539:\t\t\t\tgoto out;\n6540:\t\n6541:\t\t\tif (info-\u003esnd_portid != data2-\u003ewmediumd)\n6542:\t\t\t\tgoto out;\n6543:\t\t}\n6544:\t\n6545:\t\t/* look for the skb matching the cookie passed back from user */\n6546:\t\tif (info-\u003eattrs[HWSIM_ATTR_COOKIE] \u0026\u0026\n6547:\t\t info-\u003eattrs[HWSIM_ATTR_ADDR_TRANSMITTER]) {\n6548:\t\t\tu64 cookie = nla_get_u64(info-\u003eattrs[HWSIM_ATTR_COOKIE]);\n6549:\t\t\tstruct sk_buff *orig_skb, *found = NULL;\n6550:\t\t\tstruct mac80211_hwsim_data *txdata;\n6551:\t\t\tstruct ieee80211_tx_info *txi;\n6552:\t\t\tconst u8 *transmitter;\n6553:\t\t\tunsigned long flags;\n6554:\t\n6555:\t\t\ttransmitter = nla_data(info-\u003eattrs[HWSIM_ATTR_ADDR_TRANSMITTER]);\n6556:\t\t\ttxdata = get_hwsim_data_ref_from_addr(transmitter);\n6557:\t\t\tif (!txdata || txdata-\u003enetgroup != data2-\u003enetgroup)\n6558:\t\t\t\tgoto out;\n6559:\t\n6560:\t\t\tspin_lock_irqsave(\u0026txdata-\u003epending.lock, flags);\n6561:\t\t\tskb_queue_walk(\u0026txdata-\u003epending, orig_skb) {\n6562:\t\t\t\tuintptr_t skb_cookie;\n6563:\t\n6564:\t\t\t\ttxi = IEEE80211_SKB_CB(orig_skb);\n6565:\t\t\t\tskb_cookie = (uintptr_t)txi-\u003erate_driver_data[0];\n6566:\t\n6567:\t\t\t\tif (skb_cookie == cookie) {\n6568:\t\t\t\t\tfound = orig_skb;\n6569:\t\t\t\t\tbreak;\n6570:\t\t\t\t}\n6571:\t\t\t}\n6572:\t\n6573:\t\t\t/* that's weird */\n6574:\t\t\tif (!found) {\n6575:\t\t\t\tspin_unlock_irqrestore(\u0026txdata-\u003epending.lock, flags);\n6576:\t\t\t\tgoto out;\n6577:\t\t\t}\n6578:\t\n6579:\t\t\tif (frame_data_len \u003e found-\u003elen \u0026\u0026\n6580:\t\t\t pskb_expand_head(found, 0, frame_data_len - found-\u003elen,\n6581:\t\t\t\t\t GFP_ATOMIC)) {\n6582:\t\t\t\tspin_unlock_irqrestore(\u0026txdata-\u003epending.lock, flags);\n6583:\t\t\t\tgoto out;\n6584:\t\t\t}\n6585:\t\t\tskb_trim(found, 0);\n6586:\t\t\tskb_put_data(found, frame_data, frame_data_len);\n6587:\t\t\tspin_unlock_irqrestore(\u0026txdata-\u003epending.lock, flags);\n6588:\t\t}\n6589:\t\n"
} |
| 29/3 | 2026/09/11 14:29 | llm | kmsan-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 9326 output: 50 thoughts: 39 Thoughts: Okay, here's my take on those thoughts, framed as an expert's internal monologue: **Investigating Potential Data Loss in Simulated 802.11 Transmissions** Alright, I'm diving into this simulated 802.11 environment again. Let me just quickly confirm my understanding of the data flow around transmission. I should probably focus on verifying there are no data-loss issues happening inside the kernel itself. Specifically, I need to take a look at the interaction points between the hardware simulation and the mac80211 stack. `mac80211_hwsim_tx_frame_nl` seems like a likely entry point for handling frames destined for the simulated hardware, so let's check that. Then, since this is all internal, I need to make sure the information on what happened to the frame is properly propagated back up. Therefore I need to check `hwsim_tx_info_frame_received_nl` which I believe is where that information gets sent. I need to review these functions carefully. I'm looking for any potential race conditions, missed notifications, or data corruption during this process. A bit of static analysis is probably the best first step. Gotta ensure that everything is playing nicely in this simulated environment to prevent unexpected drops. |
| 30/3 | 2026/09/11 14:29 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/virtual/mac80211_hwsim_main.c",
"FirstLine": 1725,
"LineCount": 40
}Results: {
"Contents": "1725:\t\t\tgoto nla_put_failure;\n1726:\t\n1727:\t\tif (nla_put(skb, HWSIM_ATTR_TX_INFO_FLAGS,\n1728:\t\t\t sizeof(struct hwsim_tx_rate_flag) * IEEE80211_TX_MAX_RATES,\n1729:\t\t\t tx_attempts_flags))\n1730:\t\t\tgoto nla_put_failure;\n1731:\t\n1732:\t\t/* We create a cookie to identify this skb */\n1733:\t\tcookie = atomic_inc_return(\u0026data-\u003epending_cookie);\n1734:\t\tinfo-\u003erate_driver_data[0] = (void *)cookie;\n1735:\t\tif (nla_put_u64_64bit(skb, HWSIM_ATTR_COOKIE, cookie, HWSIM_ATTR_PAD))\n1736:\t\t\tgoto nla_put_failure;\n1737:\t\n1738:\t\t/* track the frequency */\n1739:\t\tinfo-\u003erate_driver_data[1] = (void *)(uintptr_t)channel-\u003ecenter_freq;\n1740:\t\n1741:\t\tgenlmsg_end(skb, msg_head);\n1742:\t\n1743:\t\tif (hwsim_virtio_enabled) {\n1744:\t\t\tif (hwsim_tx_virtio(data, skb))\n1745:\t\t\t\tgoto err_free_txskb;\n1746:\t\t} else {\n1747:\t\t\tif (hwsim_unicast_netgroup(data, skb, dst_portid))\n1748:\t\t\t\tgoto err_free_txskb;\n1749:\t\t}\n1750:\t\n1751:\t\t/* Enqueue the packet */\n1752:\t\tskb_queue_tail(\u0026data-\u003epending, my_skb);\n1753:\t\tdata-\u003etx_pkts++;\n1754:\t\tdata-\u003etx_bytes += my_skb-\u003elen;\n1755:\t\treturn;\n1756:\t\n1757:\tnla_put_failure:\n1758:\t\tnlmsg_free(skb);\n1759:\terr_free_txskb:\n1760:\t\tpr_debug(\"mac80211_hwsim: error occurred in %s\\n\", __func__);\n1761:\t\tieee80211_free_txskb(hw, my_skb);\n1762:\t\tdata-\u003etx_failed++;\n1763:\t}\n1764:\t\n"
} |
| 31/3 | 2026/09/11 14:29 | llm | kmsan-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 10369 output: 50 thoughts: 21 Thoughts: Here's my take on those thoughts, tailored for an expert audience: **Diving Deeper into the Receiver Path** Alright, I need to make sure we haven't overlooked any potential issues in the receive path. I've been focusing on the standard flow, but a good engineer knows to double-check edge cases. Specifically, I'm going to run a diagnostics check on `hwsim_tx_info_frame_received_nl` now. It's possible there are some issues with the TX Info Frame handling, and this could be subtly impacting the RX side or hiding some other issues. It's a key spot that can give us hints for deeper debugging if other diagnostics come up empty. |
| 32/3 | 2026/09/11 14:29 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/virtual/mac80211_hwsim_main.c",
"FirstLine": 6382,
"LineCount": 80
}Results: {
"Contents": "6382:\tstatic int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,\n6383:\t\t\t\t\t\t struct genl_info *info)\n6384:\t{\n6385:\t\n6386:\t\tstruct ieee80211_hdr *hdr;\n6387:\t\tstruct mac80211_hwsim_data *data2;\n6388:\t\tstruct ieee80211_tx_info *txi;\n6389:\t\tstruct hwsim_tx_rate *tx_attempts;\n6390:\t\tu64 ret_skb_cookie;\n6391:\t\tstruct sk_buff *skb, *tmp;\n6392:\t\tconst u8 *src;\n6393:\t\tunsigned int hwsim_flags;\n6394:\t\tint i;\n6395:\t\tunsigned long flags;\n6396:\t\tbool found = false;\n6397:\t\tbool no_monitor;\n6398:\t\tu32 freq;\n6399:\t\n6400:\t\tif (!info-\u003eattrs[HWSIM_ATTR_ADDR_TRANSMITTER] ||\n6401:\t\t !info-\u003eattrs[HWSIM_ATTR_FLAGS] ||\n6402:\t\t !info-\u003eattrs[HWSIM_ATTR_COOKIE] ||\n6403:\t\t !info-\u003eattrs[HWSIM_ATTR_SIGNAL] ||\n6404:\t\t !info-\u003eattrs[HWSIM_ATTR_TX_INFO])\n6405:\t\t\tgoto out;\n6406:\t\n6407:\t\tsrc = (void *)nla_data(info-\u003eattrs[HWSIM_ATTR_ADDR_TRANSMITTER]);\n6408:\t\thwsim_flags = nla_get_u32(info-\u003eattrs[HWSIM_ATTR_FLAGS]);\n6409:\t\tret_skb_cookie = nla_get_u64(info-\u003eattrs[HWSIM_ATTR_COOKIE]);\n6410:\t\tno_monitor = nla_get_flag(info-\u003eattrs[HWSIM_ATTR_NO_MONITOR]);\n6411:\t\n6412:\t\tdata2 = get_hwsim_data_ref_from_addr(src);\n6413:\t\tif (!data2)\n6414:\t\t\tgoto out;\n6415:\t\n6416:\t\tif (!hwsim_virtio_enabled) {\n6417:\t\t\tif (hwsim_net_get_netgroup(genl_info_net(info)) !=\n6418:\t\t\t data2-\u003enetgroup)\n6419:\t\t\t\tgoto out;\n6420:\t\n6421:\t\t\tif (info-\u003esnd_portid != data2-\u003ewmediumd)\n6422:\t\t\t\tgoto out;\n6423:\t\t}\n6424:\t\n6425:\t\t/* look for the skb matching the cookie passed back from user */\n6426:\t\tspin_lock_irqsave(\u0026data2-\u003epending.lock, flags);\n6427:\t\tskb_queue_walk_safe(\u0026data2-\u003epending, skb, tmp) {\n6428:\t\t\tuintptr_t skb_cookie;\n6429:\t\n6430:\t\t\ttxi = IEEE80211_SKB_CB(skb);\n6431:\t\t\tskb_cookie = (uintptr_t)txi-\u003erate_driver_data[0];\n6432:\t\n6433:\t\t\tif (skb_cookie == ret_skb_cookie) {\n6434:\t\t\t\t__skb_unlink(skb, \u0026data2-\u003epending);\n6435:\t\t\t\tfound = true;\n6436:\t\t\t\tbreak;\n6437:\t\t\t}\n6438:\t\t}\n6439:\t\tspin_unlock_irqrestore(\u0026data2-\u003epending.lock, flags);\n6440:\t\n6441:\t\t/* not found */\n6442:\t\tif (!found)\n6443:\t\t\tgoto out;\n6444:\t\n6445:\t\ttxi = IEEE80211_SKB_CB(skb);\n6446:\t\tfreq = (uintptr_t)txi-\u003erate_driver_data[1];\n6447:\t\n6448:\t\tif (!no_monitor)\n6449:\t\t\tmac80211_hwsim_monitor_rx(data2-\u003ehw, skb, freq);\n6450:\t\n6451:\t\t/* Tx info received because the frame was broadcasted on user space,\n6452:\t\t so we get all the necessary info: tx attempts and skb control buff */\n6453:\t\n6454:\t\ttx_attempts = (struct hwsim_tx_rate *)nla_data(\n6455:\t\t\t info-\u003eattrs[HWSIM_ATTR_TX_INFO]);\n6456:\t\n6457:\t\t/* now send back TX status */\n6458:\t\tieee80211_tx_info_clear_status(txi);\n6459:\t\n6460:\t\tfor (i = 0; i \u003c IEEE80211_TX_MAX_RATES; i++) {\n6461:\t\t\ttxi-\u003estatus.rates[i].idx = tx_attempts[i].idx;\n"
} |
| 33/3 | 2026/09/11 14:29 | llm | kmsan-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 11955 output: 241 thoughts: 1020 Thoughts: **KMSAN Assessment: No KMSAN Needed** Okay, let's break this down. First, I've reviewed the patch and the core changes are: a new `HWSIM_ATTR_NO_MONITOR` attribute for selectively disabling monitor frames, storage and retrieval of the transmission frequency via `rate_driver_data[1]`, and the ability to update a pending frame's data from a netlink message. My concern is always uninitialized memory. So, I went through it with a fine-toothed comb. The frequency, now stored in `rate_driver_data[1]`, is explicitly initialized. The frame data copied into the skb in `hwsim_cloned_frame_received_nl` comes directly from the netlink message, and length checks are in place, so the data is bounded, and we're not dealing with uninitialized memory. The monitor functions also receive the frequency as a `u32` and write it to a header field. There are no new uninitialized stack variables, nothing is getting copied to userspace uninitialized, no conditional branching based on uninitialized variables, and no information leaks. Given that I know the KMSAN guidelines well, I've carefully considered the rules. The patch changes and additions: `HWSIM_ATTR_NO_MONITOR`, `freq`, `skb_cookie`, and `rate_driver_data[1]` are fully initialized before use. The frame data comes from a netlink attribute with length verification. Regarding the "do we need KMSAN" question - any potential memory safety bugs, such as concurrency, buffer overruns, or use-after-free on the skb, are already caught by KASAN and LOCKDEP. KMSAN is overkill here because the patch does *not* introduce kernel structures being sent to userspace with uninitialized fields, depend on uninitialized variables, allocate complex data structures with uninitialized fields, or create bounds checks that lead to accessing uninitialized bytes. Therefore, my conclusion is clear: this patch doesn't introduce any KMSAN concerns. It's safe, and NeedsKMSAN = false. The standard bug detectors are sufficient. I will now `set-results`. |
| 34/3 | 2026/09/11 14:30 | tool | set-results |
0mArgs:{
"KMSANReasoning": "The patch modifies `mac80211_hwsim` to add the `HWSIM_ATTR_NO_MONITOR` netlink flag attribute for skipping monitor reports, preserves the transmission channel frequency in `rate_driver_data[1]`, and updates the pending transmitted skb in `hwsim_cloned_frame_received_nl` when matching cookie and transmitter attributes are provided.\n\nAll local variables (`freq`, `no_monitor`, `cookie`, etc.) and structure members (`rate_driver_data[1]`, `hdr-\u003ert_channel`) introduced or modified in this patch are explicitly assigned and initialized before access. SKB modifications use `skb_put_data` with verified payload lengths from validated netlink attributes. There are no uninitialized memory reads, uninitialized structure paddings, or info-leaks to userspace. Potential risks relating to SKB manipulation, queue locking, or reference handling are covered by standard KASAN and LOCKDEP detectors. Dedicated KMSAN fuzzing is not needed.",
"NeedsKMSAN": false
}Results: {
"KMSANReasoning": "The patch modifies `mac80211_hwsim` to add the `HWSIM_ATTR_NO_MONITOR` netlink flag attribute for skipping monitor reports, preserves the transmission channel frequency in `rate_driver_data[1]`, and updates the pending transmitted skb in `hwsim_cloned_frame_received_nl` when matching cookie and transmitter attributes are provided.\n\nAll local variables (`freq`, `no_monitor`, `cookie`, etc.) and structure members (`rate_driver_data[1]`, `hdr-\u003ert_channel`) introduced or modified in this patch are explicitly assigned and initialized before access. SKB modifications use `skb_put_data` with verified payload lengths from validated netlink attributes. There are no uninitialized memory reads, uninitialized structure paddings, or info-leaks to userspace. Potential risks relating to SKB manipulation, queue locking, or reference handling are covered by standard KASAN and LOCKDEP detectors. Dedicated KMSAN fuzzing is not needed.",
"NeedsKMSAN": false
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|