[PATCH 2/2] wifi: iwlwifi: mvm: add KUnit coverage for BA-window station ID bounds

From: Michael Bommarito

Date: Sat Jul 11 2026 - 11:06:41 EST


Add KUnit coverage for a malformed BA-window notification carrying an
out-of-range station ID, plus a valid-ID/null-station path to exercise the
adjacent non-bug branch. With UBSAN bounds enabled, the malformed case
reports an array-index-out-of-bounds splat before the fix and passes after
it.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Michael Bommarito <michael.bommarito@xxxxxxxxx>
---
.../wireless/intel/iwlwifi/mvm/tests/Makefile | 2 +-
.../intel/iwlwifi/mvm/tests/window-status.c | 77 +++++++++++++++++++
2 files changed, 78 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/wireless/intel/iwlwifi/mvm/tests/window-status.c

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tests/Makefile b/drivers/net/wireless/intel/iwlwifi/mvm/tests/Makefile
index 2267be4cfb441..bf22750fceafc 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tests/Makefile
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tests/Makefile
@@ -1,3 +1,3 @@
-iwlmvm-tests-y += module.o hcmd.o
+iwlmvm-tests-y += module.o hcmd.o window-status.o

obj-$(CONFIG_IWLWIFI_KUNIT_TESTS) += iwlmvm-tests.o
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tests/window-status.c b/drivers/net/wireless/intel/iwlwifi/mvm/tests/window-status.c
new file mode 100644
index 0000000000000..06807e2bdbc12
--- /dev/null
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tests/window-status.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * KUnit tests for MVM BA window status notification handling
+ */
+#include <kunit/test.h>
+#include <linux/mm.h>
+
+#include <iwl-trans.h>
+#include "../fw-api.h"
+#include "../mvm.h"
+
+MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
+
+static void iwl_mvm_test_window_status(struct kunit *test, u8 sta_id)
+{
+ struct iwl_ba_window_status_notif notif = {};
+ struct iwl_rx_cmd_buffer rxb = {
+ ._offset = 0,
+ ._rx_page_order = 0,
+ };
+ struct iwl_rx_packet *pkt;
+ struct iwl_fw *fw;
+ struct iwl_mvm *mvm;
+ u16 ratid;
+
+ BUILD_BUG_ON((IWL_STATION_COUNT_MAX + 1) >
+ (BA_WINDOW_STATUS_STA_ID_MSK >>
+ BA_WINDOW_STATUS_STA_ID_POS));
+
+ mvm = kunit_kzalloc(test, sizeof(*mvm), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, mvm);
+
+ fw = kunit_kzalloc(test, sizeof(*fw), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, fw);
+ fw->ucode_capa.num_stations = IWL_STATION_COUNT_MAX;
+ mvm->fw = fw;
+
+ rxb._page = alloc_page(GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, rxb._page);
+
+ ratid = BA_WINDOW_STATUS_VALID_MSK |
+ (sta_id << BA_WINDOW_STATUS_STA_ID_POS);
+ notif.ra_tid[0] = cpu_to_le16(ratid);
+ notif.mpdu_rx_count[0] = cpu_to_le16(1);
+
+ pkt = rxb_addr(&rxb);
+ memset(pkt, 0, PAGE_SIZE);
+ pkt->len_n_flags = cpu_to_le32(sizeof(pkt->hdr) + sizeof(notif));
+ memcpy(pkt->data, &notif, sizeof(notif));
+
+ iwl_mvm_window_status_notif(mvm, &rxb);
+
+ __free_page(rxb._page);
+}
+
+static void test_ba_window_status_station_id_bounds(struct kunit *test)
+{
+ iwl_mvm_test_window_status(test, IWL_STATION_COUNT_MAX + 1);
+}
+
+static void test_ba_window_status_valid_empty_station(struct kunit *test)
+{
+ iwl_mvm_test_window_status(test, 0);
+}
+
+static struct kunit_case window_status_cases[] = {
+ KUNIT_CASE(test_ba_window_status_station_id_bounds),
+ KUNIT_CASE(test_ba_window_status_valid_empty_station),
+ {},
+};
+
+static struct kunit_suite window_status = {
+ .name = "iwlmvm-window-status",
+ .test_cases = window_status_cases,
+};
+
+kunit_test_suite(window_status);
--
2.53.0