| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/10/04 13:45 | flow | patch-triage |
7mArgs:null Results: {
"EnableConfigs": [
"MAC80211_HWSIM",
"MAC80211",
"CFG80211"
],
"FocusSymbols": [
"mac80211_hwsim_nan_receive",
"mac80211_hwsim_nan_rx",
"mac80211_hwsim_nan_start",
"mac80211_hwsim_nan_stop",
"mac80211_hwsim_nan_change_config",
"mac80211_hwsim_nan_txq_transmitting",
"mac80211_hwsim_nan_discovery_beacon_timer",
"nl80211_start_nan",
"nl80211_nan_change_config",
"cfg80211_inform_bss_frame_data"
],
"KMSANReasoning": "The patch introduces support for NAN Instant Communication (IC) mode (Wi-Fi Aware v4.0) across cfg80211, mac80211, and the mac80211_hwsim driver.\n\n1. Netlink attributes \u0026 userspace info-leaks:\nThe only new attribute exported to userspace is NL80211_NAN_CAPA_INSTANT_COMM, emitted using nla_put_flag(), which conveys a boolean flag with no payload. No new kernel structures with uninitialized fields or padding are copied to userspace.\n\n2. Structure and memory initialization:\n- In netlink configuration handling (nl80211_start_nan and nl80211_nan_change_config), 'struct cfg80211_nan_conf conf' is fully zero-initialized with '= {}'.\n- In mac80211_hwsim_main.c, instances of 'struct tx_iter_data' are initialized with designated initializers, ensuring non-specified fields are zero-initialized.\n- In mac80211_hwsim_nan_set_config(), extra_nan_attrs is allocated and initialized via kmemdup().\n- In mac80211_hwsim_nan_tx_beacon(), beacon headers are zeroed with memset(), and all IE structures (struct ieee80211_vendor_ie, struct ieee80211_nan_attr, etc.) are __packed and fully initialized before being put into the skb.\n\n3. Frame parsing and bounds:\nThe parsing logic in ieee80211_is_nan_beacon() and hwsim_nan_beacon_has_service_ids() iterates over elements using bounds checks against the skb data length. Any potential bug involving malformed frames or buffer boundaries would be an out-of-bounds read, which is detected by KASAN rather than KMSAN.\n\nNo uninitialized memory risks or info-leaks are introduced; standard KASAN fuzzing is sufficient.",
"NeedsKMSAN": false,
"Reasoning": "The patch series introduces support for Wi-Fi Aware (NAN) Instant Communication (IC) mode across cfg80211, mac80211, and the simulated mac80211_hwsim driver. This modifies reachable netlink configuration parsers (nl80211_parse_nan_conf), frame reception and transmission paths, beacon handling, extra NAN attributes allocation/freeing, and timer callbacks in mac80211_hwsim. These code paths are fully reachable via netlink (nl80211) and virtual software wireless devices in standard fuzzing environments.",
"WorthFuzzing": true
} |
| 1/1 | 2026/10/04 13:45 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 64bd13e2ed1419f98d3aa38145753d7af0776e26\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Sun Oct 4 13:45:18 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/wireless/virtual/mac80211_hwsim_main.c b/drivers/net/wireless/virtual/mac80211_hwsim_main.c\nindex 02b6d81cccd11..5d235946e19a1 100644\n--- a/drivers/net/wireless/virtual/mac80211_hwsim_main.c\n+++ b/drivers/net/wireless/virtual/mac80211_hwsim_main.c\n@@ -1772,6 +1772,7 @@ struct tx_iter_data {\n \tstruct ieee80211_channel *channel;\n \tstruct ieee80211_rx_status *rx_status;\n \tstruct ieee80211_hw *hw;\n+\tstruct sk_buff *skb;\n \tbool receive;\n };\n \n@@ -1784,6 +1785,7 @@ static void mac80211_hwsim_tx_iter(void *_data, u8 *addr,\n \tif (vif-\u003etype == NL80211_IFTYPE_NAN ||\n \t vif-\u003etype == NL80211_IFTYPE_NAN_DATA) {\n \t\tdata-\u003ereceive = mac80211_hwsim_nan_receive(data-\u003ehw,\n+\t\t\t\t\t\t\t data-\u003eskb,\n \t\t\t\t\t\t\t data-\u003echannel,\n \t\t\t\t\t\t\t data-\u003erx_status);\n \t\treturn;\n@@ -1968,6 +1970,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,\n \t\t\t.hw = data2-\u003ehw,\n \t\t\t.channel = chan,\n \t\t\t.rx_status = \u0026rx_status,\n+\t\t\t.skb = skb,\n \t\t};\n \n \t\tif (data == data2)\n@@ -5800,7 +5803,8 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,\n \t\t\t\t\t\t BIT(NL80211_BAND_5GHZ);\n \n \t\thw-\u003ewiphy-\u003enan_capa.flags = WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC |\n-\t\t\t\t\t WIPHY_NAN_FLAGS_USERSPACE_DE;\n+\t\t\t\t\t WIPHY_NAN_FLAGS_USERSPACE_DE |\n+\t\t\t\t\t WIPHY_NAN_FLAGS_INSTANT_COMM;\n \t\thw-\u003ewiphy-\u003enan_capa.op_mode = NAN_OP_MODE_PHY_MODE_MASK |\n \t\t\t\t\t NAN_OP_MODE_80P80MHZ |\n \t\t\t\t\t NAN_OP_MODE_160MHZ;\n@@ -6546,6 +6550,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,\n \t\tstruct tx_iter_data iter_data = {\n \t\t\t.hw = data2-\u003ehw,\n \t\t\t.rx_status = \u0026rx_status,\n+\t\t\t.skb = skb,\n \t\t};\n \n \t\t/* throw away off-channel packets, but allow both the temporary\ndiff --git a/drivers/net/wireless/virtual/mac80211_hwsim_nan.c b/drivers/net/wireless/virtual/mac80211_hwsim_nan.c\nindex 7be64c45babf9..1f058ec9c159f 100644\n--- a/drivers/net/wireless/virtual/mac80211_hwsim_nan.c\n+++ b/drivers/net/wireless/virtual/mac80211_hwsim_nan.c\n@@ -33,6 +33,12 @@ static_assert(DW0_TSF_MASK + 1 == 8192 * 1024);\n #define NAN_RSSI_CLOSE (-60)\n #define NAN_RSSI_MIDDLE (-75)\n \n+/* Size of the NAN vendor element carrying the mandatory attributes */\n+#define NAN_BEACON_ELEM_LEN\t\t27\n+\n+/* Space left in the NAN vendor element for the configured attributes */\n+#define NAN_BEACON_EXTRA_ATTRS_LEN\t(255 - (NAN_BEACON_ELEM_LEN - 2))\n+\n /* Quiet time at the end of each slot where TX is suppressed */\n #define NAN_CHAN_SWITCH_TIME_US\t\t256\n \n@@ -213,6 +219,37 @@ mac80211_hwsim_nan_schedule_slot(struct mac80211_hwsim_data *data, u8 slot,\n \t\t\t mac80211_hwsim_tsf_to_boottime(data, tsf));\n }\n \n+static bool hwsim_nan_beacon_has_service_ids(struct sk_buff *skb)\n+{\n+\tconst struct ieee80211_mgmt *mgmt = (void *)skb-\u003edata;\n+\tconst struct ieee80211_nan_attr *nan_attr;\n+\tconst struct element *elem;\n+\tsize_t len;\n+\n+\tif (skb-\u003elen \u003c offsetofend(struct ieee80211_mgmt, u.beacon) ||\n+\t !ieee80211_is_beacon(mgmt-\u003eframe_control))\n+\t\treturn false;\n+\n+\tlen = skb-\u003elen - offsetofend(struct ieee80211_mgmt, u.beacon);\n+\n+\t/* TODO: fragmented NAN elements are not supported */\n+\tfor_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC,\n+\t\t\t mgmt-\u003eu.beacon.variable, len) {\n+\t\tif (elem-\u003edatalen \u003c 4 ||\n+\t\t get_unaligned_be32(elem-\u003edata) !=\n+\t\t (WLAN_OUI_WFA \u003c\u003c 8 | WLAN_OUI_TYPE_WFA_NAN))\n+\t\t\tcontinue;\n+\n+\t\tfor_each_nan_attr(nan_attr, elem-\u003edata + 4, elem-\u003edatalen - 4)\n+\t\t\tif (nan_attr-\u003eattr == NAN_ATTR_SERVICE_ID_LIST ||\n+\t\t\t nan_attr-\u003eattr ==\n+\t\t\t NAN_ATTR_SUBSCRIBE_SERVICE_ID_LIST)\n+\t\t\t\treturn true;\n+\t}\n+\n+\treturn false;\n+}\n+\n void mac80211_hwsim_nan_rx(struct ieee80211_hw *hw,\n \t\t\t struct sk_buff *skb)\n {\n@@ -230,9 +267,7 @@ void mac80211_hwsim_nan_rx(struct ieee80211_hw *hw,\n \tssize_t data_len;\n \tu8 slot;\n \n-\t/* Need a NAN vendor element at the start */\n-\tif (skb-\u003elen \u003c (offsetofend(struct ieee80211_mgmt, u.beacon) + 6) ||\n-\t !ieee80211_is_beacon(mgmt-\u003eframe_control))\n+\tif (!ieee80211_is_nan_beacon(mgmt, skb-\u003elen))\n \t\treturn;\n \n \tdata_len = skb-\u003elen - offsetofend(struct ieee80211_mgmt, u.beacon);\n@@ -266,28 +301,34 @@ void mac80211_hwsim_nan_rx(struct ieee80211_hw *hw,\n \t}\n \n \t/*\n-\t * (overly) simplify things, only track 2.4 GHz here. Also, ignore\n-\t * frames outside of the 2.4 GHz DW slot, unless in the initial SCAN\n-\t * phase.\n+\t * Only sync on 2.4 GHz, which all NAN devices attend. The slot number\n+\t * is derived from the local TSF, so before being synchronized a 5 GHz\n+\t * beacon from a different device may fall into the local 2.4 GHz DW\n+\t * slot. Filter by frequency to keep such beacons out of master\n+\t * selection and synchronization.\n \t */\n-\tif ((slot != SLOT_24GHZ_DW \u0026\u0026\n-\t data-\u003enan.phase != MAC80211_HWSIM_NAN_PHASE_SCAN) ||\n-\t rx_status.freq != 2437)\n+\tif (rx_status.freq != 2437)\n \t\treturn;\n \n-\t/* Just ignore low RSSI beacons that we cannot sync to */\n-\tif (rx_status.signal \u003c NAN_RSSI_MIDDLE)\n-\t\treturn;\n+\t/*\n+\t * Ignore frames outside of the 2.4 GHz DW slot, unless in the initial\n+\t * SCAN phase or in Instant Communication, where discovery beacons are\n+\t * received outside the DW.\n+\t */\n+\tif (slot != SLOT_24GHZ_DW) {\n+\t\tbool rx_outside_dw;\n \n-\t/* Needs to be a valid NAN cluster ID in A3 */\n-\tif (get_unaligned_be32(mgmt-\u003ebssid) != ((WLAN_OUI_WFA \u003c\u003c 8) | 0x01))\n-\t\treturn;\n+\t\tscoped_guard(spinlock_bh, \u0026data-\u003enan.state_lock)\n+\t\t\trx_outside_dw = data-\u003enan.instant_comm ||\n+\t\t\t\tdata-\u003enan.phase ==\n+\t\t\t\tMAC80211_HWSIM_NAN_PHASE_SCAN;\n \n-\t/* We are only interested in NAN beacons */\n-\tif (nan_elem-\u003eid != WLAN_EID_VENDOR_SPECIFIC ||\n-\t nan_elem-\u003edatalen \u003c 4 ||\n-\t get_unaligned_be32(nan_elem-\u003edata) !=\n-\t (WLAN_OUI_WFA \u003c\u003c 8 | WLAN_OUI_TYPE_WFA_NAN))\n+\t\tif (!rx_outside_dw)\n+\t\t\treturn;\n+\t}\n+\n+\t/* Just ignore low RSSI beacons that we cannot sync to */\n+\tif (rx_status.signal \u003c NAN_RSSI_MIDDLE)\n \t\treturn;\n \n \tu8 *nan_defragmented __free(kfree) = kzalloc(data_len, GFP_ATOMIC);\n@@ -636,10 +677,12 @@ mac80211_hwsim_nan_exec_state_transitions(struct mac80211_hwsim_data *data)\n \n \t/*\n \t * The discovery beacon timer will stop automatically. Make sure it is\n-\t * running if we are master. Do not bother with a proper alignment it\n-\t * will sync itself to the TSF after the first TX.\n+\t * running if we are master or if Instant Communication is enabled. Do\n+\t * not bother with a proper alignment it will sync itself to the TSF\n+\t * after the first TX.\n \t */\n-\tif (data-\u003enan.role == MAC80211_HWSIM_NAN_ROLE_MASTER \u0026\u0026\n+\tif ((data-\u003enan.role == MAC80211_HWSIM_NAN_ROLE_MASTER ||\n+\t data-\u003enan.instant_comm) \u0026\u0026\n \t !hrtimer_active(\u0026data-\u003enan.discovery_beacon_timer))\n \t\thrtimer_start(\u0026data-\u003enan.discovery_beacon_timer,\n \t\t\t ns_to_ktime(10 * NSEC_PER_USEC),\n@@ -698,7 +741,7 @@ mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,\n {\n \tstruct ieee80211_vendor_ie nan_ie = {\n \t\t.element_id = WLAN_EID_VENDOR_SPECIFIC,\n-\t\t.len = 27 - 2,\n+\t\t.len = NAN_BEACON_ELEM_LEN - 2,\n \t\t.oui = { u32_get_bits(WLAN_OUI_WFA, 0xff0000),\n \t\t\t u32_get_bits(WLAN_OUI_WFA, 0xff00),\n \t\t\t u32_get_bits(WLAN_OUI_WFA, 0xff) },\n@@ -707,23 +750,34 @@ mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,\n \tsize_t alloc_size =\n \t\tIEEE80211_TX_STATUS_HEADROOM +\n \t\toffsetofend(struct ieee80211_mgmt, u.beacon) +\n-\t\t27 /* size of NAN vendor element */;\n+\t\tNAN_BEACON_ELEM_LEN;\n \tstruct ieee80211_nan_master_indication master_indication;\n \tstruct ieee80211_nan_attr nan_attr;\n \tstruct ieee80211_mgmt *mgmt;\n \tstruct sk_buff *skb;\n \n \t/*\n-\t * TODO: Should the configured vendor elements or NAN attributes be\n-\t * included in some of these beacons?\n+\t * TODO: Should the configured vendor elements be included in some of\n+\t * these beacons?\n \t */\n \n+\t/* Allocate maximal size for NAN IE */\n+\tif (is_discovery)\n+\t\talloc_size += NAN_BEACON_EXTRA_ATTRS_LEN;\n+\n \tskb = alloc_skb(alloc_size, GFP_ATOMIC);\n \tif (!skb)\n \t\treturn;\n \n \tspin_lock(\u0026data-\u003enan.state_lock);\n \n+\t/*\n+\t * The attributes configured by user space are appended to the\n+\t * mandatory ones.\n+\t */\n+\tif (is_discovery)\n+\t\tnan_ie.len += data-\u003enan.extra_nan_attrs_len;\n+\n \tskb_reserve(skb, IEEE80211_TX_STATUS_HEADROOM);\n \tmgmt = skb_put(skb, offsetofend(struct ieee80211_mgmt, u.beacon));\n \n@@ -734,7 +788,9 @@ mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,\n \n \tmgmt-\u003eframe_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |\n \t\t\t\t\t IEEE80211_STYPE_BEACON);\n-\tmgmt-\u003eu.beacon.beacon_int = cpu_to_le16(is_discovery ? 100 : DWST_TU);\n+\tmgmt-\u003eu.beacon.beacon_int =\n+\t\tcpu_to_le16(is_discovery ? data-\u003enan.discovery_beacon_interval :\n+\t\t\t DWST_TU);\n \tmgmt-\u003eu.beacon.capab_info =\n \t\tcpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME |\n \t\t\t WLAN_CAPABILITY_SHORT_PREAMBLE);\n@@ -765,6 +821,10 @@ mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,\n \tskb_put_data(skb, \u0026data-\u003enan.current_ami,\n \t\t sizeof(data-\u003enan.current_ami));\n \n+\tif (is_discovery \u0026\u0026 data-\u003enan.extra_nan_attrs_len)\n+\t\tskb_put_data(skb, data-\u003enan.extra_nan_attrs,\n+\t\t\t data-\u003enan.extra_nan_attrs_len);\n+\n \tspin_unlock(\u0026data-\u003enan.state_lock);\n \n \tmac80211_hwsim_tx_frame(data-\u003ehw, skb, channel);\n@@ -877,7 +937,15 @@ mac80211_hwsim_nan_discovery_beacon_timer(struct hrtimer *timer)\n \t\treturn HRTIMER_NORESTART;\n \n \tscoped_guard(spinlock, \u0026data-\u003enan.state_lock) {\n-\t\tif (data-\u003enan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN ||\n+\t\tif (data-\u003enan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN)\n+\t\t\treturn HRTIMER_NORESTART;\n+\n+\t\t/*\n+\t\t * With Instant Communication the discovery beacons are\n+\t\t * transmitted disregarding the role and the state, see\n+\t\t * Wi-Fi Aware version 4.0 section 13.\n+\t\t */\n+\t\tif (!data-\u003enan.instant_comm \u0026\u0026\n \t\t data-\u003enan.role != MAC80211_HWSIM_NAN_ROLE_MASTER)\n \t\t\treturn HRTIMER_NORESTART;\n \t}\n@@ -894,10 +962,11 @@ mac80211_hwsim_nan_discovery_beacon_timer(struct hrtimer *timer)\n \ttsf_now = mac80211_hwsim_get_tsf(data-\u003ehw, data-\u003enan.device_vif);\n \n \t/* Wrap value to be after the next TBTT */\n-\ttbtt = tsf_now + ieee80211_tu_to_usec(100);\n+\ttbtt = tsf_now + ieee80211_tu_to_usec(data-\u003enan.discovery_beacon_interval);\n \n \t/* Round TBTT down to the correct time */\n-\tdiv_u64_rem(tbtt, ieee80211_tu_to_usec(100), \u0026remainder);\n+\tdiv_u64_rem(tbtt, ieee80211_tu_to_usec(data-\u003enan.discovery_beacon_interval),\n+\t\t \u0026remainder);\n \ttbtt = tbtt - remainder;\n \n \thrtimer_set_expires(\u0026data-\u003enan.discovery_beacon_timer,\n@@ -906,11 +975,51 @@ mac80211_hwsim_nan_discovery_beacon_timer(struct hrtimer *timer)\n \treturn HRTIMER_RESTART;\n }\n \n+static int mac80211_hwsim_nan_set_config(struct mac80211_hwsim_data *data,\n+\t\t\t\t\t struct cfg80211_nan_conf *conf)\n+{\n+\tconst u8 *extra_nan_attrs = NULL;\n+\tconst u8 *old;\n+\n+\tif (conf-\u003eextra_nan_attrs_len \u003e NAN_BEACON_EXTRA_ATTRS_LEN)\n+\t\treturn -EINVAL;\n+\n+\tif (conf-\u003eextra_nan_attrs_len) {\n+\t\textra_nan_attrs = kmemdup(conf-\u003eextra_nan_attrs,\n+\t\t\t\t\t conf-\u003eextra_nan_attrs_len,\n+\t\t\t\t\t GFP_KERNEL);\n+\t\tif (!extra_nan_attrs)\n+\t\t\treturn -ENOMEM;\n+\t}\n+\n+\tdata-\u003enan.notify_dw = conf-\u003eenable_dw_notification;\n+\n+\tscoped_guard(spinlock_bh, \u0026data-\u003enan.state_lock) {\n+\t\t/*\n+\t\t * Fall back to the device default if user space did not\n+\t\t * configure it\n+\t\t */\n+\t\tdata-\u003enan.discovery_beacon_interval =\n+\t\t\tconf-\u003ediscovery_beacon_interval ? : 100;\n+\n+\t\tdata-\u003enan.instant_comm = conf-\u003einstant_comm;\n+\n+\t\told = data-\u003enan.extra_nan_attrs;\n+\t\tdata-\u003enan.extra_nan_attrs = extra_nan_attrs;\n+\t\tdata-\u003enan.extra_nan_attrs_len = conf-\u003eextra_nan_attrs_len;\n+\t}\n+\n+\tkfree(old);\n+\n+\treturn 0;\n+}\n+\n int mac80211_hwsim_nan_start(struct ieee80211_hw *hw,\n \t\t\t struct ieee80211_vif *vif,\n \t\t\t struct cfg80211_nan_conf *conf)\n {\n \tstruct mac80211_hwsim_data *data = hw-\u003epriv;\n+\tint err;\n \n \tif (vif-\u003etype != NL80211_IFTYPE_NAN)\n \t\treturn -EINVAL;\n@@ -918,14 +1027,22 @@ int mac80211_hwsim_nan_start(struct ieee80211_hw *hw,\n \tif (data-\u003enan.device_vif)\n \t\treturn -EALREADY;\n \n+\terr = mac80211_hwsim_nan_set_config(data, conf);\n+\tif (err)\n+\t\treturn err;\n+\n \t/* set this before starting the timer, as preemption might occur */\n \tdata-\u003enan.device_vif = vif;\n \tdata-\u003enan.bands = conf-\u003ebands;\n \n \tscoped_guard(spinlock_bh, \u0026data-\u003enan.state_lock) {\n-\t\t/* Start in the \"scan\" phase and stay there for a little bit */\n+\t\t/*\n+\t\t * Start in the \"scan\" phase and stay there for a little bit,\n+\t\t * unless Instant Communication is configured, in which case an\n+\t\t * own cluster is started immediately.\n+\t\t */\n \t\tdata-\u003enan.phase = MAC80211_HWSIM_NAN_PHASE_SCAN;\n-\t\tdata-\u003enan.random_factor_valid_dwst = 1;\n+\t\tdata-\u003enan.random_factor_valid_dwst = conf-\u003einstant_comm ? 0 : 1;\n \t\tdata-\u003enan.random_factor = 0;\n \t\tdata-\u003enan.master_pref = conf-\u003emaster_pref;\n \t\tdata-\u003enan.role = MAC80211_HWSIM_NAN_ROLE_MASTER;\n@@ -943,8 +1060,6 @@ int mac80211_hwsim_nan_start(struct ieee80211_hw *hw,\n \n \tether_addr_copy(data-\u003enan.cluster_id, conf-\u003ecluster_id);\n \n-\tdata-\u003enan.notify_dw = conf-\u003eenable_dw_notification;\n-\n \treturn 0;\n }\n \n@@ -952,6 +1067,7 @@ int mac80211_hwsim_nan_stop(struct ieee80211_hw *hw,\n \t\t\t struct ieee80211_vif *vif)\n {\n \tstruct mac80211_hwsim_data *data = hw-\u003epriv;\n+\tconst u8 *old;\n \n \tif (vif-\u003etype != NL80211_IFTYPE_NAN || !data-\u003enan.device_vif ||\n \t data-\u003enan.device_vif != vif)\n@@ -962,6 +1078,15 @@ int mac80211_hwsim_nan_stop(struct ieee80211_hw *hw,\n \thrtimer_cancel(\u0026data-\u003enan.discovery_beacon_timer);\n \tdata-\u003enan.device_vif = NULL;\n \n+\tscoped_guard(spinlock_bh, \u0026data-\u003enan.state_lock) {\n+\t\told = data-\u003enan.extra_nan_attrs;\n+\t\tdata-\u003enan.extra_nan_attrs = NULL;\n+\t\tdata-\u003enan.extra_nan_attrs_len = 0;\n+\t\tdata-\u003enan.instant_comm = false;\n+\t}\n+\n+\tkfree(old);\n+\n \treturn 0;\n }\n \n@@ -980,13 +1105,27 @@ int mac80211_hwsim_nan_change_config(struct ieee80211_hw *hw,\n \n \twiphy_debug(hw-\u003ewiphy, \"nan_config_changed: changes=0x%x\\n\", changes);\n \n+\tif (changes \u0026 CFG80211_NAN_CONF_CHANGED_CONFIG) {\n+\t\tint err = mac80211_hwsim_nan_set_config(data, conf);\n+\n+\t\tif (err)\n+\t\t\treturn err;\n+\n+\t\t/*\n+\t\t * When Instant Communication is enabled discovery beacons are\n+\t\t * transmitted regardless of the role and the state.\n+\t\t */\n+\t\tif (conf-\u003einstant_comm \u0026\u0026\n+\t\t !hrtimer_active(\u0026data-\u003enan.discovery_beacon_timer))\n+\t\t\thrtimer_start(\u0026data-\u003enan.discovery_beacon_timer,\n+\t\t\t\t ns_to_ktime(10 * NSEC_PER_USEC),\n+\t\t\t\t HRTIMER_MODE_REL_SOFT);\n+\t}\n+\n \t/* Handle only the changes we care about for simulation purposes */\n \tif (changes \u0026 CFG80211_NAN_CONF_CHANGED_BANDS)\n \t\tdata-\u003enan.bands = conf-\u003ebands;\n \n-\tif (changes \u0026 CFG80211_NAN_CONF_CHANGED_CONFIG)\n-\t\tdata-\u003enan.notify_dw = conf-\u003eenable_dw_notification;\n-\n \tif (changes \u0026 CFG80211_NAN_CONF_CHANGED_PREF) {\n \t\tscoped_guard(spinlock_bh, \u0026data-\u003enan.state_lock)\n \t\t\tdata-\u003enan.master_pref = conf-\u003emaster_pref;\n@@ -1169,9 +1308,16 @@ bool mac80211_hwsim_nan_txq_transmitting(struct ieee80211_hw *hw,\n \tis_dw_slot = mac80211_hwsim_nan_is_dw_slot(data, slot);\n \n \tif (!txq-\u003esta) {\n-\t\t/* Non-STA TXQ: allow management frames during DW */\n-\t\tif (txq-\u003evif-\u003etype == NL80211_IFTYPE_NAN)\n-\t\t\treturn is_dw_slot;\n+\t\t/* Non-STA TXQ: allow management frames during DW or IC */\n+\t\tif (txq-\u003evif-\u003etype == NL80211_IFTYPE_NAN) {\n+\t\t\tif (is_dw_slot)\n+\t\t\t\treturn true;\n+\n+\t\t\t/* Outside the DW the local schedule must allow it */\n+\t\t\tguard(spinlock_bh)(\u0026data-\u003enan.state_lock);\n+\t\t\treturn data-\u003enan.instant_comm \u0026\u0026\n+\t\t\t\tdata-\u003enan.local_sched[slot].chan;\n+\t\t}\n \n \t\t/* Allow multicast data when all the peers are available\n \t\t * on this slot\n@@ -1224,15 +1370,32 @@ void mac80211_hwsim_nan_get_tx_chandef(struct ieee80211_hw *hw,\n }\n \n bool mac80211_hwsim_nan_receive(struct ieee80211_hw *hw,\n+\t\t\t\tstruct sk_buff *skb,\n \t\t\t\tstruct ieee80211_channel *channel,\n \t\t\t\tstruct ieee80211_rx_status *rx_status)\n {\n \tstruct mac80211_hwsim_data *data = hw-\u003epriv;\n+\tbool instant_comm;\n \tu8 slot;\n \n \tif (WARN_ON_ONCE(!data-\u003enan.device_vif))\n \t\treturn false;\n \n+\tscoped_guard(spinlock_bh, \u0026data-\u003enan.state_lock)\n+\t\tinstant_comm = data-\u003enan.instant_comm;\n+\n+\t/*\n+\t * During Instant Communication a peer advertises its services in the\n+\t * discovery beacons, which are transmitted disregarding the roles and\n+\t * the states, see Section 13 in Wi-Fi Aware v4.0.\n+\t * Note that while according to the specification Instant communication\n+\t * should be enabled only on the NAN discovery channels, do not force\n+\t * this here, and allow receiving NAN frames on any channel if Instant\n+\t * Communication is enabled.\n+\t */\n+\tif (instant_comm \u0026\u0026 hwsim_nan_beacon_has_service_ids(skb))\n+\t\treturn true;\n+\n \tif (data-\u003enan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN)\n \t\treturn channel-\u003ecenter_freq == 2437;\n \ndiff --git a/drivers/net/wireless/virtual/mac80211_hwsim_nan.h b/drivers/net/wireless/virtual/mac80211_hwsim_nan.h\nindex 81e105ac7b8ed..995d1f6feb291 100644\n--- a/drivers/net/wireless/virtual/mac80211_hwsim_nan.h\n+++ b/drivers/net/wireless/virtual/mac80211_hwsim_nan.h\n@@ -32,6 +32,9 @@ struct mac80211_hwsim_nan_data {\n \t/* Later members are protected by this lock */\n \tspinlock_t state_lock;\n \n+\tconst u8 *extra_nan_attrs;\n+\tu16 extra_nan_attrs_len;\n+\n \tu8 master_pref;\n \tu8 random_factor;\n \n@@ -53,6 +56,9 @@ struct mac80211_hwsim_nan_data {\n \tbool tsf_adjusted;\n \tbool tsf_discontinuity;\n \n+\tbool instant_comm;\n+\tu8 discovery_beacon_interval;\n+\n \t/*\n \t * Local schedule - stores channel definition for each 16TU slot.\n \t * Derived from NMI vif-\u003ecfg.nan_schedule. chan == NULL means not\n@@ -90,6 +96,7 @@ void mac80211_hwsim_nan_get_tx_chandef(struct ieee80211_hw *hw,\n \t\t\t\t struct cfg80211_chan_def *chandef);\n \n bool mac80211_hwsim_nan_receive(struct ieee80211_hw *hw,\n+\t\t\t\tstruct sk_buff *skb,\n \t\t\t\tstruct ieee80211_channel *channel,\n \t\t\t\tstruct ieee80211_rx_status *rx_status);\n \ndiff --git a/include/linux/ieee80211-nan.h b/include/linux/ieee80211-nan.h\nindex 455033955e545..7815a6cf81605 100644\n--- a/include/linux/ieee80211-nan.h\n+++ b/include/linux/ieee80211-nan.h\n@@ -40,6 +40,8 @@\n /* NAN attributes, as defined in Wi-Fi Aware (TM) specification 4.0 Table 42 */\n #define NAN_ATTR_MASTER_INDICATION\t\t0x00\n #define NAN_ATTR_CLUSTER_INFO\t\t\t0x01\n+#define NAN_ATTR_SERVICE_ID_LIST\t\t0x02\n+#define NAN_ATTR_SUBSCRIBE_SERVICE_ID_LIST\t0x28\n \n struct ieee80211_nan_attr {\n \tu8 attr;\n@@ -74,4 +76,30 @@ struct ieee80211_nan_anchor_master_info {\n \t _attr = (const struct ieee80211_nan_attr *)\t\t\\\n \t\t(_attr-\u003edata + le16_to_cpu(_attr-\u003elength)))\n \n+static inline bool ieee80211_is_nan_beacon(const struct ieee80211_mgmt *mgmt,\n+\t\t\t\t\t size_t len)\n+{\n+\tconst struct element *elem;\n+\n+\t/* The NAN IE is at least 6 octets */\n+\tif (len \u003c offsetofend(struct ieee80211_mgmt, u.beacon) + 6)\n+\t\treturn false;\n+\n+\tif (!ieee80211_is_beacon(mgmt-\u003eframe_control))\n+\t\treturn false;\n+\n+\t/* NAN Cluster IDs range from 50-6F-9A-01-00-00 to 50-6F-9A-01-FF-FF */\n+\tif (get_unaligned_be32(mgmt-\u003ebssid) != ((WLAN_OUI_WFA \u003c\u003c 8) | 0x01))\n+\t\treturn false;\n+\n+\telem = (const struct element *)mgmt-\u003eu.beacon.variable;\n+\tif (elem-\u003eid != WLAN_EID_VENDOR_SPECIFIC ||\n+\t elem-\u003edatalen \u003c 4 ||\n+\t get_unaligned_be32(elem-\u003edata) !=\n+\t (WLAN_OUI_WFA \u003c\u003c 8 | WLAN_OUI_TYPE_WFA_NAN))\n+\t\treturn false;\n+\n+\treturn true;\n+}\n+\n #endif /* LINUX_IEEE80211_NAN_H */\ndiff --git a/include/net/cfg80211.h b/include/net/cfg80211.h\nindex 97c16d4ff1271..f9d590facfc0b 100644\n--- a/include/net/cfg80211.h\n+++ b/include/net/cfg80211.h\n@@ -4183,9 +4183,12 @@ struct cfg80211_nan_band_config {\n *\tthat can take a value from 50-6F-9A-01-00-00 to 50-6F-9A-01-FF-FF.\n * @scan_period: period (in seconds) between NAN scans.\n * @scan_dwell_time: dwell time (in milliseconds) for NAN scans.\n- * @discovery_beacon_interval: interval (in TUs) for discovery beacons.\n+ * @discovery_beacon_interval: interval (in TUs) for discovery beacons. Must be\n+ *\tgreater than 0 when @instant_comm is true.\n * @enable_dw_notification: flag to enable/disable discovery window\n *\tnotifications.\n+ * @instant_comm: if true, start Instant Communication (IC) as defined in\n+ *\tChapter 13 of the Wi-Fi Aware Specification v4.0.\n * @band_cfgs: array of band specific configurations, indexed by\n *\t\u0026enum nl80211_band values.\n * @extra_nan_attrs: pointer to additional NAN attributes.\n@@ -4201,6 +4204,7 @@ struct cfg80211_nan_conf {\n \tu16 scan_dwell_time;\n \tu8 discovery_beacon_interval;\n \tbool enable_dw_notification;\n+\tbool instant_comm;\n \tstruct cfg80211_nan_band_config band_cfgs[NUM_NL80211_BANDS];\n \tconst u8 *extra_nan_attrs;\n \tu16 extra_nan_attrs_len;\n@@ -6266,10 +6270,13 @@ struct wiphy_radio {\n * @WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC: Device supports NAN configurable\n * synchronization.\n * @WIPHY_NAN_FLAGS_USERSPACE_DE: Device doesn't support DE offload.\n+ * @WIPHY_NAN_FLAGS_INSTANT_COMM: Device can switch to Instant Communication\n+ * (IC) mode. Can only be set along with %WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC.\n */\n enum wiphy_nan_flags {\n \tWIPHY_NAN_FLAGS_CONFIGURABLE_SYNC = BIT(0),\n \tWIPHY_NAN_FLAGS_USERSPACE_DE = BIT(1),\n+\tWIPHY_NAN_FLAGS_INSTANT_COMM = BIT(2),\n };\n \n /**\ndiff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h\nindex 020387d764122..5ac9f02f5ad26 100644\n--- a/include/uapi/linux/nl80211.h\n+++ b/include/uapi/linux/nl80211.h\n@@ -7826,6 +7826,11 @@ enum nl80211_nan_band_conf_attributes {\n *\tthe upcoming discovery window with\n *\t%NL80211_CMD_NAN_NEXT_DW_NOTIFICATION.\n *\tThis is a flag attribute.\n+ * @NL80211_NAN_CONF_INSTANT_COMM: If set, the NAN synchronization logic will\n+ *\tstart Instant Communication (IC) as defined in Chapter 13 of the\n+ *\tWi-Fi Aware Specification v4.0.\n+ *\t%NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL must be set as well.\n+ *\tThis is a flag attribute.\n * @NUM_NL80211_NAN_CONF_ATTR: Internal.\n * @NL80211_NAN_CONF_ATTR_MAX: Highest NAN configuration attribute.\n *\n@@ -7841,6 +7846,7 @@ enum nl80211_nan_conf_attributes {\n \tNL80211_NAN_CONF_SCAN_DWELL_TIME,\n \tNL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL,\n \tNL80211_NAN_CONF_NOTIFY_DW,\n+\tNL80211_NAN_CONF_INSTANT_COMM,\n \n \t/* keep last */\n \tNUM_NL80211_NAN_CONF_ATTR,\n@@ -9057,6 +9063,11 @@ enum nl80211_s1g_short_beacon_attrs {\n *\tspecification Table 79 (Capabilities field).\n * @NL80211_NAN_CAPA_PHY: nested attribute containing band-agnostic\n *\tcapabilities for NAN data path. See \u0026enum nl80211_nan_phy_cap_attr.\n+ * @NL80211_NAN_CAPA_INSTANT_COMM: Flag attribute indicating that the device\n+ *\tcan switch to Instant Communication (IC) mode, as defined in Chapter 13\n+ *\tof the Wi-Fi Aware Specification v4.0. Can only be set if\n+ *\t%NL80211_NAN_CAPA_CONFIGURABLE_SYNC is set. When IC is enabled, the IC\n+ *\tschedule is expected to be configured by user space.\n * @__NL80211_NAN_CAPABILITIES_LAST: Internal\n * @NL80211_NAN_CAPABILITIES_MAX: Highest NAN capability attribute.\n */\n@@ -9070,6 +9081,7 @@ enum nl80211_nan_capabilities {\n \tNL80211_NAN_CAPA_MAX_CHANNEL_SWITCH_TIME,\n \tNL80211_NAN_CAPA_CAPABILITIES,\n \tNL80211_NAN_CAPA_PHY,\n+\tNL80211_NAN_CAPA_INSTANT_COMM,\n \t/* keep last */\n \t__NL80211_NAN_CAPABILITIES_LAST,\n \tNL80211_NAN_CAPABILITIES_MAX = __NL80211_NAN_CAPABILITIES_LAST - 1,\ndiff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c\nindex 23f4f9ec86d0a..7a7acbfeeba92 100644\n--- a/net/mac80211/cfg.c\n+++ b/net/mac80211/cfg.c\n@@ -364,6 +364,7 @@ static int ieee80211_nan_conf_copy(struct cfg80211_nan_conf *dst,\n \t\tdst-\u003ediscovery_beacon_interval =\n \t\t\tsrc-\u003ediscovery_beacon_interval;\n \t\tdst-\u003eenable_dw_notification = src-\u003eenable_dw_notification;\n+\t\tdst-\u003einstant_comm = src-\u003einstant_comm;\n \t\tmemcpy(\u0026dst-\u003eband_cfgs, \u0026src-\u003eband_cfgs,\n \t\t sizeof(dst-\u003eband_cfgs));\n \ndiff --git a/net/mac80211/main.c b/net/mac80211/main.c\nindex a59837b9f480f..9553ea77cfe84 100644\n--- a/net/mac80211/main.c\n+++ b/net/mac80211/main.c\n@@ -745,8 +745,13 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {\n \t},\n \t[NL80211_IFTYPE_NAN] = {\n \t\t.tx = 0xffff,\n+\t\t/*\n+\t\t * Beacon Rx registration is needed to let user space handle\n+\t\t * service discovery when Instant Communication is enabled.\n+\t\t */\n \t\t.rx = BIT(IEEE80211_STYPE_ACTION \u003e\u003e 4) |\n-\t\t\tBIT(IEEE80211_STYPE_AUTH \u003e\u003e 4),\n+\t\t\tBIT(IEEE80211_STYPE_AUTH \u003e\u003e 4) |\n+\t\t\tBIT(IEEE80211_STYPE_BEACON \u003e\u003e 4),\n \t},\n \t[NL80211_IFTYPE_NAN_DATA] = {\n \t\t.tx = 0xffff,\ndiff --git a/net/mac80211/rx.c b/net/mac80211/rx.c\nindex 5e26be8e27d8f..eb1578b2d6d79 100644\n--- a/net/mac80211/rx.c\n+++ b/net/mac80211/rx.c\n@@ -4660,7 +4660,8 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)\n \t\t * Accept only frames that are addressed to the NAN cluster\n \t\t * (based on the Cluster ID). From these frames, accept only\n \t\t * - public action frames,\n-\t\t * - authentication frames to the local address, and\n+\t\t * - authentication frames to the local address,\n+\t\t * - NAN beacons, when Instant Communication is enabled, and\n \t\t * - robust management frames except disassoc.\n \t\t */\n \t\tif (!ether_addr_equal(sdata-\u003eu.nan.conf.cluster_id, hdr-\u003eaddr3))\n@@ -4670,6 +4671,9 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)\n \t\tif (ieee80211_is_auth(hdr-\u003eframe_control) \u0026\u0026\n \t\t ether_addr_equal(sdata-\u003evif.addr, hdr-\u003eaddr1))\n \t\t\treturn true;\n+\t\tif (ieee80211_is_nan_beacon((struct ieee80211_mgmt *)hdr,\n+\t\t\t\t\t skb-\u003elen))\n+\t\t\treturn sdata-\u003eu.nan.conf.instant_comm;\n \t\tif (!ieee80211_is_disassoc(hdr-\u003eframe_control) \u0026\u0026\n \t\t ieee80211_is_robust_mgmt_frame(skb))\n \t\t\treturn true;\ndiff --git a/net/wireless/core.c b/net/wireless/core.c\nindex d13310fef691a..fc9b97888191d 100644\n--- a/net/wireless/core.c\n+++ b/net/wireless/core.c\n@@ -888,6 +888,18 @@ int wiphy_register(struct wiphy *wiphy)\n \t\t (!wiphy-\u003enan_capa.phy.ht.ht_supported || wiphy-\u003en_radio \u003e 1)))\n \t\treturn -EINVAL;\n \n+\tif (WARN_ON((wiphy-\u003enan_capa.flags \u0026 WIPHY_NAN_FLAGS_INSTANT_COMM) \u0026\u0026\n+\t\t !(wiphy-\u003enan_capa.flags \u0026\n+\t\t WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC)))\n+\t\treturn -EINVAL;\n+\n+\t/* Instant Communication requires user space to track NAN beacons */\n+\tif (WARN_ON((wiphy-\u003enan_capa.flags \u0026 WIPHY_NAN_FLAGS_INSTANT_COMM) \u0026\u0026\n+\t\t (!wiphy-\u003emgmt_stypes ||\n+\t\t !(wiphy-\u003emgmt_stypes[NL80211_IFTYPE_NAN].rx \u0026\n+\t\t BIT(IEEE80211_STYPE_BEACON \u003e\u003e 4)))))\n+\t\treturn -EINVAL;\n+\n \tif (WARN_ON(wiphy-\u003einterface_modes \u0026 BIT(NL80211_IFTYPE_WDS)))\n \t\treturn -EINVAL;\n \ndiff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c\nindex 44f2bad086705..94d92b0ebc54e 100644\n--- a/net/wireless/nl80211.c\n+++ b/net/wireless/nl80211.c\n@@ -686,6 +686,7 @@ nl80211_nan_conf_policy[NL80211_NAN_CONF_ATTR_MAX + 1] = {\n \t[NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL] =\n \t\tNLA_POLICY_RANGE(NLA_U8, 50, 200),\n \t[NL80211_NAN_CONF_NOTIFY_DW] = { .type = NLA_FLAG },\n+\t[NL80211_NAN_CONF_INSTANT_COMM] = { .type = NLA_FLAG },\n };\n \n static const struct netlink_range_validation nl80211_punct_bitmap_range = {\n@@ -3025,6 +3026,10 @@ static int nl80211_put_nan_capa(struct wiphy *wiphy, struct sk_buff *msg)\n \t nla_put_flag(msg, NL80211_NAN_CAPA_USERSPACE_DE))\n \t\tgoto fail;\n \n+\tif ((wiphy-\u003enan_capa.flags \u0026 WIPHY_NAN_FLAGS_INSTANT_COMM) \u0026\u0026\n+\t nla_put_flag(msg, NL80211_NAN_CAPA_INSTANT_COMM))\n+\t\tgoto fail;\n+\n \tif (nla_put_u8(msg, NL80211_NAN_CAPA_OP_MODE,\n \t\t wiphy-\u003enan_capa.op_mode) ||\n \t nla_put_u8(msg, NL80211_NAN_CAPA_NUM_ANTENNAS,\n@@ -16663,6 +16668,23 @@ static int nl80211_parse_nan_conf(struct wiphy *wiphy,\n \t\tconf-\u003eenable_dw_notification =\n \t\t\tnla_get_flag(attrs[NL80211_NAN_CONF_NOTIFY_DW]);\n \n+\tconf-\u003einstant_comm = nla_get_flag(attrs[NL80211_NAN_CONF_INSTANT_COMM]);\n+\tif (conf-\u003einstant_comm) {\n+\t\tif (!(wiphy-\u003enan_capa.flags \u0026 WIPHY_NAN_FLAGS_INSTANT_COMM)) {\n+\t\t\tNL_SET_ERR_MSG_ATTR(info-\u003eextack,\n+\t\t\t\t\t attrs[NL80211_NAN_CONF_INSTANT_COMM],\n+\t\t\t\t\t \"Instant Communication is not supported\");\n+\t\t\treturn -EOPNOTSUPP;\n+\t\t}\n+\n+\t\tif (!conf-\u003ediscovery_beacon_interval) {\n+\t\t\tNL_SET_ERR_MSG_ATTR(info-\u003eextack,\n+\t\t\t\t\t attrs[NL80211_NAN_CONF_INSTANT_COMM],\n+\t\t\t\t\t \"Instant Communication requires a discovery beacon interval\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n out:\n \tif (!conf-\u003eband_cfgs[NL80211_BAND_5GHZ].chan \u0026\u0026\n \t (!conf-\u003ebands || conf-\u003ebands \u0026 BIT(NL80211_BAND_5GHZ))) {\ndiff --git a/net/wireless/scan.c b/net/wireless/scan.c\nindex 9e934b185e341..c5dad787747a5 100644\n--- a/net/wireless/scan.c\n+++ b/net/wireless/scan.c\n@@ -3302,6 +3302,10 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,\n \tif (WARN_ON(!wiphy))\n \t\treturn NULL;\n \n+\t/* NAN beacons are not a BSS, don't add to the BSS table */\n+\tif (ieee80211_is_nan_beacon(mgmt, len))\n+\t\treturn NULL;\n+\n \tBUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) !=\n \t\t offsetof(struct ieee80211_mgmt, u.beacon.variable));\n \n"
} |
| 2/1 | 2026/10/04 13:45 | agent | patch-evaluator |
1mModel:core Args: null Results: {
"EnableConfigs": [
"MAC80211_HWSIM",
"MAC80211",
"CFG80211"
],
"FocusSymbols": [
"mac80211_hwsim_nan_receive",
"mac80211_hwsim_nan_rx",
"mac80211_hwsim_nan_start",
"mac80211_hwsim_nan_stop",
"mac80211_hwsim_nan_change_config",
"mac80211_hwsim_nan_txq_transmitting",
"mac80211_hwsim_nan_discovery_beacon_timer",
"nl80211_start_nan",
"nl80211_nan_change_config",
"cfg80211_inform_bss_frame_data"
],
"Reasoning": "The patch series introduces support for Wi-Fi Aware (NAN) Instant Communication (IC) mode across cfg80211, mac80211, and the simulated mac80211_hwsim driver. This modifies reachable netlink configuration parsers (nl80211_parse_nan_conf), frame reception and transmission paths, beacon handling, extra NAN attributes allocation/freeing, and timer callbacks in mac80211_hwsim. These code paths are fully reachable via netlink (nl80211) and virtual software wireless devices in standard fuzzing environments.",
"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 64bd13e2ed1419f98d3aa38145753d7af0776e26
Author: syz-cluster <triage@syzkaller.com>
Date: Sun Oct 4 13:45:18 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_main.c b/drivers/net/wireless/virtual/mac80211_hwsim_main.c
index 02b6d81cccd11..5d235946e19a1 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim_main.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim_main.c
@@ -1772,6 +1772,7 @@ struct tx_iter_data {
struct ieee80211_channel *channel;
struct ieee80211_rx_status *rx_status;
struct ieee80211_hw *hw;
+ struct sk_buff *skb;
bool receive;
};
@@ -1784,6 +1785,7 @@ static void mac80211_hwsim_tx_iter(void *_data, u8 *addr,
if (vif->type == NL80211_IFTYPE_NAN ||
vif->type == NL80211_IFTYPE_NAN_DATA) {
data->receive = mac80211_hwsim_nan_receive(data->hw,
+ data->skb,
data->channel,
data->rx_status);
return;
@@ -1968,6 +1970,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
.hw = data2->hw,
.channel = chan,
.rx_status = &rx_status,
+ .skb = skb,
};
if (data == data2)
@@ -5800,7 +5803,8 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
BIT(NL80211_BAND_5GHZ);
hw->wiphy->nan_capa.flags = WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC |
- WIPHY_NAN_FLAGS_USERSPACE_DE;
+ WIPHY_NAN_FLAGS_USERSPACE_DE |
+ WIPHY_NAN_FLAGS_INSTANT_COMM;
hw->wiphy->nan_capa.op_mode = NAN_OP_MODE_PHY_MODE_MASK |
NAN_OP_MODE_80P80MHZ |
NAN_OP_MODE_160MHZ;
@@ -6546,6 +6550,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
struct tx_iter_data iter_data = {
.hw = data2->hw,
.rx_status = &rx_status,
+ .skb = skb,
};
/* throw away off-channel packets, but allow both the temporary
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_nan.c b/drivers/net/wireless/virtual/mac80211_hwsim_nan.c
index 7be64c45babf9..1f058ec9c159f 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim_nan.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim_nan.c
@@ -33,6 +33,12 @@ static_assert(DW0_TSF_MASK + 1 == 8192 * 1024);
#define NAN_RSSI_CLOSE (-60)
#define NAN_RSSI_MIDDLE (-75)
+/* Size of the NAN vendor element carrying the mandatory attributes */
+#define NAN_BEACON_ELEM_LEN 27
+
+/* Space left in the NAN vendor element for the configured attributes */
+#define NAN_BEACON_EXTRA_ATTRS_LEN (255 - (NAN_BEACON_ELEM_LEN - 2))
+
/* Quiet time at the end of each slot where TX is suppressed */
#define NAN_CHAN_SWITCH_TIME_US 256
@@ -213,6 +219,37 @@ mac80211_hwsim_nan_schedule_slot(struct mac80211_hwsim_data *data, u8 slot,
mac80211_hwsim_tsf_to_boottime(data, tsf));
}
+static bool hwsim_nan_beacon_has_service_ids(struct sk_buff *skb)
+{
+ const struct ieee80211_mgmt *mgmt = (void *)skb->data;
+ const struct ieee80211_nan_attr *nan_attr;
+ const struct element *elem;
+ size_t len;
+
+ if (skb->len < offsetofend(struct ieee80211_mgmt, u.beacon) ||
+ !ieee80211_is_beacon(mgmt->frame_control))
+ return false;
+
+ len = skb->len - offsetofend(struct ieee80211_mgmt, u.beacon);
+
+ /* TODO: fragmented NAN elements are not supported */
+ for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC,
+ mgmt->u.beacon.variable, len) {
+ if (elem->datalen < 4 ||
+ get_unaligned_be32(elem->data) !=
+ (WLAN_OUI_WFA << 8 | WLAN_OUI_TYPE_WFA_NAN))
+ continue;
+
+ for_each_nan_attr(nan_attr, elem->data + 4, elem->datalen - 4)
+ if (nan_attr->attr == NAN_ATTR_SERVICE_ID_LIST ||
+ nan_attr->attr ==
+ NAN_ATTR_SUBSCRIBE_SERVICE_ID_LIST)
+ return true;
+ }
+
+ return false;
+}
+
void mac80211_hwsim_nan_rx(struct ieee80211_hw *hw,
struct sk_buff *skb)
{
@@ -230,9 +267,7 @@ void mac80211_hwsim_nan_rx(struct ieee80211_hw *hw,
ssize_t data_len;
u8 slot;
- /* Need a NAN vendor element at the start */
- if (skb->len < (offsetofend(struct ieee80211_mgmt, u.beacon) + 6) ||
- !ieee80211_is_beacon(mgmt->frame_control))
+ if (!ieee80211_is_nan_beacon(mgmt, skb->len))
return;
data_len = skb->len - offsetofend(struct ieee80211_mgmt, u.beacon);
@@ -266,28 +301,34 @@ void mac80211_hwsim_nan_rx(struct ieee80211_hw *hw,
}
/*
- * (overly) simplify things, only track 2.4 GHz here. Also, ignore
- * frames outside of the 2.4 GHz DW slot, unless in the initial SCAN
- * phase.
+ * Only sync on 2.4 GHz, which all NAN devices attend. The slot number
+ * is derived from the local TSF, so before being synchronized a 5 GHz
+ * beacon from a different device may fall into the local 2.4 GHz DW
+ * slot. Filter by frequency to keep such beacons out of master
+ * selection and synchronization.
*/
- if ((slot != SLOT_24GHZ_DW &&
- data->nan.phase != MAC80211_HWSIM_NAN_PHASE_SCAN) ||
- rx_status.freq != 2437)
+ if (rx_status.freq != 2437)
return;
- /* Just ignore low RSSI beacons that we cannot sync to */
- if (rx_status.signal < NAN_RSSI_MIDDLE)
- return;
+ /*
+ * Ignore frames outside of the 2.4 GHz DW slot, unless in the initial
+ * SCAN phase or in Instant Communication, where discovery beacons are
+ * received outside the DW.
+ */
+ if (slot != SLOT_24GHZ_DW) {
+ bool rx_outside_dw;
- /* Needs to be a valid NAN cluster ID in A3 */
- if (get_unaligned_be32(mgmt->bssid) != ((WLAN_OUI_WFA << 8) | 0x01))
- return;
+ scoped_guard(spinlock_bh, &data->nan.state_lock)
+ rx_outside_dw = data->nan.instant_comm ||
+ data->nan.phase ==
+ MAC80211_HWSIM_NAN_PHASE_SCAN;
- /* We are only interested in NAN beacons */
- if (nan_elem->id != WLAN_EID_VENDOR_SPECIFIC ||
- nan_elem->datalen < 4 ||
- get_unaligned_be32(nan_elem->data) !=
- (WLAN_OUI_WFA << 8 | WLAN_OUI_TYPE_WFA_NAN))
+ if (!rx_outside_dw)
+ return;
+ }
+
+ /* Just ignore low RSSI beacons that we cannot sync to */
+ if (rx_status.signal < NAN_RSSI_MIDDLE)
return;
u8 *nan_defragmented __free(kfree) = kzalloc(data_len, GFP_ATOMIC);
@@ -636,10 +677,12 @@ mac80211_hwsim_nan_exec_state_transitions(struct mac80211_hwsim_data *data)
/*
* The discovery beacon timer will stop automatically. Make sure it is
- * running if we are master. Do not bother with a proper alignment it
- * will sync itself to the TSF after the first TX.
+ * running if we are master or if Instant Communication is enabled. Do
+ * not bother with a proper alignment it will sync itself to the TSF
+ * after the first TX.
*/
- if (data->nan.role == MAC80211_HWSIM_NAN_ROLE_MASTER &&
+ if ((data->nan.role == MAC80211_HWSIM_NAN_ROLE_MASTER ||
+ data->nan.instant_comm) &&
!hrtimer_active(&data->nan.discovery_beacon_timer))
hrtimer_start(&data->nan.discovery_beacon_timer,
ns_to_ktime(10 * NSEC_PER_USEC),
@@ -698,7 +741,7 @@ mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,
{
struct ieee80211_vendor_ie nan_ie = {
.element_id = WLAN_EID_VENDOR_SPECIFIC,
- .len = 27 - 2,
+ .len = NAN_BEACON_ELEM_LEN - 2,
.oui = { u32_get_bits(WLAN_OUI_WFA, 0xff0000),
u32_get_bits(WLAN_OUI_WFA, 0xff00),
u32_get_bits(WLAN_OUI_WFA, 0xff) },
@@ -707,23 +750,34 @@ mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,
size_t alloc_size =
IEEE80211_TX_STATUS_HEADROOM +
offsetofend(struct ieee80211_mgmt, u.beacon) +
- 27 /* size of NAN vendor element */;
+ NAN_BEACON_ELEM_LEN;
struct ieee80211_nan_master_indication master_indication;
struct ieee80211_nan_attr nan_attr;
struct ieee80211_mgmt *mgmt;
struct sk_buff *skb;
/*
- * TODO: Should the configured vendor elements or NAN attributes be
- * included in some of these beacons?
+ * TODO: Should the configured vendor elements be included in some of
+ * these beacons?
*/
+ /* Allocate maximal size for NAN IE */
+ if (is_discovery)
+ alloc_size += NAN_BEACON_EXTRA_ATTRS_LEN;
+
skb = alloc_skb(alloc_size, GFP_ATOMIC);
if (!skb)
return;
spin_lock(&data->nan.state_lock);
+ /*
+ * The attributes configured by user space are appended to the
+ * mandatory ones.
+ */
+ if (is_discovery)
+ nan_ie.len += data->nan.extra_nan_attrs_len;
+
skb_reserve(skb, IEEE80211_TX_STATUS_HEADROOM);
mgmt = skb_put(skb, offsetofend(struct ieee80211_mgmt, u.beacon));
@@ -734,7 +788,9 @@ mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_BEACON);
- mgmt->u.beacon.beacon_int = cpu_to_le16(is_discovery ? 100 : DWST_TU);
+ mgmt->u.beacon.beacon_int =
+ cpu_to_le16(is_discovery ? data->nan.discovery_beacon_interval :
+ DWST_TU);
mgmt->u.beacon.capab_info =
cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME |
WLAN_CAPABILITY_SHORT_PREAMBLE);
@@ -765,6 +821,10 @@ mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,
skb_put_data(skb, &data->nan.current_ami,
sizeof(data->nan.current_ami));
+ if (is_discovery && data->nan.extra_nan_attrs_len)
+ skb_put_data(skb, data->nan.extra_nan_attrs,
+ data->nan.extra_nan_attrs_len);
+
spin_unlock(&data->nan.state_lock);
mac80211_hwsim_tx_frame(data->hw, skb, channel);
@@ -877,7 +937,15 @@ mac80211_hwsim_nan_discovery_beacon_timer(struct hrtimer *timer)
return HRTIMER_NORESTART;
scoped_guard(spinlock, &data->nan.state_lock) {
- if (data->nan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN ||
+ if (data->nan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN)
+ return HRTIMER_NORESTART;
+
+ /*
+ * With Instant Communication the discovery beacons are
+ * transmitted disregarding the role and the state, see
+ * Wi-Fi Aware version 4.0 section 13.
+ */
+ if (!data->nan.instant_comm &&
data->nan.role != MAC80211_HWSIM_NAN_ROLE_MASTER)
return HRTIMER_NORESTART;
}
@@ -894,10 +962,11 @@ mac80211_hwsim_nan_discovery_beacon_timer(struct hrtimer *timer)
tsf_now = mac80211_hwsim_get_tsf(data->hw, data->nan.device_vif);
/* Wrap value to be after the next TBTT */
- tbtt = tsf_now + ieee80211_tu_to_usec(100);
+ tbtt = tsf_now + ieee80211_tu_to_usec(data->nan.discovery_beacon_interval);
/* Round TBTT down to the correct time */
- div_u64_rem(tbtt, ieee80211_tu_to_usec(100), &remainder);
+ div_u64_rem(tbtt, ieee80211_tu_to_usec(data->nan.discovery_beacon_interval),
+ &remainder);
tbtt = tbtt - remainder;
hrtimer_set_expires(&data->nan.discovery_beacon_timer,
@@ -906,11 +975,51 @@ mac80211_hwsim_nan_discovery_beacon_timer(struct hrtimer *timer)
return HRTIMER_RESTART;
}
+static int mac80211_hwsim_nan_set_config(struct mac80211_hwsim_data *data,
+ struct cfg80211_nan_conf *conf)
+{
+ const u8 *extra_nan_attrs = NULL;
+ const u8 *old;
+
+ if (conf->extra_nan_attrs_len > NAN_BEACON_EXTRA_ATTRS_LEN)
+ return -EINVAL;
+
+ if (conf->extra_nan_attrs_len) {
+ extra_nan_attrs = kmemdup(conf->extra_nan_attrs,
+ conf->extra_nan_attrs_len,
+ GFP_KERNEL);
+ if (!extra_nan_attrs)
+ return -ENOMEM;
+ }
+
+ data->nan.notify_dw = conf->enable_dw_notification;
+
+ scoped_guard(spinlock_bh, &data->nan.state_lock) {
+ /*
+ * Fall back to the device default if user space did not
+ * configure it
+ */
+ data->nan.discovery_beacon_interval =
+ conf->discovery_beacon_interval ? : 100;
+
+ data->nan.instant_comm = conf->instant_comm;
+
+ old = data->nan.extra_nan_attrs;
+ data->nan.extra_nan_attrs = extra_nan_attrs;
+ data->nan.extra_nan_attrs_len = conf->extra_nan_attrs_len;
+ }
+
+ kfree(old);
+
+ return 0;
+}
+
int mac80211_hwsim_nan_start(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_nan_conf *conf)
{
struct mac80211_hwsim_data *data = hw->priv;
+ int err;
if (vif->type != NL80211_IFTYPE_NAN)
return -EINVAL;
@@ -918,14 +1027,22 @@ int mac80211_hwsim_nan_start(struct ieee80211_hw *hw,
if (data->nan.device_vif)
return -EALREADY;
+ err = mac80211_hwsim_nan_set_config(data, conf);
+ if (err)
+ return err;
+
/* set this before starting the timer, as preemption might occur */
data->nan.device_vif = vif;
data->nan.bands = conf->bands;
scoped_guard(spinlock_bh, &data->nan.state_lock) {
- /* Start in the "scan" phase and stay there for a little bit */
+ /*
+ * Start in the "scan" phase and stay there for a little bit,
+ * unless Instant Communication is configured, in which case an
+ * own cluster is started immediately.
+ */
data->nan.phase = MAC80211_HWSIM_NAN_PHASE_SCAN;
- data->nan.random_factor_valid_dwst = 1;
+ data->nan.random_factor_valid_dwst = conf->instant_comm ? 0 : 1;
data->nan.random_factor = 0;
data->nan.master_pref = conf->master_pref;
data->nan.role = MAC80211_HWSIM_NAN_ROLE_MASTER;
@@ -943,8 +1060,6 @@ int mac80211_hwsim_nan_start(struct ieee80211_hw *hw,
ether_addr_copy(data->nan.cluster_id, conf->cluster_id);
- data->nan.notify_dw = conf->enable_dw_notification;
-
return 0;
}
@@ -952,6 +1067,7 @@ int mac80211_hwsim_nan_stop(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct mac80211_hwsim_data *data = hw->priv;
+ const u8 *old;
if (vif->type != NL80211_IFTYPE_NAN || !data->nan.device_vif ||
data->nan.device_vif != vif)
@@ -962,6 +1078,15 @@ int mac80211_hwsim_nan_stop(struct ieee80211_hw *hw,
hrtimer_cancel(&data->nan.discovery_beacon_timer);
data->nan.device_vif = NULL;
+ scoped_guard(spinlock_bh, &data->nan.state_lock) {
+ old = data->nan.extra_nan_attrs;
+ data->nan.extra_nan_attrs = NULL;
+ data->nan.extra_nan_attrs_len = 0;
+ data->nan.instant_comm = false;
+ }
+
+ kfree(old);
+
return 0;
}
@@ -980,13 +1105,27 @@ int mac80211_hwsim_nan_change_config(struct ieee80211_hw *hw,
wiphy_debug(hw->wiphy, "nan_config_changed: changes=0x%x\n", changes);
+ if (changes & CFG80211_NAN_CONF_CHANGED_CONFIG) {
+ int err = mac80211_hwsim_nan_set_config(data, conf);
+
+ if (err)
+ return err;
+
+ /*
+ * When Instant Communication is enabled discovery beacons are
+ * transmitted regardless of the role and the state.
+ */
+ if (conf->instant_comm &&
+ !hrtimer_active(&data->nan.discovery_beacon_timer))
+ hrtimer_start(&data->nan.discovery_beacon_timer,
+ ns_to_ktime(10 * NSEC_PER_USEC),
+ HRTIMER_MODE_REL_SOFT);
+ }
+
/* Handle only the changes we care about for simulation purposes */
if (changes & CFG80211_NAN_CONF_CHANGED_BANDS)
data->nan.bands = conf->bands;
- if (changes & CFG80211_NAN_CONF_CHANGED_CONFIG)
- data->nan.notify_dw = conf->enable_dw_notification;
-
if (changes & CFG80211_NAN_CONF_CHANGED_PREF) {
scoped_guard(spinlock_bh, &data->nan.state_lock)
data->nan.master_pref = conf->master_pref;
@@ -1169,9 +1308,16 @@ bool mac80211_hwsim_nan_txq_transmitting(struct ieee80211_hw *hw,
is_dw_slot = mac80211_hwsim_nan_is_dw_slot(data, slot);
if (!txq->sta) {
- /* Non-STA TXQ: allow management frames during DW */
- if (txq->vif->type == NL80211_IFTYPE_NAN)
- return is_dw_slot;
+ /* Non-STA TXQ: allow management frames during DW or IC */
+ if (txq->vif->type == NL80211_IFTYPE_NAN) {
+ if (is_dw_slot)
+ return true;
+
+ /* Outside the DW the local schedule must allow it */
+ guard(spinlock_bh)(&data->nan.state_lock);
+ return data->nan.instant_comm &&
+ data->nan.local_sched[slot].chan;
+ }
/* Allow multicast data when all the peers are available
* on this slot
@@ -1224,15 +1370,32 @@ void mac80211_hwsim_nan_get_tx_chandef(struct ieee80211_hw *hw,
}
bool mac80211_hwsim_nan_receive(struct ieee80211_hw *hw,
+ struct sk_buff *skb,
struct ieee80211_channel *channel,
struct ieee80211_rx_status *rx_status)
{
struct mac80211_hwsim_data *data = hw->priv;
+ bool instant_comm;
u8 slot;
if (WARN_ON_ONCE(!data->nan.device_vif))
return false;
+ scoped_guard(spinlock_bh, &data->nan.state_lock)
+ instant_comm = data->nan.instant_comm;
+
+ /*
+ * During Instant Communication a peer advertises its services in the
+ * discovery beacons, which are transmitted disregarding the roles and
+ * the states, see Section 13 in Wi-Fi Aware v4.0.
+ * Note that while according to the specification Instant communication
+ * should be enabled only on the NAN discovery channels, do not force
+ * this here, and allow receiving NAN frames on any channel if Instant
+ * Communication is enabled.
+ */
+ if (instant_comm && hwsim_nan_beacon_has_service_ids(skb))
+ return true;
+
if (data->nan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN)
return channel->center_freq == 2437;
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_nan.h b/drivers/net/wireless/virtual/mac80211_hwsim_nan.h
index 81e105ac7b8ed..995d1f6feb291 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim_nan.h
+++ b/drivers/net/wireless/virtual/mac80211_hwsim_nan.h
@@ -32,6 +32,9 @@ struct mac80211_hwsim_nan_data {
/* Later members are protected by this lock */
spinlock_t state_lock;
+ const u8 *extra_nan_attrs;
+ u16 extra_nan_attrs_len;
+
u8 master_pref;
u8 random_factor;
@@ -53,6 +56,9 @@ struct mac80211_hwsim_nan_data {
bool tsf_adjusted;
bool tsf_discontinuity;
+ bool instant_comm;
+ u8 discovery_beacon_interval;
+
/*
* Local schedule - stores channel definition for each 16TU slot.
* Derived from NMI vif->cfg.nan_schedule. chan == NULL means not
@@ -90,6 +96,7 @@ void mac80211_hwsim_nan_get_tx_chandef(struct ieee80211_hw *hw,
struct cfg80211_chan_def *chandef);
bool mac80211_hwsim_nan_receive(struct ieee80211_hw *hw,
+ struct sk_buff *skb,
struct ieee80211_channel *channel,
struct ieee80211_rx_status *rx_status);
diff --git a/include/linux/ieee80211-nan.h b/include/linux/ieee80211-nan.h
index 455033955e545..7815a6cf81605 100644
--- a/include/linux/ieee80211-nan.h
+++ b/include/linux/ieee80211-nan.h
@@ -40,6 +40,8 @@
/* NAN attributes, as defined in Wi-Fi Aware (TM) specification 4.0 Table 42 */
#define NAN_ATTR_MASTER_INDICATION 0x00
#define NAN_ATTR_CLUSTER_INFO 0x01
+#define NAN_ATTR_SERVICE_ID_LIST 0x02
+#define NAN_ATTR_SUBSCRIBE_SERVICE_ID_LIST 0x28
struct ieee80211_nan_attr {
u8 attr;
@@ -74,4 +76,30 @@ struct ieee80211_nan_anchor_master_info {
_attr = (const struct ieee80211_nan_attr *) \
(_attr->data + le16_to_cpu(_attr->length)))
+static inline bool ieee80211_is_nan_beacon(const struct ieee80211_mgmt *mgmt,
+ size_t len)
+{
+ const struct element *elem;
+
+ /* The NAN IE is at least 6 octets */
+ if (len < offsetofend(struct ieee80211_mgmt, u.beacon) + 6)
+ return false;
+
+ if (!ieee80211_is_beacon(mgmt->frame_control))
+ return false;
+
+ /* NAN Cluster IDs range from 50-6F-9A-01-00-00 to 50-6F-9A-01-FF-FF */
+ if (get_unaligned_be32(mgmt->bssid) != ((WLAN_OUI_WFA << 8) | 0x01))
+ return false;
+
+ elem = (const struct element *)mgmt->u.beacon.variable;
+ if (elem->id != WLAN_EID_VENDOR_SPECIFIC ||
+ elem->datalen < 4 ||
+ get_unaligned_be32(elem->data) !=
+ (WLAN_OUI_WFA << 8 | WLAN_OUI_TYPE_WFA_NAN))
+ return false;
+
+ return true;
+}
+
#endif /* LINUX_IEEE80211_NAN_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 97c16d4ff1271..f9d590facfc0b 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -4183,9 +4183,12 @@ struct cfg80211_nan_band_config {
* that can take a value from 50-6F-9A-01-00-00 to 50-6F-9A-01-FF-FF.
* @scan_period: period (in seconds) between NAN scans.
* @scan_dwell_time: dwell time (in milliseconds) for NAN scans.
- * @discovery_beacon_interval: interval (in TUs) for discovery beacons.
+ * @discovery_beacon_interval: interval (in TUs) for discovery beacons. Must be
+ * greater than 0 when @instant_comm is true.
* @enable_dw_notification: flag to enable/disable discovery window
* notifications.
+ * @instant_comm: if true, start Instant Communication (IC) as defined in
+ * Chapter 13 of the Wi-Fi Aware Specification v4.0.
* @band_cfgs: array of band specific configurations, indexed by
* &enum nl80211_band values.
* @extra_nan_attrs: pointer to additional NAN attributes.
@@ -4201,6 +4204,7 @@ struct cfg80211_nan_conf {
u16 scan_dwell_time;
u8 discovery_beacon_interval;
bool enable_dw_notification;
+ bool instant_comm;
struct cfg80211_nan_band_config band_cfgs[NUM_NL80211_BANDS];
const u8 *extra_nan_attrs;
u16 extra_nan_attrs_len;
@@ -6266,10 +6270,13 @@ struct wiphy_radio {
* @WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC: Device supports NAN configurable
* synchronization.
* @WIPHY_NAN_FLAGS_USERSPACE_DE: Device doesn't support DE offload.
+ * @WIPHY_NAN_FLAGS_INSTANT_COMM: Device can switch to Instant Communication
+ * (IC) mode. Can only be set along with %WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC.
*/
enum wiphy_nan_flags {
WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC = BIT(0),
WIPHY_NAN_FLAGS_USERSPACE_DE = BIT(1),
+ WIPHY_NAN_FLAGS_INSTANT_COMM = BIT(2),
};
/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 020387d764122..5ac9f02f5ad26 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -7826,6 +7826,11 @@ enum nl80211_nan_band_conf_attributes {
* the upcoming discovery window with
* %NL80211_CMD_NAN_NEXT_DW_NOTIFICATION.
* This is a flag attribute.
+ * @NL80211_NAN_CONF_INSTANT_COMM: If set, the NAN synchronization logic will
+ * start Instant Communication (IC) as defined in Chapter 13 of the
+ * Wi-Fi Aware Specification v4.0.
+ * %NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL must be set as well.
+ * This is a flag attribute.
* @NUM_NL80211_NAN_CONF_ATTR: Internal.
* @NL80211_NAN_CONF_ATTR_MAX: Highest NAN configuration attribute.
*
@@ -7841,6 +7846,7 @@ enum nl80211_nan_conf_attributes {
NL80211_NAN_CONF_SCAN_DWELL_TIME,
NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL,
NL80211_NAN_CONF_NOTIFY_DW,
+ NL80211_NAN_CONF_INSTANT_COMM,
/* keep last */
NUM_NL80211_NAN_CONF_ATTR,
@@ -9057,6 +9063,11 @@ enum nl80211_s1g_short_beacon_attrs {
* specification Table 79 (Capabilities field).
* @NL80211_NAN_CAPA_PHY: nested attribute containing band-agnostic
* capabilities for NAN data path. See &enum nl80211_nan_phy_cap_attr.
+ * @NL80211_NAN_CAPA_INSTANT_COMM: Flag attribute indicating that the device
+ * can switch to Instant Communication (IC) mode, as defined in Chapter 13
+ * of the Wi-Fi Aware Specification v4.0. Can only be set if
+ * %NL80211_NAN_CAPA_CONFIGURABLE_SYNC is set. When IC is enabled, the IC
+ * schedule is expected to be configured by user space.
* @__NL80211_NAN_CAPABILITIES_LAST: Internal
* @NL80211_NAN_CAPABILITIES_MAX: Highest NAN capability attribute.
*/
@@ -9070,6 +9081,7 @@ enum nl80211_nan_capabilities {
NL80211_NAN_CAPA_MAX_CHANNEL_SWITCH_TIME,
NL80211_NAN_CAPA_CAPABILITIES,
NL80211_NAN_CAPA_PHY,
+ NL80211_NAN_CAPA_INSTANT_COMM,
/* keep last */
__NL80211_NAN_CAPABILITIES_LAST,
NL80211_NAN_CAPABILITIES_MAX = __NL80211_NAN_CAPABILITIES_LAST - 1,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 23f4f9ec86d0a..7a7acbfeeba92 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -364,6 +364,7 @@ static int ieee80211_nan_conf_copy(struct cfg80211_nan_conf *dst,
dst->discovery_beacon_interval =
src->discovery_beacon_interval;
dst->enable_dw_notification = src->enable_dw_notification;
+ dst->instant_comm = src->instant_comm;
memcpy(&dst->band_cfgs, &src->band_cfgs,
sizeof(dst->band_cfgs));
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index a59837b9f480f..9553ea77cfe84 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -745,8 +745,13 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
},
[NL80211_IFTYPE_NAN] = {
.tx = 0xffff,
+ /*
+ * Beacon Rx registration is needed to let user space handle
+ * service discovery when Instant Communication is enabled.
+ */
.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_AUTH >> 4),
+ BIT(IEEE80211_STYPE_AUTH >> 4) |
+ BIT(IEEE80211_STYPE_BEACON >> 4),
},
[NL80211_IFTYPE_NAN_DATA] = {
.tx = 0xffff,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 5e26be8e27d8f..eb1578b2d6d79 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -4660,7 +4660,8 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
* Accept only frames that are addressed to the NAN cluster
* (based on the Cluster ID). From these frames, accept only
* - public action frames,
- * - authentication frames to the local address, and
+ * - authentication frames to the local address,
+ * - NAN beacons, when Instant Communication is enabled, and
* - robust management frames except disassoc.
*/
if (!ether_addr_equal(sdata->u.nan.conf.cluster_id, hdr->addr3))
@@ -4670,6 +4671,9 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
if (ieee80211_is_auth(hdr->frame_control) &&
ether_addr_equal(sdata->vif.addr, hdr->addr1))
return true;
+ if (ieee80211_is_nan_beacon((struct ieee80211_mgmt *)hdr,
+ skb->len))
+ return sdata->u.nan.conf.instant_comm;
if (!ieee80211_is_disassoc(hdr->frame_control) &&
ieee80211_is_robust_mgmt_frame(skb))
return true;
diff --git a/net/wireless/core.c b/net/wireless/core.c
index d13310fef691a..fc9b97888191d 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -888,6 +888,18 @@ int wiphy_register(struct wiphy *wiphy)
(!wiphy->nan_capa.phy.ht.ht_supported || wiphy->n_radio > 1)))
return -EINVAL;
+ if (WARN_ON((wiphy->nan_capa.flags & WIPHY_NAN_FLAGS_INSTANT_COMM) &&
+ !(wiphy->nan_capa.flags &
+ WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC)))
+ return -EINVAL;
+
+ /* Instant Communication requires user space to track NAN beacons */
+ if (WARN_ON((wiphy->nan_capa.flags & WIPHY_NAN_FLAGS_INSTANT_COMM) &&
+ (!wiphy->mgmt_stypes ||
+ !(wiphy->mgmt_stypes[NL80211_IFTYPE_NAN].rx &
+ BIT(IEEE80211_STYPE_BEACON >> 4)))))
+ return -EINVAL;
+
if (WARN_ON(wiphy->interface_modes & BIT(NL80211_IFTYPE_WDS)))
return -EINVAL;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 44f2bad086705..94d92b0ebc54e 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -686,6 +686,7 @@ nl80211_nan_conf_policy[NL80211_NAN_CONF_ATTR_MAX + 1] = {
[NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL] =
NLA_POLICY_RANGE(NLA_U8, 50, 200),
[NL80211_NAN_CONF_NOTIFY_DW] = { .type = NLA_FLAG },
+ [NL80211_NAN_CONF_INSTANT_COMM] = { .type = NLA_FLAG },
};
static const struct netlink_range_validation nl80211_punct_bitmap_range = {
@@ -3025,6 +3026,10 @@ static int nl80211_put_nan_capa(struct wiphy *wiphy, struct sk_buff *msg)
nla_put_flag(msg, NL80211_NAN_CAPA_USERSPACE_DE))
goto fail;
+ if ((wiphy->nan_capa.flags & WIPHY_NAN_FLAGS_INSTANT_COMM) &&
+ nla_put_flag(msg, NL80211_NAN_CAPA_INSTANT_COMM))
+ goto fail;
+
if (nla_put_u8(msg, NL80211_NAN_CAPA_OP_MODE,
wiphy->nan_capa.op_mode) ||
nla_put_u8(msg, NL80211_NAN_CAPA_NUM_ANTENNAS,
@@ -16663,6 +16668,23 @@ static int nl80211_parse_nan_conf(struct wiphy *wiphy,
conf->enable_dw_notification =
nla_get_flag(attrs[NL80211_NAN_CONF_NOTIFY_DW]);
+ conf->instant_comm = nla_get_flag(attrs[NL80211_NAN_CONF_INSTANT_COMM]);
+ if (conf->instant_comm) {
+ if (!(wiphy->nan_capa.flags & WIPHY_NAN_FLAGS_INSTANT_COMM)) {
+ NL_SET_ERR_MSG_ATTR(info->extack,
+ attrs[NL80211_NAN_CONF_INSTANT_COMM],
+ "Instant Communication is not supported");
+ return -EOPNOTSUPP;
+ }
+
+ if (!conf->discovery_beacon_interval) {
+ NL_SET_ERR_MSG_ATTR(info->extack,
+ attrs[NL80211_NAN_CONF_INSTANT_COMM],
+ "Instant Communication requires a discovery beacon interval");
+ return -EINVAL;
+ }
+ }
+
out:
if (!conf->band_cfgs[NL80211_BAND_5GHZ].chan &&
(!conf->bands || conf->bands & BIT(NL80211_BAND_5GHZ))) {
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 9e934b185e341..c5dad787747a5 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -3302,6 +3302,10 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
if (WARN_ON(!wiphy))
return NULL;
+ /* NAN beacons are not a BSS, don't add to the BSS table */
+ if (ieee80211_is_nan_beacon(mgmt, len))
+ return NULL;
+
BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) !=
offsetof(struct ieee80211_mgmt, u.beacon.variable));
|
| 3/2 | 2026/10/04 13:45 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 15050 output: 38 thoughts: 982 Thoughts: **NAN Instant Communication Support in the Wireless Subsystem** Alright, let me break down what I'm seeing in this patch. It's focused on adding Instant Communication (IC) mode support for NAN (Wi-Fi Aware) within the core wireless infrastructure. We're talking about modifications across the board: `cfg80211`, `mac80211`, and even the `mac80211_hwsim` virtual driver. It looks like a comprehensive integration effort. Specifically, it seems the patch enables IC features in several key areas. With respect to `mac80211_hwsim`, it touches beacon transmission (appending attributes, timer management), reception logic, and capability advertisements, adding `WIPHY_NAN_FLAGS_INSTANT_COMM`. There are some interesting calls in the hwsim code, like `hwsim_nan_beacon_has_service_ids(skb)` and `mac80211_hwsim_nan_set_config`. And I see the addition of `ieee80211_is_nan_beacon()` which is crucial for identifying NAN beacons. `cfg80211` and `mac80211` are also getting love. I'm picking up on `ieee80211_nan_conf_copy` in the cfg code, which is responsible for propagating `instant_comm` settings. In `mac80211`, changes are going into the management frame processing, adding beacon types for NAN interfaces and ensuring NAN beacons are accepted if IC is enabled. The core wireless handling in `net/wireless/core.c` checks for, and warns on, the instant communication flag, ensuring correct usage. NL80211 commands in `net/wireless/nl80211.c` are handling configuration parsing and capabilities reporting for this new instant comm mode. Finally, I see the scan code in `net/wireless/scan.c` has been updated to filter NAN beacons, so they don't pollute the BSS table. Now, as an expert, I'm already thinking about potential implications. I can see this is not just theoretical; `mac80211_hwsim` is definitely a key piece here, and I know it's used extensively in testing, especially with syzkaller. Since it’s a virtual driver, this is great for verifying and testing without real hardware. I can instantiate it, configure it with the `nl80211` family, and inject frames to simulate different scenarios. Since NAN is configured via NL80211 commands like `NL80211_CMD_START_NAN`, `NL80211_CMD_CHANGE_NAN_CONFIG`, and `NL80211_CMD_STOP_NAN`, that is exactly the interface I would be looking to exploit to test this. I also see common areas for potential issues: the memory allocations with `kmemdup`, `alloc_skb`, and lock handling, as well as the pointer accesses I mentioned are something to watch, and I can start thinking about fuzzing and testing these scenarios. It's a non-trivial change, but a well-integrated addition to the existing NAN framework. |
| 4/2 | 2026/10/04 13:45 | tool | grepper |
0mArgs:{
"Expression": "MAC80211_HWSIM",
"PathPrefix": "drivers/net/wireless/virtual/"
}Results: {
"Output": "\nFull output is too long, showing 200 out of 258 lines.\nUse more precise expression if possible.\n\ndrivers/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=217=struct hwsim_tx_rate {\n--\ndrivers/net/wireless/virtual/mac80211_hwsim.h-230- *\ndrivers/net/wireless/virtual/mac80211_hwsim.h:231: * @MAC80211_HWSIM_TX_RC_USE_RTS_CTS: Use RTS/CTS exchange for this rate.\ndrivers/net/wireless/virtual/mac80211_hwsim.h:232: * @MAC80211_HWSIM_TX_RC_USE_CTS_PROTECT: CTS-to-self protection is required.\ndrivers/net/wireless/virtual/mac80211_hwsim.h-233- *\tThis is set if the current BSS requires ERP protection.\ndrivers/net/wireless/virtual/mac80211_hwsim.h:234: * @MAC80211_HWSIM_TX_RC_USE_SHORT_PREAMBLE: Use short preamble.\ndrivers/net/wireless/virtual/mac80211_hwsim.h:235: * @MAC80211_HWSIM_TX_RC_MCS: HT rate.\ndrivers/net/wireless/virtual/mac80211_hwsim.h:236: * @MAC80211_HWSIM_TX_RC_VHT_MCS: VHT MCS rate, in this case the idx field is\ndrivers/net/wireless/virtual/mac80211_hwsim.h-237- *\tsplit into a higher 4 bits (Nss) and lower 4 bits (MCS number)\ndrivers/net/wireless/virtual/mac80211_hwsim.h:238: * @MAC80211_HWSIM_TX_RC_GREEN_FIELD: Indicates whether this rate should be used\ndrivers/net/wireless/virtual/mac80211_hwsim.h-239- *\tin Greenfield mode.\ndrivers/net/wireless/virtual/mac80211_hwsim.h:240: * @MAC80211_HWSIM_TX_RC_40_MHZ_WIDTH: Indicates if the Channel Width should be\ndrivers/net/wireless/virtual/mac80211_hwsim.h-241- *\t40 MHz.\ndrivers/net/wireless/virtual/mac80211_hwsim.h:242: * @MAC80211_HWSIM_TX_RC_80_MHZ_WIDTH: Indicates 80 MHz transmission\ndrivers/net/wireless/virtual/mac80211_hwsim.h:243: * @MAC80211_HWSIM_TX_RC_160_MHZ_WIDTH: Indicates 160 MHz transmission\ndrivers/net/wireless/virtual/mac80211_hwsim.h-244- *\t(80+80 isn't supported yet)\ndrivers/net/wireless/virtual/mac80211_hwsim.h:245: * @MAC80211_HWSIM_TX_RC_DUP_DATA: The frame should be transmitted on both of\ndrivers/net/wireless/virtual/mac80211_hwsim.h-246- *\tthe adjacent 20 MHz channels, if the current channel type is\ndrivers/net/wireless/virtual/mac80211_hwsim.h-247- *\tNL80211_CHAN_HT40MINUS or NL80211_CHAN_HT40PLUS.\ndrivers/net/wireless/virtual/mac80211_hwsim.h:248: * @MAC80211_HWSIM_TX_RC_SHORT_GI: Short Guard interval should be used for this\ndrivers/net/wireless/virtual/mac80211_hwsim.h-249- *\trate.\n--\ndrivers/net/wireless/virtual/mac80211_hwsim.h=251=enum hwsim_tx_rate_flags {\ndrivers/net/wireless/virtual/mac80211_hwsim.h:252:\tMAC80211_HWSIM_TX_RC_USE_RTS_CTS\t\t= BIT(0),\ndrivers/net/wireless/virtual/mac80211_hwsim.h:253:\tMAC80211_HWSIM_TX_RC_USE_CTS_PROTECT\t\t= BIT(1),\ndrivers/net/wireless/virtual/mac80211_hwsim.h:254:\tMAC80211_HWSIM_TX_RC_USE_SHORT_PREAMBLE\t= BIT(2),\ndrivers/net/wireless/virtual/mac80211_hwsim.h-255-\ndrivers/net/wireless/virtual/mac80211_hwsim.h-256-\t/* rate index is an HT/VHT MCS instead of an index */\ndrivers/net/wireless/virtual/mac80211_hwsim.h:257:\tMAC80211_HWSIM_TX_RC_MCS\t\t\t= BIT(3),\ndrivers/net/wireless/virtual/mac80211_hwsim.h:258:\tMAC80211_HWSIM_TX_RC_GREEN_FIELD\t\t= BIT(4),\ndrivers/net/wireless/virtual/mac80211_hwsim.h:259:\tMAC80211_HWSIM_TX_RC_40_MHZ_WIDTH\t\t= BIT(5),\ndrivers/net/wireless/virtual/mac80211_hwsim.h:260:\tMAC80211_HWSIM_TX_RC_DUP_DATA\t\t= BIT(6),\ndrivers/net/wireless/virtual/mac80211_hwsim.h:261:\tMAC80211_HWSIM_TX_RC_SHORT_GI\t\t= BIT(7),\ndrivers/net/wireless/virtual/mac80211_hwsim.h:262:\tMAC80211_HWSIM_TX_RC_VHT_MCS\t\t\t= BIT(8),\ndrivers/net/wireless/virtual/mac80211_hwsim.h:263:\tMAC80211_HWSIM_TX_RC_80_MHZ_WIDTH\t\t= BIT(9),\ndrivers/net/wireless/virtual/mac80211_hwsim.h:264:\tMAC80211_HWSIM_TX_RC_160_MHZ_WIDTH\t\t= BIT(10),\ndrivers/net/wireless/virtual/mac80211_hwsim.h-265-};\n--\ndrivers/net/wireless/virtual/mac80211_hwsim.h=328=enum hwsim_rate_info_attributes {\n--\ndrivers/net/wireless/virtual/mac80211_hwsim.h-347-\ndrivers/net/wireless/virtual/mac80211_hwsim.h:348:#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-901-\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:902:/* MAC80211_HWSIM virtio queues */\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-903-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=7152=static struct genl_family hwsim_genl_family __ro_after_init = {\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:7153:\t.name = \"MAC80211_HWSIM\",\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-7154-\t.version = 1,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=7472=static void hwsim_virtio_remove(struct virtio_device *vdev)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-7480-\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:7481:/* MAC80211_HWSIM virtio device id table */\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-7482-static const struct virtio_device_id id_table[] = {\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:7483:\t{ VIRTIO_ID_MAC80211_HWSIM, VIRTIO_DEV_ANY_ID },\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-7484-\t{ 0 }\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=84=static u64 hwsim_nan_get_master_rank(struct mac80211_hwsim_data *data)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-88-\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:89:\tif (data-\u003enan.phase == MAC80211_HWSIM_NAN_PHASE_UP) {\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-90-\t\tmaster_pref = data-\u003enan.master_pref;\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=253=void mac80211_hwsim_nan_rx(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-323-\t\t\t\tdata-\u003enan.phase ==\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:324:\t\t\t\tMAC80211_HWSIM_NAN_PHASE_SCAN;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-325-\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-477-\t\t (cg == own_cg \u0026\u0026 frame_amr \u003e curr_amr) ||\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:478:\t\t data-\u003enan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN) {\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-479-\t\t\t/* Avoid a state transition */\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-509-\t\t\t */\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:510:\t\t\tdata-\u003enan.phase = MAC80211_HWSIM_NAN_PHASE_UP;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-511-\t\t\tdata-\u003enan.random_factor_valid_dwst = 0;\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=653=mac80211_hwsim_nan_exec_state_transitions(struct mac80211_hwsim_data *data)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-666-\tif (data-\u003enan.master_transition_score \u003c 3)\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:667:\t\tdata-\u003enan.role = MAC80211_HWSIM_NAN_ROLE_MASTER;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:668:\telse if (data-\u003enan.role == MAC80211_HWSIM_NAN_ROLE_MASTER \u0026\u0026\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-669-\t\t data-\u003enan.master_transition_score \u003e= 3)\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:670:\t\tdata-\u003enan.role = MAC80211_HWSIM_NAN_ROLE_SYNC;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:671:\telse if (data-\u003enan.role == MAC80211_HWSIM_NAN_ROLE_SYNC \u0026\u0026\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-672-\t\t data-\u003enan.sync_transition_score \u003e= 3)\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:673:\t\tdata-\u003enan.role = MAC80211_HWSIM_NAN_ROLE_NON_SYNC;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:674:\telse if (data-\u003enan.role == MAC80211_HWSIM_NAN_ROLE_NON_SYNC \u0026\u0026\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-675-\t\t data-\u003enan.sync_transition_score \u003c 3)\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:676:\t\tdata-\u003enan.role = MAC80211_HWSIM_NAN_ROLE_SYNC;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-677-\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-683-\t */\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:684:\tif ((data-\u003enan.role == MAC80211_HWSIM_NAN_ROLE_MASTER ||\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-685-\t data-\u003enan.instant_comm) \u0026\u0026\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-696-\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:697:\t\tif (data-\u003enan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN) {\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:698:\t\t\tdata-\u003enan.phase = MAC80211_HWSIM_NAN_PHASE_WARMUP;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-699-\t\t\tdata-\u003enan.random_factor_valid_dwst = NAN_WARMUP_DWST;\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-702-\t\t} else {\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:703:\t\t\tdata-\u003enan.phase = MAC80211_HWSIM_NAN_PHASE_UP;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-704-\t\t\tdata-\u003enan.random_factor_valid_dwst =\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=738=mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,\n\n"
} |
| 5/2 | 2026/10/04 13:45 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 23908 output: 36 thoughts: 16 Thoughts: Here's a summary of my thought process, as requested: **Kconfig Dive** Alright, time to dive in. My immediate thought is to check the `drivers/net/wireless/virtual/Kconfig` file. That's the logical starting point for understanding the configuration options related to virtual wireless interfaces within this kernel tree. I'm going to want to understand what features are enabled, what dependencies exist, and how the various virtual wireless functionalities are controlled via the build system. This Kconfig file should be the central point to begin untangling all of that. |
| 6/2 | 2026/10/04 13:45 | 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"
} |
| 7/2 | 2026/10/04 13:45 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 24404 output: 38 thoughts: 31 Thoughts: Here's my thought process, as if I were considering this myself: **Investigating Kconfig Dependencies for Wireless Configuration** Okay, so I need to figure out the dependencies for a particular wireless configuration option. My immediate instinct is to dive into the kernel's Kconfig files. Specifically, I'll start by checking the `net/mac80211/Kconfig` and `net/wireless/Kconfig` files. These are the usual suspects when dealing with anything related to 802.11 and wireless networking in the kernel. I'll need to see how options are defined, what other options they depend on, and where these settings are placed within the larger configuration hierarchy. I'm expecting to find the key to what's going on here in those files, and the relations between the various wireless subsystems. Let's see what we can find. |
| 8/2 | 2026/10/04 13:45 | tool | grepper |
0mArgs:{
"Expression": "config MAC80211\\b",
"PathPrefix": "net/mac80211/"
}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"
} |
| 9/2 | 2026/10/04 13:45 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 24759 output: 37 thoughts: 25 Thoughts: Here's a summary of my thought process, as requested: **Diving into `net/mac80211/Kconfig`** Okay, time to get my bearings. I need to understand the configuration options for the mac80211 wireless stack. Let's start by zeroing in on lines 1 through 40 in `net/mac80211/Kconfig`. This is usually a good place to begin; those initial lines often lay out the high-level structure or introduce the most fundamental configuration variables. I'm expecting to find the top-level feature flags, maybe some core architectural choices presented as configuration options, or perhaps the initial dependencies that define the base system. I'm hoping to get a quick overview of what's *controllable* at compile time within the wireless subsystem. From there I'll have a better picture to look at the other configuration options. I'll be looking for keywords or variable names that indicate the focus of those lines, and the initial dependencies for the rest of the configuration. Let's see what the developers have deemed important enough to expose at the outset. |
| 10/2 | 2026/10/04 13:45 | tool | read-file |
0mArgs:{
"File": "net/mac80211/Kconfig",
"FirstLine": 1,
"LineCount": 40
}Results: {
"Contents": " 1:\t# SPDX-License-Identifier: GPL-2.0-only\n 2:\tconfig MAC80211\n 3:\t\ttristate \"Generic IEEE 802.11 Networking Stack (mac80211)\"\n 4:\t\tdepends on CFG80211\n 5:\t\tselect CRYPTO\n 6:\t\tselect CRYPTO_LIB_AES_CBC_MACS\n 7:\t\tselect CRYPTO_LIB_ARC4\n 8:\t\tselect CRYPTO_AES\n 9:\t\tselect CRYPTO_CCM\n 10:\t\tselect CRYPTO_GCM\n 11:\t\tselect CRC32\n 12:\t\thelp\n 13:\t\t This option enables the hardware independent IEEE 802.11\n 14:\t\t networking stack.\n 15:\t\n 16:\tcomment \"CFG80211 needs to be enabled for MAC80211\"\n 17:\t\tdepends on CFG80211=n\n 18:\t\n 19:\tif MAC80211 != n\n 20:\t\n 21:\tconfig MAC80211_HAS_RC\n 22:\t\tbool\n 23:\t\n 24:\tconfig MAC80211_RC_MINSTREL\n 25:\t\tbool \"Minstrel\" if EXPERT\n 26:\t\tselect MAC80211_HAS_RC\n 27:\t\tdefault y\n 28:\t\thelp\n 29:\t\t This option enables the 'minstrel' TX rate control algorithm\n 30:\t\n 31:\tchoice\n 32:\t\tprompt \"Default rate control algorithm\"\n 33:\t\tdepends on MAC80211_HAS_RC\n 34:\t\tdefault MAC80211_RC_DEFAULT_MINSTREL\n 35:\t\thelp\n 36:\t\t This option selects the default rate control algorithm\n 37:\t\t mac80211 will use. Note that this default can still be\n 38:\t\t overridden through the ieee80211_default_rc_algo module\n 39:\t\t parameter if different algorithms are available.\n 40:\t\n"
} |
| 11/2 | 2026/10/04 13:45 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 25614 output: 34 thoughts: 12 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience, presented in the first person: **Navigating the Wireless Configuration Landscape** Right, let's dive into this. My initial thought process is to immediately go to `net/wireless/Kconfig`. This is the logical starting point, as this file is the central hub for all things wireless-related within the kernel's configuration system. I *know* this is where I'll find the main menu structure, the various feature switches, and dependencies for the wireless subsystem. It’s where I'll begin to understand how everything interconnects and, most importantly, what options are available for enabling or disabling specific wireless functionalities. I need to get a high-level view and this is the best spot to start. No need to re-invent the wheel when a known location exists. |
| 12/2 | 2026/10/04 13:45 | tool | grepper |
0mArgs:{
"Expression": "config CFG80211\\b",
"PathPrefix": "net/wireless/"
}Results: {
"Output": "net/wireless/Kconfig=14=config WEXT_PRIV\n--\nnet/wireless/Kconfig-16-\nnet/wireless/Kconfig:17:config CFG80211\nnet/wireless/Kconfig-18-\ttristate \"cfg80211 - wireless configuration API\"\n"
} |
| 13/2 | 2026/10/04 13:45 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 25926 output: 33 thoughts: 20 Thoughts: Okay, here's my take on those lines in `net/wireless/Kconfig`. As an expert, I'm already anticipating what I'll find, but let's break it down and see if my assumptions hold true. **Digging into `net/wireless/Kconfig` (Lines 17-50)** Alright, time to dive in. Lines 17-50 in `net/wireless/Kconfig`... I'm immediately expecting to see configurations related to... *something*. Based on the filename, probably wireless functionality. Given the line range, it's likely a relatively self-contained chunk. Could be a specific wireless standard, a feature set, or maybe the core configuration for a particular driver. I'm mentally preparing to parse the options, looking for dependencies ( `depends on`, `select` ), default values, and the overall structure. I'll be keeping an eye out for keywords like "mac80211", "wext", "cfg80211," "IEEE," "HT," "VHT," or even specific wireless chipsets. The indentation will be crucial – I'll be looking for any logical groupings to quickly understand the modularity of the options. If I see any *prominent* options, I'll assess their impact: are they critical, optional, or potentially conflicting? I'll also be mentally noting any potentially new or interesting features being introduced, or, if I see any deprecated options, what they are. From a high-level perspective, I'm expecting this section to provide the build system with the information it needs to support a given wireless configuration. Alright, let's see what's actually there. Now, let's go line by line... *click*. |
| 14/2 | 2026/10/04 13:45 | tool | read-file |
0mArgs:{
"File": "net/wireless/Kconfig",
"FirstLine": 17,
"LineCount": 40
}Results: {
"Contents": " 17:\tconfig CFG80211\n 18:\t\ttristate \"cfg80211 - wireless configuration API\"\n 19:\t\tdepends on RFKILL || !RFKILL\n 20:\t\tselect FW_LOADER\n 21:\t\tselect CRC32\n 22:\t\t# may need to update this when certificates are changed and are\n 23:\t\t# using a different algorithm, though right now they shouldn't\n 24:\t\t# (this is here rather than below to allow it to be a module)\n 25:\t\tselect CRYPTO_SHA256 if CFG80211_USE_KERNEL_REGDB_KEYS\n 26:\t\thelp\n 27:\t\t cfg80211 is the Linux wireless LAN (802.11) configuration API.\n 28:\t\t Enable this if you have a wireless device.\n 29:\t\n 30:\t\t For more information refer to documentation on the wireless wiki:\n 31:\t\n 32:\t\t https://wireless.wiki.kernel.org/en/developers/Documentation/cfg80211\n 33:\t\n 34:\t\t When built as a module it will be called cfg80211.\n 35:\t\n 36:\tif CFG80211\n 37:\t\n 38:\tconfig NL80211_TESTMODE\n 39:\t\tbool \"nl80211 testmode command\"\n 40:\t\thelp\n 41:\t\t The nl80211 testmode command helps implementing things like\n 42:\t\t factory calibration or validation tools for wireless chips.\n 43:\t\n 44:\t\t Select this option ONLY for kernels that are specifically\n 45:\t\t built for such purposes.\n 46:\t\n 47:\t\t Debugging tools that are supposed to end up in the hands of\n 48:\t\t users should better be implemented with debugfs.\n 49:\t\n 50:\t\t Say N.\n 51:\t\n 52:\tconfig CFG80211_DEVELOPER_WARNINGS\n 53:\t\tbool \"enable developer warnings\"\n 54:\t\tdefault n\n 55:\t\thelp\n 56:\t\t This option enables some additional warnings that help\n"
} |
| 15/2 | 2026/10/04 13:45 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 26929 output: 23 thoughts: 40 Thoughts: Here's my thought process, summarized as you requested: **Investigating Potential NAN Configuration Options** Okay, so I'm thinking about how NAN – that is, Neighbor Awareness Networking – might be configured within this kernel. My first instinct is to check the relevant Kconfig files. Specifically, I'll need to see if there are any specific options defined that relate to NAN. Given the typical structure, the logical places to start are the Kconfig files for both the broader networking wireless stack and the mac80211 component. So, I need to *grep* for "NAN" within the `net/wireless/Kconfig` and `net/mac80211/Kconfig` files. That should quickly uncover any dedicated configuration options that are available. |
| 16/2 | 2026/10/04 13:45 | tool | grepper |
0mArgs:{
"Expression": "NAN",
"PathPrefix": "net/"
}Results: {
"Output": "\nFull output is too long, showing 200 out of 1960 lines.\nUse more precise expression if possible.\n\nnet/core/sock_reuseport.c=302=static void reuseport_free_rcu(struct rcu_head *head)\n--\nnet/core/sock_reuseport.c-315- * @sk2: Socket belonging to the existing reuseport group.\nnet/core/sock_reuseport.c:316: * @bind_inany: Whether or not the group is bound to a local INANY address.\nnet/core/sock_reuseport.c-317- *\n--\nnet/ipv4/tcp_input.c=87=int sysctl_tcp_max_orphans __read_mostly = NR_FILE;\n--\nnet/ipv4/tcp_input.c-113-\nnet/ipv4/tcp_input.c:114:#define TCP_REMNANT (TCP_FLAG_FIN|TCP_FLAG_URG|TCP_FLAG_SYN|TCP_FLAG_PSH)\nnet/ipv4/tcp_input.c-115-#define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH))\n--\nnet/ipv4/tcp_input.c=227=static void tcp_measure_rcv_mss(struct sock *sk, const struct sk_buff *skb)\n--\nnet/ipv4/tcp_input.c-292-\t\t (len \u003e= TCP_MIN_MSS + sizeof(struct tcphdr) \u0026\u0026\nnet/ipv4/tcp_input.c:293:\t\t !(tcp_flag_word(tcp_hdr(skb)) \u0026 TCP_REMNANT))) {\nnet/ipv4/tcp_input.c-294-\t\t\t/* Subtract also invariant (if peer is RFC compliant),\n--\nnet/mac80211/agg-tx.c=603=int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,\n--\nnet/mac80211/agg-tx.c-644-\t sdata-\u003evif.type != NL80211_IFTYPE_ADHOC \u0026\u0026\nnet/mac80211/agg-tx.c:645:\t sdata-\u003evif.type != NL80211_IFTYPE_NAN_DATA)\nnet/mac80211/agg-tx.c-646-\t\treturn -EINVAL;\n--\nnet/mac80211/cfg.c=351=static int ieee80211_nan_conf_copy(struct cfg80211_nan_conf *dst,\n--\nnet/mac80211/cfg.c-354-{\nnet/mac80211/cfg.c:355:\tif (changes \u0026 CFG80211_NAN_CONF_CHANGED_PREF)\nnet/mac80211/cfg.c-356-\t\tdst-\u003emaster_pref = src-\u003emaster_pref;\nnet/mac80211/cfg.c-357-\nnet/mac80211/cfg.c:358:\tif (changes \u0026 CFG80211_NAN_CONF_CHANGED_BANDS)\nnet/mac80211/cfg.c-359-\t\tdst-\u003ebands = src-\u003ebands;\nnet/mac80211/cfg.c-360-\nnet/mac80211/cfg.c:361:\tif (changes \u0026 CFG80211_NAN_CONF_CHANGED_CONFIG) {\nnet/mac80211/cfg.c-362-\t\tdst-\u003escan_period = src-\u003escan_period;\n--\nnet/mac80211/cfg.c=448=static int ieee80211_nan_change_conf(struct wiphy *wiphy,\n--\nnet/mac80211/cfg.c-456-\nnet/mac80211/cfg.c:457:\tif (sdata-\u003evif.type != NL80211_IFTYPE_NAN)\nnet/mac80211/cfg.c-458-\t\treturn -EOPNOTSUPP;\n--\nnet/mac80211/cfg.c=489=static int ieee80211_add_nan_func(struct wiphy *wiphy,\n--\nnet/mac80211/cfg.c-495-\nnet/mac80211/cfg.c:496:\tif (sdata-\u003evif.type != NL80211_IFTYPE_NAN)\nnet/mac80211/cfg.c-497-\t\treturn -EOPNOTSUPP;\n--\nnet/mac80211/cfg.c-501-\nnet/mac80211/cfg.c:502:\tif (WARN_ON(wiphy-\u003enan_capa.flags \u0026 WIPHY_NAN_FLAGS_USERSPACE_DE))\nnet/mac80211/cfg.c-503-\t\treturn -EOPNOTSUPP;\n--\nnet/mac80211/cfg.c=547=static void ieee80211_del_nan_func(struct wiphy *wiphy,\n--\nnet/mac80211/cfg.c-553-\nnet/mac80211/cfg.c:554:\tif (sdata-\u003evif.type != NL80211_IFTYPE_NAN ||\nnet/mac80211/cfg.c-555-\t !ieee80211_sdata_running(sdata))\n--\nnet/mac80211/cfg.c-557-\nnet/mac80211/cfg.c:558:\tif (WARN_ON(wiphy-\u003enan_capa.flags \u0026 WIPHY_NAN_FLAGS_USERSPACE_DE))\nnet/mac80211/cfg.c-559-\t\treturn;\n--\nnet/mac80211/cfg.c=614=static int ieee80211_add_key(struct wiphy *wiphy, struct wireless_dev *wdev,\n--\nnet/mac80211/cfg.c-701-\tcase NL80211_IFTYPE_AP_VLAN:\nnet/mac80211/cfg.c:702:\tcase NL80211_IFTYPE_NAN:\nnet/mac80211/cfg.c:703:\tcase NL80211_IFTYPE_NAN_DATA:\nnet/mac80211/cfg.c-704-\t\t/* Keys without a station are used for TX only */\n--\nnet/mac80211/cfg.c=2262=static int sta_link_apply_parameters(struct ieee80211_local *local,\n--\nnet/mac80211/cfg.c-2310-\t */\nnet/mac80211/cfg.c:2311:\tif (WARN_ON(sdata-\u003evif.type == NL80211_IFTYPE_NAN_DATA))\nnet/mac80211/cfg.c-2312-\t\treturn -EINVAL;\nnet/mac80211/cfg.c-2313-\nnet/mac80211/cfg.c:2314:\tif (sdata-\u003evif.type == NL80211_IFTYPE_NAN) {\nnet/mac80211/cfg.c-2315-\t\town_ht_cap = \u0026local-\u003ehw.wiphy-\u003enan_capa.phy.ht;\n--\nnet/mac80211/cfg.c-2348-\nnet/mac80211/cfg.c:2349:\tif (sdata-\u003evif.type == NL80211_IFTYPE_NAN) {\nnet/mac80211/cfg.c-2350-\t\tstatic const u8 all_ofdm_rates[] = {\n--\nnet/mac80211/cfg.c-2415-\tswitch (sdata-\u003evif.type) {\nnet/mac80211/cfg.c:2416:\tcase NL80211_IFTYPE_NAN:\nnet/mac80211/cfg.c:2417:\tcase NL80211_IFTYPE_NAN_DATA:\nnet/mac80211/cfg.c-2418-\t\t/* not applicable - they don't use NSS/BW as capability */\n--\nnet/mac80211/cfg.c=2451=static int sta_apply_parameters(struct ieee80211_local *local,\n--\nnet/mac80211/cfg.c-2604-\nnet/mac80211/cfg.c:2605:\t\t/* For NAN_DATA stations, copy capabilities from the NMI station */\nnet/mac80211/cfg.c-2606-\t\tif (!nmi_sta-\u003edeflink.pub-\u003eht_cap.ht_supported)\n--\nnet/mac80211/cfg.c=2635=static int ieee80211_add_station(struct wiphy *wiphy, struct wireless_dev *wdev,\n--\nnet/mac80211/cfg.c-2709-\t */\nnet/mac80211/cfg.c:2710:\tif (!err \u0026\u0026 sdata-\u003evif.type == NL80211_IFTYPE_NAN_DATA)\nnet/mac80211/cfg.c-2711-\t\tieee80211_nan_update_ndi_carrier(sta-\u003esdata);\n--\nnet/mac80211/cfg.c=2788=static int ieee80211_change_station(struct wiphy *wiphy,\n--\nnet/mac80211/cfg.c-2831-\t\tbreak;\nnet/mac80211/cfg.c:2832:\tcase NL80211_IFTYPE_NAN:\nnet/mac80211/cfg.c:2833:\t\tstatype = CFG80211_STA_NAN_MGMT;\nnet/mac80211/cfg.c-2834-\t\tbreak;\nnet/mac80211/cfg.c:2835:\tcase NL80211_IFTYPE_NAN_DATA:\nnet/mac80211/cfg.c:2836:\t\tstatype = CFG80211_STA_NAN_DATA;\nnet/mac80211/cfg.c-2837-\t\tbreak;\n--\nnet/mac80211/cfg.c-2873-\nnet/mac80211/cfg.c:2874:\t/* NAN capabilties should not change */\nnet/mac80211/cfg.c:2875:\tif (statype == CFG80211_STA_NAN_DATA \u0026\u0026\nnet/mac80211/cfg.c-2876-\t sta-\u003edeflink.pub-\u003eht_cap.ht_supported \u0026\u0026\n--\nnet/mac80211/cfg.c=3491=static int ieee80211_scan(struct wiphy *wiphy,\n--\nnet/mac80211/cfg.c-3539-\t\tbreak;\nnet/mac80211/cfg.c:3540:\tcase NL80211_IFTYPE_NAN:\nnet/mac80211/cfg.c-3541-\tcase NL80211_IFTYPE_PD:\n--\nnet/mac80211/cfg.c=5225=void ieee80211_nan_func_terminated(struct ieee80211_vif *vif,\n--\nnet/mac80211/cfg.c-5233-\nnet/mac80211/cfg.c:5234:\tif (WARN_ON(vif-\u003etype != NL80211_IFTYPE_NAN))\nnet/mac80211/cfg.c-5235-\t\treturn;\n--\nnet/mac80211/cfg.c-5237-\tif (WARN_ON(sdata-\u003elocal-\u003ehw.wiphy-\u003enan_capa.flags \u0026\nnet/mac80211/cfg.c:5238:\t\t WIPHY_NAN_FLAGS_USERSPACE_DE))\nnet/mac80211/cfg.c-5239-\t\treturn;\n--\nnet/mac80211/cfg.c=5261=void ieee80211_nan_func_match(struct ieee80211_vif *vif,\n--\nnet/mac80211/cfg.c-5267-\nnet/mac80211/cfg.c:5268:\tif (WARN_ON(vif-\u003etype != NL80211_IFTYPE_NAN))\nnet/mac80211/cfg.c-5269-\t\treturn;\n--\nnet/mac80211/cfg.c-5271-\tif (WARN_ON(sdata-\u003elocal-\u003ehw.wiphy-\u003enan_capa.flags \u0026\nnet/mac80211/cfg.c:5272:\t\t WIPHY_NAN_FLAGS_USERSPACE_DE))\nnet/mac80211/cfg.c-5273-\t\treturn;\n--\nnet/mac80211/cfg.c=5290=void ieee80211_nan_cluster_joined(struct ieee80211_vif *vif,\n--\nnet/mac80211/cfg.c-5295-\nnet/mac80211/cfg.c:5296:\tif (WARN_ON(vif-\u003etype != NL80211_IFTYPE_NAN))\nnet/mac80211/cfg.c-5297-\t\treturn;\n--\nnet/mac80211/chan.c=112=ieee80211_chanctx_user_iter_next(struct ieee80211_local *local,\n--\nnet/mac80211/chan.c-127-next_user:\nnet/mac80211/chan.c:128:\tif (iter-\u003eiftype == NL80211_IFTYPE_NAN)\nnet/mac80211/chan.c-129-\t\tfound = ieee80211_chanctx_user_iter_next_nan_channel(ctx, iter);\n--\nnet/mac80211/chan.c-146-\nnet/mac80211/chan.c:147:\t\t/* NAN channels don't reserve channel context */\nnet/mac80211/chan.c:148:\t\tif (iter-\u003esdata-\u003evif.type == NL80211_IFTYPE_NAN \u0026\u0026\nnet/mac80211/chan.c-149-\t\t type == CHANCTX_ITER_RESERVED)\n--\nnet/mac80211/chan.c=519=ieee80211_get_width_of_link(struct ieee80211_link_data *link)\n--\nnet/mac80211/chan.c-557-\tcase NL80211_IFTYPE_P2P_GO:\nnet/mac80211/chan.c:558:\tcase NL80211_IFTYPE_NAN:\nnet/mac80211/chan.c:559:\tcase NL80211_IFTYPE_NAN_DATA:\nnet/mac80211/chan.c-560-\tcase NL80211_IFTYPE_PD:\n--\nnet/mac80211/chan.c=1181=static int ieee80211_assign_link_chanctx(struct ieee80211_link_data *link,\n--\nnet/mac80211/chan.c-1191-\nnet/mac80211/chan.c:1192:\tif (WARN_ON(sdata-\u003evif.type == NL80211_IFTYPE_NAN))\nnet/mac80211/chan.c-1193-\t\treturn -EOPNOTSUPP;\n--\nnet/mac80211/chan.c=1263=void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,\n--\nnet/mac80211/chan.c-1290-\t\tcase NL80211_IFTYPE_OCB:\nnet/mac80211/chan.c:1291:\t\tcase NL80211_IFTYPE_NAN:\nnet/mac80211/chan.c-1292-\t\t\tbreak;\n--\nnet/mac80211/chan.c=1581=ieee80211_link_chanctx_reservation_complete(struct ieee80211_link_data *link)\n--\nnet/mac80211/chan.c-1603-\tcase NL80211_IFTYPE_P2P_DEVICE:\nnet/mac80211/chan.c:1604:\tcase NL80211_IFTYPE_NAN:\nnet/mac80211/chan.c:1605:\tcase NL80211_IFTYPE_NAN_DATA:\nnet/mac80211/chan.c-1606-\tcase NL80211_IFTYPE_PD:\n--\nnet/mac80211/chan.c=2277=int _ieee80211_link_use_channel(struct ieee80211_link_data *link,\n--\nnet/mac80211/chan.c-2308-\tif (ret \u003c 0) {\nnet/mac80211/chan.c:2309:\t\t/* Let's check if evacuating a NAN channel will help */\nnet/mac80211/chan.c-2310-\t\tret = ieee80211_try_nan_chan_evacuation(local, sdata,\n--\nnet/mac80211/debugfs_netdev.c=821=static void add_common_files(struct ieee80211_sub_if_data *sdata)\n--\nnet/mac80211/debugfs_netdev.c-831-\tif (sdata-\u003evif.type != NL80211_IFTYPE_P2P_DEVICE \u0026\u0026\nnet/mac80211/debugfs_netdev.c:832:\t sdata-\u003evif.type != NL80211_IFTYPE_NAN)\nnet/mac80211/debugfs_netdev.c-833-\t\tDEBUGFS_ADD(aqm);\n--\nnet/mac80211/driver-ops.c=460=void drv_link_info_changed(struct ieee80211_local *local,\n--\nnet/mac80211/driver-ops.c-476-\tif (WARN_ON_ONCE(sdata-\u003evif.type == NL80211_IFTYPE_P2P_DEVICE ||\nnet/mac80211/driver-ops.c:477:\t\t\t sdata-\u003evif.type == NL80211_IFTYPE_NAN ||\nnet/mac80211/driver-ops.c-478-\t\t\t (sdata-\u003evif.type == NL80211_IFTYPE_MONITOR \u0026\u0026\n\n"
} |
| 17/2 | 2026/10/04 13:45 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 32230 output: 35 thoughts: 72 Thoughts: **NAN Configuration Investigation** Okay, so I'm digging into this NAN situation. My immediate understanding is that NAN functionality isn't some standalone module; it's deeply integrated within the standard CFG80211 and MAC80211 frameworks. There shouldn't be a dedicated `CONFIG_NAN` option or a separate module name. To confirm that hunch, I'm going to look for any specific configurations related to `mac80211_hwsim_nan.c`. That file name feels like a likely candidate for where things might be happening on the hardware simulation side. And just to be thorough, let's also examine `drivers/net/wireless/virtual/Makefile`. The virtual directory is often a good place to find things related to testing and simulation, so it's worth checking to see if there are clues regarding how NAN support might be built or enabled there. This should give me a better handle on how this all hangs together within the kernel's wireless infrastructure. |
| 18/2 | 2026/10/04 13:45 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/virtual/Makefile",
"FirstLine": 1,
"LineCount": 20
}Results: {
"Contents": " 1:\tobj-$(CONFIG_MAC80211_HWSIM)\t+= mac80211_hwsim.o\n 2:\tmac80211_hwsim-objs\t\t+= mac80211_hwsim_main.o\n 3:\tmac80211_hwsim-objs\t\t+= mac80211_hwsim_nan.o\n 4:\t\n 5:\tobj-$(CONFIG_VIRT_WIFI)\t+= virt_wifi.o\n"
} |
| 19/2 | 2026/10/04 13:45 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 32687 output: 36 thoughts: 2736 Thoughts: **Analysis of mac80211_hwsim_nan.c for Fuzzing Potential** Okay, so I'm digging into `mac80211_hwsim_nan.c`. This is part of the `MAC80211_HWSIM` subsystem, which in turn depends on `MAC80211` and `CFG80211`. My primary concern here is identifying potential fuzzing targets within this NAN (Neighbor Awareness Networking) implementation. First, I confirmed the dependencies and that this is accessible through syzkaller and virtualized environments, specifically leveraging netlink and socket interfaces. This means fuzzing this area is viable. I'm focusing on areas where data from potentially untrusted sources (e.g., netlink messages) is parsed and processed, particularly where the code interacts with NAN configuration, beacon transmission, and state transitions. I see that `wiphy_register` has NAN related checks. Specifically, the following functions warrant close scrutiny: * `hwsim_nan_beacon_has_service_ids`: This is dealing with parsing service IDs from incoming frames, and it seems to have a lot of OUI processing logic. Vulnerabilities might be present in the data handling. * `mac80211_hwsim_nan_set_config`: Handles setting the NAN configuration, including allocation and copying of `extra_nan_attrs`. This is a clear target, especially given the `NAN_BEACON_EXTRA_ATTRS_LEN` check. * `mac80211_hwsim_nan_tx_beacon`: This is sending NAN beacons. Sending potentially malformed data into this could have interesting effects. * `nl80211_parse_nan_conf`: This processes the NAN configuration via nl80211, which looks like a key entry point for manipulation, and is a definite target. The interaction with `instant_comm` and the `discovery_beacon_interval` is a specific area of concern. Specifically, potential division by zero. * `mac80211_hwsim_nan_discovery_beacon_timer`: This handles timer logic related to the discovery beacon interval. Potential vulnerabilities could exist if the interval isn't properly initialized or handled, I have already spotted a potential division by zero if interval is zero. The analysis is targeting those that are new or directly involved with this new functionality. Based on the code inspection, there's a strong case for fuzzing. The logic involved with parsing data from incoming frames and netlink messages, memory allocation, timers, division and locking are prime targets for fuzzing. This should be labeled `WorthFuzzing = true`. |
| 20/2 | 2026/10/04 13:46 | tool | grepper |
0mArgs:{
"Expression": "nl80211_parse_nan_conf",
"PathPrefix": "net/wireless/"
}Results: {
"Output": "net/wireless/nl80211.c=16502=static int nl80211_parse_nan_band_config(struct wiphy *wiphy,\n--\nnet/wireless/nl80211.c-16547-\nnet/wireless/nl80211.c:16548:static int nl80211_parse_nan_conf(struct wiphy *wiphy,\nnet/wireless/nl80211.c-16549-\t\t\t\t struct genl_info *info,\n--\nnet/wireless/nl80211.c=16714=static int nl80211_start_nan(struct sk_buff *skb, struct genl_info *info)\n--\nnet/wireless/nl80211.c-16733-\nnet/wireless/nl80211.c:16734:\terr = nl80211_parse_nan_conf(\u0026rdev-\u003ewiphy, info, \u0026conf, NULL, true);\nnet/wireless/nl80211.c-16735-\tif (err)\n--\nnet/wireless/nl80211.c=17088=static int nl80211_nan_change_config(struct sk_buff *skb,\n--\nnet/wireless/nl80211.c-17102-\nnet/wireless/nl80211.c:17103:\terr = nl80211_parse_nan_conf(\u0026rdev-\u003ewiphy, info, \u0026conf, \u0026changed, false);\nnet/wireless/nl80211.c-17104-\tif (err)\n"
} |
| 21/2 | 2026/10/04 13:46 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 36481 output: 48 thoughts: 1611 Thoughts: **Analyzing NAN Implementation and Identifying Key Functions** Okay, let's break this down. My initial focus is on the NAN (Neighbor Awareness Networking) implementation, so I'm starting by looking at `nl80211_start_nan` and `nl80211_nan_change_config` in `nl80211.c`. These are likely entry points for NAN configuration via the nl80211 netlink interface, so they are probably very important. Next, I'm diving into the `mac80211_hwsim_nan.c` driver, which is part of the virtual mac80211 hardware simulation. This is likely where the core NAN logic for the hardware simulation resides. There are quite a few functions there that look relevant: `hwsim_nan_beacon_has_service_ids`, `mac80211_hwsim_nan_set_config`, `mac80211_hwsim_nan_rx`, `mac80211_hwsim_nan_tx_beacon`, `mac80211_hwsim_nan_discovery_beacon_timer`, `mac80211_hwsim_nan_start`, `mac80211_hwsim_nan_stop`, `mac80211_hwsim_nan_change_config`, `mac80211_hwsim_nan_txq_transmitting`, and `mac80211_hwsim_nan_receive`. The non-static ones look like the most important since they are the API entrypoints for this subsystem. The static ones might be inlined. The task guidance wants me to avoid ubiquitous lifecycle hot-paths, and I noticed `wiphy_register` in `net/wireless/core.c`. This *could* be a critical function, but as it's called during the virtual radio creation, this seems less likely to be a problem. This should be fine. Moving on, I'm checking other potential call sites. In `net/mac80211/rx.c`, `ieee80211_accept_frame` looks like it might touch the data path. In `net/mac80211/cfg.c`, `ieee80211_nan_conf_copy` is worth a look to ensure that NAN configurations are handled correctly. Also, `cfg80211_inform_bss_frame_data` in `net/wireless/scan.c` calls `ieee80211_is_nan_beacon`, so that's another important function. Now, let's get into the specifics of these functions in `mac80211_hwsim_nan.c` again. I have a good understanding of what they do based on the function names: `mac80211_hwsim_nan_receive`, `mac80211_hwsim_nan_rx`, `mac80211_hwsim_nan_start`, `mac80211_hwsim_nan_change_config`, `mac80211_hwsim_nan_stop`, `mac80211_hwsim_nan_discovery_beacon_timer`, `mac80211_hwsim_nan_txq_transmitting`, and `cfg80211_inform_bss_frame_data`. The hrtimer in `mac80211_hwsim_nan_discovery_beacon_timer` is important. I need to make sure the time is correctly calculated and that the timer callback doesn't have any obvious issues. The static helper functions are more difficult to analyze and may not be useful. The compiler may inline them. Let's see: I see that `hwsim_nan_beacon_has_service_ids` is only called in one place: `mac80211_hwsim_nan_receive`, so the compiler may inline it. So, let's check `mac80211_hwsim_nan_receive` is non-static (exported or called across translation units from `mac80211_hwsim_main.c`) Let's verify in `drivers/net/wireless/virtual/mac80211_hwsim_nan.h`: `mac80211_hwsim_nan_receive` is declared there. `mac80211_hwsim_nan_start`, `mac80211_hwsim_nan_stop`, `mac80211_hwsim_nan_change_ |
| 22/2 | 2026/10/04 13:46 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/virtual/mac80211_hwsim_nan.h",
"FirstLine": 80,
"LineCount": 40
}Results: {
"Contents": " 80:\t\n 81:\tint mac80211_hwsim_nan_stop(struct ieee80211_hw *hw,\n 82:\t\t\t\t struct ieee80211_vif *vif);\n 83:\t\n 84:\tint mac80211_hwsim_nan_change_config(struct ieee80211_hw *hw,\n 85:\t\t\t\t\t struct ieee80211_vif *vif,\n 86:\t\t\t\t\t struct cfg80211_nan_conf *conf,\n 87:\t\t\t\t\t u32 changes);\n 88:\t\n 89:\tint mac80211_hwsim_nan_peer_sched_changed(struct ieee80211_hw *hw,\n 90:\t\t\t\t\t\t struct ieee80211_sta *sta);\n 91:\t\n 92:\tbool mac80211_hwsim_nan_txq_transmitting(struct ieee80211_hw *hw,\n 93:\t\t\t\t\t\t struct ieee80211_txq *txq);\n 94:\t\n 95:\tvoid mac80211_hwsim_nan_get_tx_chandef(struct ieee80211_hw *hw,\n 96:\t\t\t\t\t struct cfg80211_chan_def *chandef);\n 97:\t\n 98:\tbool mac80211_hwsim_nan_receive(struct ieee80211_hw *hw,\n 99:\t\t\t\t\tstruct sk_buff *skb,\n 100:\t\t\t\t\tstruct ieee80211_channel *channel,\n 101:\t\t\t\t\tstruct ieee80211_rx_status *rx_status);\n 102:\t\n 103:\tvoid mac80211_hwsim_nan_rx(struct ieee80211_hw *hw,\n 104:\t\t\t\t struct sk_buff *skb);\n 105:\t\n 106:\tvoid mac80211_hwsim_nan_local_sched_changed(struct ieee80211_hw *hw,\n 107:\t\t\t\t\t\t struct ieee80211_vif *vif);\n 108:\t\n 109:\t#endif /* __MAC80211_HWSIM_NAN_H */\n"
} |
| 23/2 | 2026/10/04 13:46 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 39791 output: 45 thoughts: 171 Thoughts: Here's a breakdown of my thought process: **Analyzing `mac80211_hwsim_nan.c` Symbol Visibility** Okay, so I'm looking at `mac80211_hwsim_nan.c` and immediately I'm noticing a cluster of symbols: `mac80211_hwsim_nan_receive`, `mac80211_hwsim_nan_start`, `mac80211_hwsim_nan_stop`, `mac80211_hwsim_nan_change_config`, `mac80211_hwsim_nan_rx`, and `mac80211_hwsim_nan_txq_transmitting`. Right off the bat, I see that these are all *non-static* symbols, which suggests they're likely exported and accessible outside of this specific compilation unit. That means other parts of the system or other modules could be directly calling these functions. Now, I also see `mac80211_hwsim_nan_discovery_beacon_timer` listed. The first thing I'm doing is a mental check to see if this is also exported or static. I *need* to know if it's visible outside of this file. So, I need to check the definition of that symbol to determine its scope. It's critical to understanding how the NAN functionality interacts with the broader system, so I'm going to track it down. |
| 24/2 | 2026/10/04 13:46 | tool | grepper |
0mArgs:{
"Expression": "mac80211_hwsim_nan_discovery_beacon_timer",
"PathPrefix": "drivers/net/wireless/virtual/"
}Results: {
"Output": "drivers/net/wireless/virtual/mac80211_hwsim_main.c=5677=static int mac80211_hwsim_new_radio(struct genl_info *info,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-5824-\t\thrtimer_setup(\u0026data-\u003enan.discovery_beacon_timer,\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:5825:\t\t\t mac80211_hwsim_nan_discovery_beacon_timer,\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-5826-\t\t\t CLOCK_BOOTTIME, HRTIMER_MODE_ABS_SOFT);\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=926=enum hrtimer_restart\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:927:mac80211_hwsim_nan_discovery_beacon_timer(struct hrtimer *timer)\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-928-{\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h=74=enum hrtimer_restart\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h:75:mac80211_hwsim_nan_discovery_beacon_timer(struct hrtimer *timer);\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h-76-\n"
} |
| 25/2 | 2026/10/04 13:46 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 40756 output: 40 thoughts: 169 Thoughts: Okay, let's see what we have here. **Investigating Potential Data Leakage Points in the mac80211 Subsystem** Alright, so I'm digging into this mac80211 code and need to understand the data flow. First, it seems `mac80211_hwsim_nan_discovery_beacon_timer` isn't static, which immediately flags it for further investigation – could be a point of entry. Then, over in `net/wireless/nl80211.c`, I've got `nl80211_start_nan` and `nl80211_nan_change_config` to consider. Those functions deal with NAN configurations, so they are likely involved. Next, I notice `cfg80211_inform_bss_frame_data` in `net/wireless/scan.c`. Always good to check what data the scanning functionality deals with. Now, the more interesting bit: `net/mac80211/rx.c`. I need to figure out how frame data is processed and if there are any exploitable areas. Looks like `ieee80211_accept_frame` is static. That *likely* restricts its scope, but I need to confirm where it's called. It's called from `ieee80211_rx_handlers`, so my next step is to trace all the callers of `ieee80211_accept_frame`. Let's see if those calling points look suspicious. |
| 26/2 | 2026/10/04 13:46 | tool | grepper |
0mArgs:{
"Expression": "ieee80211_accept_frame",
"PathPrefix": "net/mac80211/"
}Results: {
"Output": "net/mac80211/rx.c=4505=static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)\n--\nnet/mac80211/rx.c-4510-\nnet/mac80211/rx.c:4511:static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)\nnet/mac80211/rx.c-4512-{\n--\nnet/mac80211/rx.c=5019=static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,\n--\nnet/mac80211/rx.c-5069-\t * punting here will make it go through the full checks in\nnet/mac80211/rx.c:5070:\t * ieee80211_accept_frame().\nnet/mac80211/rx.c-5071-\t */\n--\nnet/mac80211/rx.c=5177=static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,\n--\nnet/mac80211/rx.c-5191-\t *\nnet/mac80211/rx.c:5192:\t * We skip the ieee80211_accept_frame() call and do the necessary\nnet/mac80211/rx.c-5193-\t * checking inside ieee80211_invoke_fast_rx().\n--\nnet/mac80211/rx.c-5202-\nnet/mac80211/rx.c:5203:\tif (!ieee80211_accept_frame(rx))\nnet/mac80211/rx.c-5204-\t\treturn false;\n"
} |
| 27/2 | 2026/10/04 13:46 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 41826 output: 357 thoughts: 554 Thoughts: **Fuzzing Strategy for NAN Support in mac80211** Okay, let's solidify this fuzzing plan. I'm focusing specifically on the NAN aspects within mac80211. While `ieee80211_prepare_and_rx_handle` is involved in RX, it's too general – we need to concentrate on the NAN-specific pathways and any modifications. Given that `rx.c` is the primary entry point for packet processing in mac80211, I will narrow the fuzzing scope to the specified entrypoints. The core of this strategy revolves around these `FocusSymbols`: `nl80211_start_nan`, `nl80211_nan_change_config`, `cfg80211_inform_bss_frame_data`, and then the hwsim functions: `mac80211_hwsim_nan_receive`, `mac80211_hwsim_nan_rx`, `mac80211_hwsim_nan_start`, `mac80211_hwsim_nan_stop`, `mac80211_hwsim_nan_change_config`, `mac80211_hwsim_nan_txq_transmitting`, and `mac80211_hwsim_nan_discovery_beacon_timer`. These symbols will be the targets for in-depth fuzzing. To enable this fuzzing, the necessary kernel configurations are also straightforward: `MAC80211_HWSIM`, `CFG80211`, and `MAC80211`. I've double-checked that these are properly set to support the fuzzing strategy. Finally, I've confirmed that this is considered `WorthFuzzing`, and the `Reasoning` provides a concise explanation for the fuzzing decision. Everything is precise, complete and well-defined. I'm confident in this approach. Time to call `set-results`. |
| 28/2 | 2026/10/04 13:46 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"MAC80211_HWSIM",
"MAC80211",
"CFG80211"
],
"FocusSymbols": [
"mac80211_hwsim_nan_receive",
"mac80211_hwsim_nan_rx",
"mac80211_hwsim_nan_start",
"mac80211_hwsim_nan_stop",
"mac80211_hwsim_nan_change_config",
"mac80211_hwsim_nan_txq_transmitting",
"mac80211_hwsim_nan_discovery_beacon_timer",
"nl80211_start_nan",
"nl80211_nan_change_config",
"cfg80211_inform_bss_frame_data"
],
"Reasoning": "The patch series introduces support for Wi-Fi Aware (NAN) Instant Communication (IC) mode across cfg80211, mac80211, and the simulated mac80211_hwsim driver. This modifies reachable netlink configuration parsers (nl80211_parse_nan_conf), frame reception and transmission paths, beacon handling, extra NAN attributes allocation/freeing, and timer callbacks in mac80211_hwsim. These code paths are fully reachable via netlink (nl80211) and virtual software wireless devices in standard fuzzing environments.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"MAC80211_HWSIM",
"MAC80211",
"CFG80211"
],
"FocusSymbols": [
"mac80211_hwsim_nan_receive",
"mac80211_hwsim_nan_rx",
"mac80211_hwsim_nan_start",
"mac80211_hwsim_nan_stop",
"mac80211_hwsim_nan_change_config",
"mac80211_hwsim_nan_txq_transmitting",
"mac80211_hwsim_nan_discovery_beacon_timer",
"nl80211_start_nan",
"nl80211_nan_change_config",
"cfg80211_inform_bss_frame_data"
],
"Reasoning": "The patch series introduces support for Wi-Fi Aware (NAN) Instant Communication (IC) mode across cfg80211, mac80211, and the simulated mac80211_hwsim driver. This modifies reachable netlink configuration parsers (nl80211_parse_nan_conf), frame reception and transmission paths, beacon handling, extra NAN attributes allocation/freeing, and timer callbacks in mac80211_hwsim. These code paths are fully reachable via netlink (nl80211) and virtual software wireless devices in standard fuzzing environments.",
"WorthFuzzing": true
} |
| 29/1 | 2026/10/04 13:46 | action | If |
6mArgs:{
"WorthFuzzing": true
}Results: null |
| 30/2 | 2026/10/04 13:46 | agent | kmsan-evaluator |
6mModel:core Args: null Results: {
"KMSANReasoning": "The patch introduces support for NAN Instant Communication (IC) mode (Wi-Fi Aware v4.0) across cfg80211, mac80211, and the mac80211_hwsim driver.\n\n1. Netlink attributes \u0026 userspace info-leaks:\nThe only new attribute exported to userspace is NL80211_NAN_CAPA_INSTANT_COMM, emitted using nla_put_flag(), which conveys a boolean flag with no payload. No new kernel structures with uninitialized fields or padding are copied to userspace.\n\n2. Structure and memory initialization:\n- In netlink configuration handling (nl80211_start_nan and nl80211_nan_change_config), 'struct cfg80211_nan_conf conf' is fully zero-initialized with '= {}'.\n- In mac80211_hwsim_main.c, instances of 'struct tx_iter_data' are initialized with designated initializers, ensuring non-specified fields are zero-initialized.\n- In mac80211_hwsim_nan_set_config(), extra_nan_attrs is allocated and initialized via kmemdup().\n- In mac80211_hwsim_nan_tx_beacon(), beacon headers are zeroed with memset(), and all IE structures (struct ieee80211_vendor_ie, struct ieee80211_nan_attr, etc.) are __packed and fully initialized before being put into the skb.\n\n3. Frame parsing and bounds:\nThe parsing logic in ieee80211_is_nan_beacon() and hwsim_nan_beacon_has_service_ids() iterates over elements using bounds checks against the skb data length. Any potential bug involving malformed frames or buffer boundaries would be an out-of-bounds read, which is detected by KASAN rather than KMSAN.\n\nNo uninitialized memory risks or info-leaks are introduced; standard KASAN fuzzing is sufficient.",
"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 64bd13e2ed1419f98d3aa38145753d7af0776e26
Author: syz-cluster <triage@syzkaller.com>
Date: Sun Oct 4 13:45:18 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_main.c b/drivers/net/wireless/virtual/mac80211_hwsim_main.c
index 02b6d81cccd11..5d235946e19a1 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim_main.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim_main.c
@@ -1772,6 +1772,7 @@ struct tx_iter_data {
struct ieee80211_channel *channel;
struct ieee80211_rx_status *rx_status;
struct ieee80211_hw *hw;
+ struct sk_buff *skb;
bool receive;
};
@@ -1784,6 +1785,7 @@ static void mac80211_hwsim_tx_iter(void *_data, u8 *addr,
if (vif->type == NL80211_IFTYPE_NAN ||
vif->type == NL80211_IFTYPE_NAN_DATA) {
data->receive = mac80211_hwsim_nan_receive(data->hw,
+ data->skb,
data->channel,
data->rx_status);
return;
@@ -1968,6 +1970,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
.hw = data2->hw,
.channel = chan,
.rx_status = &rx_status,
+ .skb = skb,
};
if (data == data2)
@@ -5800,7 +5803,8 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
BIT(NL80211_BAND_5GHZ);
hw->wiphy->nan_capa.flags = WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC |
- WIPHY_NAN_FLAGS_USERSPACE_DE;
+ WIPHY_NAN_FLAGS_USERSPACE_DE |
+ WIPHY_NAN_FLAGS_INSTANT_COMM;
hw->wiphy->nan_capa.op_mode = NAN_OP_MODE_PHY_MODE_MASK |
NAN_OP_MODE_80P80MHZ |
NAN_OP_MODE_160MHZ;
@@ -6546,6 +6550,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
struct tx_iter_data iter_data = {
.hw = data2->hw,
.rx_status = &rx_status,
+ .skb = skb,
};
/* throw away off-channel packets, but allow both the temporary
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_nan.c b/drivers/net/wireless/virtual/mac80211_hwsim_nan.c
index 7be64c45babf9..1f058ec9c159f 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim_nan.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim_nan.c
@@ -33,6 +33,12 @@ static_assert(DW0_TSF_MASK + 1 == 8192 * 1024);
#define NAN_RSSI_CLOSE (-60)
#define NAN_RSSI_MIDDLE (-75)
+/* Size of the NAN vendor element carrying the mandatory attributes */
+#define NAN_BEACON_ELEM_LEN 27
+
+/* Space left in the NAN vendor element for the configured attributes */
+#define NAN_BEACON_EXTRA_ATTRS_LEN (255 - (NAN_BEACON_ELEM_LEN - 2))
+
/* Quiet time at the end of each slot where TX is suppressed */
#define NAN_CHAN_SWITCH_TIME_US 256
@@ -213,6 +219,37 @@ mac80211_hwsim_nan_schedule_slot(struct mac80211_hwsim_data *data, u8 slot,
mac80211_hwsim_tsf_to_boottime(data, tsf));
}
+static bool hwsim_nan_beacon_has_service_ids(struct sk_buff *skb)
+{
+ const struct ieee80211_mgmt *mgmt = (void *)skb->data;
+ const struct ieee80211_nan_attr *nan_attr;
+ const struct element *elem;
+ size_t len;
+
+ if (skb->len < offsetofend(struct ieee80211_mgmt, u.beacon) ||
+ !ieee80211_is_beacon(mgmt->frame_control))
+ return false;
+
+ len = skb->len - offsetofend(struct ieee80211_mgmt, u.beacon);
+
+ /* TODO: fragmented NAN elements are not supported */
+ for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC,
+ mgmt->u.beacon.variable, len) {
+ if (elem->datalen < 4 ||
+ get_unaligned_be32(elem->data) !=
+ (WLAN_OUI_WFA << 8 | WLAN_OUI_TYPE_WFA_NAN))
+ continue;
+
+ for_each_nan_attr(nan_attr, elem->data + 4, elem->datalen - 4)
+ if (nan_attr->attr == NAN_ATTR_SERVICE_ID_LIST ||
+ nan_attr->attr ==
+ NAN_ATTR_SUBSCRIBE_SERVICE_ID_LIST)
+ return true;
+ }
+
+ return false;
+}
+
void mac80211_hwsim_nan_rx(struct ieee80211_hw *hw,
struct sk_buff *skb)
{
@@ -230,9 +267,7 @@ void mac80211_hwsim_nan_rx(struct ieee80211_hw *hw,
ssize_t data_len;
u8 slot;
- /* Need a NAN vendor element at the start */
- if (skb->len < (offsetofend(struct ieee80211_mgmt, u.beacon) + 6) ||
- !ieee80211_is_beacon(mgmt->frame_control))
+ if (!ieee80211_is_nan_beacon(mgmt, skb->len))
return;
data_len = skb->len - offsetofend(struct ieee80211_mgmt, u.beacon);
@@ -266,28 +301,34 @@ void mac80211_hwsim_nan_rx(struct ieee80211_hw *hw,
}
/*
- * (overly) simplify things, only track 2.4 GHz here. Also, ignore
- * frames outside of the 2.4 GHz DW slot, unless in the initial SCAN
- * phase.
+ * Only sync on 2.4 GHz, which all NAN devices attend. The slot number
+ * is derived from the local TSF, so before being synchronized a 5 GHz
+ * beacon from a different device may fall into the local 2.4 GHz DW
+ * slot. Filter by frequency to keep such beacons out of master
+ * selection and synchronization.
*/
- if ((slot != SLOT_24GHZ_DW &&
- data->nan.phase != MAC80211_HWSIM_NAN_PHASE_SCAN) ||
- rx_status.freq != 2437)
+ if (rx_status.freq != 2437)
return;
- /* Just ignore low RSSI beacons that we cannot sync to */
- if (rx_status.signal < NAN_RSSI_MIDDLE)
- return;
+ /*
+ * Ignore frames outside of the 2.4 GHz DW slot, unless in the initial
+ * SCAN phase or in Instant Communication, where discovery beacons are
+ * received outside the DW.
+ */
+ if (slot != SLOT_24GHZ_DW) {
+ bool rx_outside_dw;
- /* Needs to be a valid NAN cluster ID in A3 */
- if (get_unaligned_be32(mgmt->bssid) != ((WLAN_OUI_WFA << 8) | 0x01))
- return;
+ scoped_guard(spinlock_bh, &data->nan.state_lock)
+ rx_outside_dw = data->nan.instant_comm ||
+ data->nan.phase ==
+ MAC80211_HWSIM_NAN_PHASE_SCAN;
- /* We are only interested in NAN beacons */
- if (nan_elem->id != WLAN_EID_VENDOR_SPECIFIC ||
- nan_elem->datalen < 4 ||
- get_unaligned_be32(nan_elem->data) !=
- (WLAN_OUI_WFA << 8 | WLAN_OUI_TYPE_WFA_NAN))
+ if (!rx_outside_dw)
+ return;
+ }
+
+ /* Just ignore low RSSI beacons that we cannot sync to */
+ if (rx_status.signal < NAN_RSSI_MIDDLE)
return;
u8 *nan_defragmented __free(kfree) = kzalloc(data_len, GFP_ATOMIC);
@@ -636,10 +677,12 @@ mac80211_hwsim_nan_exec_state_transitions(struct mac80211_hwsim_data *data)
/*
* The discovery beacon timer will stop automatically. Make sure it is
- * running if we are master. Do not bother with a proper alignment it
- * will sync itself to the TSF after the first TX.
+ * running if we are master or if Instant Communication is enabled. Do
+ * not bother with a proper alignment it will sync itself to the TSF
+ * after the first TX.
*/
- if (data->nan.role == MAC80211_HWSIM_NAN_ROLE_MASTER &&
+ if ((data->nan.role == MAC80211_HWSIM_NAN_ROLE_MASTER ||
+ data->nan.instant_comm) &&
!hrtimer_active(&data->nan.discovery_beacon_timer))
hrtimer_start(&data->nan.discovery_beacon_timer,
ns_to_ktime(10 * NSEC_PER_USEC),
@@ -698,7 +741,7 @@ mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,
{
struct ieee80211_vendor_ie nan_ie = {
.element_id = WLAN_EID_VENDOR_SPECIFIC,
- .len = 27 - 2,
+ .len = NAN_BEACON_ELEM_LEN - 2,
.oui = { u32_get_bits(WLAN_OUI_WFA, 0xff0000),
u32_get_bits(WLAN_OUI_WFA, 0xff00),
u32_get_bits(WLAN_OUI_WFA, 0xff) },
@@ -707,23 +750,34 @@ mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,
size_t alloc_size =
IEEE80211_TX_STATUS_HEADROOM +
offsetofend(struct ieee80211_mgmt, u.beacon) +
- 27 /* size of NAN vendor element */;
+ NAN_BEACON_ELEM_LEN;
struct ieee80211_nan_master_indication master_indication;
struct ieee80211_nan_attr nan_attr;
struct ieee80211_mgmt *mgmt;
struct sk_buff *skb;
/*
- * TODO: Should the configured vendor elements or NAN attributes be
- * included in some of these beacons?
+ * TODO: Should the configured vendor elements be included in some of
+ * these beacons?
*/
+ /* Allocate maximal size for NAN IE */
+ if (is_discovery)
+ alloc_size += NAN_BEACON_EXTRA_ATTRS_LEN;
+
skb = alloc_skb(alloc_size, GFP_ATOMIC);
if (!skb)
return;
spin_lock(&data->nan.state_lock);
+ /*
+ * The attributes configured by user space are appended to the
+ * mandatory ones.
+ */
+ if (is_discovery)
+ nan_ie.len += data->nan.extra_nan_attrs_len;
+
skb_reserve(skb, IEEE80211_TX_STATUS_HEADROOM);
mgmt = skb_put(skb, offsetofend(struct ieee80211_mgmt, u.beacon));
@@ -734,7 +788,9 @@ mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_BEACON);
- mgmt->u.beacon.beacon_int = cpu_to_le16(is_discovery ? 100 : DWST_TU);
+ mgmt->u.beacon.beacon_int =
+ cpu_to_le16(is_discovery ? data->nan.discovery_beacon_interval :
+ DWST_TU);
mgmt->u.beacon.capab_info =
cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME |
WLAN_CAPABILITY_SHORT_PREAMBLE);
@@ -765,6 +821,10 @@ mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,
skb_put_data(skb, &data->nan.current_ami,
sizeof(data->nan.current_ami));
+ if (is_discovery && data->nan.extra_nan_attrs_len)
+ skb_put_data(skb, data->nan.extra_nan_attrs,
+ data->nan.extra_nan_attrs_len);
+
spin_unlock(&data->nan.state_lock);
mac80211_hwsim_tx_frame(data->hw, skb, channel);
@@ -877,7 +937,15 @@ mac80211_hwsim_nan_discovery_beacon_timer(struct hrtimer *timer)
return HRTIMER_NORESTART;
scoped_guard(spinlock, &data->nan.state_lock) {
- if (data->nan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN ||
+ if (data->nan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN)
+ return HRTIMER_NORESTART;
+
+ /*
+ * With Instant Communication the discovery beacons are
+ * transmitted disregarding the role and the state, see
+ * Wi-Fi Aware version 4.0 section 13.
+ */
+ if (!data->nan.instant_comm &&
data->nan.role != MAC80211_HWSIM_NAN_ROLE_MASTER)
return HRTIMER_NORESTART;
}
@@ -894,10 +962,11 @@ mac80211_hwsim_nan_discovery_beacon_timer(struct hrtimer *timer)
tsf_now = mac80211_hwsim_get_tsf(data->hw, data->nan.device_vif);
/* Wrap value to be after the next TBTT */
- tbtt = tsf_now + ieee80211_tu_to_usec(100);
+ tbtt = tsf_now + ieee80211_tu_to_usec(data->nan.discovery_beacon_interval);
/* Round TBTT down to the correct time */
- div_u64_rem(tbtt, ieee80211_tu_to_usec(100), &remainder);
+ div_u64_rem(tbtt, ieee80211_tu_to_usec(data->nan.discovery_beacon_interval),
+ &remainder);
tbtt = tbtt - remainder;
hrtimer_set_expires(&data->nan.discovery_beacon_timer,
@@ -906,11 +975,51 @@ mac80211_hwsim_nan_discovery_beacon_timer(struct hrtimer *timer)
return HRTIMER_RESTART;
}
+static int mac80211_hwsim_nan_set_config(struct mac80211_hwsim_data *data,
+ struct cfg80211_nan_conf *conf)
+{
+ const u8 *extra_nan_attrs = NULL;
+ const u8 *old;
+
+ if (conf->extra_nan_attrs_len > NAN_BEACON_EXTRA_ATTRS_LEN)
+ return -EINVAL;
+
+ if (conf->extra_nan_attrs_len) {
+ extra_nan_attrs = kmemdup(conf->extra_nan_attrs,
+ conf->extra_nan_attrs_len,
+ GFP_KERNEL);
+ if (!extra_nan_attrs)
+ return -ENOMEM;
+ }
+
+ data->nan.notify_dw = conf->enable_dw_notification;
+
+ scoped_guard(spinlock_bh, &data->nan.state_lock) {
+ /*
+ * Fall back to the device default if user space did not
+ * configure it
+ */
+ data->nan.discovery_beacon_interval =
+ conf->discovery_beacon_interval ? : 100;
+
+ data->nan.instant_comm = conf->instant_comm;
+
+ old = data->nan.extra_nan_attrs;
+ data->nan.extra_nan_attrs = extra_nan_attrs;
+ data->nan.extra_nan_attrs_len = conf->extra_nan_attrs_len;
+ }
+
+ kfree(old);
+
+ return 0;
+}
+
int mac80211_hwsim_nan_start(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_nan_conf *conf)
{
struct mac80211_hwsim_data *data = hw->priv;
+ int err;
if (vif->type != NL80211_IFTYPE_NAN)
return -EINVAL;
@@ -918,14 +1027,22 @@ int mac80211_hwsim_nan_start(struct ieee80211_hw *hw,
if (data->nan.device_vif)
return -EALREADY;
+ err = mac80211_hwsim_nan_set_config(data, conf);
+ if (err)
+ return err;
+
/* set this before starting the timer, as preemption might occur */
data->nan.device_vif = vif;
data->nan.bands = conf->bands;
scoped_guard(spinlock_bh, &data->nan.state_lock) {
- /* Start in the "scan" phase and stay there for a little bit */
+ /*
+ * Start in the "scan" phase and stay there for a little bit,
+ * unless Instant Communication is configured, in which case an
+ * own cluster is started immediately.
+ */
data->nan.phase = MAC80211_HWSIM_NAN_PHASE_SCAN;
- data->nan.random_factor_valid_dwst = 1;
+ data->nan.random_factor_valid_dwst = conf->instant_comm ? 0 : 1;
data->nan.random_factor = 0;
data->nan.master_pref = conf->master_pref;
data->nan.role = MAC80211_HWSIM_NAN_ROLE_MASTER;
@@ -943,8 +1060,6 @@ int mac80211_hwsim_nan_start(struct ieee80211_hw *hw,
ether_addr_copy(data->nan.cluster_id, conf->cluster_id);
- data->nan.notify_dw = conf->enable_dw_notification;
-
return 0;
}
@@ -952,6 +1067,7 @@ int mac80211_hwsim_nan_stop(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct mac80211_hwsim_data *data = hw->priv;
+ const u8 *old;
if (vif->type != NL80211_IFTYPE_NAN || !data->nan.device_vif ||
data->nan.device_vif != vif)
@@ -962,6 +1078,15 @@ int mac80211_hwsim_nan_stop(struct ieee80211_hw *hw,
hrtimer_cancel(&data->nan.discovery_beacon_timer);
data->nan.device_vif = NULL;
+ scoped_guard(spinlock_bh, &data->nan.state_lock) {
+ old = data->nan.extra_nan_attrs;
+ data->nan.extra_nan_attrs = NULL;
+ data->nan.extra_nan_attrs_len = 0;
+ data->nan.instant_comm = false;
+ }
+
+ kfree(old);
+
return 0;
}
@@ -980,13 +1105,27 @@ int mac80211_hwsim_nan_change_config(struct ieee80211_hw *hw,
wiphy_debug(hw->wiphy, "nan_config_changed: changes=0x%x\n", changes);
+ if (changes & CFG80211_NAN_CONF_CHANGED_CONFIG) {
+ int err = mac80211_hwsim_nan_set_config(data, conf);
+
+ if (err)
+ return err;
+
+ /*
+ * When Instant Communication is enabled discovery beacons are
+ * transmitted regardless of the role and the state.
+ */
+ if (conf->instant_comm &&
+ !hrtimer_active(&data->nan.discovery_beacon_timer))
+ hrtimer_start(&data->nan.discovery_beacon_timer,
+ ns_to_ktime(10 * NSEC_PER_USEC),
+ HRTIMER_MODE_REL_SOFT);
+ }
+
/* Handle only the changes we care about for simulation purposes */
if (changes & CFG80211_NAN_CONF_CHANGED_BANDS)
data->nan.bands = conf->bands;
- if (changes & CFG80211_NAN_CONF_CHANGED_CONFIG)
- data->nan.notify_dw = conf->enable_dw_notification;
-
if (changes & CFG80211_NAN_CONF_CHANGED_PREF) {
scoped_guard(spinlock_bh, &data->nan.state_lock)
data->nan.master_pref = conf->master_pref;
@@ -1169,9 +1308,16 @@ bool mac80211_hwsim_nan_txq_transmitting(struct ieee80211_hw *hw,
is_dw_slot = mac80211_hwsim_nan_is_dw_slot(data, slot);
if (!txq->sta) {
- /* Non-STA TXQ: allow management frames during DW */
- if (txq->vif->type == NL80211_IFTYPE_NAN)
- return is_dw_slot;
+ /* Non-STA TXQ: allow management frames during DW or IC */
+ if (txq->vif->type == NL80211_IFTYPE_NAN) {
+ if (is_dw_slot)
+ return true;
+
+ /* Outside the DW the local schedule must allow it */
+ guard(spinlock_bh)(&data->nan.state_lock);
+ return data->nan.instant_comm &&
+ data->nan.local_sched[slot].chan;
+ }
/* Allow multicast data when all the peers are available
* on this slot
@@ -1224,15 +1370,32 @@ void mac80211_hwsim_nan_get_tx_chandef(struct ieee80211_hw *hw,
}
bool mac80211_hwsim_nan_receive(struct ieee80211_hw *hw,
+ struct sk_buff *skb,
struct ieee80211_channel *channel,
struct ieee80211_rx_status *rx_status)
{
struct mac80211_hwsim_data *data = hw->priv;
+ bool instant_comm;
u8 slot;
if (WARN_ON_ONCE(!data->nan.device_vif))
return false;
+ scoped_guard(spinlock_bh, &data->nan.state_lock)
+ instant_comm = data->nan.instant_comm;
+
+ /*
+ * During Instant Communication a peer advertises its services in the
+ * discovery beacons, which are transmitted disregarding the roles and
+ * the states, see Section 13 in Wi-Fi Aware v4.0.
+ * Note that while according to the specification Instant communication
+ * should be enabled only on the NAN discovery channels, do not force
+ * this here, and allow receiving NAN frames on any channel if Instant
+ * Communication is enabled.
+ */
+ if (instant_comm && hwsim_nan_beacon_has_service_ids(skb))
+ return true;
+
if (data->nan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN)
return channel->center_freq == 2437;
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_nan.h b/drivers/net/wireless/virtual/mac80211_hwsim_nan.h
index 81e105ac7b8ed..995d1f6feb291 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim_nan.h
+++ b/drivers/net/wireless/virtual/mac80211_hwsim_nan.h
@@ -32,6 +32,9 @@ struct mac80211_hwsim_nan_data {
/* Later members are protected by this lock */
spinlock_t state_lock;
+ const u8 *extra_nan_attrs;
+ u16 extra_nan_attrs_len;
+
u8 master_pref;
u8 random_factor;
@@ -53,6 +56,9 @@ struct mac80211_hwsim_nan_data {
bool tsf_adjusted;
bool tsf_discontinuity;
+ bool instant_comm;
+ u8 discovery_beacon_interval;
+
/*
* Local schedule - stores channel definition for each 16TU slot.
* Derived from NMI vif->cfg.nan_schedule. chan == NULL means not
@@ -90,6 +96,7 @@ void mac80211_hwsim_nan_get_tx_chandef(struct ieee80211_hw *hw,
struct cfg80211_chan_def *chandef);
bool mac80211_hwsim_nan_receive(struct ieee80211_hw *hw,
+ struct sk_buff *skb,
struct ieee80211_channel *channel,
struct ieee80211_rx_status *rx_status);
diff --git a/include/linux/ieee80211-nan.h b/include/linux/ieee80211-nan.h
index 455033955e545..7815a6cf81605 100644
--- a/include/linux/ieee80211-nan.h
+++ b/include/linux/ieee80211-nan.h
@@ -40,6 +40,8 @@
/* NAN attributes, as defined in Wi-Fi Aware (TM) specification 4.0 Table 42 */
#define NAN_ATTR_MASTER_INDICATION 0x00
#define NAN_ATTR_CLUSTER_INFO 0x01
+#define NAN_ATTR_SERVICE_ID_LIST 0x02
+#define NAN_ATTR_SUBSCRIBE_SERVICE_ID_LIST 0x28
struct ieee80211_nan_attr {
u8 attr;
@@ -74,4 +76,30 @@ struct ieee80211_nan_anchor_master_info {
_attr = (const struct ieee80211_nan_attr *) \
(_attr->data + le16_to_cpu(_attr->length)))
+static inline bool ieee80211_is_nan_beacon(const struct ieee80211_mgmt *mgmt,
+ size_t len)
+{
+ const struct element *elem;
+
+ /* The NAN IE is at least 6 octets */
+ if (len < offsetofend(struct ieee80211_mgmt, u.beacon) + 6)
+ return false;
+
+ if (!ieee80211_is_beacon(mgmt->frame_control))
+ return false;
+
+ /* NAN Cluster IDs range from 50-6F-9A-01-00-00 to 50-6F-9A-01-FF-FF */
+ if (get_unaligned_be32(mgmt->bssid) != ((WLAN_OUI_WFA << 8) | 0x01))
+ return false;
+
+ elem = (const struct element *)mgmt->u.beacon.variable;
+ if (elem->id != WLAN_EID_VENDOR_SPECIFIC ||
+ elem->datalen < 4 ||
+ get_unaligned_be32(elem->data) !=
+ (WLAN_OUI_WFA << 8 | WLAN_OUI_TYPE_WFA_NAN))
+ return false;
+
+ return true;
+}
+
#endif /* LINUX_IEEE80211_NAN_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 97c16d4ff1271..f9d590facfc0b 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -4183,9 +4183,12 @@ struct cfg80211_nan_band_config {
* that can take a value from 50-6F-9A-01-00-00 to 50-6F-9A-01-FF-FF.
* @scan_period: period (in seconds) between NAN scans.
* @scan_dwell_time: dwell time (in milliseconds) for NAN scans.
- * @discovery_beacon_interval: interval (in TUs) for discovery beacons.
+ * @discovery_beacon_interval: interval (in TUs) for discovery beacons. Must be
+ * greater than 0 when @instant_comm is true.
* @enable_dw_notification: flag to enable/disable discovery window
* notifications.
+ * @instant_comm: if true, start Instant Communication (IC) as defined in
+ * Chapter 13 of the Wi-Fi Aware Specification v4.0.
* @band_cfgs: array of band specific configurations, indexed by
* &enum nl80211_band values.
* @extra_nan_attrs: pointer to additional NAN attributes.
@@ -4201,6 +4204,7 @@ struct cfg80211_nan_conf {
u16 scan_dwell_time;
u8 discovery_beacon_interval;
bool enable_dw_notification;
+ bool instant_comm;
struct cfg80211_nan_band_config band_cfgs[NUM_NL80211_BANDS];
const u8 *extra_nan_attrs;
u16 extra_nan_attrs_len;
@@ -6266,10 +6270,13 @@ struct wiphy_radio {
* @WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC: Device supports NAN configurable
* synchronization.
* @WIPHY_NAN_FLAGS_USERSPACE_DE: Device doesn't support DE offload.
+ * @WIPHY_NAN_FLAGS_INSTANT_COMM: Device can switch to Instant Communication
+ * (IC) mode. Can only be set along with %WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC.
*/
enum wiphy_nan_flags {
WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC = BIT(0),
WIPHY_NAN_FLAGS_USERSPACE_DE = BIT(1),
+ WIPHY_NAN_FLAGS_INSTANT_COMM = BIT(2),
};
/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 020387d764122..5ac9f02f5ad26 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -7826,6 +7826,11 @@ enum nl80211_nan_band_conf_attributes {
* the upcoming discovery window with
* %NL80211_CMD_NAN_NEXT_DW_NOTIFICATION.
* This is a flag attribute.
+ * @NL80211_NAN_CONF_INSTANT_COMM: If set, the NAN synchronization logic will
+ * start Instant Communication (IC) as defined in Chapter 13 of the
+ * Wi-Fi Aware Specification v4.0.
+ * %NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL must be set as well.
+ * This is a flag attribute.
* @NUM_NL80211_NAN_CONF_ATTR: Internal.
* @NL80211_NAN_CONF_ATTR_MAX: Highest NAN configuration attribute.
*
@@ -7841,6 +7846,7 @@ enum nl80211_nan_conf_attributes {
NL80211_NAN_CONF_SCAN_DWELL_TIME,
NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL,
NL80211_NAN_CONF_NOTIFY_DW,
+ NL80211_NAN_CONF_INSTANT_COMM,
/* keep last */
NUM_NL80211_NAN_CONF_ATTR,
@@ -9057,6 +9063,11 @@ enum nl80211_s1g_short_beacon_attrs {
* specification Table 79 (Capabilities field).
* @NL80211_NAN_CAPA_PHY: nested attribute containing band-agnostic
* capabilities for NAN data path. See &enum nl80211_nan_phy_cap_attr.
+ * @NL80211_NAN_CAPA_INSTANT_COMM: Flag attribute indicating that the device
+ * can switch to Instant Communication (IC) mode, as defined in Chapter 13
+ * of the Wi-Fi Aware Specification v4.0. Can only be set if
+ * %NL80211_NAN_CAPA_CONFIGURABLE_SYNC is set. When IC is enabled, the IC
+ * schedule is expected to be configured by user space.
* @__NL80211_NAN_CAPABILITIES_LAST: Internal
* @NL80211_NAN_CAPABILITIES_MAX: Highest NAN capability attribute.
*/
@@ -9070,6 +9081,7 @@ enum nl80211_nan_capabilities {
NL80211_NAN_CAPA_MAX_CHANNEL_SWITCH_TIME,
NL80211_NAN_CAPA_CAPABILITIES,
NL80211_NAN_CAPA_PHY,
+ NL80211_NAN_CAPA_INSTANT_COMM,
/* keep last */
__NL80211_NAN_CAPABILITIES_LAST,
NL80211_NAN_CAPABILITIES_MAX = __NL80211_NAN_CAPABILITIES_LAST - 1,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 23f4f9ec86d0a..7a7acbfeeba92 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -364,6 +364,7 @@ static int ieee80211_nan_conf_copy(struct cfg80211_nan_conf *dst,
dst->discovery_beacon_interval =
src->discovery_beacon_interval;
dst->enable_dw_notification = src->enable_dw_notification;
+ dst->instant_comm = src->instant_comm;
memcpy(&dst->band_cfgs, &src->band_cfgs,
sizeof(dst->band_cfgs));
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index a59837b9f480f..9553ea77cfe84 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -745,8 +745,13 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
},
[NL80211_IFTYPE_NAN] = {
.tx = 0xffff,
+ /*
+ * Beacon Rx registration is needed to let user space handle
+ * service discovery when Instant Communication is enabled.
+ */
.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_AUTH >> 4),
+ BIT(IEEE80211_STYPE_AUTH >> 4) |
+ BIT(IEEE80211_STYPE_BEACON >> 4),
},
[NL80211_IFTYPE_NAN_DATA] = {
.tx = 0xffff,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 5e26be8e27d8f..eb1578b2d6d79 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -4660,7 +4660,8 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
* Accept only frames that are addressed to the NAN cluster
* (based on the Cluster ID). From these frames, accept only
* - public action frames,
- * - authentication frames to the local address, and
+ * - authentication frames to the local address,
+ * - NAN beacons, when Instant Communication is enabled, and
* - robust management frames except disassoc.
*/
if (!ether_addr_equal(sdata->u.nan.conf.cluster_id, hdr->addr3))
@@ -4670,6 +4671,9 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
if (ieee80211_is_auth(hdr->frame_control) &&
ether_addr_equal(sdata->vif.addr, hdr->addr1))
return true;
+ if (ieee80211_is_nan_beacon((struct ieee80211_mgmt *)hdr,
+ skb->len))
+ return sdata->u.nan.conf.instant_comm;
if (!ieee80211_is_disassoc(hdr->frame_control) &&
ieee80211_is_robust_mgmt_frame(skb))
return true;
diff --git a/net/wireless/core.c b/net/wireless/core.c
index d13310fef691a..fc9b97888191d 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -888,6 +888,18 @@ int wiphy_register(struct wiphy *wiphy)
(!wiphy->nan_capa.phy.ht.ht_supported || wiphy->n_radio > 1)))
return -EINVAL;
+ if (WARN_ON((wiphy->nan_capa.flags & WIPHY_NAN_FLAGS_INSTANT_COMM) &&
+ !(wiphy->nan_capa.flags &
+ WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC)))
+ return -EINVAL;
+
+ /* Instant Communication requires user space to track NAN beacons */
+ if (WARN_ON((wiphy->nan_capa.flags & WIPHY_NAN_FLAGS_INSTANT_COMM) &&
+ (!wiphy->mgmt_stypes ||
+ !(wiphy->mgmt_stypes[NL80211_IFTYPE_NAN].rx &
+ BIT(IEEE80211_STYPE_BEACON >> 4)))))
+ return -EINVAL;
+
if (WARN_ON(wiphy->interface_modes & BIT(NL80211_IFTYPE_WDS)))
return -EINVAL;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 44f2bad086705..94d92b0ebc54e 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -686,6 +686,7 @@ nl80211_nan_conf_policy[NL80211_NAN_CONF_ATTR_MAX + 1] = {
[NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL] =
NLA_POLICY_RANGE(NLA_U8, 50, 200),
[NL80211_NAN_CONF_NOTIFY_DW] = { .type = NLA_FLAG },
+ [NL80211_NAN_CONF_INSTANT_COMM] = { .type = NLA_FLAG },
};
static const struct netlink_range_validation nl80211_punct_bitmap_range = {
@@ -3025,6 +3026,10 @@ static int nl80211_put_nan_capa(struct wiphy *wiphy, struct sk_buff *msg)
nla_put_flag(msg, NL80211_NAN_CAPA_USERSPACE_DE))
goto fail;
+ if ((wiphy->nan_capa.flags & WIPHY_NAN_FLAGS_INSTANT_COMM) &&
+ nla_put_flag(msg, NL80211_NAN_CAPA_INSTANT_COMM))
+ goto fail;
+
if (nla_put_u8(msg, NL80211_NAN_CAPA_OP_MODE,
wiphy->nan_capa.op_mode) ||
nla_put_u8(msg, NL80211_NAN_CAPA_NUM_ANTENNAS,
@@ -16663,6 +16668,23 @@ static int nl80211_parse_nan_conf(struct wiphy *wiphy,
conf->enable_dw_notification =
nla_get_flag(attrs[NL80211_NAN_CONF_NOTIFY_DW]);
+ conf->instant_comm = nla_get_flag(attrs[NL80211_NAN_CONF_INSTANT_COMM]);
+ if (conf->instant_comm) {
+ if (!(wiphy->nan_capa.flags & WIPHY_NAN_FLAGS_INSTANT_COMM)) {
+ NL_SET_ERR_MSG_ATTR(info->extack,
+ attrs[NL80211_NAN_CONF_INSTANT_COMM],
+ "Instant Communication is not supported");
+ return -EOPNOTSUPP;
+ }
+
+ if (!conf->discovery_beacon_interval) {
+ NL_SET_ERR_MSG_ATTR(info->extack,
+ attrs[NL80211_NAN_CONF_INSTANT_COMM],
+ "Instant Communication requires a discovery beacon interval");
+ return -EINVAL;
+ }
+ }
+
out:
if (!conf->band_cfgs[NL80211_BAND_5GHZ].chan &&
(!conf->bands || conf->bands & BIT(NL80211_BAND_5GHZ))) {
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 9e934b185e341..c5dad787747a5 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -3302,6 +3302,10 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
if (WARN_ON(!wiphy))
return NULL;
+ /* NAN beacons are not a BSS, don't add to the BSS table */
+ if (ieee80211_is_nan_beacon(mgmt, len))
+ return NULL;
+
BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) !=
offsetof(struct ieee80211_mgmt, u.beacon.variable));
|
| 31/3 | 2026/10/04 13:46 | llm | kmsan-evaluator |
1mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 14262 output: 19 thoughts: 1648 Thoughts: **KMSAN Fuzzing Session Justification** Okay, so the task at hand is to determine if this patch, which introduces Wi-Fi Aware v4.0 Instant Communication (IC) mode, warrants a dedicated KMSAN fuzzing session. Let's break this down. Firstly, I need to grasp the patch's scope. It's touching a significant number of files, mostly within the `mac80211` and `cfg80211` subsystems. This signals a fair amount of new code and logic, which automatically raises a red flag. The introduction of IC mode means new data structures, new control flows, and potentially new vulnerabilities. The patch seems to revolve around handling "extra NAN attributes" (`extra_nan_attrs`). This is where I need to focus my attention. The patch is adding `instant_comm` everywhere, which has a corresponding flag in the firmware. I can see that the patch: * Adds the `instant_comm` field and associated constants. * Introduces functions to handle the new IC mode, which has the `extra_nan_attrs`. * Adds a new field `extra_nan_attrs` and related fields. * Adds functions to check/validate the data. * Handles parsing/copying the `extra_nan_attrs`. My concern centers on how these `extra_nan_attrs` are handled, particularly memory allocation, copying, and any interaction with user-provided data. I need to know where the data comes from, how it's validated, how it's copied (is `kmemdup` used correctly, or are there potential buffer overflows?), and how it's used downstream. User-supplied attributes are always a prime target for fuzzing. I'm thinking, in terms of risk assessment, that the `extra_nan_attrs` will be a significant attack vector. Also, the patch has logic to handle beacon and the data can be manipulated. If a malicious packet gets the data on the network, it would create more attack vectors. Given the scope and the introduction of new data structures and control flows related to Wi-Fi Aware IC mode, the addition of potentially user-controlled `extra_nan_attrs`, and the potential for memory corruption, a dedicated KMSAN fuzzing session is likely *justified*. I'd like to do the following: 1. Search for the occurrences of `extra_nan_attrs`. 2. Review the code handling `instant_comm`, focusing on validation and data copying. 3. Design a fuzzing campaign focused on crafting malicious NAN beacons with malformed attributes. |
| 32/3 | 2026/10/04 13:47 | tool | grepper |
0mArgs:{
"Expression": "extra_nan_attrs"
}Results: {
"Output": "drivers/net/wireless/intel/iwlwifi/mld/nan.c=146=static int iwl_mld_nan_config(struct iwl_mld *mld,\n--\ndrivers/net/wireless/intel/iwlwifi/mld/nan.c-202-\ndrivers/net/wireless/intel/iwlwifi/mld/nan.c:203:\tif (conf-\u003eextra_nan_attrs_len || conf-\u003evendor_elems_len) {\ndrivers/net/wireless/intel/iwlwifi/mld/nan.c:204:\t\tdata = kmalloc(conf-\u003eextra_nan_attrs_len +\ndrivers/net/wireless/intel/iwlwifi/mld/nan.c-205-\t\t\t conf-\u003evendor_elems_len, GFP_KERNEL);\n--\ndrivers/net/wireless/intel/iwlwifi/mld/nan.c-208-\ndrivers/net/wireless/intel/iwlwifi/mld/nan.c:209:\t\tcmd.nan_attr_len = cpu_to_le32(conf-\u003eextra_nan_attrs_len);\ndrivers/net/wireless/intel/iwlwifi/mld/nan.c-210-\t\tcmd.nan_vendor_elems_len = cpu_to_le32(conf-\u003evendor_elems_len);\ndrivers/net/wireless/intel/iwlwifi/mld/nan.c-211-\ndrivers/net/wireless/intel/iwlwifi/mld/nan.c:212:\t\tif (conf-\u003eextra_nan_attrs_len)\ndrivers/net/wireless/intel/iwlwifi/mld/nan.c:213:\t\t\tmemcpy(data, conf-\u003eextra_nan_attrs,\ndrivers/net/wireless/intel/iwlwifi/mld/nan.c:214:\t\t\t conf-\u003eextra_nan_attrs_len);\ndrivers/net/wireless/intel/iwlwifi/mld/nan.c-215-\ndrivers/net/wireless/intel/iwlwifi/mld/nan.c-216-\t\tif (conf-\u003evendor_elems_len)\ndrivers/net/wireless/intel/iwlwifi/mld/nan.c:217:\t\t\tmemcpy(data + conf-\u003eextra_nan_attrs_len,\ndrivers/net/wireless/intel/iwlwifi/mld/nan.c-218-\t\t\t conf-\u003evendor_elems,\n--\ndrivers/net/wireless/intel/iwlwifi/mld/nan.c-228-\treturn iwl_mld_nan_send_config_cmd(mld, \u0026cmd, data,\ndrivers/net/wireless/intel/iwlwifi/mld/nan.c:229:\t\t\t\t\t conf-\u003eextra_nan_attrs_len +\ndrivers/net/wireless/intel/iwlwifi/mld/nan.c-230-\t\t\t\t\t conf-\u003evendor_elems_len);\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=738=mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-778-\tif (is_discovery)\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:779:\t\tnan_ie.len += data-\u003enan.extra_nan_attrs_len;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-780-\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-823-\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:824:\tif (is_discovery \u0026\u0026 data-\u003enan.extra_nan_attrs_len)\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:825:\t\tskb_put_data(skb, data-\u003enan.extra_nan_attrs,\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:826:\t\t\t data-\u003enan.extra_nan_attrs_len);\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-827-\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=978=static int mac80211_hwsim_nan_set_config(struct mac80211_hwsim_data *data,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-980-{\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:981:\tconst u8 *extra_nan_attrs = NULL;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-982-\tconst u8 *old;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-983-\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:984:\tif (conf-\u003eextra_nan_attrs_len \u003e NAN_BEACON_EXTRA_ATTRS_LEN)\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-985-\t\treturn -EINVAL;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-986-\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:987:\tif (conf-\u003eextra_nan_attrs_len) {\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:988:\t\textra_nan_attrs = kmemdup(conf-\u003eextra_nan_attrs,\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:989:\t\t\t\t\t conf-\u003eextra_nan_attrs_len,\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-990-\t\t\t\t\t GFP_KERNEL);\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:991:\t\tif (!extra_nan_attrs)\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-992-\t\t\treturn -ENOMEM;\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1006-\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:1007:\t\told = data-\u003enan.extra_nan_attrs;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:1008:\t\tdata-\u003enan.extra_nan_attrs = extra_nan_attrs;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:1009:\t\tdata-\u003enan.extra_nan_attrs_len = conf-\u003eextra_nan_attrs_len;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1010-\t}\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=1066=int mac80211_hwsim_nan_stop(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1081-\tscoped_guard(spinlock_bh, \u0026data-\u003enan.state_lock) {\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:1082:\t\told = data-\u003enan.extra_nan_attrs;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:1083:\t\tdata-\u003enan.extra_nan_attrs = NULL;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:1084:\t\tdata-\u003enan.extra_nan_attrs_len = 0;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1085-\t\tdata-\u003enan.instant_comm = false;\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h=22=struct mac80211_hwsim_nan_data {\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h-34-\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h:35:\tconst u8 *extra_nan_attrs;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h:36:\tu16 extra_nan_attrs_len;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h-37-\n--\ninclude/net/cfg80211.h=4165=struct cfg80211_nan_band_config {\n--\ninclude/net/cfg80211.h-4193- *\t\u0026enum nl80211_band values.\ninclude/net/cfg80211.h:4194: * @extra_nan_attrs: pointer to additional NAN attributes.\ninclude/net/cfg80211.h:4195: * @extra_nan_attrs_len: length of the additional NAN attributes.\ninclude/net/cfg80211.h-4196- * @vendor_elems: pointer to vendor-specific elements.\n--\ninclude/net/cfg80211.h=4199=struct cfg80211_nan_conf {\n--\ninclude/net/cfg80211.h-4208-\tstruct cfg80211_nan_band_config band_cfgs[NUM_NL80211_BANDS];\ninclude/net/cfg80211.h:4209:\tconst u8 *extra_nan_attrs;\ninclude/net/cfg80211.h:4210:\tu16 extra_nan_attrs_len;\ninclude/net/cfg80211.h-4211-\tconst u8 *vendor_elems;\n--\nnet/mac80211/cfg.c=327=static void ieee80211_nan_conf_free(struct cfg80211_nan_conf *conf)\nnet/mac80211/cfg.c-328-{\nnet/mac80211/cfg.c:329:\tkfree(conf-\u003eextra_nan_attrs);\nnet/mac80211/cfg.c-330-\tkfree(conf-\u003evendor_elems);\n--\nnet/mac80211/cfg.c=351=static int ieee80211_nan_conf_copy(struct cfg80211_nan_conf *dst,\n--\nnet/mac80211/cfg.c-370-\nnet/mac80211/cfg.c:371:\t\tkfree(dst-\u003eextra_nan_attrs);\nnet/mac80211/cfg.c:372:\t\tdst-\u003eextra_nan_attrs = NULL;\nnet/mac80211/cfg.c:373:\t\tdst-\u003eextra_nan_attrs_len = 0;\nnet/mac80211/cfg.c-374-\n--\nnet/mac80211/cfg.c-381-\nnet/mac80211/cfg.c:382:\t\tif (src-\u003eextra_nan_attrs \u0026\u0026 src-\u003eextra_nan_attrs_len) {\nnet/mac80211/cfg.c:383:\t\t\tdst-\u003eextra_nan_attrs = kmemdup(src-\u003eextra_nan_attrs,\nnet/mac80211/cfg.c:384:\t\t\t\t\t\t src-\u003eextra_nan_attrs_len,\nnet/mac80211/cfg.c-385-\t\t\t\t\t\t GFP_KERNEL);\nnet/mac80211/cfg.c:386:\t\t\tif (!dst-\u003eextra_nan_attrs)\nnet/mac80211/cfg.c-387-\t\t\t\tgoto no_mem;\nnet/mac80211/cfg.c-388-\nnet/mac80211/cfg.c:389:\t\t\tdst-\u003eextra_nan_attrs_len = src-\u003eextra_nan_attrs_len;\nnet/mac80211/cfg.c-390-\t\t}\n--\nnet/wireless/nl80211.c=16548=static int nl80211_parse_nan_conf(struct wiphy *wiphy,\n--\nnet/wireless/nl80211.c-16610-\tif (attrs[NL80211_NAN_CONF_EXTRA_ATTRS]) {\nnet/wireless/nl80211.c:16611:\t\tconf-\u003eextra_nan_attrs =\nnet/wireless/nl80211.c-16612-\t\t\tnla_data(attrs[NL80211_NAN_CONF_EXTRA_ATTRS]);\nnet/wireless/nl80211.c:16613:\t\tconf-\u003eextra_nan_attrs_len =\nnet/wireless/nl80211.c-16614-\t\t\tnla_len(attrs[NL80211_NAN_CONF_EXTRA_ATTRS]);\n"
} |
| 33/3 | 2026/10/04 13:47 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 19911 output: 50 thoughts: 383 Thoughts: **Analyzing NAN Beacon Transmission in mac80211_hwsim** Okay, so I've been tracing the path of NAN configuration, and I've just revisited how the NAN beacon is actually built and transmitted. I've already confirmed that `extra_nan_attrs` gets parsed from the netlink attributes in `nl80211_parse_nan_conf()`, which is good. Now, I'm specifically looking at the function `mac80211_hwsim_nan_tx_beacon()` and making sure everything makes sense. It looks like the initial allocation size for the SKB is calculated with this overhead plus the beacon and the `NAN_BEACON_ELEM_LEN`. Seems reasonable so far. Then, if it's a discovery beacon, it adds the `NAN_BEACON_EXTRA_ATTRS_LEN`. That makes sense. I see the allocation with `alloc_skb()` using the calculated `alloc_size`. Aha! Now I see what's happening. The function locks `data->nan.state_lock`, which makes sense for concurrency. Inside the conditional block, if the beacon is a discovery beacon, it appends the user-space configured attributes to the mandatory ones. Specifically, the length of the `nan_ie` is updated, based on the `data->nan.extra_nan_attrs_len`. Then, if `extra_nan_attrs_len` is non-zero, it puts those extra attributes into the SKB. Seems straightforward enough. The code snippet looks good and the logic appears sound, but to be sure I am reviewing this correctly, I will need to check the entire beacon build to make sure no errors exist. Now, let's dive into `drivers/net/wireless/virtual/mac80211_hwsim_nan.c` to fully understand `mac80211_hwsim_nan_tx_beacon()` and how the beacon frame is assembled. This will give me the complete picture. |
| 34/3 | 2026/10/04 13:47 | tool | read-file |
0mArgs:{
"File": "drivers/net/wireless/virtual/mac80211_hwsim_nan.c",
"FirstLine": 730,
"LineCount": 100
}Results: {
"Contents": " 730:\t\n 731:\t\tif (notify_join)\n 732:\t\t\tieee80211_nan_cluster_joined(data-\u003enan.device_vif,\n 733:\t\t\t\t\t\t data-\u003enan.cluster_id, true,\n 734:\t\t\t\t\t\t GFP_ATOMIC);\n 735:\t}\n 736:\t\n 737:\tstatic void\n 738:\tmac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,\n 739:\t\t\t\t bool is_discovery,\n 740:\t\t\t\t struct ieee80211_channel *channel)\n 741:\t{\n 742:\t\tstruct ieee80211_vendor_ie nan_ie = {\n 743:\t\t\t.element_id = WLAN_EID_VENDOR_SPECIFIC,\n 744:\t\t\t.len = NAN_BEACON_ELEM_LEN - 2,\n 745:\t\t\t.oui = { u32_get_bits(WLAN_OUI_WFA, 0xff0000),\n 746:\t\t\t\t u32_get_bits(WLAN_OUI_WFA, 0xff00),\n 747:\t\t\t\t u32_get_bits(WLAN_OUI_WFA, 0xff) },\n 748:\t\t\t.oui_type = WLAN_OUI_TYPE_WFA_NAN,\n 749:\t\t};\n 750:\t\tsize_t alloc_size =\n 751:\t\t\tIEEE80211_TX_STATUS_HEADROOM +\n 752:\t\t\toffsetofend(struct ieee80211_mgmt, u.beacon) +\n 753:\t\t\tNAN_BEACON_ELEM_LEN;\n 754:\t\tstruct ieee80211_nan_master_indication master_indication;\n 755:\t\tstruct ieee80211_nan_attr nan_attr;\n 756:\t\tstruct ieee80211_mgmt *mgmt;\n 757:\t\tstruct sk_buff *skb;\n 758:\t\n 759:\t\t/*\n 760:\t\t * TODO: Should the configured vendor elements be included in some of\n 761:\t\t * these beacons?\n 762:\t\t */\n 763:\t\n 764:\t\t/* Allocate maximal size for NAN IE */\n 765:\t\tif (is_discovery)\n 766:\t\t\talloc_size += NAN_BEACON_EXTRA_ATTRS_LEN;\n 767:\t\n 768:\t\tskb = alloc_skb(alloc_size, GFP_ATOMIC);\n 769:\t\tif (!skb)\n 770:\t\t\treturn;\n 771:\t\n 772:\t\tspin_lock(\u0026data-\u003enan.state_lock);\n 773:\t\n 774:\t\t/*\n 775:\t\t * The attributes configured by user space are appended to the\n 776:\t\t * mandatory ones.\n 777:\t\t */\n 778:\t\tif (is_discovery)\n 779:\t\t\tnan_ie.len += data-\u003enan.extra_nan_attrs_len;\n 780:\t\n 781:\t\tskb_reserve(skb, IEEE80211_TX_STATUS_HEADROOM);\n 782:\t\tmgmt = skb_put(skb, offsetofend(struct ieee80211_mgmt, u.beacon));\n 783:\t\n 784:\t\tmemset(mgmt, 0, offsetofend(struct ieee80211_mgmt, u.beacon));\n 785:\t\tmemcpy(mgmt-\u003esa, data-\u003enan.device_vif-\u003eaddr, ETH_ALEN);\n 786:\t\tmemset(mgmt-\u003eda, 0xff, ETH_ALEN);\n 787:\t\tmemcpy(mgmt-\u003ebssid, data-\u003enan.cluster_id, ETH_ALEN);\n 788:\t\n 789:\t\tmgmt-\u003eframe_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |\n 790:\t\t\t\t\t\t IEEE80211_STYPE_BEACON);\n 791:\t\tmgmt-\u003eu.beacon.beacon_int =\n 792:\t\t\tcpu_to_le16(is_discovery ? data-\u003enan.discovery_beacon_interval :\n 793:\t\t\t\t DWST_TU);\n 794:\t\tmgmt-\u003eu.beacon.capab_info =\n 795:\t\t\tcpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME |\n 796:\t\t\t\t WLAN_CAPABILITY_SHORT_PREAMBLE);\n 797:\t\n 798:\t\t/* FIXME: set these to saner values? */\n 799:\t\tmgmt-\u003eduration = 0;\n 800:\t\tmgmt-\u003eseq_ctrl = 0;\n 801:\t\n 802:\t\t/* Put the NAN element */\n 803:\t\tskb_put_data(skb, \u0026nan_ie, sizeof(nan_ie));\n 804:\t\n 805:\t\tnan_attr.attr = NAN_ATTR_MASTER_INDICATION;\n 806:\t\tnan_attr.length = cpu_to_le16(sizeof(master_indication));\n 807:\t\tif (data-\u003enan.phase == MAC80211_HWSIM_NAN_PHASE_UP) {\n 808:\t\t\tmaster_indication.master_pref = data-\u003enan.master_pref;\n 809:\t\t\tmaster_indication.random_factor = data-\u003enan.random_factor;\n 810:\t\t} else {\n 811:\t\t\tmaster_indication.master_pref = 0;\n 812:\t\t\tmaster_indication.random_factor = 0;\n 813:\t\t}\n 814:\t\n 815:\t\tskb_put_data(skb, \u0026nan_attr, sizeof(nan_attr));\n 816:\t\tskb_put_data(skb, \u0026master_indication, sizeof(master_indication));\n 817:\t\n 818:\t\tnan_attr.attr = NAN_ATTR_CLUSTER_INFO;\n 819:\t\tnan_attr.length = cpu_to_le16(sizeof(data-\u003enan.current_ami));\n 820:\t\tskb_put_data(skb, \u0026nan_attr, sizeof(nan_attr));\n 821:\t\tskb_put_data(skb, \u0026data-\u003enan.current_ami,\n 822:\t\t\t sizeof(data-\u003enan.current_ami));\n 823:\t\n 824:\t\tif (is_discovery \u0026\u0026 data-\u003enan.extra_nan_attrs_len)\n 825:\t\t\tskb_put_data(skb, data-\u003enan.extra_nan_attrs,\n 826:\t\t\t\t data-\u003enan.extra_nan_attrs_len);\n 827:\t\n 828:\t\tspin_unlock(\u0026data-\u003enan.state_lock);\n 829:\t\n"
} |
| 35/3 | 2026/10/04 13:47 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 22585 output: 42 thoughts: 173 Thoughts: **Analyzing the `mac80211_hwsim_nan_tx_beacon()` Function and Potential Data Structure Padding**
Okay, so I'm diving into `mac80211_hwsim_nan_tx_beacon()` and right away, I see that it uses `struct ieee80211_nan_attr nan_attr`. My brain immediately flags this – I've been burned by structure padding too many times! My first thought is: does this structure contain any padding? That could mess things up with memory layout. So, I need to verify its definition. Let's see... looking at the definition of `struct ieee80211_nan_attr`, here it is:
```c
struct ieee80211_nan_attr {
u8 attr;
__le16 length;
u8 data[];
} __packed;
```
Aha! It *is* packed! The `__packed` attribute means the compiler won't insert any padding bytes for alignment. That's a relief. It looks like we should be good to go.
|
| 36/3 | 2026/10/04 13:47 | tool | read-file |
0mArgs:{
"File": "include/linux/ieee80211-nan.h",
"FirstLine": 40,
"LineCount": 40
}Results: {
"Contents": " 40:\t/* NAN attributes, as defined in Wi-Fi Aware (TM) specification 4.0 Table 42 */\n 41:\t#define NAN_ATTR_MASTER_INDICATION\t\t0x00\n 42:\t#define NAN_ATTR_CLUSTER_INFO\t\t\t0x01\n 43:\t#define NAN_ATTR_SERVICE_ID_LIST\t\t0x02\n 44:\t#define NAN_ATTR_SUBSCRIBE_SERVICE_ID_LIST\t0x28\n 45:\t\n 46:\tstruct ieee80211_nan_attr {\n 47:\t\tu8 attr;\n 48:\t\t__le16 length;\n 49:\t\tu8 data[];\n 50:\t} __packed;\n 51:\t\n 52:\tstruct ieee80211_nan_master_indication {\n 53:\t\tu8 master_pref;\n 54:\t\tu8 random_factor;\n 55:\t} __packed;\n 56:\t\n 57:\tstruct ieee80211_nan_anchor_master_info {\n 58:\t\tunion {\n 59:\t\t\t__le64 master_rank;\n 60:\t\t\tstruct {\n 61:\t\t\t\tu8 master_addr[ETH_ALEN];\n 62:\t\t\t\tu8 random_factor;\n 63:\t\t\t\tu8 master_pref;\n 64:\t\t\t} __packed;\n 65:\t\t} __packed;\n 66:\t\tu8 hop_count;\n 67:\t\t__le32 ambtt;\n 68:\t} __packed;\n 69:\t\n 70:\t#define for_each_nan_attr(_attr, _data, _datalen)\t\t\t\\\n 71:\t\tfor (_attr = (const struct ieee80211_nan_attr *)(_data);\t\\\n 72:\t\t (const u8 *)(_data) + (_datalen) - (const u8 *)_attr \u003e=\t\\\n 73:\t\t\t(int)sizeof(*_attr) \u0026\u0026\t\t\t\t\t\\\n 74:\t\t (const u8 *)(_data) + (_datalen) - (const u8 *)_attr \u003e=\t\\\n 75:\t\t\t(int)sizeof(*_attr) + le16_to_cpu(_attr-\u003elength);\t\\\n 76:\t\t _attr = (const struct ieee80211_nan_attr *)\t\t\\\n 77:\t\t\t(_attr-\u003edata + le16_to_cpu(_attr-\u003elength)))\n 78:\t\n 79:\tstatic inline bool ieee80211_is_nan_beacon(const struct ieee80211_mgmt *mgmt,\n"
} |
| 37/3 | 2026/10/04 13:47 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 23723 output: 23 thoughts: 1448 Thoughts: **Analyzing NAN Beacon Transmission and Attribute Handling** Okay, so I'm looking at this code and it's all `__packed`, which is good. Focusing on `mac80211_hwsim_nan_tx_beacon()`, I'm tracing the data flow for NAN beacon transmission. It seems like the core issue revolves around how extra attributes provided by userspace are handled and included in the beacon frame. Initially, I see that the `nan_attr` was already present. Now, the key is `data->nan.extra_nan_attrs`. This seems to be where the user-provided attributes come into play. `mac80211_hwsim_nan_set_config()` checks the length of these `extra_nan_attrs` and limits it to `NAN_BEACON_EXTRA_ATTRS_LEN`. A `kmemdup` is used to create a copy from the userspace buffer. Digging into `nl80211_parse_nan_conf`, I see that `conf->extra_nan_attrs` comes directly from netlink attributes sent by userspace, and it's a direct copy with `kmemdup`. Back in `mac80211_hwsim_nan_tx_beacon()`, the code then uses `skb_put_data` to put this user-provided data into the skb (the network buffer). I'm tracking the lengths here, noticing the interplay between `nan_ie.len`, which is initialized to `NAN_BEACON_ELEM_LEN - 2`, and potentially incremented by `data->nan.extra_nan_attrs_len` if it's a discovery beacon. The `alloc_size` calculation is crucial here. I see that it includes a base size plus `NAN_BEACON_EXTRA_ATTRS_LEN` (which is calculated as 230). So `alloc_size` seems large enough to include user-supplied attributes. Looking at the contents of the `skb`, I can see that all data is correctly initialized. The skb is then transmitted. Next, I'm checking `hwsim_nan_beacon_has_service_ids()`. This function seems to parse the beacon to check for service IDs. I'm focusing on the checks within this function. I am checking the `for_each_element_id` and `for_each_nan_attr` macros and element bounds checking. I need to make sure those checks are robust. And I'm looking for where `for_each_element_id` is defined. |
| 38/3 | 2026/10/04 13:47 | tool | grepper |
0mArgs:{
"Expression": "#define for_each_element_id"
}Results: {
"Output": "include/linux/ieee80211.h=2727=struct element {\n--\ninclude/linux/ieee80211.h-2741-\ninclude/linux/ieee80211.h:2742:#define for_each_element_id(element, _id, data, datalen)\t\t\\\ninclude/linux/ieee80211.h-2743-\tfor_each_element(element, data, datalen)\t\t\t\\\n"
} |
| 39/3 | 2026/10/04 13:47 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 25885 output: 42 thoughts: 40 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience: **Diving into the 802.11 Header Definitions** Right, before I go any further, I need to ground myself in the specifics. I know these functions like the back of my hand, but it's always worth double-checking the definitions of `for_each_element` and `for_each_element_id` within `include/linux/ieee80211.h`. Context is everything, and a quick review will refresh the memory on the exact structures and types involved. It's too easy to make assumptions, especially with those iterator macros – a quick peek will help ensure I'm keeping everything straight and avoid wasting time hunting down a trivial error later. Let's see what those macros are actually doing under the hood, I'm thinking about the implications for memory management and potential race conditions specifically. Better to be safe than sorry, I suppose. |
| 40/3 | 2026/10/04 13:47 | tool | read-file |
0mArgs:{
"File": "include/linux/ieee80211.h",
"FirstLine": 2725,
"LineCount": 30
}Results: {
"Contents": "2725:\t}\n2726:\t\n2727:\tstruct element {\n2728:\t\tu8 id;\n2729:\t\tu8 datalen;\n2730:\t\tu8 data[];\n2731:\t} __packed;\n2732:\t\n2733:\t/* element iteration helpers */\n2734:\t#define for_each_element(_elem, _data, _datalen)\t\t\t\\\n2735:\t\tfor (_elem = (const struct element *)(_data);\t\t\t\\\n2736:\t\t (const u8 *)(_data) + (_datalen) - (const u8 *)_elem \u003e=\t\\\n2737:\t\t\t(int)sizeof(*_elem) \u0026\u0026\t\t\t\t\t\\\n2738:\t\t (const u8 *)(_data) + (_datalen) - (const u8 *)_elem \u003e=\t\\\n2739:\t\t\t(int)sizeof(*_elem) + _elem-\u003edatalen;\t\t\t\\\n2740:\t\t _elem = (const struct element *)(_elem-\u003edata + _elem-\u003edatalen))\n2741:\t\n2742:\t#define for_each_element_id(element, _id, data, datalen)\t\t\\\n2743:\t\tfor_each_element(element, data, datalen)\t\t\t\\\n2744:\t\t\tif (element-\u003eid == (_id))\n2745:\t\n2746:\t#define for_each_element_extid(element, extid, _data, _datalen)\t\t\\\n2747:\t\tfor_each_element(element, _data, _datalen)\t\t\t\\\n2748:\t\t\tif (element-\u003eid == WLAN_EID_EXTENSION \u0026\u0026\t\t\\\n2749:\t\t\t element-\u003edatalen \u003e 0 \u0026\u0026\t\t\t\t\\\n2750:\t\t\t element-\u003edata[0] == (extid))\n2751:\t\n2752:\t#define for_each_subelement(sub, element)\t\t\t\t\\\n2753:\t\tfor_each_element(sub, (element)-\u003edata, (element)-\u003edatalen)\n2754:\t\n"
} |
| 41/3 | 2026/10/04 13:47 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 26713 output: 27 thoughts: 807 Thoughts: **Analyzing NAN Frame Handling in mac80211_hwsim**
Okay, let's break this down systematically. First, I need to understand how the Network Awareness Networking (NAN) attributes are parsed. The `for_each_nan_attr` macro looks like a good starting point. Right, it iterates through a buffer of NAN attributes, ensuring that there's enough space remaining in the buffer for the current attribute and its associated length field. Specifically, it verifies that the remaining data is at least the size of the attribute struct itself, plus the attribute's length. I need to keep that size calculation in mind. The macro also seems to handle the basic integrity check of `_attr->attr` in the loop condition, nice.
Now, let's trace where these attributes are processed. I'm focusing on the `mac80211_hwsim_nan_receive` function. Okay, it receives an `skb` (socket buffer), which presumably contains the NAN frame. And if `instant_comm` is set and the frame has service IDs, then return true.
Where is `mac80211_hwsim_nan_receive` called? Tracing it, I see that it's called within `mac80211_hwsim_tx_iter`. This function is part of the transmission iteration, which makes sense. If the virtual interface is NAN or NAN_DATA, the `receive` flag is set by a call to `mac80211_hwsim_nan_receive`.
So, where does that `skb` in `mac80211_hwsim_nan_receive` originate? Looking at the definition of `mac80211_hwsim_tx_iter`, I see that it is passed in as part of the `tx_iter_data` structure. Now, where is `tx_iter_data` initialized? There are two places: `mac80211_hwsim_tx_frame_no_nl` and `hwsim_cloned_frame_received_nl`. In both cases, the `skb` is passed in to the `tx_iter_data` struct.
Important question: Is the struct `iter_data` completely initialized, including the `receive` flag or is that a stack-initialized member? Looking at the code, it uses the designated initializer syntax: `struct tx_iter_data iter_data = { ... };`. That means all unspecified fields are zero-initialized. Therefore, the `receive` field will be initialized to `false` unless explicitly set.
Finally, I need to check if there are other callers of `mac80211_hwsim_tx_iter` that I'm missing!
|
| 42/3 | 2026/10/04 13:48 | tool | grepper |
0mArgs:{
"Expression": "mac80211_hwsim_tx_iter"
}Results: {
"Output": "drivers/net/wireless/virtual/mac80211_hwsim_main.c=1771=struct tx_iter_data {\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-1778-\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:1779:static void mac80211_hwsim_tx_iter(void *_data, u8 *addr,\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-1780-\t\t\t\t struct ieee80211_vif *vif)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=1904=static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-1998-\t\t\t\tdata2-\u003ehw, IEEE80211_IFACE_ITER_NORMAL,\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:1999:\t\t\t\tmac80211_hwsim_tx_iter, \u0026tx_iter_data);\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-2000-\t\t\tif (!tx_iter_data.receive)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c=6488=static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-6571-\t\t\t\tdata2-\u003ehw, IEEE80211_IFACE_ITER_NORMAL,\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c:6572:\t\t\t\tmac80211_hwsim_tx_iter, \u0026iter_data);\ndrivers/net/wireless/virtual/mac80211_hwsim_main.c-6573-\t\t\tif (!iter_data.receive) {\n"
} |
| 43/3 | 2026/10/04 13:48 | llm | kmsan-evaluator |
1mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 28704 output: 37 thoughts: 1559 Thoughts: **Analyzing Potential Vulnerabilities in NAN Beacon Handling** Okay, so I'm looking at `mac80211_hwsim_tx_iter` and how it uses the `skb`. It appears both callers initialize `.skb = skb`. My primary concern now is centered on `ieee80211_is_nan_beacon`. Let's dive into its implementation. First, I see the check for minimum length: `len < offsetofend(struct ieee80211_mgmt, u.beacon) + 6`. It ensures there are enough bytes to check. The function then verifies it's actually a beacon and checks the BSSID for a specific OUI and cluster ID range. The key part is examining the Vendor Specific Information Element (IE). I see `elem = (const struct element *)mgmt->u.beacon.variable;`. Okay, is reading `elem->datalen` safe here? Given `len` is at least `offsetofend(...) + 6`, and `mgmt->u.beacon.variable` starts at `offsetofend(...)`, this implies a minimum of 6 bytes are available. The `struct element` contains `id` (1 byte), `datalen` (1 byte), and `data[]`. Reading `elem->id` and `elem->datalen` (offsets 0 and 1) are thus within bounds. Now, if `elem->datalen` is at least 4, `elem->data` is 4 bytes, and `get_unaligned_be32(elem->data)` reads those 4 bytes. Ah, but what if `elem->datalen` is large, but `len` is small? For example, if `elem->datalen` is 100, and `len` is only `offsetofend(...) + 6`, it doesn't matter. The important thing is that, since the minimum `len` guarantees at least `offsetofend(...) + 6`, and `elem->data` begins at offset 2, the 4 bytes needed for `elem->data` are always within the bounds: `offsetofend(...) + 2 + 4 == offsetofend(...) + 6 <= len`. The check that `elem->datalen >= 4` ensures we are trying to read 4 bytes of valid data. Therefore, the read is safe. Next question: could `skb->data` or `mgmt` contain uninitialized memory? No. The `skb` is coming over the network (or virtual bus), and therefore the packet data is initialized, either from userspace or packet generation. Received `skb` data is always initialized in the Linux kernel networking stack, either allocated or received. Also, the function only returns a `bool`, which doesn't leak data to userspace. Okay, let's look at how this is used within `ieee80211_accept_frame()`. The call to `ieee80211_is_nan_beacon` determines if the frame is accepted if `sdata->u.nan.conf.instant_comm` is set. Then, if `instant_comm` is set, the frame is accepted for a `NL80211_IFTYPE_NAN` interface. And in `ieee80211_default_mgmt_stypes`, beacon Rx registration happens, allowing user space to handle service discovery when Instant Communication is enabled. So, the beacons are delivered to user space. This brings me to `nl80211_parse_nan_conf`. If `instant_comm` is enabled, the code verifies the hardware supports Instant Communication and that a `discovery_beacon_interval` is set. I need to understand where `conf->discovery_beacon_interval` is initialized or parsed. Looks like I have to check `nl80211_parse_nan_conf` to find out. |
| 44/3 | 2026/10/04 13:49 | tool | grepper |
0mArgs:{
"Expression": "discovery_beacon_interval",
"PathPrefix": "net/wireless/nl80211.c"
}Results: {
"Output": "net/wireless/nl80211.c=16548=static int nl80211_parse_nan_conf(struct wiphy *wiphy,\n--\nnet/wireless/nl80211.c-16663-\tif (attrs[NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL])\nnet/wireless/nl80211.c:16664:\t\tconf-\u003ediscovery_beacon_interval =\nnet/wireless/nl80211.c-16665-\t\t\tnla_get_u8(attrs[NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL]);\n--\nnet/wireless/nl80211.c-16679-\nnet/wireless/nl80211.c:16680:\t\tif (!conf-\u003ediscovery_beacon_interval) {\nnet/wireless/nl80211.c-16681-\t\t\tNL_SET_ERR_MSG_ATTR(info-\u003eextack,\n"
} |
| 45/3 | 2026/10/04 13:49 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 31409 output: 26 thoughts: 40 Thoughts: Okay, let's break this down. **Investigating the `nl80211_parse_nan_conf` Function** Alright, my immediate focus is on understanding the interaction with this `nl80211_parse_nan_conf` function. I need to trace its callers. I'll need to know where it's being invoked to grasp its context and purpose. This is step one, and crucial for anything more in-depth. My next line of investigation concerns the `struct cfg80211_nan_conf conf` variable. Specifically, I need to know *where* this configuration structure is being allocated. Is it stack-allocated, heap-allocated, perhaps part of a larger structure? Understanding the scope and lifetime of this `conf` variable is critical. That'll inform my understanding of how this config is initialized and, ultimately, utilized. |
| 46/3 | 2026/10/04 13:49 | tool | grepper |
0mArgs:{
"Expression": "nl80211_parse_nan_conf"
}Results: {
"Output": "net/wireless/nl80211.c=16502=static int nl80211_parse_nan_band_config(struct wiphy *wiphy,\n--\nnet/wireless/nl80211.c-16547-\nnet/wireless/nl80211.c:16548:static int nl80211_parse_nan_conf(struct wiphy *wiphy,\nnet/wireless/nl80211.c-16549-\t\t\t\t struct genl_info *info,\n--\nnet/wireless/nl80211.c=16714=static int nl80211_start_nan(struct sk_buff *skb, struct genl_info *info)\n--\nnet/wireless/nl80211.c-16733-\nnet/wireless/nl80211.c:16734:\terr = nl80211_parse_nan_conf(\u0026rdev-\u003ewiphy, info, \u0026conf, NULL, true);\nnet/wireless/nl80211.c-16735-\tif (err)\n--\nnet/wireless/nl80211.c=17088=static int nl80211_nan_change_config(struct sk_buff *skb,\n--\nnet/wireless/nl80211.c-17102-\nnet/wireless/nl80211.c:17103:\terr = nl80211_parse_nan_conf(\u0026rdev-\u003ewiphy, info, \u0026conf, \u0026changed, false);\nnet/wireless/nl80211.c-17104-\tif (err)\n"
} |
| 47/3 | 2026/10/04 13:49 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 32107 output: 42 thoughts: 38 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience: **Analyzing NAN Configuration Initialization and Modification** Alright, let's get down to brass tacks. I need to quickly refresh my understanding of how the `conf` variable is handled within the NAN context. Specifically, I want to drill into its declaration and use in two key areas: `nl80211_start_nan` and `nl80211_nan_change_config`. It’s crucial to know *exactly* how the configuration data flows from the initial setup to any subsequent modifications. I need to ensure that whatever data structures or context are passed around are correctly initialized, thread-safe (if applicable), and handled with the right locking (if multi-threaded). I also want to make sure the right data is getting passed to the driver, as a misconfiguration here can cause serious issues with the NAN setup. I need to make sure I am not missing anything that could result in unexpected behavior. I'm especially interested in the scope and lifetime of `conf` in each of these functions; is it a stack variable, dynamically allocated, shared across multiple calls, etc? This is fundamental to avoiding any memory corruption, resource leaks, or unexpected interactions. I'll need to pay close attention to the data types involved, to guarantee all data is transferred safely. |
| 48/3 | 2026/10/04 13:49 | tool | read-file |
0mArgs:{
"File": "net/wireless/nl80211.c",
"FirstLine": 16715,
"LineCount": 25
}Results: {
"Contents": "16715:\t{\n16716:\t\tstruct cfg80211_registered_device *rdev = info-\u003euser_ptr[0];\n16717:\t\tstruct wireless_dev *wdev = info-\u003euser_ptr[1];\n16718:\t\tstruct cfg80211_nan_conf conf = {};\n16719:\t\tint err;\n16720:\t\n16721:\t\tif (wdev-\u003eiftype != NL80211_IFTYPE_NAN)\n16722:\t\t\treturn -EOPNOTSUPP;\n16723:\t\n16724:\t\tif (wdev_running(wdev))\n16725:\t\t\treturn -EEXIST;\n16726:\t\n16727:\t\tif (rfkill_blocked(rdev-\u003ewiphy.rfkill))\n16728:\t\t\treturn -ERFKILL;\n16729:\t\n16730:\t\t/* Master preference is mandatory for START_NAN */\n16731:\t\tif (!info-\u003eattrs[NL80211_ATTR_NAN_MASTER_PREF])\n16732:\t\t\treturn -EINVAL;\n16733:\t\n16734:\t\terr = nl80211_parse_nan_conf(\u0026rdev-\u003ewiphy, info, \u0026conf, NULL, true);\n16735:\t\tif (err)\n16736:\t\t\treturn err;\n16737:\t\n16738:\t\terr = rdev_start_nan(rdev, wdev, \u0026conf);\n16739:\t\tif (err)\n"
} |
| 49/3 | 2026/10/04 13:49 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 32902 output: 42 thoughts: 45 Thoughts: Okay, here's my take on those thoughts, framed as a first-person expert summary:
**Initial Configuration and Verification**
Alright, so the `cfg80211_nan_conf conf = {};` line... that's a classic zero-initialization. Good. It's the standard, safe practice to ensure a clean slate for the configuration structure. No surprises there. I'm glad to see it, because a misconfigured NAN (Neighbor Awareness Networking) structure could lead to some nasty unexpected behaviors down the line, and that is absolutely the last thing I need to debug.
Then, moving on to the `nl80211_nan_change_config` function... it makes sense to revisit the initialization within that context as well. We need to be absolutely certain the NAN configuration is as intended as we're making these changes. That function is the entry point for changing the NAN configuration via the nl80211 interface, so it *must* start with a well-defined initial state. Double-checking the zero-initialization there is just smart, proactive coding. It's a key sanity check. Prevents any uninitialized memory from causing issues. Proper initialization is the foundation. It's all about robustness and preventing subtle, difficult-to-track-down bugs. Good. Good.
|
| 50/3 | 2026/10/04 13:49 | tool | read-file |
0mArgs:{
"File": "net/wireless/nl80211.c",
"FirstLine": 17088,
"LineCount": 25
}Results: {
"Contents": "17088:\tstatic int nl80211_nan_change_config(struct sk_buff *skb,\n17089:\t\t\t\t\t struct genl_info *info)\n17090:\t{\n17091:\t\tstruct cfg80211_registered_device *rdev = info-\u003euser_ptr[0];\n17092:\t\tstruct wireless_dev *wdev = info-\u003euser_ptr[1];\n17093:\t\tstruct cfg80211_nan_conf conf = {};\n17094:\t\tu32 changed = 0;\n17095:\t\tint err;\n17096:\t\n17097:\t\tif (wdev-\u003eiftype != NL80211_IFTYPE_NAN)\n17098:\t\t\treturn -EOPNOTSUPP;\n17099:\t\n17100:\t\tif (!wdev_running(wdev))\n17101:\t\t\treturn -ENOTCONN;\n17102:\t\n17103:\t\terr = nl80211_parse_nan_conf(\u0026rdev-\u003ewiphy, info, \u0026conf, \u0026changed, false);\n17104:\t\tif (err)\n17105:\t\t\treturn err;\n17106:\t\n17107:\t\tif (!changed)\n17108:\t\t\treturn -EINVAL;\n17109:\t\n17110:\t\treturn rdev_nan_change_conf(rdev, wdev, \u0026conf, changed);\n17111:\t}\n17112:\t\n"
} |
| 51/3 | 2026/10/04 13:49 | llm | kmsan-evaluator |
1mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 33696 output: 42 thoughts: 62 Thoughts: Okay, here's my take on those thoughts, keeping in mind my expertise:
**Checking Code for Configuration Zeroing and Change Tracking**
Right, so, first observation – both approaches are using `= {};` to essentially initialize the structure. This is a quick and dirty method, but it effectively zeroes out the entire configuration. Always good to start with the basics, but it's important to understand the implications for downstream logic.
Now, that gets me thinking about `nl80211_parse_nan_conf`. Specifically, I need to know if this function actually sets the `changed` flag correctly. It's crucial for the driver to know what parts of the configuration have been modified, so it can take appropriate action. A bug here could lead to unnecessary reconfigurations or, even worse, missed updates. Time to dig in and meticulously examine the code within that function to ensure that `changed` is updated appropriately whenever a relevant parameter is changed. I want to see exactly *how* it's being updated.
|
| 52/3 | 2026/10/04 13:50 | tool | read-file |
0mArgs:{
"File": "net/wireless/nl80211.c",
"FirstLine": 16660,
"LineCount": 40
}Results: {
"Contents": "16660:\t\t\tconf-\u003escan_dwell_time =\n16661:\t\t\t\tnla_get_u16(attrs[NL80211_NAN_CONF_SCAN_DWELL_TIME]);\n16662:\t\n16663:\t\tif (attrs[NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL])\n16664:\t\t\tconf-\u003ediscovery_beacon_interval =\n16665:\t\t\t\tnla_get_u8(attrs[NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL]);\n16666:\t\n16667:\t\tif (attrs[NL80211_NAN_CONF_NOTIFY_DW])\n16668:\t\t\tconf-\u003eenable_dw_notification =\n16669:\t\t\t\tnla_get_flag(attrs[NL80211_NAN_CONF_NOTIFY_DW]);\n16670:\t\n16671:\t\tconf-\u003einstant_comm = nla_get_flag(attrs[NL80211_NAN_CONF_INSTANT_COMM]);\n16672:\t\tif (conf-\u003einstant_comm) {\n16673:\t\t\tif (!(wiphy-\u003enan_capa.flags \u0026 WIPHY_NAN_FLAGS_INSTANT_COMM)) {\n16674:\t\t\t\tNL_SET_ERR_MSG_ATTR(info-\u003eextack,\n16675:\t\t\t\t\t\t attrs[NL80211_NAN_CONF_INSTANT_COMM],\n16676:\t\t\t\t\t\t \"Instant Communication is not supported\");\n16677:\t\t\t\treturn -EOPNOTSUPP;\n16678:\t\t\t}\n16679:\t\n16680:\t\t\tif (!conf-\u003ediscovery_beacon_interval) {\n16681:\t\t\t\tNL_SET_ERR_MSG_ATTR(info-\u003eextack,\n16682:\t\t\t\t\t\t attrs[NL80211_NAN_CONF_INSTANT_COMM],\n16683:\t\t\t\t\t\t \"Instant Communication requires a discovery beacon interval\");\n16684:\t\t\t\treturn -EINVAL;\n16685:\t\t\t}\n16686:\t\t}\n16687:\t\n16688:\tout:\n16689:\t\tif (!conf-\u003eband_cfgs[NL80211_BAND_5GHZ].chan \u0026\u0026\n16690:\t\t (!conf-\u003ebands || conf-\u003ebands \u0026 BIT(NL80211_BAND_5GHZ))) {\n16691:\t\t\t/* If no 5GHz channel is specified use default, if possible */\n16692:\t\t\tconf-\u003eband_cfgs[NL80211_BAND_5GHZ].chan =\n16693:\t\t\t\t\tnl80211_get_nan_channel(wiphy, 5745);\n16694:\t\t\tif (!conf-\u003eband_cfgs[NL80211_BAND_5GHZ].chan)\n16695:\t\t\t\tconf-\u003eband_cfgs[NL80211_BAND_5GHZ].chan =\n16696:\t\t\t\t\t\tnl80211_get_nan_channel(wiphy, 5220);\n16697:\t\n16698:\t\t\t/* Return error if user space asked explicitly for 5 GHz */\n16699:\t\t\tif (!conf-\u003eband_cfgs[NL80211_BAND_5GHZ].chan \u0026\u0026\n"
} |
| 53/3 | 2026/10/04 13:50 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 34890 output: 33 thoughts: 25 Thoughts: Okay, here's my thought process, summarized as you requested: **Tracing the Source of `changed` in `nl80211_parse_nan_conf`** Alright, I need to understand how the `changed` variable is being updated within the `nl80211_parse_nan_conf` function. I know this function is critical for parsing and configuring NAN (Neighbor Awareness Networking) parameters within the nl80211 framework. Therefore, pinpointing where `changed` gets modified will give me crucial insights into which aspects of the NAN configuration are actually being... well, *changed* by the processing of the incoming netlink messages. This is the first step I need to take in assessing this part of the implementation. So, my focus is now directed on tracing the updates to the variable named `changed` inside this function. |
| 54/3 | 2026/10/04 13:50 | tool | grepper |
0mArgs:{
"Expression": "changed",
"PathPrefix": "net/wireless/nl80211.c"
}Results: {
"Output": "\nFull output is too long, showing 200 out of 233 lines.\nUse more precise expression if possible.\n\nnet/wireless/nl80211.c=4223=static int nl80211_set_wiphy_radio(struct genl_info *info,\n--\nnet/wireless/nl80211.c-4226-{\nnet/wireless/nl80211.c:4227:\tu32 rts_threshold = 0, old_rts, changed = 0;\nnet/wireless/nl80211.c-4228-\tint result;\n--\nnet/wireless/nl80211.c-4235-\t\t\t\tinfo-\u003eattrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);\nnet/wireless/nl80211.c:4236:\t\tchanged |= WIPHY_PARAM_RTS_THRESHOLD;\nnet/wireless/nl80211.c-4237-\t}\n--\nnet/wireless/nl80211.c-4242-\nnet/wireless/nl80211.c:4243:\tresult = rdev_set_wiphy_params(rdev, radio_idx, changed);\nnet/wireless/nl80211.c-4244-\tif (result)\n--\nnet/wireless/nl80211.c=4250=static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)\n--\nnet/wireless/nl80211.c-4256-\tstruct nlattr *nl_txq_params;\nnet/wireless/nl80211.c:4257:\tu32 changed;\nnet/wireless/nl80211.c-4258-\tu8 retry_short = 0, retry_long = 0;\n--\nnet/wireless/nl80211.c-4446-\nnet/wireless/nl80211.c:4447:\tchanged = 0;\nnet/wireless/nl80211.c-4448-\n--\nnet/wireless/nl80211.c-4452-\nnet/wireless/nl80211.c:4453:\t\tchanged |= WIPHY_PARAM_RETRY_SHORT;\nnet/wireless/nl80211.c-4454-\t}\n--\nnet/wireless/nl80211.c-4459-\nnet/wireless/nl80211.c:4460:\t\tchanged |= WIPHY_PARAM_RETRY_LONG;\nnet/wireless/nl80211.c-4461-\t}\n--\nnet/wireless/nl80211.c-4477-\t\t}\nnet/wireless/nl80211.c:4478:\t\tchanged |= WIPHY_PARAM_FRAG_THRESHOLD;\nnet/wireless/nl80211.c-4479-\t}\n--\nnet/wireless/nl80211.c-4483-\t\t\tinfo-\u003eattrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);\nnet/wireless/nl80211.c:4484:\t\tchanged |= WIPHY_PARAM_RTS_THRESHOLD;\nnet/wireless/nl80211.c-4485-\t}\n--\nnet/wireless/nl80211.c-4492-\t\t\tinfo-\u003eattrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);\nnet/wireless/nl80211.c:4493:\t\tchanged |= WIPHY_PARAM_COVERAGE_CLASS;\nnet/wireless/nl80211.c-4494-\t}\n--\nnet/wireless/nl80211.c-4499-\nnet/wireless/nl80211.c:4500:\t\tchanged |= WIPHY_PARAM_DYN_ACK;\nnet/wireless/nl80211.c-4501-\t}\n--\nnet/wireless/nl80211.c-4509-\t\t\tinfo-\u003eattrs[NL80211_ATTR_TXQ_LIMIT]);\nnet/wireless/nl80211.c:4510:\t\tchanged |= WIPHY_PARAM_TXQ_LIMIT;\nnet/wireless/nl80211.c-4511-\t}\n--\nnet/wireless/nl80211.c-4519-\t\t\tinfo-\u003eattrs[NL80211_ATTR_TXQ_MEMORY_LIMIT]);\nnet/wireless/nl80211.c:4520:\t\tchanged |= WIPHY_PARAM_TXQ_MEMORY_LIMIT;\nnet/wireless/nl80211.c-4521-\t}\n--\nnet/wireless/nl80211.c-4529-\t\t\tinfo-\u003eattrs[NL80211_ATTR_TXQ_QUANTUM]);\nnet/wireless/nl80211.c:4530:\t\tchanged |= WIPHY_PARAM_TXQ_QUANTUM;\nnet/wireless/nl80211.c-4531-\t}\nnet/wireless/nl80211.c-4532-\nnet/wireless/nl80211.c:4533:\tif (changed) {\nnet/wireless/nl80211.c-4534-\t\tu8 old_retry_short, old_retry_long;\n--\nnet/wireless/nl80211.c-4564-\nnet/wireless/nl80211.c:4565:\t\tif (changed \u0026 WIPHY_PARAM_RETRY_SHORT)\nnet/wireless/nl80211.c-4566-\t\t\trdev-\u003ewiphy.retry_short = retry_short;\nnet/wireless/nl80211.c:4567:\t\tif (changed \u0026 WIPHY_PARAM_RETRY_LONG)\nnet/wireless/nl80211.c-4568-\t\t\trdev-\u003ewiphy.retry_long = retry_long;\nnet/wireless/nl80211.c:4569:\t\tif (changed \u0026 WIPHY_PARAM_FRAG_THRESHOLD)\nnet/wireless/nl80211.c-4570-\t\t\trdev-\u003ewiphy.frag_threshold = frag_threshold;\nnet/wireless/nl80211.c:4571:\t\tif ((changed \u0026 WIPHY_PARAM_RTS_THRESHOLD) \u0026\u0026\nnet/wireless/nl80211.c-4572-\t\t old_radio_rts_threshold) {\n--\nnet/wireless/nl80211.c-4577-\t\t}\nnet/wireless/nl80211.c:4578:\t\tif (changed \u0026 WIPHY_PARAM_COVERAGE_CLASS)\nnet/wireless/nl80211.c-4579-\t\t\trdev-\u003ewiphy.coverage_class = coverage_class;\nnet/wireless/nl80211.c:4580:\t\tif (changed \u0026 WIPHY_PARAM_TXQ_LIMIT)\nnet/wireless/nl80211.c-4581-\t\t\trdev-\u003ewiphy.txq_limit = txq_limit;\nnet/wireless/nl80211.c:4582:\t\tif (changed \u0026 WIPHY_PARAM_TXQ_MEMORY_LIMIT)\nnet/wireless/nl80211.c-4583-\t\t\trdev-\u003ewiphy.txq_memory_limit = txq_memory_limit;\nnet/wireless/nl80211.c:4584:\t\tif (changed \u0026 WIPHY_PARAM_TXQ_QUANTUM)\nnet/wireless/nl80211.c-4585-\t\t\trdev-\u003ewiphy.txq_quantum = txq_quantum;\nnet/wireless/nl80211.c-4586-\nnet/wireless/nl80211.c:4587:\t\tresult = rdev_set_wiphy_params(rdev, radio_idx, changed);\nnet/wireless/nl80211.c-4588-\t\tif (result) {\n--\nnet/wireless/nl80211.c=7509=static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)\n--\nnet/wireless/nl80211.c-7539-\nnet/wireless/nl80211.c:7540:\t/* recheck beaconing is permitted with possibly changed power type */\nnet/wireless/nl80211.c-7541-\tbeacon_check.iftype = wdev-\u003eiftype;\n--\nnet/wireless/nl80211.c=10067=static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)\n--\nnet/wireless/nl80211.c-10072-\tu32 bss_param_support = rdev-\u003ewiphy.bss_param_support;\nnet/wireless/nl80211.c:10073:\tu32 changed = 0;\nnet/wireless/nl80211.c-10074-\tbool strict;\n--\nnet/wireless/nl80211.c-10092-\t\t nla_get_u8(info-\u003eattrs[NL80211_ATTR_BSS_CTS_PROT]);\nnet/wireless/nl80211.c:10093:\t\tchanged |= WIPHY_BSS_PARAM_CTS_PROT;\nnet/wireless/nl80211.c-10094-\t}\n--\nnet/wireless/nl80211.c-10100-\t\t nla_get_u8(info-\u003eattrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);\nnet/wireless/nl80211.c:10101:\t\tchanged |= WIPHY_BSS_PARAM_SHORT_PREAMBLE;\nnet/wireless/nl80211.c-10102-\t}\n--\nnet/wireless/nl80211.c-10108-\t\t nla_get_u8(info-\u003eattrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);\nnet/wireless/nl80211.c:10109:\t\tchanged |= WIPHY_BSS_PARAM_SHORT_SLOT_TIME;\nnet/wireless/nl80211.c-10110-\t}\n--\nnet/wireless/nl80211.c-10118-\t\t\tnla_len(info-\u003eattrs[NL80211_ATTR_BSS_BASIC_RATES]);\nnet/wireless/nl80211.c:10119:\t\tchanged |= WIPHY_BSS_PARAM_BASIC_RATES;\nnet/wireless/nl80211.c-10120-\t}\n--\nnet/wireless/nl80211.c-10125-\t\t\t!!nla_get_u8(info-\u003eattrs[NL80211_ATTR_AP_ISOLATE]);\nnet/wireless/nl80211.c:10126:\t\tchanged |= WIPHY_BSS_PARAM_AP_ISOLATE;\nnet/wireless/nl80211.c-10127-\t}\n--\nnet/wireless/nl80211.c-10132-\t\t\tnla_get_u16(info-\u003eattrs[NL80211_ATTR_BSS_HT_OPMODE]);\nnet/wireless/nl80211.c:10133:\t\tchanged |= WIPHY_BSS_PARAM_HT_OPMODE;\nnet/wireless/nl80211.c-10134-\t}\n--\nnet/wireless/nl80211.c-10143-\t\t\treturn -EINVAL;\nnet/wireless/nl80211.c:10144:\t\tchanged |= WIPHY_BSS_PARAM_P2P_CTWINDOW;\nnet/wireless/nl80211.c-10145-\t}\n--\nnet/wireless/nl80211.c-10167-\nnet/wireless/nl80211.c:10168:\tchanged \u0026= rdev-\u003ewiphy.bss_param_support;\nnet/wireless/nl80211.c:10169:\tif (!changed)\nnet/wireless/nl80211.c-10170-\t\treturn 0;\n--\nnet/wireless/nl80211.c=14250=static int nl80211_update_connect_params(struct sk_buff *skb,\n--\nnet/wireless/nl80211.c-14258-\tu32 auth_type;\nnet/wireless/nl80211.c:14259:\tu32 changed = 0;\nnet/wireless/nl80211.c-14260-\n--\nnet/wireless/nl80211.c-14266-\t\tconnect.ie_len = nla_len(info-\u003eattrs[NL80211_ATTR_IE]);\nnet/wireless/nl80211.c:14267:\t\tchanged |= UPDATE_ASSOC_IES;\nnet/wireless/nl80211.c-14268-\t}\n--\nnet/wireless/nl80211.c-14297-\t\t\tnla_len(info-\u003eattrs[NL80211_ATTR_FILS_ERP_RRK]);\nnet/wireless/nl80211.c:14298:\t\tchanged |= UPDATE_FILS_ERP_INFO;\nnet/wireless/nl80211.c-14299-\t} else if (info-\u003eattrs[NL80211_ATTR_FILS_ERP_USERNAME] ||\n--\nnet/wireless/nl80211.c-14312-\t\tif (auth_type == NL80211_AUTHTYPE_FILS_SK \u0026\u0026\nnet/wireless/nl80211.c:14313:\t\t fils_sk_offload \u0026\u0026 !(changed \u0026 UPDATE_FILS_ERP_INFO))\nnet/wireless/nl80211.c-14314-\t\t\treturn -EINVAL;\n--\nnet/wireless/nl80211.c-14316-\t\tconnect.auth_type = auth_type;\nnet/wireless/nl80211.c:14317:\t\tchanged |= UPDATE_AUTH_TYPE;\nnet/wireless/nl80211.c-14318-\t}\n--\nnet/wireless/nl80211.c-14322-\nnet/wireless/nl80211.c:14323:\treturn rdev_update_connect_params(rdev, dev, \u0026connect, changed);\nnet/wireless/nl80211.c-14324-}\n--\nnet/wireless/nl80211.c=16548=static int nl80211_parse_nan_conf(struct wiphy *wiphy,\n--\nnet/wireless/nl80211.c-16550-\t\t\t\t struct cfg80211_nan_conf *conf,\nnet/wireless/nl80211.c:16551:\t\t\t\t u32 *changed_flags,\nnet/wireless/nl80211.c-16552-\t\t\t\t bool start)\n--\nnet/wireless/nl80211.c-16555-\tint err, rem;\nnet/wireless/nl80211.c:16556:\tu32 changed = 0;\nnet/wireless/nl80211.c-16557-\tstruct nlattr *band_config;\n--\nnet/wireless/nl80211.c-16562-\nnet/wireless/nl80211.c:16563:\t\tchanged |= CFG80211_NAN_CONF_CHANGED_PREF;\nnet/wireless/nl80211.c-16564-\t}\n--\nnet/wireless/nl80211.c-16575-\t\tconf-\u003ebands = bands;\nnet/wireless/nl80211.c:16576:\t\tchanged |= CFG80211_NAN_CONF_CHANGED_BANDS;\nnet/wireless/nl80211.c-16577-\t}\n--\nnet/wireless/nl80211.c-16597-\nnet/wireless/nl80211.c:16598:\tchanged |= CFG80211_NAN_CONF_CHANGED_CONFIG;\nnet/wireless/nl80211.c-16599-\tif (attrs[NL80211_NAN_CONF_CLUSTER_ID] \u0026\u0026 start) {\n--\nnet/wireless/nl80211.c-16707-\nnet/wireless/nl80211.c:16708:\tif (changed_flags)\nnet/wireless/nl80211.c:16709:\t\t*changed_flags = changed;\nnet/wireless/nl80211.c-16710-\n--\nnet/wireless/nl80211.c=17088=static int nl80211_nan_change_config(struct sk_buff *skb,\n--\nnet/wireless/nl80211.c-17093-\tstruct cfg80211_nan_conf conf = {};\nnet/wireless/nl80211.c:17094:\tu32 changed = 0;\nnet/wireless/nl80211.c-17095-\tint err;\n--\nnet/wireless/nl80211.c-17102-\nnet/wireless/nl80211.c:17103:\terr = nl80211_parse_nan_conf(\u0026rdev-\u003ewiphy, info, \u0026conf, \u0026changed, false);\nnet/wireless/nl80211.c-17104-\tif (err)\n--\nnet/wireless/nl80211.c-17106-\nnet/wireless/nl80211.c:17107:\tif (!changed)\nnet/wireless/nl80211.c-17108-\t\treturn -EINVAL;\nnet/wireless/nl80211.c-17109-\nnet/wireless/nl80211.c:17110:\treturn rdev_nan_change_conf(rdev, wdev, \u0026conf, changed);\nnet/wireless/nl80211.c-17111-}\n\n"
} |
| 55/3 | 2026/10/04 13:50 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 39998 output: 26 thoughts: 2063 Thoughts: **KMSAN Assessment: NAN Beacon Interval and Uninitialized Memory** Okay, let's break this down. First, I'm checking the `nl80211_put_nan_capa` function. It seems straightforward; it's just putting a flag attribute, `NL80211_NAN_CAPA_INSTANT_COMM`, into a netlink message. The flag itself has no payload, so no uninitialized memory issues there. Moving on to `mac80211_hwsim_nan_receive`, I'm looking at how NAN frames are handled. I see a check for `data->nan.instant_comm`, and now I'm thinking about the implications. Now, my mind shifts to this `data->nan.discovery_beacon_interval`. Where is it set? Aha, in `mac80211_hwsim_nan_set_config`. And it uses a ternary operator: `conf->discovery_beacon_interval ? : 100`. So, if the configuration provides a value, we use it, otherwise it defaults to 100. Does this have anything to do with uninitialized memory? The critical question here is whether this interval can be zero or uninitialized. Given the default value, it can't be zero, and if `mac80211_hwsim_nan_start` is called, it initializes to at least 100. The timer, which uses this value, is also started in `mac80211_hwsim_nan_start`, `mac80211_hwsim_nan_change_config` or `mac80211_hwsim_nan_exec_state_transitions`, so I think it's unlikely to cause an issue. While the interval is used in division and modulo operations, it defaults to 100. I'm also considering `scan.c` and how it handles NAN beacons. The code checks if it's a NAN beacon and returns NULL, so no NAN beacons are added to the BSS table. This looks safe. Now, I'm focusing on KMSAN specifically. I remember KMSAN's role: detecting reads of UNINITIALIZED memory that might lead to kernel-to-user info leaks. I have to think about the four criteria. The most relevant is kernel structures sent to user space where fields or padding might not be fully initialized. I go back to `nl80211_put_nan_capa`. I have to check: does this patch send any kernel structures to user space? I remember, the netlink attribute `NL80211_NAN_CAPA_INSTANT_COMM` is just a flag, it doesn't send any struct payload or padding. Okay, let's move on. I look at `mac80211_default_mgmt_stypes` which enables `BIT(IEEE80211_STYPE_BEACON >> 4)` on `NL80211_IFTYPE_NAN`. This enables receiving the beacon as a management frame. Looking at `ieee80211_accept_frame`, I see that the frame is passed to the userspace. The `skb` used by `ieee80211_is_nan_beacon` comes from the driver, or in this case, `mac80211_hwsim`, not from some uninitialized kernel struct. What about beacons generated in the kernel? I have to look at `mac80211_hwsim_nan_tx_beacon()` carefully. Let's see... The function defines a `struct ieee80211_vendor_ie` called `nan_ie`. This looks like a potentially risky area. I need to make sure this structure is correctly initialized. The code sets the `element_id`, `len`, `oui`, and `oui_type`. Is there uninitialized padding? Let's check the definition of `struct ieee80211_vendor_ie`. After this review, the concerns about uninitialized memory look minimal, and so KMSAN doesn't seem necessary in this case. |
| 56/3 | 2026/10/04 13:51 | tool | grepper |
0mArgs:{
"Expression": "struct ieee80211_vendor_ie"
}Results: {
"Output": "drivers/net/wireless/ath/wil6210/cfg80211.c=1767=static const u8 *_wil_cfg80211_find_ie(const u8 *ies, u16 ies_len, const u8 *ie,\n--\ndrivers/net/wireless/ath/wil6210/cfg80211.c-1769-{\ndrivers/net/wireless/ath/wil6210/cfg80211.c:1770:\tstruct ieee80211_vendor_ie *vie;\ndrivers/net/wireless/ath/wil6210/cfg80211.c-1771-\tu32 oui;\n--\ndrivers/net/wireless/ath/wil6210/cfg80211.c-1782-\t\treturn NULL;\ndrivers/net/wireless/ath/wil6210/cfg80211.c:1783:\tvie = (struct ieee80211_vendor_ie *)ie;\ndrivers/net/wireless/ath/wil6210/cfg80211.c-1784-\toui = vie-\u003eoui[0] \u003c\u003c 16 | vie-\u003eoui[1] \u003c\u003c 8 | vie-\u003eoui[2];\n--\ndrivers/net/wireless/intel/iwlwifi/mld/iface.c=684=void iwl_mld_handle_probe_resp_data_notif(struct iwl_mld *mld,\n--\ndrivers/net/wireless/intel/iwlwifi/mld/iface.c-739-\t/* noa_attr contains 1 reserved byte, need to substruct it */\ndrivers/net/wireless/intel/iwlwifi/mld/iface.c:740:\tnew_data-\u003enoa_len = sizeof(struct ieee80211_vendor_ie) +\ndrivers/net/wireless/intel/iwlwifi/mld/iface.c-741-\t\t\t sizeof(new_data-\u003enotif.noa_attr) - 1;\n--\ndrivers/net/wireless/intel/iwlwifi/mld/tx.c=703=static void iwl_mld_probe_resp_set_noa(struct iwl_mld *mld,\n--\ndrivers/net/wireless/intel/iwlwifi/mld/tx.c-742-\tmemcpy(pos, \u0026resp_data-\u003enotif.noa_attr,\ndrivers/net/wireless/intel/iwlwifi/mld/tx.c:743:\t resp_data-\u003enoa_len - sizeof(struct ieee80211_vendor_ie));\ndrivers/net/wireless/intel/iwlwifi/mld/tx.c-744-\n--\ndrivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c=1748=void iwl_mvm_probe_resp_data_notif(struct iwl_mvm *mvm,\n--\ndrivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c-1787-\t/* noa_attr contains 1 reserved byte, need to substruct it */\ndrivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c:1788:\tnew_data-\u003enoa_len = sizeof(struct ieee80211_vendor_ie) +\ndrivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c-1789-\t\t\t sizeof(new_data-\u003enotif.noa_attr) - 1;\n--\ndrivers/net/wireless/intel/iwlwifi/mvm/tx.c=709=static void iwl_mvm_probe_resp_set_noa(struct iwl_mvm *mvm,\n--\ndrivers/net/wireless/intel/iwlwifi/mvm/tx.c-763-\tmemcpy(pos, \u0026resp_data-\u003enotif.noa_attr,\ndrivers/net/wireless/intel/iwlwifi/mvm/tx.c:764:\t resp_data-\u003enoa_len - sizeof(struct ieee80211_vendor_ie));\ndrivers/net/wireless/intel/iwlwifi/mvm/tx.c-765-\n--\ndrivers/net/wireless/marvell/mwifiex/ie.c=314=static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,\n--\ndrivers/net/wireless/marvell/mwifiex/ie.c-318-\tstruct ieee_types_header *hdr;\ndrivers/net/wireless/marvell/mwifiex/ie.c:319:\tstruct ieee80211_vendor_ie *vendorhdr;\ndrivers/net/wireless/marvell/mwifiex/ie.c-320-\tu16 gen_idx = MWIFIEX_AUTO_IDX_MASK, ie_len = 0;\n--\ndrivers/net/wireless/nxp/nxpwifi/fw.h=1814=struct ieee_types_wmm_info {\n--\ndrivers/net/wireless/nxp/nxpwifi/fw.h-1823-\t */\ndrivers/net/wireless/nxp/nxpwifi/fw.h:1824:\tstruct ieee80211_vendor_ie vend_hdr;\ndrivers/net/wireless/nxp/nxpwifi/fw.h-1825-\tu8 oui_subtype;\n--\ndrivers/net/wireless/nxp/nxpwifi/ie.c=298=static int nxpwifi_uap_parse_tail_ies(struct nxpwifi_private *priv,\n--\ndrivers/net/wireless/nxp/nxpwifi/ie.c-302-\tstruct element *hdr;\ndrivers/net/wireless/nxp/nxpwifi/ie.c:303:\tstruct ieee80211_vendor_ie *vendorhdr;\ndrivers/net/wireless/nxp/nxpwifi/ie.c-304-\tu16 gen_idx = NXPWIFI_AUTO_IDX_MASK, ie_len = 0;\n--\ndrivers/net/wireless/nxp/nxpwifi/main.h=327=struct ieee_types_vendor_specific {\ndrivers/net/wireless/nxp/nxpwifi/main.h:328:\tstruct ieee80211_vendor_ie vend_hdr;\ndrivers/net/wireless/nxp/nxpwifi/main.h:329:\tu8 data[IEEE_MAX_IE_SIZE - sizeof(struct ieee80211_vendor_ie)];\ndrivers/net/wireless/nxp/nxpwifi/main.h-330-} __packed;\n--\ndrivers/net/wireless/nxp/nxpwifi/sta_cfg.c=1029=nxpwifi_set_gen_ie_helper(struct nxpwifi_private *priv, u8 *ie_data_ptr,\n--\ndrivers/net/wireless/nxp/nxpwifi/sta_cfg.c-1031-{\ndrivers/net/wireless/nxp/nxpwifi/sta_cfg.c:1032:\tstruct ieee80211_vendor_ie *pvendor_ie;\ndrivers/net/wireless/nxp/nxpwifi/sta_cfg.c-1033-\tstatic const u8 wpa_oui[] = { 0x00, 0x50, 0xf2, 0x01 };\n--\ndrivers/net/wireless/nxp/nxpwifi/sta_cfg.c-1045-\t}\ndrivers/net/wireless/nxp/nxpwifi/sta_cfg.c:1046:\tpvendor_ie = (struct ieee80211_vendor_ie *)ie_data_ptr;\ndrivers/net/wireless/nxp/nxpwifi/sta_cfg.c-1047-\n--\ndrivers/net/wireless/nxp/nxpwifi/sta_cfg.c-1102-\t\telse\ndrivers/net/wireless/nxp/nxpwifi/sta_cfg.c:1103:\t\t\tpvendor_ie = (struct ieee80211_vendor_ie *)\ndrivers/net/wireless/nxp/nxpwifi/sta_cfg.c-1104-\t\t\t\t(((u8 *)pvendor_ie) + cur_ie_len);\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=738=mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-741-{\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:742:\tstruct ieee80211_vendor_ie nan_ie = {\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-743-\t\t.element_id = WLAN_EID_VENDOR_SPECIFIC,\n--\ninclude/linux/ieee80211.h=1251=struct ieee80211_mmie_var {\n--\ninclude/linux/ieee80211.h-1258-\ninclude/linux/ieee80211.h:1259:struct ieee80211_vendor_ie {\ninclude/linux/ieee80211.h-1260-\tu8 element_id;\n"
} |
| 57/3 | 2026/10/04 13:51 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 45378 output: 42 thoughts: 37 Thoughts: Here's my take on the thought process, as requested: **Diving into the 802.11 Vendor IE Structure** Okay, time to get my hands dirty. I need to refresh my memory on the specifics of the `struct ieee80211_vendor_ie`. It's been a while since I last really dove into the kernel's 802.11 implementation at this level. Let's make sure I'm crystal clear on the data structure details, especially given the nuances involved with vendor-specific information elements. I'll head over to `include/linux/ieee80211.h` – that's where I'd expect to find the core definition. I need to confirm the fields, data layout, and any potential padding or alignment considerations that might be relevant to the task at hand. I also want to make sure my assumptions about its usage within the driver or stack are still sound. Understanding this struct is fundamental to working with custom data within the 802.11 frame format. |
| 58/3 | 2026/10/04 13:51 | tool | read-file |
0mArgs:{
"File": "include/linux/ieee80211.h",
"FirstLine": 1255,
"LineCount": 15
}Results: {
"Contents": "1255:\t\tu8 sequence_number[6];\n1256:\t\tu8 mic[]; /* 8 or 16 bytes */\n1257:\t} __packed;\n1258:\t\n1259:\tstruct ieee80211_vendor_ie {\n1260:\t\tu8 element_id;\n1261:\t\tu8 len;\n1262:\t\tu8 oui[3];\n1263:\t\tu8 oui_type;\n1264:\t} __packed;\n1265:\t\n1266:\tstruct ieee80211_wmm_ac_param {\n1267:\t\tu8 aci_aifsn; /* AIFSN, ACM, ACI */\n1268:\t\tu8 cw; /* ECWmin, ECWmax (CW = 2^ECW - 1) */\n1269:\t\t__le16 txop_limit;\n"
} |
| 59/3 | 2026/10/04 13:51 | llm | kmsan-evaluator |
1mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 45935 output: 17 thoughts: 2274 Thoughts: **My Analysis of Potential Uninitialized Memory Issues**
Okay, let's break this down systematically. My initial impression is that the code is generally careful about initialization, but I need to be thorough.
First off, it seems like `__packed`, `nan_attr`, and `master_indication` are all marked as packed, which suggests tight control over memory layout and potentially reduced alignment issues. Excellent.
Now, checking for specific areas of concern:
1. **Conditional logic based on potentially uninitialized variables**: The code uses `hwsim_nan_beacon_has_service_ids`, which, when I trace it, seems safe. I examined the conditions using `data->nan.instant_comm` and `data->nan.phase`. My analysis concludes `data->nan.instant_comm` is consistently initialized.
* It is either zero or set to a value when the code calls `set_config` and `stop`
* `mac80211_hwsim_nan_start()` sets it
* `mac80211_hwsim_nan_set_config()` and `mac80211_hwsim_nan_stop()` also set it.
And since `data->nan` starts out zeroed (thanks to `kzalloc`), I am satisfied that all of the fields have been set.
2. **Allocation and Initialization of Complex Data Structures:** I looked at structures in `nl80211.c`, `hwsim_main.c`, and `kmemdup`. I'm pleased to see that `conf` and `iter_data` are initialized either with `{}` or zero-initialized. I also verified `kmemdup` is called properly, using a zero-initialized struct. So I think these are safe.
3. **Bounds checks and uninitialized bytes in buffers**: `hwsim_nan_beacon_has_service_ids` seems like a good place to look for uninitialized memory usage. I checked the `skb` and it seems fine, and that network packets in `skb` have known lengths. Also, the code checks the length of service IDs. I reviewed the `for_each_nan_attr` macro and convinced myself that the offset and length calculations are correct and handle edge cases safely. I've also verified that any possible out-of-bounds reads or overflows within the macro would be caught by KASAN.
In the newer `mac80211_hwsim_nan_rx` I noted a significant change. It now calls `ieee80211_is_nan_beacon` and the subsequent allocation uses `kzalloc`, which means any new allocation here will be fine.
I checked `mac80211_hwsim_nan_txq_transmitting()` too, and verified that accesses to `local_sched` are on a zeroed array.
4. **Registration and Configuration:** I took a look at `wiphy_register` and `ieee80211_nan_conf_copy`. I observed that there were checks to make sure the flags were configured properly. The boolean field `instant_comm` is copied to the destination correctly. This also seems safe.
5. **Information Leaks:** I started searching the code base for anything that may leak information, but didn't find anything related to NAN configuration or `instant_comm`.
**Conclusion:**
Overall, I'm feeling pretty confident that there are no obvious uninitialized memory bugs lurking here. The code generally initializes data structures with `kzalloc` or zero-initialized structs, and the bounds checks look solid. I'm especially happy with how the `for_each_nan_attr` macro is constructed. The use of `kzalloc` in RX path is great. The checks in `wiphy_register` are also reassuring. I've done my best to eliminate the risks of uninitialized memory usage here.
|
| 60/3 | 2026/10/04 13:52 | tool | grepper |
0mArgs:{
"Expression": "instant_comm"
}Results: {
"Output": "drivers/net/wireless/virtual/mac80211_hwsim_nan.c=253=void mac80211_hwsim_nan_rx(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-321-\t\tscoped_guard(spinlock_bh, \u0026data-\u003enan.state_lock)\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:322:\t\t\trx_outside_dw = data-\u003enan.instant_comm ||\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-323-\t\t\t\tdata-\u003enan.phase ==\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=653=mac80211_hwsim_nan_exec_state_transitions(struct mac80211_hwsim_data *data)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-684-\tif ((data-\u003enan.role == MAC80211_HWSIM_NAN_ROLE_MASTER ||\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:685:\t data-\u003enan.instant_comm) \u0026\u0026\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-686-\t !hrtimer_active(\u0026data-\u003enan.discovery_beacon_timer))\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=927=mac80211_hwsim_nan_discovery_beacon_timer(struct hrtimer *timer)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-947-\t\t */\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:948:\t\tif (!data-\u003enan.instant_comm \u0026\u0026\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-949-\t\t data-\u003enan.role != MAC80211_HWSIM_NAN_ROLE_MASTER)\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=978=static int mac80211_hwsim_nan_set_config(struct mac80211_hwsim_data *data,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1004-\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:1005:\t\tdata-\u003enan.instant_comm = conf-\u003einstant_comm;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1006-\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=1017=int mac80211_hwsim_nan_start(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1044-\t\tdata-\u003enan.phase = MAC80211_HWSIM_NAN_PHASE_SCAN;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:1045:\t\tdata-\u003enan.random_factor_valid_dwst = conf-\u003einstant_comm ? 0 : 1;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1046-\t\tdata-\u003enan.random_factor = 0;\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=1066=int mac80211_hwsim_nan_stop(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1084-\t\tdata-\u003enan.extra_nan_attrs_len = 0;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:1085:\t\tdata-\u003enan.instant_comm = false;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1086-\t}\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=1093=int mac80211_hwsim_nan_change_config(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1117-\t\t */\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:1118:\t\tif (conf-\u003einstant_comm \u0026\u0026\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1119-\t\t !hrtimer_active(\u0026data-\u003enan.discovery_beacon_timer))\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=1288=bool mac80211_hwsim_nan_txq_transmitting(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1317-\t\t\tguard(spinlock_bh)(\u0026data-\u003enan.state_lock);\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:1318:\t\t\treturn data-\u003enan.instant_comm \u0026\u0026\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1319-\t\t\t\tdata-\u003enan.local_sched[slot].chan;\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c=1372=bool mac80211_hwsim_nan_receive(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1377-\tstruct mac80211_hwsim_data *data = hw-\u003epriv;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:1378:\tbool instant_comm;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1379-\tu8 slot;\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1384-\tscoped_guard(spinlock_bh, \u0026data-\u003enan.state_lock)\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:1385:\t\tinstant_comm = data-\u003enan.instant_comm;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1386-\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1395-\t */\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c:1396:\tif (instant_comm \u0026\u0026 hwsim_nan_beacon_has_service_ids(skb))\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.c-1397-\t\treturn true;\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h=22=struct mac80211_hwsim_nan_data {\n--\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h-58-\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h:59:\tbool instant_comm;\ndrivers/net/wireless/virtual/mac80211_hwsim_nan.h-60-\tu8 discovery_beacon_interval;\n--\ninclude/net/cfg80211.h=4165=struct cfg80211_nan_band_config {\n--\ninclude/net/cfg80211.h-4186- * @discovery_beacon_interval: interval (in TUs) for discovery beacons. Must be\ninclude/net/cfg80211.h:4187: *\tgreater than 0 when @instant_comm is true.\ninclude/net/cfg80211.h-4188- * @enable_dw_notification: flag to enable/disable discovery window\ninclude/net/cfg80211.h-4189- *\tnotifications.\ninclude/net/cfg80211.h:4190: * @instant_comm: if true, start Instant Communication (IC) as defined in\ninclude/net/cfg80211.h-4191- *\tChapter 13 of the Wi-Fi Aware Specification v4.0.\n--\ninclude/net/cfg80211.h=4199=struct cfg80211_nan_conf {\n--\ninclude/net/cfg80211.h-4206-\tbool enable_dw_notification;\ninclude/net/cfg80211.h:4207:\tbool instant_comm;\ninclude/net/cfg80211.h-4208-\tstruct cfg80211_nan_band_config band_cfgs[NUM_NL80211_BANDS];\n--\nnet/mac80211/cfg.c=351=static int ieee80211_nan_conf_copy(struct cfg80211_nan_conf *dst,\n--\nnet/mac80211/cfg.c-366-\t\tdst-\u003eenable_dw_notification = src-\u003eenable_dw_notification;\nnet/mac80211/cfg.c:367:\t\tdst-\u003einstant_comm = src-\u003einstant_comm;\nnet/mac80211/cfg.c-368-\t\tmemcpy(\u0026dst-\u003eband_cfgs, \u0026src-\u003eband_cfgs,\n--\nnet/mac80211/rx.c=4511=static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)\n--\nnet/mac80211/rx.c-4675-\t\t\t\t\t skb-\u003elen))\nnet/mac80211/rx.c:4676:\t\t\treturn sdata-\u003eu.nan.conf.instant_comm;\nnet/mac80211/rx.c-4677-\t\tif (!ieee80211_is_disassoc(hdr-\u003eframe_control) \u0026\u0026\n--\nnet/wireless/nl80211.c=16548=static int nl80211_parse_nan_conf(struct wiphy *wiphy,\n--\nnet/wireless/nl80211.c-16670-\nnet/wireless/nl80211.c:16671:\tconf-\u003einstant_comm = nla_get_flag(attrs[NL80211_NAN_CONF_INSTANT_COMM]);\nnet/wireless/nl80211.c:16672:\tif (conf-\u003einstant_comm) {\nnet/wireless/nl80211.c-16673-\t\tif (!(wiphy-\u003enan_capa.flags \u0026 WIPHY_NAN_FLAGS_INSTANT_COMM)) {\n"
} |
| 61/3 | 2026/10/04 13:52 | llm | kmsan-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 51972 output: 473 thoughts: 1150 Thoughts: **KMSAN Assessment: NAN Instant Communication Support**
Okay, let's break this down. My analysis indicates that this patch series, which introduces support for NAN Instant Communication (IC) mode as per Wi-Fi Aware v4.0 across mac80211, cfg80211, and mac80211_hwsim, does *not* introduce or expose any significant uninitialized memory risks that would necessitate KMSAN scrutiny.
Here's my line of reasoning:
1. **Boolean Logic is Paramount**: Every relevant usage of `instant_comm` boils down to straightforward boolean logic. No complex data structures or potential for indeterminate states are introduced directly as a result of its integration.
2. **Code Walkthrough and Initialization Checks**: I've carefully reviewed the code changes.
* In `net/wireless/scan.c`, the new `ieee80211_is_nan_beacon` check is straightforward and doesn't introduce any new data structures or memory concerns.
* In `net/wireless/core.c`, I see checks related to the capabilities flags and the availability of management frame types, ensuring the driver is correctly configured for IC mode. These are conditional checks and flags, not introducing memory management issues.
* In `net/mac80211/main.c`, the management frame type definitions explicitly enable the RX path for NAN beacons, crucial for IC's service discovery. No memory allocation/initialization issues here.
* In `drivers/net/wireless/virtual/mac80211_hwsim_main.c`, the change simply adds an extra field to `tx_iter_data` structure and sets the IC flag. This field is initialized.
3. **Memory Allocation and Initialization Scrutiny**: I've paid close attention to memory allocation within the changes:
* `kmemdup` is used to allocate and initialize memory, which is safe.
* `alloc_skb` uses `memset`, `memcpy`, and `skb_put_data` to ensure proper initialization of the beacon data.
* Structs such as `nan_ie`, `master_indication`, and `nan_attr`, are either designated initialized, explicitly assigned, or packed, mitigating the risk of uninitialized padding.
4. **No Uninitialized Data Leak**: There's no uninitialized kernel data leaking to userspace. For example, the `nla_put_flag(msg, NL80211_NAN_CAPA_INSTANT_COMM)` function sends a flag with a zero payload, which eliminates any risk. Zero-initialized structs are used extensively, minimizing memory management overhead and risk.
5. **Frame Parsing and Bounds Checking**: I've analyzed potential risks with frame parsing (malformed data or length issues), such as the `ieee80211_is_nan_beacon` and `hwsim_nan_beacon_has_service_ids` calls. These functions use length-bounded checks and iterators, so any memory safety issue would manifest as an out-of-bounds read. This is a vulnerability that KASAN (Kernel Address SANitizer) is designed to catch, not KMSAN.
6. **Comprehensive Assessment**: In short, I'm confident that KASAN and the standard sanitizers are fully sufficient to cover any potential issues. There is no justification for a dedicated KMSAN session on this patch series. My review confirms that the code is well-structured, memory is properly initialized, and checks are in place to prevent uninitialized memory issues.
Therefore, `NeedsKMSAN = false`. I'm ready to call the `set-results` tool now.
|
| 62/3 | 2026/10/04 13:52 | tool | set-results |
0mArgs:{
"KMSANReasoning": "The patch introduces support for NAN Instant Communication (IC) mode (Wi-Fi Aware v4.0) across cfg80211, mac80211, and the mac80211_hwsim driver.\n\n1. Netlink attributes \u0026 userspace info-leaks:\nThe only new attribute exported to userspace is NL80211_NAN_CAPA_INSTANT_COMM, emitted using nla_put_flag(), which conveys a boolean flag with no payload. No new kernel structures with uninitialized fields or padding are copied to userspace.\n\n2. Structure and memory initialization:\n- In netlink configuration handling (nl80211_start_nan and nl80211_nan_change_config), 'struct cfg80211_nan_conf conf' is fully zero-initialized with '= {}'.\n- In mac80211_hwsim_main.c, instances of 'struct tx_iter_data' are initialized with designated initializers, ensuring non-specified fields are zero-initialized.\n- In mac80211_hwsim_nan_set_config(), extra_nan_attrs is allocated and initialized via kmemdup().\n- In mac80211_hwsim_nan_tx_beacon(), beacon headers are zeroed with memset(), and all IE structures (struct ieee80211_vendor_ie, struct ieee80211_nan_attr, etc.) are __packed and fully initialized before being put into the skb.\n\n3. Frame parsing and bounds:\nThe parsing logic in ieee80211_is_nan_beacon() and hwsim_nan_beacon_has_service_ids() iterates over elements using bounds checks against the skb data length. Any potential bug involving malformed frames or buffer boundaries would be an out-of-bounds read, which is detected by KASAN rather than KMSAN.\n\nNo uninitialized memory risks or info-leaks are introduced; standard KASAN fuzzing is sufficient.",
"NeedsKMSAN": false
}Results: {
"KMSANReasoning": "The patch introduces support for NAN Instant Communication (IC) mode (Wi-Fi Aware v4.0) across cfg80211, mac80211, and the mac80211_hwsim driver.\n\n1. Netlink attributes \u0026 userspace info-leaks:\nThe only new attribute exported to userspace is NL80211_NAN_CAPA_INSTANT_COMM, emitted using nla_put_flag(), which conveys a boolean flag with no payload. No new kernel structures with uninitialized fields or padding are copied to userspace.\n\n2. Structure and memory initialization:\n- In netlink configuration handling (nl80211_start_nan and nl80211_nan_change_config), 'struct cfg80211_nan_conf conf' is fully zero-initialized with '= {}'.\n- In mac80211_hwsim_main.c, instances of 'struct tx_iter_data' are initialized with designated initializers, ensuring non-specified fields are zero-initialized.\n- In mac80211_hwsim_nan_set_config(), extra_nan_attrs is allocated and initialized via kmemdup().\n- In mac80211_hwsim_nan_tx_beacon(), beacon headers are zeroed with memset(), and all IE structures (struct ieee80211_vendor_ie, struct ieee80211_nan_attr, etc.) are __packed and fully initialized before being put into the skb.\n\n3. Frame parsing and bounds:\nThe parsing logic in ieee80211_is_nan_beacon() and hwsim_nan_beacon_has_service_ids() iterates over elements using bounds checks against the skb data length. Any potential bug involving malformed frames or buffer boundaries would be an out-of-bounds read, which is detected by KASAN rather than KMSAN.\n\nNo uninitialized memory risks or info-leaks are introduced; standard KASAN fuzzing is sufficient.",
"NeedsKMSAN": false
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|