AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/10/01 11:41 flow patch-triage
4m Args:
null

Results:
{
  "EnableConfigs": [
    "CRYPTO_FIPS",
    "CRYPTO_DRBG",
    "CRYPTO_SELFTESTS",
    "CFG80211",
    "MAC80211",
    "MAC80211_HWSIM"
  ],
  "FocusSymbols": [
    "drv_set_key",
    "ieee80211_set_rekey_data",
    "fips_allows"
  ],
  "KMSANReasoning": "The patch introduces a kernel boot/sysctl parameter 'fips_exception' and a helper function 'fips_allows()' to conditionally allow specific non-FIPS compliant Wi-Fi features (such as Wi-Fi MFP) even when FIPS mode is enabled. It adjusts feature flags and capability checks across the iwlwifi driver and mac80211 subsystem.\n\nAll added state (e.g. 'fips_exception') is statically allocated and initialized in BSS or via kstrtoul. There are no allocations of uninitialized memory, no structures with padding exposed to userspace without initialization, no conditional branches on uninitialized memory, and no buffer length or index manipulation that could cause reads into uninitialized memory regions.\n\nAny potential bugs resulting from enabling these Wi-Fi features (such as out-of-bounds frame parsing, driver logic flaws, or reference counting issues) would be covered by KASAN and standard sanitizers rather than KMSAN. A dedicated KMSAN fuzzing session is not warranted.",
  "NeedsKMSAN": false,
  "Reasoning": "The patch introduces a new FIPS exception mechanism (fips_allows and a sysctl fips_exception) in crypto/fips.c and modifies key management logic in net/mac80211 (drv_set_key and drv_set_rekey_data). While the iwlwifi changes target vendor-specific Intel hardware, the mac80211 and crypto modifications reside in reachable core subsystems and can be exercised in standard virtualized environments using mac80211_hwsim and nl80211 netlink commands.",
  "WorthFuzzing": true
}

1/1 2026/10/01 11:41 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 499c6407815a44f1670ce2ff2665ca2c5c5a6aa1\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Thu Oct 1 11:41:47 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/crypto/fips.c b/crypto/fips.c\nindex c59711248d956..0f075e61a6577 100644\n--- a/crypto/fips.c\n+++ b/crypto/fips.c\n@@ -21,6 +21,15 @@ EXPORT_SYMBOL_GPL(fips_enabled);\n ATOMIC_NOTIFIER_HEAD(fips_fail_notif_chain);\n EXPORT_SYMBOL_GPL(fips_fail_notif_chain);\n \n+static unsigned long fips_exception;\n+\n+int fips_allows(unsigned long feature)\n+{\n+\treturn !fips_enabled ||\n+\t       (fips_exception \u0026 feature);\n+}\n+EXPORT_SYMBOL_GPL(fips_allows);\n+\n /* Process kernel command-line parameter at boot time. fips=0 or fips=1 */\n static int __init fips_enable(char *str)\n {\n@@ -34,6 +43,17 @@ static int __init fips_enable(char *str)\n \n __setup(\"fips=\", fips_enable);\n \n+static int __init fips_exception_setup(char *str)\n+{\n+\tif (kstrtoul(str, 0, \u0026fips_exception))\n+\t\treturn 0;\n+\n+\tpr_info(\"fips exceptions: 0x%lx\\n\", fips_exception);\n+\treturn 1;\n+}\n+\n+__setup(\"fips_exception=\", fips_exception_setup);\n+\n #define FIPS_MODULE_NAME CONFIG_CRYPTO_FIPS_NAME\n #ifdef CONFIG_CRYPTO_FIPS_CUSTOM_VERSION\n #define FIPS_MODULE_VERSION CONFIG_CRYPTO_FIPS_VERSION\n@@ -52,6 +72,13 @@ static const struct ctl_table crypto_sysctl_table[] = {\n \t\t.mode\t\t= 0444,\n \t\t.proc_handler\t= proc_dointvec\n \t},\n+\t{\n+\t\t.procname\t= \"fips_exception\",\n+\t\t.data\t\t= \u0026fips_exception,\n+\t\t.maxlen\t\t= sizeof(unsigned long),\n+\t\t.mode\t\t= 0444,\n+\t\t.proc_handler\t= proc_doulongvec_minmax\n+\t},\n \t{\n \t\t.procname\t= \"fips_name\",\n \t\t.data\t\t= \u0026fips_name,\ndiff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c\nindex 863d5e358152d..ca565b4311bbe 100644\n--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c\n+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c\n@@ -502,14 +502,16 @@ static void iwl_init_vht_hw_capab(struct iwl_trans *trans,\n \t */\n \tswitch (iwlwifi_mod_params.amsdu_size) {\n \tcase IWL_AMSDU_DEF:\n-\t\tif (trans-\u003emac_cfg-\u003emq_rx_supported \u0026\u0026 !fips_enabled)\n+\t\tif (trans-\u003emac_cfg-\u003emq_rx_supported \u0026\u0026\n+\t\t    fips_allows(FIPS_EXCEPTION_WIFI_MFP))\n \t\t\tvht_cap-\u003ecap |=\n \t\t\t\tIEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;\n \t\telse\n \t\t\tvht_cap-\u003ecap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;\n \t\tbreak;\n \tcase IWL_AMSDU_2K:\n-\t\tif (trans-\u003emac_cfg-\u003emq_rx_supported \u0026\u0026 !fips_enabled)\n+\t\tif (trans-\u003emac_cfg-\u003emq_rx_supported \u0026\u0026\n+\t\t    fips_allows(FIPS_EXCEPTION_WIFI_MFP))\n \t\t\tvht_cap-\u003ecap |=\n \t\t\t\tIEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;\n \t\telse\n@@ -886,7 +888,7 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans,\n \n \t/* EHT needs WPA3/MFP so cannot do it for fips_enabled */\n \tif (!data-\u003esku_cap_11be_enable || iwlwifi_mod_params.disable_11be ||\n-\t    fips_enabled)\n+\t    !fips_allows(FIPS_EXCEPTION_WIFI_MFP))\n \t\tiftype_data-\u003eeht_cap.has_eht = false;\n \n \tif (!data-\u003esku_cap_11bn_enable || !iftype_data-\u003eeht_cap.has_eht)\n@@ -1221,7 +1223,8 @@ static void iwl_init_sbands(struct iwl_trans *trans,\n \t * avoid spending time on scanning those channels and perhaps\n \t * even finding APs there that cannot be used.\n \t */\n-\tif (!fips_enabled \u0026\u0026 data-\u003esku_cap_11ax_enable \u0026\u0026\n+\tif (fips_allows(FIPS_EXCEPTION_WIFI_MFP) \u0026\u0026\n+\t    data-\u003esku_cap_11ax_enable \u0026\u0026\n \t    !iwlwifi_mod_params.disable_11ax)\n \t\tiwl_init_he_hw_capab(trans, data, sband, tx_chains, rx_chains,\n \t\t\t\t     fw);\ndiff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c\nindex 3a4c8fda68d0a..3fd88420cd17f 100644\n--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c\n+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c\n@@ -167,7 +167,7 @@ static void iwl_mld_hw_set_security(struct iwl_mld *mld)\n \t\tWLAN_CIPHER_SUITE_BIP_GMAC_256\n \t};\n \n-\tif (fips_enabled)\n+\tif (!fips_allows(FIPS_EXCEPTION_WIFI_MFP))\n \t\treturn;\n \n \thw-\u003ewiphy-\u003en_cipher_suites = ARRAY_SIZE(mld_ciphers);\n@@ -176,6 +176,9 @@ static void iwl_mld_hw_set_security(struct iwl_mld *mld)\n \tieee80211_hw_set(hw, MFP_CAPABLE);\n \twiphy_ext_feature_set(hw-\u003ewiphy,\n \t\t\t      NL80211_EXT_FEATURE_BEACON_PROTECTION);\n+\n+\tif (fips_enabled)\n+\t\tIWL_WARN(mld, \"FIPS: MFP enabled with known firmware limitation\\n\");\n }\n \n static void iwl_mld_hw_set_antennas(struct iwl_mld *mld)\n@@ -344,7 +347,7 @@ static void iwl_mac_hw_set_wiphy(struct iwl_mld *mld)\n \tif (mld-\u003envm_data-\u003esku_cap_11be_enable \u0026\u0026\n \t    !iwlwifi_mod_params.disable_11ax \u0026\u0026\n \t    !iwlwifi_mod_params.disable_11be \u0026\u0026\n-\t    !fips_enabled)\n+\t    fips_allows(FIPS_EXCEPTION_WIFI_MFP))\n \t\twiphy-\u003eflags |= WIPHY_FLAG_SUPPORTS_MLO;\n \n \t/* the firmware uses u8 for num of iterations, but 0xff is saved for\n@@ -2227,6 +2230,9 @@ static int iwl_mld_set_key_add(struct iwl_mld *mld,\n \tcase WLAN_CIPHER_SUITE_CCMP:\n \tcase WLAN_CIPHER_SUITE_GCMP:\n \tcase WLAN_CIPHER_SUITE_GCMP_256:\n+\t\tif (fips_enabled \u0026\u0026 (key-\u003eflags \u0026 IEEE80211_KEY_FLAG_PAIRWISE))\n+\t\t\tkey-\u003eflags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;\n+\t\tbreak;\n \tcase WLAN_CIPHER_SUITE_AES_CMAC:\n \tcase WLAN_CIPHER_SUITE_BIP_GMAC_128:\n \tcase WLAN_CIPHER_SUITE_BIP_GMAC_256:\ndiff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c\nindex 5bd246e379432..38fe710ef414f 100644\n--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c\n+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c\n@@ -462,8 +462,11 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)\n \t\tIWL_ERR(mvm,\n \t\t\t\"iwlmvm doesn't allow to disable BT Coex, check bt_coex_active module parameter\\n\");\n \n-\tif (!fips_enabled)\n+\tif (fips_allows(FIPS_EXCEPTION_WIFI_MFP)) {\n \t\tieee80211_hw_set(hw, MFP_CAPABLE);\n+\t\tif (fips_enabled)\n+\t\t\tIWL_WARN(mvm, \"FIPS: MFP enabled with known firmware limitation\\n\");\n+\t}\n \n \tmvm-\u003eciphers[hw-\u003ewiphy-\u003en_cipher_suites] = WLAN_CIPHER_SUITE_AES_CMAC;\n \thw-\u003ewiphy-\u003en_cipher_suites++;\n@@ -492,12 +495,12 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)\n \t * beacon protection must be handled by firmware,\n \t * so cannot be done with fips_enabled\n \t */\n-\tif (!fips_enabled \u0026\u0026 sec_key_ver \u0026\u0026\n+\tif (fips_allows(FIPS_EXCEPTION_WIFI_MFP) \u0026\u0026 sec_key_ver \u0026\u0026\n \t    fw_has_capa(\u0026mvm-\u003efw-\u003eucode_capa,\n \t\t\tIWL_UCODE_TLV_CAPA_BIGTK_TX_SUPPORT))\n \t\twiphy_ext_feature_set(hw-\u003ewiphy,\n \t\t\t\t      NL80211_EXT_FEATURE_BEACON_PROTECTION);\n-\telse if (!fips_enabled \u0026\u0026\n+\telse if (fips_allows(FIPS_EXCEPTION_WIFI_MFP) \u0026\u0026\n \t\t fw_has_capa(\u0026mvm-\u003efw-\u003eucode_capa,\n \t\t\t     IWL_UCODE_TLV_CAPA_BIGTK_SUPPORT))\n \t\twiphy_ext_feature_set(hw-\u003ewiphy,\n@@ -4244,6 +4247,8 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,\n \tcase WLAN_CIPHER_SUITE_GCMP_256:\n \t\tif (!iwl_mvm_has_new_tx_api(mvm))\n \t\t\tkey-\u003eflags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;\n+\t\tif (fips_enabled \u0026\u0026 (key-\u003eflags \u0026 IEEE80211_KEY_FLAG_PAIRWISE))\n+\t\t\tkey-\u003eflags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;\n \t\tbreak;\n \tcase WLAN_CIPHER_SUITE_AES_CMAC:\n \tcase WLAN_CIPHER_SUITE_BIP_GMAC_128:\ndiff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c\nindex 7f0b4f5daa214..6d223ef75bb40 100644\n--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c\n+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c\n@@ -6,6 +6,7 @@\n  */\n #include \u003clinux/etherdevice.h\u003e\n #include \u003clinux/skbuff.h\u003e\n+#include \u003clinux/fips.h\u003e\n #include \"iwl-trans.h\"\n #include \"mvm.h\"\n #include \"fw-api.h\"\n@@ -494,6 +495,14 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_sta *sta,\n \t\treturn 0;\n \tcase RX_MPDU_RES_STATUS_SEC_CMAC_GMAC_ENC:\n \t\tbreak;\n+\tcase RX_MPDU_RES_STATUS_SEC_ENC_ERR:\n+\t\tif (fips_enabled) {\n+\t\t\tIWL_DEBUG_RX(mvm,\n+\t\t\t\t     \"FIPS mode: firmware cannot decrypt, status: 0x%x\\n\",\n+\t\t\t\t     status);\n+\t\t\tbreak;\n+\t\t}\n+\t\tfallthrough;\n \tdefault:\n \t\t/*\n \t\t * Sometimes we can get frames that were not decrypted\ndiff --git a/include/linux/fips.h b/include/linux/fips.h\nindex c6961e932fef3..61fe58b0762c9 100644\n--- a/include/linux/fips.h\n+++ b/include/linux/fips.h\n@@ -2,17 +2,31 @@\n #ifndef _FIPS_H\n #define _FIPS_H\n \n+#include \u003clinux/bits.h\u003e\n+\n #ifdef CONFIG_CRYPTO_FIPS\n extern int fips_enabled;\n extern struct atomic_notifier_head fips_fail_notif_chain;\n \n void fips_fail_notify(void);\n+/*\n+ * fips_allows - check if a not fully FIPS-compliant feature is allowed\n+ * via an explicit boot-time exception (fips_exception=).\n+ * Not for fully FIPS-compliant features.\n+ */\n+int fips_allows(unsigned long feature);\n \n #else\n #define fips_enabled 0\n \n static inline void fips_fail_notify(void) {}\n+static inline int fips_allows(unsigned long feature)\n+{\n+\treturn 1;\n+}\n \n #endif\n \n+#define FIPS_EXCEPTION_WIFI_MFP\tBIT(0)\n+\n #endif\ndiff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c\nindex 49753b73aba26..0a50684d9cf65 100644\n--- a/net/mac80211/driver-ops.c\n+++ b/net/mac80211/driver-ops.c\n@@ -519,7 +519,7 @@ int drv_set_key(struct ieee80211_local *local,\n \t\t    !(sdata-\u003evif.active_links \u0026 BIT(key-\u003elink_id))))\n \t\treturn -ENOLINK;\n \n-\tif (fips_enabled)\n+\tif (!fips_allows(FIPS_EXCEPTION_WIFI_MFP))\n \t\treturn -EOPNOTSUPP;\n \n \ttrace_drv_set_key(local, cmd, sdata, sta, key);\ndiff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h\nindex f1c0b87fddd5f..a24230feb864d 100644\n--- a/net/mac80211/driver-ops.h\n+++ b/net/mac80211/driver-ops.h\n@@ -903,7 +903,7 @@ static inline void drv_set_rekey_data(struct ieee80211_local *local,\n \tif (!check_sdata_in_driver(sdata))\n \t\treturn;\n \n-\tif (fips_enabled)\n+\tif (!fips_allows(FIPS_EXCEPTION_WIFI_MFP))\n \t\treturn;\n \n \ttrace_drv_set_rekey_data(local, sdata, data);\n"
}

2/1 2026/10/01 11:41 agent patch-evaluator
3m Model:
core

Args:
null

Results:
{
  "EnableConfigs": [
    "CRYPTO_FIPS",
    "CRYPTO_DRBG",
    "CRYPTO_SELFTESTS",
    "CFG80211",
    "MAC80211",
    "MAC80211_HWSIM"
  ],
  "FocusSymbols": [
    "drv_set_key",
    "ieee80211_set_rekey_data",
    "fips_allows"
  ],
  "Reasoning": "The patch introduces a new FIPS exception mechanism (fips_allows and a sysctl fips_exception) in crypto/fips.c and modifies key management logic in net/mac80211 (drv_set_key and drv_set_rekey_data). While the iwlwifi changes target vendor-specific Intel hardware, the mac80211 and crypto modifications reside in reachable core subsystems and can be exercised in standard virtualized environments using mac80211_hwsim and nl80211 netlink commands.",
  "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 499c6407815a44f1670ce2ff2665ca2c5c5a6aa1
Author: syz-cluster <triage@syzkaller.com>
Date:   Thu Oct 1 11:41:47 2026 +0000

    syz-cluster: applied patch under review

diff --git a/crypto/fips.c b/crypto/fips.c
index c59711248d956..0f075e61a6577 100644
--- a/crypto/fips.c
+++ b/crypto/fips.c
@@ -21,6 +21,15 @@ EXPORT_SYMBOL_GPL(fips_enabled);
 ATOMIC_NOTIFIER_HEAD(fips_fail_notif_chain);
 EXPORT_SYMBOL_GPL(fips_fail_notif_chain);
 
+static unsigned long fips_exception;
+
+int fips_allows(unsigned long feature)
+{
+	return !fips_enabled ||
+	       (fips_exception & feature);
+}
+EXPORT_SYMBOL_GPL(fips_allows);
+
 /* Process kernel command-line parameter at boot time. fips=0 or fips=1 */
 static int __init fips_enable(char *str)
 {
@@ -34,6 +43,17 @@ static int __init fips_enable(char *str)
 
 __setup("fips=", fips_enable);
 
+static int __init fips_exception_setup(char *str)
+{
+	if (kstrtoul(str, 0, &fips_exception))
+		return 0;
+
+	pr_info("fips exceptions: 0x%lx\n", fips_exception);
+	return 1;
+}
+
+__setup("fips_exception=", fips_exception_setup);
+
 #define FIPS_MODULE_NAME CONFIG_CRYPTO_FIPS_NAME
 #ifdef CONFIG_CRYPTO_FIPS_CUSTOM_VERSION
 #define FIPS_MODULE_VERSION CONFIG_CRYPTO_FIPS_VERSION
@@ -52,6 +72,13 @@ static const struct ctl_table crypto_sysctl_table[] = {
 		.mode		= 0444,
 		.proc_handler	= proc_dointvec
 	},
+	{
+		.procname	= "fips_exception",
+		.data		= &fips_exception,
+		.maxlen		= sizeof(unsigned long),
+		.mode		= 0444,
+		.proc_handler	= proc_doulongvec_minmax
+	},
 	{
 		.procname	= "fips_name",
 		.data		= &fips_name,
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index 863d5e358152d..ca565b4311bbe 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -502,14 +502,16 @@ static void iwl_init_vht_hw_capab(struct iwl_trans *trans,
 	 */
 	switch (iwlwifi_mod_params.amsdu_size) {
 	case IWL_AMSDU_DEF:
-		if (trans->mac_cfg->mq_rx_supported && !fips_enabled)
+		if (trans->mac_cfg->mq_rx_supported &&
+		    fips_allows(FIPS_EXCEPTION_WIFI_MFP))
 			vht_cap->cap |=
 				IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
 		else
 			vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
 		break;
 	case IWL_AMSDU_2K:
-		if (trans->mac_cfg->mq_rx_supported && !fips_enabled)
+		if (trans->mac_cfg->mq_rx_supported &&
+		    fips_allows(FIPS_EXCEPTION_WIFI_MFP))
 			vht_cap->cap |=
 				IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
 		else
@@ -886,7 +888,7 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans,
 
 	/* EHT needs WPA3/MFP so cannot do it for fips_enabled */
 	if (!data->sku_cap_11be_enable || iwlwifi_mod_params.disable_11be ||
-	    fips_enabled)
+	    !fips_allows(FIPS_EXCEPTION_WIFI_MFP))
 		iftype_data->eht_cap.has_eht = false;
 
 	if (!data->sku_cap_11bn_enable || !iftype_data->eht_cap.has_eht)
@@ -1221,7 +1223,8 @@ static void iwl_init_sbands(struct iwl_trans *trans,
 	 * avoid spending time on scanning those channels and perhaps
 	 * even finding APs there that cannot be used.
 	 */
-	if (!fips_enabled && data->sku_cap_11ax_enable &&
+	if (fips_allows(FIPS_EXCEPTION_WIFI_MFP) &&
+	    data->sku_cap_11ax_enable &&
 	    !iwlwifi_mod_params.disable_11ax)
 		iwl_init_he_hw_capab(trans, data, sband, tx_chains, rx_chains,
 				     fw);
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
index 3a4c8fda68d0a..3fd88420cd17f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
@@ -167,7 +167,7 @@ static void iwl_mld_hw_set_security(struct iwl_mld *mld)
 		WLAN_CIPHER_SUITE_BIP_GMAC_256
 	};
 
-	if (fips_enabled)
+	if (!fips_allows(FIPS_EXCEPTION_WIFI_MFP))
 		return;
 
 	hw->wiphy->n_cipher_suites = ARRAY_SIZE(mld_ciphers);
@@ -176,6 +176,9 @@ static void iwl_mld_hw_set_security(struct iwl_mld *mld)
 	ieee80211_hw_set(hw, MFP_CAPABLE);
 	wiphy_ext_feature_set(hw->wiphy,
 			      NL80211_EXT_FEATURE_BEACON_PROTECTION);
+
+	if (fips_enabled)
+		IWL_WARN(mld, "FIPS: MFP enabled with known firmware limitation\n");
 }
 
 static void iwl_mld_hw_set_antennas(struct iwl_mld *mld)
@@ -344,7 +347,7 @@ static void iwl_mac_hw_set_wiphy(struct iwl_mld *mld)
 	if (mld->nvm_data->sku_cap_11be_enable &&
 	    !iwlwifi_mod_params.disable_11ax &&
 	    !iwlwifi_mod_params.disable_11be &&
-	    !fips_enabled)
+	    fips_allows(FIPS_EXCEPTION_WIFI_MFP))
 		wiphy->flags |= WIPHY_FLAG_SUPPORTS_MLO;
 
 	/* the firmware uses u8 for num of iterations, but 0xff is saved for
@@ -2227,6 +2230,9 @@ static int iwl_mld_set_key_add(struct iwl_mld *mld,
 	case WLAN_CIPHER_SUITE_CCMP:
 	case WLAN_CIPHER_SUITE_GCMP:
 	case WLAN_CIPHER_SUITE_GCMP_256:
+		if (fips_enabled && (key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+			key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
+		break;
 	case WLAN_CIPHER_SUITE_AES_CMAC:
 	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
 	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 5bd246e379432..38fe710ef414f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -462,8 +462,11 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
 		IWL_ERR(mvm,
 			"iwlmvm doesn't allow to disable BT Coex, check bt_coex_active module parameter\n");
 
-	if (!fips_enabled)
+	if (fips_allows(FIPS_EXCEPTION_WIFI_MFP)) {
 		ieee80211_hw_set(hw, MFP_CAPABLE);
+		if (fips_enabled)
+			IWL_WARN(mvm, "FIPS: MFP enabled with known firmware limitation\n");
+	}
 
 	mvm->ciphers[hw->wiphy->n_cipher_suites] = WLAN_CIPHER_SUITE_AES_CMAC;
 	hw->wiphy->n_cipher_suites++;
@@ -492,12 +495,12 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
 	 * beacon protection must be handled by firmware,
 	 * so cannot be done with fips_enabled
 	 */
-	if (!fips_enabled && sec_key_ver &&
+	if (fips_allows(FIPS_EXCEPTION_WIFI_MFP) && sec_key_ver &&
 	    fw_has_capa(&mvm->fw->ucode_capa,
 			IWL_UCODE_TLV_CAPA_BIGTK_TX_SUPPORT))
 		wiphy_ext_feature_set(hw->wiphy,
 				      NL80211_EXT_FEATURE_BEACON_PROTECTION);
-	else if (!fips_enabled &&
+	else if (fips_allows(FIPS_EXCEPTION_WIFI_MFP) &&
 		 fw_has_capa(&mvm->fw->ucode_capa,
 			     IWL_UCODE_TLV_CAPA_BIGTK_SUPPORT))
 		wiphy_ext_feature_set(hw->wiphy,
@@ -4244,6 +4247,8 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
 	case WLAN_CIPHER_SUITE_GCMP_256:
 		if (!iwl_mvm_has_new_tx_api(mvm))
 			key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
+		if (fips_enabled && (key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+			key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
 		break;
 	case WLAN_CIPHER_SUITE_AES_CMAC:
 	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 7f0b4f5daa214..6d223ef75bb40 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -6,6 +6,7 @@
  */
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/fips.h>
 #include "iwl-trans.h"
 #include "mvm.h"
 #include "fw-api.h"
@@ -494,6 +495,14 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
 		return 0;
 	case RX_MPDU_RES_STATUS_SEC_CMAC_GMAC_ENC:
 		break;
+	case RX_MPDU_RES_STATUS_SEC_ENC_ERR:
+		if (fips_enabled) {
+			IWL_DEBUG_RX(mvm,
+				     "FIPS mode: firmware cannot decrypt, status: 0x%x\n",
+				     status);
+			break;
+		}
+		fallthrough;
 	default:
 		/*
 		 * Sometimes we can get frames that were not decrypted
diff --git a/include/linux/fips.h b/include/linux/fips.h
index c6961e932fef3..61fe58b0762c9 100644
--- a/include/linux/fips.h
+++ b/include/linux/fips.h
@@ -2,17 +2,31 @@
 #ifndef _FIPS_H
 #define _FIPS_H
 
+#include <linux/bits.h>
+
 #ifdef CONFIG_CRYPTO_FIPS
 extern int fips_enabled;
 extern struct atomic_notifier_head fips_fail_notif_chain;
 
 void fips_fail_notify(void);
+/*
+ * fips_allows - check if a not fully FIPS-compliant feature is allowed
+ * via an explicit boot-time exception (fips_exception=).
+ * Not for fully FIPS-compliant features.
+ */
+int fips_allows(unsigned long feature);
 
 #else
 #define fips_enabled 0
 
 static inline void fips_fail_notify(void) {}
+static inline int fips_allows(unsigned long feature)
+{
+	return 1;
+}
 
 #endif
 
+#define FIPS_EXCEPTION_WIFI_MFP	BIT(0)
+
 #endif
diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c
index 49753b73aba26..0a50684d9cf65 100644
--- a/net/mac80211/driver-ops.c
+++ b/net/mac80211/driver-ops.c
@@ -519,7 +519,7 @@ int drv_set_key(struct ieee80211_local *local,
 		    !(sdata->vif.active_links & BIT(key->link_id))))
 		return -ENOLINK;
 
-	if (fips_enabled)
+	if (!fips_allows(FIPS_EXCEPTION_WIFI_MFP))
 		return -EOPNOTSUPP;
 
 	trace_drv_set_key(local, cmd, sdata, sta, key);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index f1c0b87fddd5f..a24230feb864d 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -903,7 +903,7 @@ static inline void drv_set_rekey_data(struct ieee80211_local *local,
 	if (!check_sdata_in_driver(sdata))
 		return;
 
-	if (fips_enabled)
+	if (!fips_allows(FIPS_EXCEPTION_WIFI_MFP))
 		return;
 
 	trace_drv_set_rekey_data(local, sdata, data);

3/2 2026/10/01 11:41 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 6969
							output: 33
							thoughts: 1077
						

Thoughts:
**Fuzzing Suitability Analysis: A Deep Dive**

Okay, let's break this down. My goal is to determine if this patch series warrants a full-blown fuzzing campaign with syzkaller. First, let's dissect the code changes methodically.

Alright, the core of the change seems to center around `crypto/fips.c`. It introduces the `fips_exception` variable, along with a sysctl entry and a boot parameter to control it. The critical part is the `fips_allows()` function. It appears to act as a gatekeeper, allowing certain features to bypass the FIPS restrictions based on the state of `fips_enabled` and this new `fips_exception` flag.

I see a new include file, `include/linux/fips.h` which just declares the new `FIPS_EXCEPTION_WIFI_MFP` flag.

Now, the interesting bit is the interaction with the `iwlwifi` driver, but wait.. is that reachable in the standard QEMU/syzkaller environment? Oh, and it's a hardware driver!

Hold on! The meat of the patch *isn't* directly in iwlwifi but *in* `net/mac80211/driver-ops.c` and `.h`! That's the core wireless stack! And *that* is something syzkaller has a history of fuzzing, especially via `mac80211_hwsim`. That's a good sign!

Now, the critical part... Let's analyze the code change! Before, `if (fips_enabled)` triggered a -EOPNOTSUPP, effectively blocking certain operations. Now, it's `if (!fips_allows(FIPS_EXCEPTION_WIFI_MFP))`.

Okay, I'm tracking this... `fips_allows()` has two cases:
1.  If `!fips_enabled`, the function always returns true (1), so the check evaluates to `!1`, which is `0`, and we skip the error.
2. If `fips_enabled` is true (1), and `fips_exception` is set, `fips_allows()` returns `1`, so `!1` is `0`, we proceed!
3. If `fips_enabled` is true (1), and `fips_exception` is NOT set, `fips_allows()` returns `0`, so `!0` is `1`, so we return `-EOPNOTSUPP`.

Okay, that's clear. Previously, we simply disabled the functionality if FIPS was enabled. Now, the functionality can be bypassed if the `fips_exception` flag is set.

The changes in `crypto/fips.c` are straightforward. It's really the control added to mac80211 that's significant. The `iwlwifi` connection helps me to determine how syzkaller tests mac80211.

Can syzkaller, through `mac80211_hwsim` or otherwise, hit `drv_set_key` and trigger these new code paths? That's the key question. We have to search for the driver-op function to determine if its callable.

**Conclusion:**

Given that syzkaller extensively fuzzes `mac80211`, and these changes directly influence the error return behavior of key driver operations within mac80211, *this patch series is highly likely to benefit from a syzkaller fuzzing campaign*. The new `fips_allows()` function and its interaction with `fips_exception` introduces a new control variable in the fuzzing surface. It seems to be a good target for fuzzing.



4/2 2026/10/01 11:42 tool grepper
0m Args:
{
  "Expression": "drv_set_key",
  "PathPrefix": "net/mac80211"
}

Results:
{
  "Output": "net/mac80211/driver-ops.c=460=void drv_link_info_changed(struct ieee80211_local *local,\n--\nnet/mac80211/driver-ops.c-502-\nnet/mac80211/driver-ops.c:503:int drv_set_key(struct ieee80211_local *local,\nnet/mac80211/driver-ops.c-504-\t\tenum set_key_cmd cmd,\n--\nnet/mac80211/driver-ops.c-524-\nnet/mac80211/driver-ops.c:525:\ttrace_drv_set_key(local, cmd, sdata, sta, key);\nnet/mac80211/driver-ops.c-526-\tret = local-\u003eops-\u003eset_key(\u0026local-\u003ehw, cmd, \u0026sdata-\u003evif, sta, key);\n--\nnet/mac80211/driver-ops.h=232=static inline int drv_set_tim(struct ieee80211_local *local,\n--\nnet/mac80211/driver-ops.h-242-\nnet/mac80211/driver-ops.h:243:int drv_set_key(struct ieee80211_local *local,\nnet/mac80211/driver-ops.h-244-\t\tenum set_key_cmd cmd,\n--\nnet/mac80211/key.c=120=static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)\n--\nnet/mac80211/key.c-180-\nnet/mac80211/key.c:181:\tret = drv_set_key(key-\u003elocal, SET_KEY, sdata,\nnet/mac80211/key.c-182-\t\t\t  sta ? \u0026sta-\u003esta : NULL, \u0026key-\u003econf);\n--\nnet/mac80211/key.c=231=static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)\n--\nnet/mac80211/key.c-259-\tkey-\u003eflags \u0026= ~KEY_FLAG_UPLOADED_TO_HARDWARE;\nnet/mac80211/key.c:260:\tret = drv_set_key(key-\u003elocal, DISABLE_KEY, sdata,\nnet/mac80211/key.c-261-\t\t\t  sta ? \u0026sta-\u003esta : NULL, \u0026key-\u003econf);\n--\nnet/mac80211/trace.h=624=TRACE_EVENT(drv_set_tim,\n--\nnet/mac80211/trace.h-647-\nnet/mac80211/trace.h:648:TRACE_EVENT(drv_set_key,\nnet/mac80211/trace.h-649-\tTP_PROTO(struct ieee80211_local *local,\n"
}

5/2 2026/10/01 11:42 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 9703
							output: 42
							thoughts: 70
						

Thoughts:
Here's my summary, as I delve into this code:

**Diving into the MAC80211 Driver Operations**

Okay, time to get my hands dirty. I'm going to focus on the `net/mac80211` directory, specifically examining the functions `drv_set_key` and `drv_set_rekey_data`. I know these are critical for key management within the MAC80211 framework, so understanding their implementation is key to whatever problem I'm trying to solve. I'll be looking in both `driver-ops.c` and its corresponding header file, `driver-ops.h` to see how these two are defined and called. Let's see how they interact with each other and what kind of structs or data they use. I need to understand the flow of security context here.

I'll start with `driver-ops.c`, and I'm going to zero in on the area around line 519. It looks like that's a good starting point and I need to see exactly where these functions are called, and in what context, to be able to understand the flow here. I'll need to use some basic grep/find to trace those calls, if I can't find them there. I need to figure out what those functions are _doing_.



6/2 2026/10/01 11:42 tool read-file
0m Args:
{
  "File": "net/mac80211/driver-ops.c",
  "FirstLine": 500,
  "LineCount": 40
}

Results:
{
  "Contents": " 500:\t\ttrace_drv_return_void(local);\n 501:\t}\n 502:\t\n 503:\tint drv_set_key(struct ieee80211_local *local,\n 504:\t\t\tenum set_key_cmd cmd,\n 505:\t\t\tstruct ieee80211_sub_if_data *sdata,\n 506:\t\t\tstruct ieee80211_sta *sta,\n 507:\t\t\tstruct ieee80211_key_conf *key)\n 508:\t{\n 509:\t\tint ret;\n 510:\t\n 511:\t\tmight_sleep();\n 512:\t\tlockdep_assert_wiphy(local-\u003ehw.wiphy);\n 513:\t\n 514:\t\tsdata = get_bss_sdata(sdata);\n 515:\t\tif (!check_sdata_in_driver(sdata))\n 516:\t\t\treturn -EIO;\n 517:\t\n 518:\t\tif (WARN_ON(key-\u003elink_id \u003e= 0 \u0026\u0026 sdata-\u003evif.active_links \u0026\u0026\n 519:\t\t\t    !(sdata-\u003evif.active_links \u0026 BIT(key-\u003elink_id))))\n 520:\t\t\treturn -ENOLINK;\n 521:\t\n 522:\t\tif (!fips_allows(FIPS_EXCEPTION_WIFI_MFP))\n 523:\t\t\treturn -EOPNOTSUPP;\n 524:\t\n 525:\t\ttrace_drv_set_key(local, cmd, sdata, sta, key);\n 526:\t\tret = local-\u003eops-\u003eset_key(\u0026local-\u003ehw, cmd, \u0026sdata-\u003evif, sta, key);\n 527:\t\ttrace_drv_return_int(local, ret);\n 528:\t\treturn ret;\n 529:\t}\n 530:\t\n 531:\tint drv_change_vif_links(struct ieee80211_local *local,\n 532:\t\t\t\t struct ieee80211_sub_if_data *sdata,\n 533:\t\t\t\t u16 old_links, u16 new_links,\n 534:\t\t\t\t struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS])\n 535:\t{\n 536:\t\tstruct ieee80211_link_data *link;\n 537:\t\tunsigned long links_to_add;\n 538:\t\tunsigned long links_to_rem;\n 539:\t\tunsigned int link_id;\n"
}

7/2 2026/10/01 11:42 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 10801
							output: 42
							thoughts: 32
						

Thoughts:
Here's my take on those thoughts:

**Checking `drv_set_rekey_data` in `net/mac80211/driver-ops.h`**

Alright, before we get too deep into this, I need to make sure we haven't overlooked something fundamental related to rekeying data. My immediate thought is, let's just quickly check `drv_set_rekey_data` in the `net/mac80211/driver-ops.h` header file. It’s the usual spot to look for any driver-specific handling of rekeying, and it's always smart to have a quick glance to rule out obvious connections or potential interactions with whatever we are doing. No point reinventing the wheel! This should take a second.



8/2 2026/10/01 11:42 tool read-file
0m Args:
{
  "File": "net/mac80211/driver-ops.h",
  "FirstLine": 895,
  "LineCount": 25
}

Results:
{
  "Contents": " 895:\t\n 896:\tstatic inline void drv_set_rekey_data(struct ieee80211_local *local,\n 897:\t\t\t\t\t      struct ieee80211_sub_if_data *sdata,\n 898:\t\t\t\t\t      struct cfg80211_gtk_rekey_data *data)\n 899:\t{\n 900:\t\tmight_sleep();\n 901:\t\tlockdep_assert_wiphy(local-\u003ehw.wiphy);\n 902:\t\n 903:\t\tif (!check_sdata_in_driver(sdata))\n 904:\t\t\treturn;\n 905:\t\n 906:\t\tif (!fips_allows(FIPS_EXCEPTION_WIFI_MFP))\n 907:\t\t\treturn;\n 908:\t\n 909:\t\ttrace_drv_set_rekey_data(local, sdata, data);\n 910:\t\tif (local-\u003eops-\u003eset_rekey_data)\n 911:\t\t\tlocal-\u003eops-\u003eset_rekey_data(\u0026local-\u003ehw, \u0026sdata-\u003evif, data);\n 912:\t\ttrace_drv_return_void(local);\n 913:\t}\n 914:\t\n 915:\tstatic inline void drv_event_callback(struct ieee80211_local *local,\n 916:\t\t\t\t\t      struct ieee80211_sub_if_data *sdata,\n 917:\t\t\t\t\t      const struct ieee80211_event *event)\n 918:\t{\n 919:\t\ttrace_drv_event_callback(local, sdata, event);\n"
}

9/2 2026/10/01 11:42 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 11491
							output: 27
							thoughts: 3371
						

Thoughts:
**Analysis of Kernel Patch for FIPS Exception Handling**

Alright, let's break this down. First, I see they've added a new variable `fips_exception` controlled by a boot parameter and a sysctl entry in `/proc/sys/crypto`. Crucially, this sysctl is read-only, which limits some attack surface, but it's still accessible from userspace. Next, there's a new function, `fips_allows()`, which is exported using `EXPORT_SYMBOL_GPL`. This immediately grabs my attention. An exported function is a signal the intent is for other modules to access this function.

Now, this `fips_allows()` function introduces a conditional bypass for FIPS restrictions based on the `fips_exception` value.  The key here is that if `fips_exception` is set, certain FIPS checks are bypassed. So, the question becomes, what features are these exceptions related to and where are these functions being called?

Looking at the `#define FIPS_EXCEPTION_WIFI_MFP BIT(0)` in `include/linux/fips.h` and the changes in `net/mac80211/driver-ops.c`, specifically `drv_set_key` and `drv_set_rekey_data`, I can see a clear connection to wireless key management. `fips_allows` is called, potentially bypassing FIPS restrictions when setting keys in the wireless stack.

The modification in the iwlwifi drivers is less immediately concerning, because that relates to specific hardware. However, the `mac80211` changes are definitely of concern, because `mac80211` is part of core kernel networking and is readily accessible in fuzzing environments.

I then check my triage guidelines for when fuzzing is required. I see that changes in reachable code must be fuzzed, regardless of how minor the change appears. In this case, `net/mac80211` is a core subsystem, and `crypto/fips.c` introduces a new sysctl read from userspace. Furthermore, `drv_set_key` and `drv_set_rekey_data` are directly invoked by key setup and deinstallation in `mac80211`, triggered by actions from user space. The important thing is that `mac80211` *is* reachable, and syzkaller *does* have full support for nl80211! I verify this by checking that key functions in the wireless stack can be reached by using nl80211 commands in syzkaller. The changes to the `fips_allows()` function are, therefore, highly relevant, because a user can control these conditions through `fips_exception`. Therefore, it's clear these modifications *must* be fuzzed.



10/2 2026/10/01 11:42 tool grepper
0m Args:
{
  "Expression": "crypto_sysctl_table",
  "PathPrefix": "crypto"
}

Results:
{
  "Output": "crypto/fips.c=65=static char fips_version[] = FIPS_MODULE_VERSION;\ncrypto/fips.c-66-\ncrypto/fips.c:67:static const struct ctl_table crypto_sysctl_table[] = {\ncrypto/fips.c-68-\t{\n--\ncrypto/fips.c=100=static void crypto_proc_fips_init(void)\ncrypto/fips.c-101-{\ncrypto/fips.c:102:\tcrypto_sysctls = register_sysctl(\"crypto\", crypto_sysctl_table);\ncrypto/fips.c-103-}\n"
}

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

Args:
null

Results:
null

Tokens:
							input: 15667
							output: 27
							thoughts: 20
						

Thoughts:
Okay, here's my take on those thoughts, tailored for an expert audience:

**Investigating FIPS Compliance in the Crypto Subsystem**

Alright, let's dive in. I need to quickly ascertain the status of FIPS (Federal Information Processing Standards) compliance within our kernel crypto implementation. My immediate thought is to zero in on `crypto/Kconfig`. That's the obvious place to start – it's where the kernel's configuration options related to cryptographic algorithms and features are defined. Specifically, I'm looking for the `CONFIG_CRYPTO_FIPS` option. Its presence, or lack thereof, will be the initial indicator of how deeply FIPS considerations have been integrated. Depending on the existing structure, the details behind the configuration option itself will provide additional insights into the framework's design. This will give a good starting point for further inquiry.



12/2 2026/10/01 11:42 tool grepper
0m Args:
{
  "Expression": "config CRYPTO_FIPS",
  "PathPrefix": "crypto"
}

Results:
{
  "Output": "crypto/Kconfig=22=menu \"Crypto core or helper\"\ncrypto/Kconfig-23-\ncrypto/Kconfig:24:config CRYPTO_FIPS\ncrypto/Kconfig-25-\tbool \"FIPS 200 compliance\"\n--\ncrypto/Kconfig-33-\ncrypto/Kconfig:34:config CRYPTO_FIPS_NAME\ncrypto/Kconfig-35-\tstring \"FIPS Module Name\"\n--\ncrypto/Kconfig-41-\ncrypto/Kconfig:42:config CRYPTO_FIPS_CUSTOM_VERSION\ncrypto/Kconfig-43-\tbool \"Use Custom FIPS Module Version\"\n--\ncrypto/Kconfig-46-\ncrypto/Kconfig:47:config CRYPTO_FIPS_VERSION\ncrypto/Kconfig-48-\tstring \"FIPS Module Version\"\n"
}

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

Args:
null

Results:
null

Tokens:
							input: 16106
							output: 31
							thoughts: 16
						

Thoughts:
Okay, let's dive into this. Here's my thought process:

**Diving into crypto/Kconfig**

Alright, I'm going to take a look at `crypto/Kconfig`. Specifically, I'm focusing my attention around line 24. My experience tells me that `Kconfig` files are the backbone of configuration systems, particularly in the kernel world. I'm expecting this file to define various crypto-related options, dependencies, and help text. Knowing this is a crypto-specific `Kconfig` file, I'm anticipating that it will guide configuration of kernel's cryptography functionality. I'm setting my mental context to understand which crypto features are controllable at compile-time and how these features are organized. Line 24 seems like a potential starting point for a relevant section. Let's see what gems we can unearth!



14/2 2026/10/01 11:42 tool read-file
0m Args:
{
  "File": "crypto/Kconfig",
  "FirstLine": 22,
  "LineCount": 25
}

Results:
{
  "Contents": "  22:\tmenu \"Crypto core or helper\"\n  23:\t\n  24:\tconfig CRYPTO_FIPS\n  25:\t\tbool \"FIPS 200 compliance\"\n  26:\t\tdepends on CRYPTO_DRBG=y \u0026\u0026 CRYPTO_SELFTESTS\n  27:\t\tdepends on (MODULE_SIG || !MODULES)\n  28:\t\thelp\n  29:\t\t  This option enables the fips boot option which is\n  30:\t\t  required if you want the system to operate in a FIPS 200\n  31:\t\t  certification.  You should say no unless you know what\n  32:\t\t  this is.\n  33:\t\n  34:\tconfig CRYPTO_FIPS_NAME\n  35:\t\tstring \"FIPS Module Name\"\n  36:\t\tdefault \"Linux Kernel Cryptographic API\"\n  37:\t\tdepends on CRYPTO_FIPS\n  38:\t\thelp\n  39:\t\t  This option sets the FIPS Module name reported by the Crypto API via\n  40:\t\t  the /proc/sys/crypto/fips_name file.\n  41:\t\n  42:\tconfig CRYPTO_FIPS_CUSTOM_VERSION\n  43:\t\tbool \"Use Custom FIPS Module Version\"\n  44:\t\tdepends on CRYPTO_FIPS\n  45:\t\tdefault n\n  46:\t\n"
}

15/2 2026/10/01 11:42 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 16682
							output: 25
							thoughts: 19
						

Thoughts:
Okay, here's my summary, tailored for an expert audience, presented as my own thought process:

**Diving into the FIPS Compilation**

Alright, time to get my hands dirty with this `fips.c` compilation process. I need to understand exactly how it’s being built within the `crypto/Makefile`. This likely dictates a lot about the security context, any potential overrides, and how it’s integrated with other cryptographic components. I want to see if there are any specific compiler flags being employed for FIPS compliance, like `-fips`, or something similar, maybe `-D` preprocessor definitions that enable FIPS-specific code paths. Are they using a separate object file? Is there a link step that's crucial for the FIPS module? What’s the build process looking like at the macro level and the micro level? Knowing this, I can figure out what is important here and where the vulnerabilities would be.



16/2 2026/10/01 11:42 tool grepper
0m Args:
{
  "Expression": "fips",
  "PathPrefix": "crypto/Makefile"
}

Results:
{
  "Output": "crypto/Makefile=11=obj-$(CONFIG_CRYPTO_ENGINE) += crypto_engine.o\ncrypto/Makefile:12:obj-$(CONFIG_CRYPTO_FIPS) += fips.o\ncrypto/Makefile-13-\n"
}

17/2 2026/10/01 11:42 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 16990
							output: 35
							thoughts: 46
						

Thoughts:
Okay, here's my interpretation of that thought process, tailored for an expert audience:

**Kernel Module Inclusion and Configuration**

Right, so I see a line specifying `obj-$(CONFIG_CRYPTO_FIPS) += fips.o`. My initial thought is immediately about the build system and how conditional object inclusion works in the Linux kernel. This line means that if the `CONFIG_CRYPTO_FIPS` Kconfig option is enabled, the `fips.o` object file will be included in the build for that specific module or directory. Fairly straightforward, part of standard kernel build setup.

Now, I'm thinking about related modules. The next thing that jumps to mind is `MAC80211`. Since FIPS often relates to security, and wireless drivers are frequently subject to security scrutiny, my first inclination is to check the `net/mac80211/Kconfig` file. I need to see what security-related options, dependencies, or potential FIPS compliance requirements are defined there for that subsystem. This is the logical next step in assessing the broader implications.



18/2 2026/10/01 11:42 tool grepper
0m Args:
{
  "Expression": "config MAC80211",
  "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--\nnet/mac80211/Kconfig=19=if MAC80211 != n\nnet/mac80211/Kconfig-20-\nnet/mac80211/Kconfig:21:config MAC80211_HAS_RC\nnet/mac80211/Kconfig-22-\tbool\nnet/mac80211/Kconfig-23-\nnet/mac80211/Kconfig:24:config MAC80211_RC_MINSTREL\nnet/mac80211/Kconfig-25-\tbool \"Minstrel\" if EXPERT\n--\nnet/mac80211/Kconfig=31=choice\n--\nnet/mac80211/Kconfig-40-\nnet/mac80211/Kconfig:41:config MAC80211_RC_DEFAULT_MINSTREL\nnet/mac80211/Kconfig-42-\tbool \"Minstrel\"\n--\nnet/mac80211/Kconfig=48=endchoice\nnet/mac80211/Kconfig-49-\nnet/mac80211/Kconfig:50:config MAC80211_RC_DEFAULT\nnet/mac80211/Kconfig-51-\tstring\n--\nnet/mac80211/Kconfig=57=comment \"Some wireless drivers require a rate control algorithm\"\n--\nnet/mac80211/Kconfig-59-\nnet/mac80211/Kconfig:60:config MAC80211_KUNIT_TEST\nnet/mac80211/Kconfig-61-\ttristate \"KUnit tests for mac80211\" if !KUNIT_ALL_TESTS\n--\nnet/mac80211/Kconfig-69-\nnet/mac80211/Kconfig:70:config MAC80211_MESH\nnet/mac80211/Kconfig-71-\tbool \"Enable mac80211 mesh networking support\"\n--\nnet/mac80211/Kconfig-78-\nnet/mac80211/Kconfig:79:config MAC80211_LEDS\nnet/mac80211/Kconfig-80-\tbool \"Enable LED triggers\"\n--\nnet/mac80211/Kconfig-87-\nnet/mac80211/Kconfig:88:config MAC80211_DEBUGFS\nnet/mac80211/Kconfig-89-\tbool \"Export mac80211 internals in DebugFS\"\n--\nnet/mac80211/Kconfig-96-\nnet/mac80211/Kconfig:97:config MAC80211_MESSAGE_TRACING\nnet/mac80211/Kconfig-98-\tbool \"Trace all mac80211 debug messages\"\n--\nnet/mac80211/Kconfig-109-\nnet/mac80211/Kconfig:110:menuconfig MAC80211_DEBUG_MENU\nnet/mac80211/Kconfig-111-\tbool \"Select mac80211 debugging features\"\n--\nnet/mac80211/Kconfig-115-\nnet/mac80211/Kconfig:116:config MAC80211_NOINLINE\nnet/mac80211/Kconfig-117-\tbool \"Do not inline TX/RX handlers\"\n--\nnet/mac80211/Kconfig-131-\nnet/mac80211/Kconfig:132:config MAC80211_VERBOSE_DEBUG\nnet/mac80211/Kconfig-133-\tbool \"Verbose debugging output\"\n--\nnet/mac80211/Kconfig-142-\nnet/mac80211/Kconfig:143:config MAC80211_MLME_DEBUG\nnet/mac80211/Kconfig-144-\tbool \"Verbose managed MLME output\"\n--\nnet/mac80211/Kconfig-153-\nnet/mac80211/Kconfig:154:config MAC80211_STA_DEBUG\nnet/mac80211/Kconfig-155-\tbool \"Verbose station debugging\"\n--\nnet/mac80211/Kconfig-162-\nnet/mac80211/Kconfig:163:config MAC80211_HT_DEBUG\nnet/mac80211/Kconfig-164-\tbool \"Verbose HT debugging\"\n--\nnet/mac80211/Kconfig-174-\nnet/mac80211/Kconfig:175:config MAC80211_OCB_DEBUG\nnet/mac80211/Kconfig-176-\tbool \"Verbose OCB debugging\"\n--\nnet/mac80211/Kconfig-185-\nnet/mac80211/Kconfig:186:config MAC80211_IBSS_DEBUG\nnet/mac80211/Kconfig-187-\tbool \"Verbose IBSS debugging\"\n--\nnet/mac80211/Kconfig-196-\nnet/mac80211/Kconfig:197:config MAC80211_PS_DEBUG\nnet/mac80211/Kconfig-198-\tbool \"Verbose powersave mode debugging\"\n--\nnet/mac80211/Kconfig-208-\nnet/mac80211/Kconfig:209:config MAC80211_MPL_DEBUG\nnet/mac80211/Kconfig-210-\tbool \"Verbose mesh peer link debugging\"\n--\nnet/mac80211/Kconfig-221-\nnet/mac80211/Kconfig:222:config MAC80211_MPATH_DEBUG\nnet/mac80211/Kconfig-223-\tbool \"Verbose mesh path debugging\"\n--\nnet/mac80211/Kconfig-234-\nnet/mac80211/Kconfig:235:config MAC80211_MHWMP_DEBUG\nnet/mac80211/Kconfig-236-\tbool \"Verbose mesh HWMP routing debugging\"\n--\nnet/mac80211/Kconfig-247-\nnet/mac80211/Kconfig:248:config MAC80211_MESH_SYNC_DEBUG\nnet/mac80211/Kconfig-249-\tbool \"Verbose mesh synchronization debugging\"\n--\nnet/mac80211/Kconfig-258-\nnet/mac80211/Kconfig:259:config MAC80211_MESH_CSA_DEBUG\nnet/mac80211/Kconfig-260-\tbool \"Verbose mesh channel switch debugging\"\n--\nnet/mac80211/Kconfig-269-\nnet/mac80211/Kconfig:270:config MAC80211_MESH_PS_DEBUG\nnet/mac80211/Kconfig-271-\tbool \"Verbose mesh powersave debugging\"\n--\nnet/mac80211/Kconfig-280-\nnet/mac80211/Kconfig:281:config MAC80211_TDLS_DEBUG\nnet/mac80211/Kconfig-282-\tbool \"Verbose TDLS debugging\"\n--\nnet/mac80211/Kconfig-292-\nnet/mac80211/Kconfig:293:config MAC80211_DEBUG_COUNTERS\nnet/mac80211/Kconfig-294-\tbool \"Extra statistics for TX/RX debugging\"\n--\nnet/mac80211/Kconfig-307-\nnet/mac80211/Kconfig:308:config MAC80211_STA_HASH_MAX_SIZE\nnet/mac80211/Kconfig-309-\tint \"Station hash table maximum size\" if MAC80211_DEBUG_MENU\n"
}

19/2 2026/10/01 11:42 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 19484
							output: 26
							thoughts: 20
						

Thoughts:
Okay, here's my take on summarizing those thoughts, speaking as an expert, and assuming a high degree of familiarity with version control:

**Investigating Patch Context through Git History**

Alright, I'm looking at this patch and immediately my mind goes to understanding its genesis. Before I even dive into the code itself, I need context. The commit message is the starting point, the key to understanding *why* this change was made, and often, what problem it's trying to solve. But it's not just about the message; the author's rationale, hopefully captured within that message or in related commit details, is crucial. I want to quickly understand the intent behind these lines. Was this a bug fix? A new feature implementation? A performance optimization? Understanding the *why* guides me as I evaluate the *how*. It's a natural reflex: good commit hygiene is a cornerstone of maintainable code, and a well-written message should provide a helpful roadmap for any engineer who comes to understand the change. Jumping into the log is the fastest way to get that roadmap.



20/2 2026/10/01 11:43 tool grepper
0m Args:
{
  "Expression": "fips_allows",
  "PathPrefix": "crypto/"
}

Results:
{
  "Output": "crypto/fips.c=24=static unsigned long fips_exception;\ncrypto/fips.c-25-\ncrypto/fips.c:26:int fips_allows(unsigned long feature)\ncrypto/fips.c-27-{\n--\ncrypto/fips.c-30-}\ncrypto/fips.c:31:EXPORT_SYMBOL_GPL(fips_allows);\ncrypto/fips.c-32-\n"
}

21/2 2026/10/01 11:43 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 19877
							output: 18
							thoughts: 134
						

Thoughts:
**Analyzing the Commit and Codebase**

Okay, first things first, I need to understand this commit. I was going to use `git log -1`, a standard approach, but I'm reminded that grepper doesn't execute that command directly. Ah, right, the commit details *are* right here in the prompt. I see: `Author: syz-cluster <triage@syzkaller.com>`, `Date: Thu Oct 1 11:41:47 2026 +0000`, and the commit message "syz-cluster: applied patch under review". Good. That gives me the basic context.

Now, I need to see what this means for the codebase. My next step is to examine if there are other places where `fips_allows` is used. I'll need to locate where else this is called.



22/2 2026/10/01 11:43 tool grepper
0m Args:
{
  "Expression": "fips_allows"
}

Results:
{
  "Output": "crypto/fips.c=24=static unsigned long fips_exception;\ncrypto/fips.c-25-\ncrypto/fips.c:26:int fips_allows(unsigned long feature)\ncrypto/fips.c-27-{\n--\ncrypto/fips.c-30-}\ncrypto/fips.c:31:EXPORT_SYMBOL_GPL(fips_allows);\ncrypto/fips.c-32-\n--\ndrivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c=456=static void iwl_init_vht_hw_capab(struct iwl_trans *trans,\n--\ndrivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c-505-\t\tif (trans-\u003emac_cfg-\u003emq_rx_supported \u0026\u0026\ndrivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c:506:\t\t    fips_allows(FIPS_EXCEPTION_WIFI_MFP))\ndrivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c-507-\t\t\tvht_cap-\u003ecap |=\n--\ndrivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c-513-\t\tif (trans-\u003emac_cfg-\u003emq_rx_supported \u0026\u0026\ndrivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c:514:\t\t    fips_allows(FIPS_EXCEPTION_WIFI_MFP))\ndrivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c-515-\t\t\tvht_cap-\u003ecap |=\n--\ndrivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c=877=iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans,\n--\ndrivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c-890-\tif (!data-\u003esku_cap_11be_enable || iwlwifi_mod_params.disable_11be ||\ndrivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c:891:\t    !fips_allows(FIPS_EXCEPTION_WIFI_MFP))\ndrivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c-892-\t\tiftype_data-\u003eeht_cap.has_eht = false;\n--\ndrivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c=1169=static void iwl_init_sbands(struct iwl_trans *trans,\n--\ndrivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c-1225-\t */\ndrivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c:1226:\tif (fips_allows(FIPS_EXCEPTION_WIFI_MFP) \u0026\u0026\ndrivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c-1227-\t    data-\u003esku_cap_11ax_enable \u0026\u0026\n--\ndrivers/net/wireless/intel/iwlwifi/mld/mac80211.c=155=static void iwl_mld_hw_set_security(struct iwl_mld *mld)\n--\ndrivers/net/wireless/intel/iwlwifi/mld/mac80211.c-169-\ndrivers/net/wireless/intel/iwlwifi/mld/mac80211.c:170:\tif (!fips_allows(FIPS_EXCEPTION_WIFI_MFP))\ndrivers/net/wireless/intel/iwlwifi/mld/mac80211.c-171-\t\treturn;\n--\ndrivers/net/wireless/intel/iwlwifi/mld/mac80211.c=310=static void iwl_mac_hw_set_wiphy(struct iwl_mld *mld)\n--\ndrivers/net/wireless/intel/iwlwifi/mld/mac80211.c-349-\t    !iwlwifi_mod_params.disable_11be \u0026\u0026\ndrivers/net/wireless/intel/iwlwifi/mld/mac80211.c:350:\t    fips_allows(FIPS_EXCEPTION_WIFI_MFP))\ndrivers/net/wireless/intel/iwlwifi/mld/mac80211.c-351-\t\twiphy-\u003eflags |= WIPHY_FLAG_SUPPORTS_MLO;\n--\ndrivers/net/wireless/intel/iwlwifi/mvm/mac80211.c=331=int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)\n--\ndrivers/net/wireless/intel/iwlwifi/mvm/mac80211.c-464-\ndrivers/net/wireless/intel/iwlwifi/mvm/mac80211.c:465:\tif (fips_allows(FIPS_EXCEPTION_WIFI_MFP)) {\ndrivers/net/wireless/intel/iwlwifi/mvm/mac80211.c-466-\t\tieee80211_hw_set(hw, MFP_CAPABLE);\n--\ndrivers/net/wireless/intel/iwlwifi/mvm/mac80211.c-497-\t */\ndrivers/net/wireless/intel/iwlwifi/mvm/mac80211.c:498:\tif (fips_allows(FIPS_EXCEPTION_WIFI_MFP) \u0026\u0026 sec_key_ver \u0026\u0026\ndrivers/net/wireless/intel/iwlwifi/mvm/mac80211.c-499-\t    fw_has_capa(\u0026mvm-\u003efw-\u003eucode_capa,\n--\ndrivers/net/wireless/intel/iwlwifi/mvm/mac80211.c-502-\t\t\t\t      NL80211_EXT_FEATURE_BEACON_PROTECTION);\ndrivers/net/wireless/intel/iwlwifi/mvm/mac80211.c:503:\telse if (fips_allows(FIPS_EXCEPTION_WIFI_MFP) \u0026\u0026\ndrivers/net/wireless/intel/iwlwifi/mvm/mac80211.c-504-\t\t fw_has_capa(\u0026mvm-\u003efw-\u003eucode_capa,\n--\ninclude/linux/fips.h=11=void fips_fail_notify(void);\ninclude/linux/fips.h-12-/*\ninclude/linux/fips.h:13: * fips_allows - check if a not fully FIPS-compliant feature is allowed\ninclude/linux/fips.h-14- * via an explicit boot-time exception (fips_exception=).\n--\ninclude/linux/fips.h-16- */\ninclude/linux/fips.h:17:int fips_allows(unsigned long feature);\ninclude/linux/fips.h-18-\n--\ninclude/linux/fips.h=22=static inline void fips_fail_notify(void) {}\ninclude/linux/fips.h:23:static inline int fips_allows(unsigned long feature)\ninclude/linux/fips.h-24-{\n--\nnet/mac80211/driver-ops.c=503=int drv_set_key(struct ieee80211_local *local,\n--\nnet/mac80211/driver-ops.c-521-\nnet/mac80211/driver-ops.c:522:\tif (!fips_allows(FIPS_EXCEPTION_WIFI_MFP))\nnet/mac80211/driver-ops.c-523-\t\treturn -EOPNOTSUPP;\n--\nnet/mac80211/driver-ops.h=896=static inline void drv_set_rekey_data(struct ieee80211_local *local,\n--\nnet/mac80211/driver-ops.h-905-\nnet/mac80211/driver-ops.h:906:\tif (!fips_allows(FIPS_EXCEPTION_WIFI_MFP))\nnet/mac80211/driver-ops.h-907-\t\treturn;\n"
}

23/2 2026/10/01 11:43 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 22320
							output: 37
							thoughts: 423
						

Thoughts:
**FIPS Exception Patch Evaluation**

Okay, let's break this down. First, I see that `fips_allows` is getting called in `crypto/fips.c`, some `iwlwifi` drivers, and within `mac80211`'s driver operations. My immediate thought is, can this be fuzzed effectively? Is it even *worth* fuzzing? We have a new mechanism, `fips_allows()` and a `fips_exception` option. This is about selectively bypassing FIPS restrictions, specifically for Wi-Fi MFP, when the system is in FIPS mode. Interesting. It's replacing the more general `fips_enabled` checks in `iwlwifi` and `mac80211` with something more granular.

Diving into the changes, within `iwlwifi`, there's some additional flag handling, particularly around pairwise keys when FIPS is enabled, and handling for `RX_MPDU_RES_STATUS_SEC_ENC_ERR` in `iwl_mvm_rx_crypto`.

Now, the crucial question: Can we trigger and test this? Looking at `iwlwifi`, it screams "Intel Wi-Fi hardware" to me. That's a huge hurdle. QEMU and GCE, standard test environments, *don't* emulate Intel Wi-Fi PCI devices. Practically unreachable hardware. This makes fuzzing challenging, right off the bat. But wait, can we *probe* the iwlwifi driver without the hardware? Let me check quickly if it is a PCI driver. That will tell me how easily (or not) it can be accessed in a testing environment.



24/2 2026/10/01 11:43 tool grepper
0m Args:
{
  "Expression": "pci_register_driver",
  "PathPrefix": "drivers/net/wireless/intel/iwlwifi"
}

Results:
{
  "Output": "drivers/net/wireless/intel/iwlwifi/iwl-drv.c=2109=static int __init iwl_drv_init(void)\n--\ndrivers/net/wireless/intel/iwlwifi/iwl-drv.c-2120-\ndrivers/net/wireless/intel/iwlwifi/iwl-drv.c:2121:\terr = iwl_pci_register_driver();\ndrivers/net/wireless/intel/iwlwifi/iwl-drv.c-2122-\tif (err)\n--\ndrivers/net/wireless/intel/iwlwifi/iwl-trans.h=1141=static inline void iwl_trans_notify_fw_error(struct iwl_trans *trans)\n--\ndrivers/net/wireless/intel/iwlwifi/iwl-trans.h-1148- *****************************************************/\ndrivers/net/wireless/intel/iwlwifi/iwl-trans.h:1149:int __must_check iwl_pci_register_driver(void);\ndrivers/net/wireless/intel/iwlwifi/iwl-trans.h-1150-void iwl_pci_unregister_driver(void);\n--\ndrivers/net/wireless/intel/iwlwifi/pcie/drv.c=1339=static struct pci_driver iwl_pci_driver = {\n--\ndrivers/net/wireless/intel/iwlwifi/pcie/drv.c-1347-\ndrivers/net/wireless/intel/iwlwifi/pcie/drv.c:1348:int __must_check iwl_pci_register_driver(void)\ndrivers/net/wireless/intel/iwlwifi/pcie/drv.c-1349-{\ndrivers/net/wireless/intel/iwlwifi/pcie/drv.c-1350-\tint ret;\ndrivers/net/wireless/intel/iwlwifi/pcie/drv.c:1351:\tret = pci_register_driver(\u0026iwl_pci_driver);\ndrivers/net/wireless/intel/iwlwifi/pcie/drv.c-1352-\tif (ret)\n"
}

25/2 2026/10/01 11:43 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 23681
							output: 25
							thoughts: 1611
						

Thoughts:
**Fuzzing Decision for the Patch: WorthFuzzing=true**

Okay, so the initial focus on `iwlwifi` was a dead end – that's just the PCI driver, and seemingly isolated. But, let's look at the meat of this patch. It touches `crypto/fips.c`, `include/linux/fips.h`, `net/mac80211/driver-ops.c`, and `net/mac80211/driver-ops.h`. My immediate thought is, are these reachable?

I need to re-familiarize myself with the triage rules. Crucially, reachability is the primary gate. Anything unreachable, even with assertions, gets a "no". But, these rules say to be wary of "no functional change" claims, refactorings and new assertions. If the code is reachable, it must be fuzzed!

`mac80211` is definitely reachable. I know that can be accessed through `mac80211_hwsim`, which means I can trigger this code in QEMU using nl80211. Good.

Now, that critical phrase pops out: "Return WorthFuzzing=false ONLY IF all modified code falls strictly into one or more of these categories." And then, "Return WorthFuzzing=true whenever the patch touches reachable executable code". `mac80211` is a core networking component, and "Reachable Drivers and Protocols" makes it crystal clear. This is directly relevant.

`crypto/fips.c` needs further examination. I see that it includes `fips_allows()` and a sysctl entry. I need to figure out how that is reached. Checking the Kconfig options, `CRYPTO_FIPS` is the key. If enabled, `crypto/fips.o` is built, and `fips_allows()` gets compiled. This is also reachable via sysctl and kernel crypto/mac80211 callers. 

So, I need to check the Kconfig and ensure `CRYPTO_FIPS` is enabled. Also, `CONFIG_MAC80211_HWSIM` needs to be enabled to reach mac80211. `net/mac80211/driver-ops.c` is part of `mac80211` which is reachable using `mac80211_hwsim`.

This patch *definitely* touches reachable executable code. The changes in `mac80211` and `crypto/fips.c` are directly fuzzable using existing infrastructure in QEMU.
Therefore, my verdict is: **WorthFuzzing=true**.



26/2 2026/10/01 11:43 tool grepper
0m Args:
{
  "Expression": "config MAC80211_HWSIM"
}

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

27/2 2026/10/01 11:43 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 25968
							output: 36
							thoughts: 16
						

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

**Navigating the Wireless Network Driver Configuration**

Okay, so I need to find something related to the wireless network drivers. Where would I start? Let's see... a good first step, particularly when dealing with kernel configuration, is usually the `Kconfig` files. These are the blueprints, so to speak, that define what options are available and how they relate to each other. Alright, let's target the likely location... `drivers/net/wireless/virtual/Kconfig`. That sounds about right. It's the virtual driver section of wireless network drivers so it's probably the right Kconfig file to get started. I need to dive in and see what's in there. I bet I can find what I'm looking for in that file.



28/2 2026/10/01 11:43 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/virtual/Kconfig",
  "FirstLine": 1,
  "LineCount": 20
}

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

29/2 2026/10/01 11:43 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 26519
							output: 44
							thoughts: 211
						

Thoughts:
**Investigating `drv_set_key` Call Paths**

Okay, let's dive into this `drv_set_key` function and figure out its call paths, specifically whether it's reachable from user space through the `nl80211` interface. My initial thought is to trace the execution and see how this function is actually called within the kernel.

I remember doing a `grep` earlier that turned up some interesting results in `net/mac80211/key.c`. It looks like `drv_set_key` is called within both `ieee80211_key_enable_hw_accel` and `ieee80211_key_disable_hw_accel` functions. Now, the key here is to find out who calls *those* functions. This will help clarify the call graph and ultimately determine if `drv_set_key` is accessible from the user-space domain, directly or indirectly.



30/2 2026/10/01 11:43 tool grepper
0m Args:
{
  "Expression": "ieee80211_key_.*_hw_accel",
  "PathPrefix": "net/mac80211"
}

Results:
{
  "Output": "net/mac80211/key.c=109=static void decrease_tailroom_need_count(struct ieee80211_sub_if_data *sdata,\n--\nnet/mac80211/key.c-119-\nnet/mac80211/key.c:120:static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)\nnet/mac80211/key.c-121-{\n--\nnet/mac80211/key.c-230-\nnet/mac80211/key.c:231:static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)\nnet/mac80211/key.c-232-{\n--\nnet/mac80211/key.c=440=static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,\n--\nnet/mac80211/key.c-507-\t\tif (old-\u003eflags \u0026 KEY_FLAG_UPLOADED_TO_HARDWARE) {\nnet/mac80211/key.c:508:\t\t\tieee80211_key_disable_hw_accel(old);\nnet/mac80211/key.c-509-\nnet/mac80211/key.c-510-\t\t\tif (new)\nnet/mac80211/key.c:511:\t\t\t\tret = ieee80211_key_enable_hw_accel(new);\nnet/mac80211/key.c-512-\t\t}\n--\nnet/mac80211/key.c-514-\t\tif (!new-\u003elocal-\u003ewowlan) {\nnet/mac80211/key.c:515:\t\t\tret = ieee80211_key_enable_hw_accel(new);\nnet/mac80211/key.c-516-\t\t} else if (link_id \u003c 0 || !sdata-\u003evif.active_links ||\n--\nnet/mac80211/key.c=974=void ieee80211_reenable_keys(struct ieee80211_sub_if_data *sdata)\n--\nnet/mac80211/key.c-994-\t\t\t\tincrement_tailroom_need_count(sdata);\nnet/mac80211/key.c:995:\t\t\tieee80211_key_enable_hw_accel(key);\nnet/mac80211/key.c-996-\t\t}\n--\nnet/mac80211/key.c=1486=int ieee80211_key_switch_links(struct ieee80211_sub_if_data *sdata,\n--\nnet/mac80211/key.c-1500-\nnet/mac80211/key.c:1501:\t\tieee80211_key_disable_hw_accel(key);\nnet/mac80211/key.c-1502-\t}\n--\nnet/mac80211/key.c-1511-\nnet/mac80211/key.c:1512:\t\tret = ieee80211_key_enable_hw_accel(key);\nnet/mac80211/key.c-1513-\t\tif (ret)\n"
}

31/2 2026/10/01 11:43 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 27925
							output: 31
							thoughts: 51
						

Thoughts:
Okay, here's my take on those thoughts, framed as my own:

**Investigating the cfg80211 - mac80211 Key Interaction**

Alright, I'm diving into the nitty-gritty of how `cfg80211` actually interacts with the `mac80211` key management functions. The question that's driving me is: *how* does the regulatory interface, specifically `cfg80211`, initiate calls to the cryptographic key manipulation routines within `mac80211`? I need to understand this linkage for some upcoming work.

My initial approach is to get my hands dirty with the code. I'll start by taking a targeted look within `net/mac80211/cfg.c`. I'm going to search specifically for calls related to key replacement or key setting operations. Keywords like `key_replace` and `set_key` are probably my best bet to find the key function calls. Hopefully, I'll be able to trace the control flow to identify where `cfg80211` triggers these core security functions in `mac80211`.



32/2 2026/10/01 11:43 tool grepper
0m Args:
{
  "Expression": "key_replace",
  "PathPrefix": "net/mac80211"
}

Results:
{
  "Output": "net/mac80211/key.c=432=void ieee80211_set_default_beacon_key(struct ieee80211_link_data *link,\n--\nnet/mac80211/key.c-439-\nnet/mac80211/key.c:440:static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,\nnet/mac80211/key.c-441-\t\t\t\t struct ieee80211_link_data *link,\n--\nnet/mac80211/key.c=846=int ieee80211_key_link(struct ieee80211_key *key,\n--\nnet/mac80211/key.c-942-\nnet/mac80211/key.c:943:\tret = ieee80211_key_replace(sdata, link, sta, pairwise, old_key, key);\nnet/mac80211/key.c-944-\n--\nnet/mac80211/key.c=959=void ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom)\n--\nnet/mac80211/key.c-967-\tif (key-\u003esdata)\nnet/mac80211/key.c:968:\t\tieee80211_key_replace(key-\u003esdata, NULL, key-\u003esta,\nnet/mac80211/key.c-969-\t\t\t\t      key-\u003econf.flags \u0026 IEEE80211_KEY_FLAG_PAIRWISE,\n--\nnet/mac80211/key.c=1087=static void ieee80211_free_keys_iface(struct ieee80211_sub_if_data *sdata,\n--\nnet/mac80211/key.c-1099-\tlist_for_each_entry_safe(key, tmp, \u0026sdata-\u003ekey_list, list) {\nnet/mac80211/key.c:1100:\t\tieee80211_key_replace(key-\u003esdata, NULL, key-\u003esta,\nnet/mac80211/key.c-1101-\t\t\t\t      key-\u003econf.flags \u0026 IEEE80211_KEY_FLAG_PAIRWISE,\n--\nnet/mac80211/key.c=1109=void ieee80211_remove_link_keys(struct ieee80211_link_data *link,\n--\nnet/mac80211/key.c-1120-\t\t\tcontinue;\nnet/mac80211/key.c:1121:\t\tieee80211_key_replace(key-\u003esdata, link, key-\u003esta,\nnet/mac80211/key.c-1122-\t\t\t\t      key-\u003econf.flags \u0026 IEEE80211_KEY_FLAG_PAIRWISE,\n--\nnet/mac80211/key.c=1186=void ieee80211_free_sta_keys(struct ieee80211_local *local,\n--\nnet/mac80211/key.c-1197-\t\t\tcontinue;\nnet/mac80211/key.c:1198:\t\tieee80211_key_replace(key-\u003esdata, NULL, key-\u003esta,\nnet/mac80211/key.c-1199-\t\t\t\t      key-\u003econf.flags \u0026 IEEE80211_KEY_FLAG_PAIRWISE,\n--\nnet/mac80211/key.c-1208-\t\t\tcontinue;\nnet/mac80211/key.c:1209:\t\tieee80211_key_replace(key-\u003esdata, NULL, key-\u003esta,\nnet/mac80211/key.c-1210-\t\t\t\t      key-\u003econf.flags \u0026 IEEE80211_KEY_FLAG_PAIRWISE,\n"
}

33/2 2026/10/01 11:43 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 29329
							output: 39
							thoughts: 31
						

Thoughts:
Okay, here's my interpretation of that.

**Analyzing the Function Call Location: IEEE80211 Key Linking**

Alright, so I see `ieee80211_key_link` being called from `net/mac80211/cfg.c`. Right away, this tells me a few things. First, `mac80211`... that's the core of the 802.11 wireless stack in the kernel.  `cfg.c` likely deals with *configuration* aspects – setting up, modifying, and tearing down the wireless interfaces and their associated parameters.

The fact that key linking is happening within the configuration file, strongly suggests that `ieee80211_key_link` is responsible for associating cryptographic keys with a particular station, a specific BSSID or a particular interface. This function likely establishes the crucial link between the authentication/encryption mechanism and the actual data transmission process. It's probably called whenever a new key is added, updated, or removed, or when a station joins or leaves the network. This also could be triggered during a rekeying event or when the security policy changes, as well.
It's definitely a crucial piece of the puzzle for secure wireless communication. From here, I would look for clues about whether this is a static or dynamic key.



34/2 2026/10/01 11:44 tool grepper
0m Args:
{
  "Expression": "ieee80211_key_link",
  "PathPrefix": "net/mac80211"
}

Results:
{
  "Output": "net/mac80211/cfg.c=613=static int ieee80211_add_key(struct wiphy *wiphy, struct wireless_dev *wdev,\n--\nnet/mac80211/cfg.c-729-\nnet/mac80211/cfg.c:730:\terr = ieee80211_key_link(key, link, sta);\nnet/mac80211/cfg.c-731-\t/* KRACK protection, shouldn't happen but just silently accept key */\n--\nnet/mac80211/key.c=813=static bool ieee80211_key_identical(struct ieee80211_sub_if_data *sdata,\n--\nnet/mac80211/key.c-845-\nnet/mac80211/key.c:846:int ieee80211_key_link(struct ieee80211_key *key,\nnet/mac80211/key.c-847-\t\t       struct ieee80211_link_data *link,\n--\nnet/mac80211/key.c=1367=ieee80211_gtk_rekey_add(struct ieee80211_vif *vif,\n--\nnet/mac80211/key.c-1428-\nnet/mac80211/key.c:1429:\terr = ieee80211_key_link(key, link_data, NULL);\nnet/mac80211/key.c-1430-\tif (err)\n--\nnet/mac80211/key.h=141=ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,\n--\nnet/mac80211/key.h-147- */\nnet/mac80211/key.h:148:int ieee80211_key_link(struct ieee80211_key *key,\nnet/mac80211/key.h-149-\t\t       struct ieee80211_link_data *link,\n"
}

35/2 2026/10/01 11:44 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 30274
							output: 36
							thoughts: 48
						

Thoughts:
Here's my analysis of the provided information, as though it were my own thought process:

**Diving into Key Management in nl80211 and the Driver Interface**

Okay, so I'm tracing this key management logic within the wireless stack. I see that `drv_set_key` is the crucial function called when we're injecting a new key, specifically via nl80211 using `ieee80211_add_key`. Makes sense. That's the core method for setting up those cryptographic keys for secure communications.

Now, I need to understand the broader picture and particularly how key refreshing fits in. What's the context for `drv_set_rekey_data`? Is it just for PMK or other data for rekeying like GTK? Is it called independently, or is there a sequence? Knowing the exact situation is critical to understanding the refresh process. I'll need to dig deeper into the code that calls that function to clarify its purpose within the driver model.



36/2 2026/10/01 11:44 tool grepper
0m Args:
{
  "Expression": "drv_set_rekey_data",
  "PathPrefix": "net/mac80211"
}

Results:
{
  "Output": "net/mac80211/cfg.c=4927=static int ieee80211_set_rekey_data(struct wiphy *wiphy,\n--\nnet/mac80211/cfg.c-4936-\nnet/mac80211/cfg.c:4937:\tdrv_set_rekey_data(local, sdata, data);\nnet/mac80211/cfg.c-4938-\n--\nnet/mac80211/driver-ops.h=875=static inline int drv_set_bitrate_mask(struct ieee80211_local *local,\n--\nnet/mac80211/driver-ops.h-895-\nnet/mac80211/driver-ops.h:896:static inline void drv_set_rekey_data(struct ieee80211_local *local,\nnet/mac80211/driver-ops.h-897-\t\t\t\t      struct ieee80211_sub_if_data *sdata,\n--\nnet/mac80211/driver-ops.h-908-\nnet/mac80211/driver-ops.h:909:\ttrace_drv_set_rekey_data(local, sdata, data);\nnet/mac80211/driver-ops.h-910-\tif (local-\u003eops-\u003eset_rekey_data)\n--\nnet/mac80211/trace.h=1480=TRACE_EVENT(drv_set_bitrate_mask,\n--\nnet/mac80211/trace.h-1506-\nnet/mac80211/trace.h:1507:TRACE_EVENT(drv_set_rekey_data,\nnet/mac80211/trace.h-1508-\tTP_PROTO(struct ieee80211_local *local,\n"
}

37/2 2026/10/01 11:44 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 31083
							output: 41
							thoughts: 1760
						

Thoughts:
**Fuzzing Triage: Analyzing a WiFi MFP (Protected Management Frames) FIPS Exception Patch**

Okay, here's my thought process. I need to figure out if this patch is worth fuzzing. First, I see `drv_set_rekey_data` being called directly from `ieee80211_set_rekey_data`, which is itself a callback within `cfg80211_ops` and triggered by a userspace command. So that's the entry point to investigate.

The main question: does this patch affect *reachable* code? It looks like it touches `crypto/fips.c` and `net/mac80211/driver-ops.c`, which are both part of core kernel subsystems—the crypto library and the 802.11 wireless networking stack, respectively. This seems promising for fuzzing.

Now, what did the patch *actually* change?  I see that both `drv_set_key` and `drv_set_rekey_data` within `net/mac80211` have had a condition added, checking `fips_allows(FIPS_EXCEPTION_WIFI_MFP)`.  Essentially, the code will now *only* error out if WiFi MFP isn't allowed by FIPS exceptions, and otherwise the function can continue as normal. Then I need to see what's happening with `crypto/fips.c`.  I see a `fips_allows` function, which determines if a feature is allowed based on the `fips_enabled` flag and a mask stored in `fips_exception`. Also, the patch introduces a `/proc/sys/crypto/fips_exception` sysctl, which is pretty interesting, because it can be used from userspace to control the exception mask.

Time for the triage criteria. I need to determine if this patch meets the criteria for fuzzing. According to the "Reachable Code" rule, this should be fuzzed if the modified code is executable in the standard virtualized environments.  The key part is that the patch modifies code in both the `net/mac80211` and `crypto` subsystems, and both are reachable because both are not hardware-only and reachable through userspace APIs. I can get to `net/mac80211` via netlink and virtual devices like `mac80211_hwsim`, and `crypto/fips.c` is core kernel code with a new sysctl! So, no, the modified code doesn't fall strictly into the negative categories. Therefore, it's worth fuzzing.

Now, what about `FocusSymbols`? I need to pick good symbols to focus the fuzzing effort. I'll avoid ubiquitous functions. The obvious choices are `fips_allows`, `drv_set_key`, and *potentially* `drv_set_rekey_data`. But `drv_set_rekey_data` is `static inline` in the header. Its caller `ieee80211_set_rekey_data`, is in `net/mac80211/cfg.c`. I need to choose non-static entry points, so both `fips_allows` and `drv_set_key` are good.  Specifically, `fips_allows` is a distinct symbol since it's exported.  I'll add it.  And I know `drv_set_key` is also a non-static symbol.  So I'll include that as well.



38/2 2026/10/01 11:44 tool read-file
0m Args:
{
  "File": "net/mac80211/cfg.c",
  "FirstLine": 4925,
  "LineCount": 20
}

Results:
{
  "Contents": "4925:\t}\n4926:\t\n4927:\tstatic int ieee80211_set_rekey_data(struct wiphy *wiphy,\n4928:\t\t\t\t\t    struct net_device *dev,\n4929:\t\t\t\t\t    struct cfg80211_gtk_rekey_data *data)\n4930:\t{\n4931:\t\tstruct ieee80211_local *local = wiphy_priv(wiphy);\n4932:\t\tstruct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);\n4933:\t\n4934:\t\tif (!local-\u003eops-\u003eset_rekey_data)\n4935:\t\t\treturn -EOPNOTSUPP;\n4936:\t\n4937:\t\tdrv_set_rekey_data(local, sdata, data);\n4938:\t\n4939:\t\treturn 0;\n4940:\t}\n4941:\t\n4942:\tstatic int ieee80211_probe_peer(struct wiphy *wiphy, struct net_device *dev,\n4943:\t\t\t\t\tconst u8 *peer, u64 cookie)\n4944:\t{\n"
}

39/2 2026/10/01 11:44 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 33993
							output: 38
							thoughts: 240
						

Thoughts:
**Analyzing Symbol Visibility and Reachability for Fuzzing**

Okay, hold on a second. I'm just reviewing this code and I've got a question about `ieee80211_set_rekey_data`. Even though it's declared `static`, and I'm looking at `net/mac80211/cfg.c`, it seems to be assigned to `local->ops.set_rekey_data` or something similar within a struct. I need to be sure the fuzzer can see it.

Hmm, can a `static` function even be in `kallsyms`? Yes, of course, static functions defined within a `.c` file *are* symbols in `vmlinux` and thus in `kallsyms`, unless the compiler inlines them. But hang on, `drv_set_key` is *already* non-static, so that's not the issue here.

Now, I'm thinking about `iwlwifi` symbols. Are those something we need to consider? Should we include `iwlwifi` symbols in `FocusSymbols`?

Wait a minute, a critical point! `iwlwifi` requires physical Intel hardware! If syzkaller is running in QEMU without that specific hardware, functions within `iwlwifi` are *never* going to be reachable. If we include them, we'll be pointing the fuzzer towards dead code, symbols that can't possibly be executed in the QEMU environment. That's just a waste of time and computational resources.

So, let's confirm this. Let's make sure that `iwlwifi` can't be probed in QEMU, to be absolutely sure that it is purely hardware-dependent. I'll check `iwl_pci_driver.id_table` to see how the driver detects hardware, and determine whether it's reliant on specific PCI device IDs.



40/2 2026/10/01 11:44 tool grepper
0m Args:
{
  "Expression": "iwl_pci_driver",
  "PathPrefix": "drivers/net/wireless/intel/iwlwifi"
}

Results:
{
  "Output": "drivers/net/wireless/intel/iwlwifi/pcie/drv.c=1331=static void iwl_pci_dump(struct device *device)\n--\ndrivers/net/wireless/intel/iwlwifi/pcie/drv.c-1338-\ndrivers/net/wireless/intel/iwlwifi/pcie/drv.c:1339:static struct pci_driver iwl_pci_driver = {\ndrivers/net/wireless/intel/iwlwifi/pcie/drv.c-1340-\t.name = DRV_NAME,\n--\ndrivers/net/wireless/intel/iwlwifi/pcie/drv.c=1348=int __must_check iwl_pci_register_driver(void)\n--\ndrivers/net/wireless/intel/iwlwifi/pcie/drv.c-1350-\tint ret;\ndrivers/net/wireless/intel/iwlwifi/pcie/drv.c:1351:\tret = pci_register_driver(\u0026iwl_pci_driver);\ndrivers/net/wireless/intel/iwlwifi/pcie/drv.c-1352-\tif (ret)\n--\ndrivers/net/wireless/intel/iwlwifi/pcie/drv.c=1358=void iwl_pci_unregister_driver(void)\ndrivers/net/wireless/intel/iwlwifi/pcie/drv.c-1359-{\ndrivers/net/wireless/intel/iwlwifi/pcie/drv.c:1360:\tpci_unregister_driver(\u0026iwl_pci_driver);\ndrivers/net/wireless/intel/iwlwifi/pcie/drv.c-1361-}\n"
}

41/2 2026/10/01 11:44 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 35122
							output: 37
							thoughts: 841
						

Thoughts:
**Analyzing Reachability of Kernel Symbols**

Okay, so I'm looking at how we can reach certain symbols in the kernel, specifically in the context of simulated hardware for testing. My initial thought is that `iwlwifi` is a dead end here because it only binds to Intel PCI devices, meaning it's structurally unreachable. The easily reachable symbols I've identified are `drv_set_key` and `fips_allows`.

But hold on, what about `ieee80211_set_rekey_data`? Let me double-check the relevant documentation on handling static inline functions. Ah, right, the compiler inlines static functions, and those don't have distinct symbols in `vmlinux`. So, if changes are primarily within static inline helpers, I need to find non-static caller functions in `.c` files that exercise them.

`drv_set_rekey_data` is a static inline within `net/mac80211/driver-ops.h`. Its caller is `ieee80211_set_rekey_data`, which lives in `net/mac80211/cfg.c`. Now, is `ieee80211_set_rekey_data` static? Yep, it's defined as `static int ieee80211_set_rekey_data(...)`. So, where else is `drv_set_rekey_data` called? I need to check for any non-static callers of `drv_set_rekey_data`.

Let me see what the previous grep query revealed: `net/mac80211/cfg.c:4937: drv_set_rekey_data(local, sdata, data);`. Okay, that's the *only* place it's called from within `.c` files. There's also a `TRACE_EVENT` in `net/mac80211/trace.h`, but that's a different story.

Okay, here's an interesting point: `ieee80211_set_rekey_data` is static, but with standard kernel builds using GCC/Clang, functions like these that are assigned to function pointer tables (like `cfg80211_ops`) are *not* inlined! They have symbols in `kallsyms`. However, `drv_set_key` is already non-static, and so is `fips_allows`.

Alright, I need to make sure the right configuration options are selected to ensure proper reachability. The relevant config is `EnableConfigs`.

Let's check what configs are required:

To compile `crypto/fips.c`: `CONFIG_CRYPTO_FIPS`, which depends on `CRYPTO_DRBG`, `CRYPTO_SELFTESTS`, and either `MODULE_SIG` or `!MODULES`.

To compile `net/mac80211/`: `CONFIG_MAC80211` is needed.

To reach this via simulated hardware in QEMU: `CONFIG_MAC80211_HWSIM` is needed. Also, `CONFIG_CFG80211` is required (which `MAC80211` depends on).

Let's quickly check the dependencies within `net/mac80211/Kconfig`. `config MAC80211` `depends on CFG80211` - yep.



42/2 2026/10/01 11:44 tool read-file
0m Args:
{
  "File": "net/mac80211/Kconfig",
  "FirstLine": 1,
  "LineCount": 18
}

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"
}

43/2 2026/10/01 11:44 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 37021
							output: 237
							thoughts: 895
						

Thoughts:
**Fuzzing Configuration Decision**

Okay, let's break this down. First, the key configurations we're dealing with are `CRYPTO_FIPS`, `CRYPTO_DRBG`, `CRYPTO_SELFTESTS`, `CFG80211`, `MAC80211`, and `MAC80211_HWSIM`. Now, the crucial question: is this code worthy of fuzzing? We need to determine if `WorthFuzzing` should be `true`.

Let's re-examine the negative criteria: non-kernel/non-executable changes, structurally unreachable hardware, and unreachable execution paths. The code changes include `crypto/fips.c`, specifically the executable logic in `fips_allows`, and a sysctl handler; also `net/mac80211/driver-ops.c` and `.h` with `drv_set_key` and `drv_set_rekey_data`, which is executable, and, finally, the hardware driver for Intel wireless. The core of this decision rests on the fact that while some changes touch hardware drivers, the core crypto and 802.11 code are reachable in virtualized environments via sysctls and `mac80211_hwsim`/`nl80211`. So, it's NOT all unreachable. Therefore, `WorthFuzzing` MUST be `true`.

Now, the `FocusSymbols`. We've identified `fips_allows`, `drv_set_key`, and `ieee80211_set_rekey_data`. Let's check for ubiquity. `fips_allows` is specific to the iwlwifi and mac80211 driver-ops. `drv_set_key` is specific to wireless key configuration. And `ieee80211_set_rekey_data` is called on `NL80211_CMD_SET_REKEY_DATA`, specific to GTK rekeying. None are ubiquitous.

The `EnableConfigs` are as listed previously: `CRYPTO_FIPS`, `CRYPTO_DRBG`, `CRYPTO_SELFTESTS`, `CFG80211`, `MAC80211`, and `MAC80211_HWSIM`.

Finally, after a careful review, the conclusion is clear:

*   `WorthFuzzing`: true
*   `FocusSymbols`: \["drv\_set\_key", "ieee80211\_set\_rekey\_data", "fips\_allows"]
*   `EnableConfigs`: \["CRYPTO\_FIPS", "CRYPTO\_DRBG", "CRYPTO\_SELFTESTS", "CFG80211", "MAC80211", "MAC80211\_HWSIM"]
*   Reasoning: We *are* fuzzing because while the changes *do* touch the Intel Wi-Fi driver, which generally requires physical hardware, modifications to core cryptographic logic (`crypto/fips.c`) and the generic IEEE 802.11 stack (`net/mac80211/driver-ops.c` and `driver-ops.h`) are reachable. Specifically, `fips_allows()` and the `fips_exception` sysctl, are in there, along with key management changes in `drv_set_key()` and `drv_set_rekey_data()`. All of these are easily reached in QEMU via `mac80211_hwsim` and userspace nl80211 commands. That satisfies all criteria. Time to proceed and call `set-results`.



44/2 2026/10/01 11:44 tool set-results
0m Args:
{
  "EnableConfigs": [
    "CRYPTO_FIPS",
    "CRYPTO_DRBG",
    "CRYPTO_SELFTESTS",
    "CFG80211",
    "MAC80211",
    "MAC80211_HWSIM"
  ],
  "FocusSymbols": [
    "drv_set_key",
    "ieee80211_set_rekey_data",
    "fips_allows"
  ],
  "Reasoning": "The patch introduces a new FIPS exception mechanism (fips_allows and a sysctl fips_exception) in crypto/fips.c and modifies key management logic in net/mac80211 (drv_set_key and drv_set_rekey_data). While the iwlwifi changes target vendor-specific Intel hardware, the mac80211 and crypto modifications reside in reachable core subsystems and can be exercised in standard virtualized environments using mac80211_hwsim and nl80211 netlink commands.",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "CRYPTO_FIPS",
    "CRYPTO_DRBG",
    "CRYPTO_SELFTESTS",
    "CFG80211",
    "MAC80211",
    "MAC80211_HWSIM"
  ],
  "FocusSymbols": [
    "drv_set_key",
    "ieee80211_set_rekey_data",
    "fips_allows"
  ],
  "Reasoning": "The patch introduces a new FIPS exception mechanism (fips_allows and a sysctl fips_exception) in crypto/fips.c and modifies key management logic in net/mac80211 (drv_set_key and drv_set_rekey_data). While the iwlwifi changes target vendor-specific Intel hardware, the mac80211 and crypto modifications reside in reachable core subsystems and can be exercised in standard virtualized environments using mac80211_hwsim and nl80211 netlink commands.",
  "WorthFuzzing": true
}

45/1 2026/10/01 11:44 action If
1m Args:
{
  "WorthFuzzing": true
}

Results:
null

46/2 2026/10/01 11:44 agent kmsan-evaluator
1m Model:
core

Args:
null

Results:
{
  "KMSANReasoning": "The patch introduces a kernel boot/sysctl parameter 'fips_exception' and a helper function 'fips_allows()' to conditionally allow specific non-FIPS compliant Wi-Fi features (such as Wi-Fi MFP) even when FIPS mode is enabled. It adjusts feature flags and capability checks across the iwlwifi driver and mac80211 subsystem.\n\nAll added state (e.g. 'fips_exception') is statically allocated and initialized in BSS or via kstrtoul. There are no allocations of uninitialized memory, no structures with padding exposed to userspace without initialization, no conditional branches on uninitialized memory, and no buffer length or index manipulation that could cause reads into uninitialized memory regions.\n\nAny potential bugs resulting from enabling these Wi-Fi features (such as out-of-bounds frame parsing, driver logic flaws, or reference counting issues) would be covered by KASAN and standard sanitizers rather than KMSAN. A dedicated KMSAN fuzzing session is not warranted.",
  "NeedsKMSAN": false
}

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

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

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

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

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

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

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


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

Prompt:
Target architecture: amd64

For your convenience, here is the diff of the changes:
commit 499c6407815a44f1670ce2ff2665ca2c5c5a6aa1
Author: syz-cluster <triage@syzkaller.com>
Date:   Thu Oct 1 11:41:47 2026 +0000

    syz-cluster: applied patch under review

diff --git a/crypto/fips.c b/crypto/fips.c
index c59711248d956..0f075e61a6577 100644
--- a/crypto/fips.c
+++ b/crypto/fips.c
@@ -21,6 +21,15 @@ EXPORT_SYMBOL_GPL(fips_enabled);
 ATOMIC_NOTIFIER_HEAD(fips_fail_notif_chain);
 EXPORT_SYMBOL_GPL(fips_fail_notif_chain);
 
+static unsigned long fips_exception;
+
+int fips_allows(unsigned long feature)
+{
+	return !fips_enabled ||
+	       (fips_exception & feature);
+}
+EXPORT_SYMBOL_GPL(fips_allows);
+
 /* Process kernel command-line parameter at boot time. fips=0 or fips=1 */
 static int __init fips_enable(char *str)
 {
@@ -34,6 +43,17 @@ static int __init fips_enable(char *str)
 
 __setup("fips=", fips_enable);
 
+static int __init fips_exception_setup(char *str)
+{
+	if (kstrtoul(str, 0, &fips_exception))
+		return 0;
+
+	pr_info("fips exceptions: 0x%lx\n", fips_exception);
+	return 1;
+}
+
+__setup("fips_exception=", fips_exception_setup);
+
 #define FIPS_MODULE_NAME CONFIG_CRYPTO_FIPS_NAME
 #ifdef CONFIG_CRYPTO_FIPS_CUSTOM_VERSION
 #define FIPS_MODULE_VERSION CONFIG_CRYPTO_FIPS_VERSION
@@ -52,6 +72,13 @@ static const struct ctl_table crypto_sysctl_table[] = {
 		.mode		= 0444,
 		.proc_handler	= proc_dointvec
 	},
+	{
+		.procname	= "fips_exception",
+		.data		= &fips_exception,
+		.maxlen		= sizeof(unsigned long),
+		.mode		= 0444,
+		.proc_handler	= proc_doulongvec_minmax
+	},
 	{
 		.procname	= "fips_name",
 		.data		= &fips_name,
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index 863d5e358152d..ca565b4311bbe 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -502,14 +502,16 @@ static void iwl_init_vht_hw_capab(struct iwl_trans *trans,
 	 */
 	switch (iwlwifi_mod_params.amsdu_size) {
 	case IWL_AMSDU_DEF:
-		if (trans->mac_cfg->mq_rx_supported && !fips_enabled)
+		if (trans->mac_cfg->mq_rx_supported &&
+		    fips_allows(FIPS_EXCEPTION_WIFI_MFP))
 			vht_cap->cap |=
 				IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
 		else
 			vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
 		break;
 	case IWL_AMSDU_2K:
-		if (trans->mac_cfg->mq_rx_supported && !fips_enabled)
+		if (trans->mac_cfg->mq_rx_supported &&
+		    fips_allows(FIPS_EXCEPTION_WIFI_MFP))
 			vht_cap->cap |=
 				IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
 		else
@@ -886,7 +888,7 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans,
 
 	/* EHT needs WPA3/MFP so cannot do it for fips_enabled */
 	if (!data->sku_cap_11be_enable || iwlwifi_mod_params.disable_11be ||
-	    fips_enabled)
+	    !fips_allows(FIPS_EXCEPTION_WIFI_MFP))
 		iftype_data->eht_cap.has_eht = false;
 
 	if (!data->sku_cap_11bn_enable || !iftype_data->eht_cap.has_eht)
@@ -1221,7 +1223,8 @@ static void iwl_init_sbands(struct iwl_trans *trans,
 	 * avoid spending time on scanning those channels and perhaps
 	 * even finding APs there that cannot be used.
 	 */
-	if (!fips_enabled && data->sku_cap_11ax_enable &&
+	if (fips_allows(FIPS_EXCEPTION_WIFI_MFP) &&
+	    data->sku_cap_11ax_enable &&
 	    !iwlwifi_mod_params.disable_11ax)
 		iwl_init_he_hw_capab(trans, data, sband, tx_chains, rx_chains,
 				     fw);
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
index 3a4c8fda68d0a..3fd88420cd17f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
@@ -167,7 +167,7 @@ static void iwl_mld_hw_set_security(struct iwl_mld *mld)
 		WLAN_CIPHER_SUITE_BIP_GMAC_256
 	};
 
-	if (fips_enabled)
+	if (!fips_allows(FIPS_EXCEPTION_WIFI_MFP))
 		return;
 
 	hw->wiphy->n_cipher_suites = ARRAY_SIZE(mld_ciphers);
@@ -176,6 +176,9 @@ static void iwl_mld_hw_set_security(struct iwl_mld *mld)
 	ieee80211_hw_set(hw, MFP_CAPABLE);
 	wiphy_ext_feature_set(hw->wiphy,
 			      NL80211_EXT_FEATURE_BEACON_PROTECTION);
+
+	if (fips_enabled)
+		IWL_WARN(mld, "FIPS: MFP enabled with known firmware limitation\n");
 }
 
 static void iwl_mld_hw_set_antennas(struct iwl_mld *mld)
@@ -344,7 +347,7 @@ static void iwl_mac_hw_set_wiphy(struct iwl_mld *mld)
 	if (mld->nvm_data->sku_cap_11be_enable &&
 	    !iwlwifi_mod_params.disable_11ax &&
 	    !iwlwifi_mod_params.disable_11be &&
-	    !fips_enabled)
+	    fips_allows(FIPS_EXCEPTION_WIFI_MFP))
 		wiphy->flags |= WIPHY_FLAG_SUPPORTS_MLO;
 
 	/* the firmware uses u8 for num of iterations, but 0xff is saved for
@@ -2227,6 +2230,9 @@ static int iwl_mld_set_key_add(struct iwl_mld *mld,
 	case WLAN_CIPHER_SUITE_CCMP:
 	case WLAN_CIPHER_SUITE_GCMP:
 	case WLAN_CIPHER_SUITE_GCMP_256:
+		if (fips_enabled && (key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+			key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
+		break;
 	case WLAN_CIPHER_SUITE_AES_CMAC:
 	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
 	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 5bd246e379432..38fe710ef414f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -462,8 +462,11 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
 		IWL_ERR(mvm,
 			"iwlmvm doesn't allow to disable BT Coex, check bt_coex_active module parameter\n");
 
-	if (!fips_enabled)
+	if (fips_allows(FIPS_EXCEPTION_WIFI_MFP)) {
 		ieee80211_hw_set(hw, MFP_CAPABLE);
+		if (fips_enabled)
+			IWL_WARN(mvm, "FIPS: MFP enabled with known firmware limitation\n");
+	}
 
 	mvm->ciphers[hw->wiphy->n_cipher_suites] = WLAN_CIPHER_SUITE_AES_CMAC;
 	hw->wiphy->n_cipher_suites++;
@@ -492,12 +495,12 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
 	 * beacon protection must be handled by firmware,
 	 * so cannot be done with fips_enabled
 	 */
-	if (!fips_enabled && sec_key_ver &&
+	if (fips_allows(FIPS_EXCEPTION_WIFI_MFP) && sec_key_ver &&
 	    fw_has_capa(&mvm->fw->ucode_capa,
 			IWL_UCODE_TLV_CAPA_BIGTK_TX_SUPPORT))
 		wiphy_ext_feature_set(hw->wiphy,
 				      NL80211_EXT_FEATURE_BEACON_PROTECTION);
-	else if (!fips_enabled &&
+	else if (fips_allows(FIPS_EXCEPTION_WIFI_MFP) &&
 		 fw_has_capa(&mvm->fw->ucode_capa,
 			     IWL_UCODE_TLV_CAPA_BIGTK_SUPPORT))
 		wiphy_ext_feature_set(hw->wiphy,
@@ -4244,6 +4247,8 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
 	case WLAN_CIPHER_SUITE_GCMP_256:
 		if (!iwl_mvm_has_new_tx_api(mvm))
 			key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
+		if (fips_enabled && (key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+			key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
 		break;
 	case WLAN_CIPHER_SUITE_AES_CMAC:
 	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 7f0b4f5daa214..6d223ef75bb40 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -6,6 +6,7 @@
  */
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/fips.h>
 #include "iwl-trans.h"
 #include "mvm.h"
 #include "fw-api.h"
@@ -494,6 +495,14 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
 		return 0;
 	case RX_MPDU_RES_STATUS_SEC_CMAC_GMAC_ENC:
 		break;
+	case RX_MPDU_RES_STATUS_SEC_ENC_ERR:
+		if (fips_enabled) {
+			IWL_DEBUG_RX(mvm,
+				     "FIPS mode: firmware cannot decrypt, status: 0x%x\n",
+				     status);
+			break;
+		}
+		fallthrough;
 	default:
 		/*
 		 * Sometimes we can get frames that were not decrypted
diff --git a/include/linux/fips.h b/include/linux/fips.h
index c6961e932fef3..61fe58b0762c9 100644
--- a/include/linux/fips.h
+++ b/include/linux/fips.h
@@ -2,17 +2,31 @@
 #ifndef _FIPS_H
 #define _FIPS_H
 
+#include <linux/bits.h>
+
 #ifdef CONFIG_CRYPTO_FIPS
 extern int fips_enabled;
 extern struct atomic_notifier_head fips_fail_notif_chain;
 
 void fips_fail_notify(void);
+/*
+ * fips_allows - check if a not fully FIPS-compliant feature is allowed
+ * via an explicit boot-time exception (fips_exception=).
+ * Not for fully FIPS-compliant features.
+ */
+int fips_allows(unsigned long feature);
 
 #else
 #define fips_enabled 0
 
 static inline void fips_fail_notify(void) {}
+static inline int fips_allows(unsigned long feature)
+{
+	return 1;
+}
 
 #endif
 
+#define FIPS_EXCEPTION_WIFI_MFP	BIT(0)
+
 #endif
diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c
index 49753b73aba26..0a50684d9cf65 100644
--- a/net/mac80211/driver-ops.c
+++ b/net/mac80211/driver-ops.c
@@ -519,7 +519,7 @@ int drv_set_key(struct ieee80211_local *local,
 		    !(sdata->vif.active_links & BIT(key->link_id))))
 		return -ENOLINK;
 
-	if (fips_enabled)
+	if (!fips_allows(FIPS_EXCEPTION_WIFI_MFP))
 		return -EOPNOTSUPP;
 
 	trace_drv_set_key(local, cmd, sdata, sta, key);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index f1c0b87fddd5f..a24230feb864d 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -903,7 +903,7 @@ static inline void drv_set_rekey_data(struct ieee80211_local *local,
 	if (!check_sdata_in_driver(sdata))
 		return;
 
-	if (fips_enabled)
+	if (!fips_allows(FIPS_EXCEPTION_WIFI_MFP))
 		return;
 
 	trace_drv_set_rekey_data(local, sdata, data);

47/3 2026/10/01 11:44 llm kmsan-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 6181
							output: 48
							thoughts: 853
						

Thoughts:
**Kernel Patch Evaluation for KMSAN Fuzzing**

Alright, let's dive into this patch and determine if it justifies a dedicated KMSAN fuzzing session. The core of this seems to be around introducing an exception mechanism to FIPS compliance, specifically for WiFi MFP (Management Frame Protection) features within the Intel iwlwifi driver.

I see a new `fips_exception` variable and `fips_allows()` function being added, along with a sysctl entry to configure this exception. The `fips_allows()` function's logic is pretty straightforward: essentially, it allows the feature if FIPS isn't enabled OR if the `fips_exception` bit corresponding to the feature is set. The primary focus here is `FIPS_EXCEPTION_WIFI_MFP`. This is where it gets interesting, as it appears this exception is being applied liberally across the iwlwifi code. The patch replaces several `!fips_enabled` checks with `fips_allows(FIPS_EXCEPTION_WIFI_MFP)`.

Specifically, I notice a lot of changes impacting how MFP is handled and how keys are set.  The patch modifies checks in `iwl-nvm-parse.c`, `mac80211.c`, `mvm/mac80211.c`, and `rxmq.c` and driver-ops.c and driver-ops.h to allow MFP when the exception is set. I immediately think that setting a key to be software managed with a pairwise flag, as appears in `__iwl_mvm_mac_set_key` will be a nice target to fuzz.

I need to quickly analyze that error code from `rxmq.c`. I need to figure out how `RX_MPDU_RES_STATUS_SEC_ENC_ERR` is handled. It seems that when FIPS is enabled, a firmware decryption failure throws a warning. However, if the exception is enabled, this warning is *not* emitted. This could mask some interesting flaws. I want to see how that `status` variable is used and what other things depend on it. That looks like a good place to start, especially with MFP and decryption in the mix. Let me grab a tool. I'm going to quickly read the file or look for related function calls. Let's see how `iwl_mvm_rx_crypto` handles this.



48/3 2026/10/01 11:45 tool grepper
0m Args:
{
  "Expression": "iwl_mvm_rx_crypto",
  "PathPrefix": "drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c"
}

Results:
{
  "Output": "drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c=323=static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,\n--\ndrivers/net/wireless/intel/iwlwifi/mvm/rxmq.c-414-\ndrivers/net/wireless/intel/iwlwifi/mvm/rxmq.c:415:static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_sta *sta,\ndrivers/net/wireless/intel/iwlwifi/mvm/rxmq.c-416-\t\t\t     struct ieee80211_hdr *hdr,\n--\ndrivers/net/wireless/intel/iwlwifi/mvm/rxmq.c=2104=void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,\n--\ndrivers/net/wireless/intel/iwlwifi/mvm/rxmq.c-2277-\ndrivers/net/wireless/intel/iwlwifi/mvm/rxmq.c:2278:\tif (iwl_mvm_rx_crypto(mvm, sta, hdr, rx_status, phy_data.phy_info, desc,\ndrivers/net/wireless/intel/iwlwifi/mvm/rxmq.c-2279-\t\t\t      le32_to_cpu(pkt-\u003elen_n_flags), queue,\n"
}

49/3 2026/10/01 11:45 llm kmsan-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 7976
							output: 47
							thoughts: 36
						

Thoughts:
Okay, let's dive into this. Here's my take on those lines (around 490-530) of `drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c`:

**Analyzing RXMQ Handling in iwlwifi**

Alright, I need to get a handle on what's happening with the RXMQ – the Receive Message Queue – within this specific Intel wireless driver module. Specifically, I'm going to focus my attention on lines 490 through 530, right in the middle of this area, as I've found that these lines are an integral part to understanding the way the driver processes incoming data from the wireless interface. I'm guessing this section probably handles some key logic around packet reception, possibly de-queuing packets, managing buffers, or dealing with interrupt handling related to RXMQ events. Knowing Intel's architecture, there's likely some hardware-specific interaction in there as well. I expect to see references to DMA, perhaps some buffer descriptors, and probably some state management for different receive queues. I'm going to look for any clues about error handling or flow control – those are always critical in the RX path. I'm going to look for patterns, and connections to the overall RX path to get a clear picture of how the RXMQ is used.



50/3 2026/10/01 11:45 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c",
  "FirstLine": 480,
  "LineCount": 50
}

Results:
{
  "Contents": " 480:\t\t\tif ((status \u0026 IWL_RX_MPDU_STATUS_SEC_MASK) ==\n 481:\t\t\t\t\tIWL_RX_MPDU_STATUS_SEC_WEP)\n 482:\t\t\t\t*crypt_len = IEEE80211_WEP_IV_LEN;\n 483:\t\n 484:\t\t\tif (pkt_flags \u0026 FH_RSCSR_RADA_EN) {\n 485:\t\t\t\tstats-\u003eflag |= RX_FLAG_ICV_STRIPPED;\n 486:\t\t\t\tif (mvm-\u003etrans-\u003emac_cfg-\u003egen2)\n 487:\t\t\t\t\tstats-\u003eflag |= RX_FLAG_MMIC_STRIPPED;\n 488:\t\t\t}\n 489:\t\n 490:\t\t\treturn 0;\n 491:\t\tcase IWL_RX_MPDU_STATUS_SEC_EXT_ENC:\n 492:\t\t\tif (!(status \u0026 IWL_RX_MPDU_STATUS_MIC_OK))\n 493:\t\t\t\treturn -1;\n 494:\t\t\tstats-\u003eflag |= RX_FLAG_DECRYPTED;\n 495:\t\t\treturn 0;\n 496:\t\tcase RX_MPDU_RES_STATUS_SEC_CMAC_GMAC_ENC:\n 497:\t\t\tbreak;\n 498:\t\tcase RX_MPDU_RES_STATUS_SEC_ENC_ERR:\n 499:\t\t\tif (fips_enabled) {\n 500:\t\t\t\tIWL_DEBUG_RX(mvm,\n 501:\t\t\t\t\t     \"FIPS mode: firmware cannot decrypt, status: 0x%x\\n\",\n 502:\t\t\t\t\t     status);\n 503:\t\t\t\tbreak;\n 504:\t\t\t}\n 505:\t\t\tfallthrough;\n 506:\t\tdefault:\n 507:\t\t\t/*\n 508:\t\t\t * Sometimes we can get frames that were not decrypted\n 509:\t\t\t * because the firmware didn't have the keys yet. This can\n 510:\t\t\t * happen after connection where we can get multicast frames\n 511:\t\t\t * before the GTK is installed.\n 512:\t\t\t * Silently drop those frames.\n 513:\t\t\t * Also drop un-decrypted frames in monitor mode.\n 514:\t\t\t */\n 515:\t\t\tif (!is_multicast_ether_addr(hdr-\u003eaddr1) \u0026\u0026\n 516:\t\t\t    !mvm-\u003emonitor_on \u0026\u0026 net_ratelimit())\n 517:\t\t\t\tIWL_WARN(mvm, \"Unhandled alg: 0x%x\\n\", status);\n 518:\t\t}\n 519:\t\n 520:\t\treturn 0;\n 521:\t}\n 522:\t\n 523:\tstatic void iwl_mvm_rx_csum(struct iwl_mvm *mvm,\n 524:\t\t\t\t    struct ieee80211_sta *sta,\n 525:\t\t\t\t    struct sk_buff *skb,\n 526:\t\t\t\t    struct iwl_rx_packet *pkt)\n 527:\t{\n 528:\t\tstruct iwl_rx_mpdu_desc *desc = (void *)pkt-\u003edata;\n 529:\t\n"
}

51/3 2026/10/01 11:45 llm kmsan-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 9168
							output: 237
							thoughts: 767
						

Thoughts:
**KMSAN Assessment: No Concerns Detected**

Okay, let's break this down. First, I was curious about the logic difference between a `break` returning 0 versus a `fallthrough` with a `default` returning 0. That looks like a FIPS-related check, potentially suppressing a warning. Specifically, it seems like in `default`, we skip an `IWL_WARN` print if it's not a multicast address and we're in monitor mode, and we have rate limiting. The key part is that in FIPS mode, it's really about suppressing that `IWL_WARN` for the `RX_MPDU_RES_STATUS_SEC_ENC_ERR` error. Got it.

Next, I looked at the sysctl table entry. The `fips_exception` is a read-only (`0444`) unsigned long. It's static, initialized to zero in BSS or via the kernel command line. The handler `proc_doulongvec_minmax` simply reads it. There's no uninitialized memory concern there. This is good.

Then, the code sets a flag, `IEEE80211_KEY_FLAG_SW_MGMT_TX`, within a conditional: `fips_enabled && (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)`. Pretty straightforward flag manipulation.

Now, the important part: KMSAN. I need to make sure this change doesn't introduce uninitialized memory reads. I checked the KMSAN criteria one by one.

1.  **Kernel structures to user space**: The sysctl handler reads the `fips_exception` variable, which is a static global, initialized, and there's no padding. No issue.
2.  **Conditional logic**: The code uses scalar values like `fips_exception` and `feature` in boolean logic, simple checks, so no problems here.
3.  **Complex data structure allocation**: No new structures are allocated or modified that could lead to uninitialized fields being read later.
4.  **Bounds checks/lengths**: No code introduced anything dangerous to access uninitialized bytes. Enabling MFP (Management Frame Protection) / WPA3 features when `fips_allows(FIPS_EXCEPTION_WIFI_MFP)` is set simply allows wifi features previously blocked in FIPS mode and follows the normal non-FIPS code paths. This looks fine.

So, after a thorough review, the changed code does not handle uninitialized buffers, stack allocations, or copies to userspace without zeroing. KASAN and the other sanitizers should cover memory safety, and fuzzing already tests these wifi paths. Therefore, KMSAN is not necessary here. That's a "NeedsKMSAN=false" scenario. Time to formulate a response and call `set-results`.



52/3 2026/10/01 11:46 tool set-results
0m Args:
{
  "KMSANReasoning": "The patch introduces a kernel boot/sysctl parameter 'fips_exception' and a helper function 'fips_allows()' to conditionally allow specific non-FIPS compliant Wi-Fi features (such as Wi-Fi MFP) even when FIPS mode is enabled. It adjusts feature flags and capability checks across the iwlwifi driver and mac80211 subsystem.\n\nAll added state (e.g. 'fips_exception') is statically allocated and initialized in BSS or via kstrtoul. There are no allocations of uninitialized memory, no structures with padding exposed to userspace without initialization, no conditional branches on uninitialized memory, and no buffer length or index manipulation that could cause reads into uninitialized memory regions.\n\nAny potential bugs resulting from enabling these Wi-Fi features (such as out-of-bounds frame parsing, driver logic flaws, or reference counting issues) would be covered by KASAN and standard sanitizers rather than KMSAN. A dedicated KMSAN fuzzing session is not warranted.",
  "NeedsKMSAN": false
}

Results:
{
  "KMSANReasoning": "The patch introduces a kernel boot/sysctl parameter 'fips_exception' and a helper function 'fips_allows()' to conditionally allow specific non-FIPS compliant Wi-Fi features (such as Wi-Fi MFP) even when FIPS mode is enabled. It adjusts feature flags and capability checks across the iwlwifi driver and mac80211 subsystem.\n\nAll added state (e.g. 'fips_exception') is statically allocated and initialized in BSS or via kstrtoul. There are no allocations of uninitialized memory, no structures with padding exposed to userspace without initialization, no conditional branches on uninitialized memory, and no buffer length or index manipulation that could cause reads into uninitialized memory regions.\n\nAny potential bugs resulting from enabling these Wi-Fi features (such as out-of-bounds frame parsing, driver logic flaws, or reference counting issues) would be covered by KASAN and standard sanitizers rather than KMSAN. A dedicated KMSAN fuzzing session is not warranted.",
  "NeedsKMSAN": false
}

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