From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-qt1-f169.google.com (mail-qt1-f169.google.com [209.85.160.169]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E762E480340 for ; Fri, 15 May 2026 12:12:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.169 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778847151; cv=none; b=tbkCiYfusSlIfGSRqP4TyoscoIjr9aVtsr2yL4FDIxyn6yymLEYsfwYNPjGTPEChwCOZ+C8eJMUqN0MDmVY62pNOPyKCe0xeeNuqwae2A6Uh/W2fCNtw+zI3SW/igebtWwELjSCYveTkYUZfMocCJsoJQ8TOLI/TmJPw3+oEk0c= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778847151; c=relaxed/simple; bh=C8otXdXqe2mbvIpCi+y4ZxuYrmyZ1+jVBFbLm5wowDc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=od1rfJT9T1+lNyvdgzjC+CSqpeHrrKKm67sVhzvIpNtNbFPMs0egIeq37uaF+6ru7XbrM1911jY3f10qZOfevy2l/9YUEtM0RaKd4mJOa6TXFCTzLP8i8PwFEQXibdJC0kJmd7Em+A/lFnb2I7aa396oqQkaespbLPbIJNAyK1E= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=JLVrDdNX; arc=none smtp.client-ip=209.85.160.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="JLVrDdNX" Received: by mail-qt1-f169.google.com with SMTP id d75a77b69052e-50e63771d91so88335791cf.0 for ; Fri, 15 May 2026 05:12:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778847149; x=1779451949; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=7R2gnYRUyTuipxUzgFJAVrQVtPiXN+G/kZsPRoJVzxw=; b=JLVrDdNXWVnw8mdwabCQzQY/4yzdEe7Wq9M/r7OvqmAoDswWkrPmZgJ/eq4xR6Azqk F0iM9QhAKRd3BOERQ/clHXPpweXKNDZBMtm43KeOARgvddhgTukiQ9sz/2XiZp5QW/g4 d3YVoVRE8YivAUeb4ElwJiDHVN3oJXJ2XodcPR5bm5I6RURcMwR+eO8XEtD3m1BpdkJc oIBv53wiCeRLuEugnudSa5bOe0D7csa3PVgsOwHM75Rw3zrAMlOwD1IvrscZUDyYQWpn uWBVBrPloaGw80rwxNGd7Nunh1qZUm2I62kD66o+52uwj9HcajcM14kyF1UdrNCxHsE8 JDdg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778847149; x=1779451949; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=7R2gnYRUyTuipxUzgFJAVrQVtPiXN+G/kZsPRoJVzxw=; b=rgWMPpDsSUoEeoBB2MpHH2kDxjbClGVArYYJVWHVIk+bq4bKKAeYZvtyu7zg7JNvb6 k7TdMMxHkcZqJllH5vDp8iW4BugoVB6xkhwY+D8N4XViCrZ2caBxnYVRSD/jNv4h9u+k WQUUOiTQ+VQWrClG+Oe7sGPFdF6SCZp8sj6DFHkThaIyD2ggktaTFB72hqvFeqz5eGVb 6IVilmt1IBYk2FP8dx21ah15oJ4p2ZJ2pY0Hu8pW7KAf6l0BmFNn0GzHj5Qu0Q8HE0jq FcQ8hddS6pqTQKu9UQt9VKMNb6x0bxhrAs9QpeVBcZpt3GiTi5TZA6FBmDrOYbPg7vbh LgfQ== X-Forwarded-Encrypted: i=1; AFNElJ+4FXXUf8pMmUVMVvxKIkfYyDGldRjBMMymYaZgxHV1Zw5+AqyLAnes1UwsnppB5oYDXcdUG6Z+RJ1RMNE=@vger.kernel.org X-Gm-Message-State: AOJu0YzWZJFC7i2CT9lzNe95lLYqsbaqagd2DeB/KP5iGVZ4/+3q949e 43dsoXWEoLJAFaHwz4m3T8xbz/TcI5Tcx6non2sVqyKHdeddMRPAscOA X-Gm-Gg: Acq92OFR9nrXX7asLXkJSMGLhPL7svguBOHEb39nMevmZiBuOKBb9uaRkFclwen6qEL oo2nBCqvKDbFUn7spkDP5l9Yc8bNxDWOWh1al36cHJYEVb/DJ3O9LEOpi4CahV1sFZyLIkQFHTu BBTVf99g3uajzEgrZfAIzfBQVWjJ4eRA1zTtTo7Q1l1dVTkKaqih3qXptu36Ycvl98FStjtqhHa bBTvAcjq55czmIH+QNAzYZgk4ey9QYv71Y+x9I7naYaD5EiP3m99SMUJELfre8FX0RF3hfnFsfy +35oLyh9LVo6l2/DpDcN+3Z/KIjRRRDYa+GCWCJn+TZtrXy7PZWFGT6z083EDvSNqYjWzEDtR8V uOH1QYXuNPzzIUUgtKrEvEFfR0eo+gQT2jfjN8q4L0B2rmv1FOW33BXFMEZPxJAHDV+h/VPqnYW rFhKsyfRVE0yllR22PB8khvxHUsNnxg1+vIfQkGKvMRk80ZwMRGjM3aU1TlPKbmh+zosIrocxym N6cn7iIWKtuDRyMj8Q2J6Q3anFMBsNdDIubZN6br3BXlFoIR9Mu0w== X-Received: by 2002:ac8:5703:0:b0:510:1b61:d0e4 with SMTP id d75a77b69052e-5165a0e34ffmr47763431cf.35.1778847148790; Fri, 15 May 2026 05:12:28 -0700 (PDT) Received: from server0.tail6e7dd.ts.net (c-68-48-65-54.hsd1.mi.comcast.net. [68.48.65.54]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-516456888f6sm45534491cf.3.2026.05.15.05.12.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 May 2026 05:12:28 -0700 (PDT) From: Michael Bommarito To: Miri Korenblit Cc: Johannes Berg , Emmanuel Grumbach , linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org Subject: [PATCH 4/4] wifi: iwlwifi: mld: clamp netdetect channel iteration to n_channels Date: Fri, 15 May 2026 08:11:00 -0400 Message-ID: <20260515121100.649334-5-michael.bommarito@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260515121100.649334-1-michael.bommarito@gmail.com> References: <20260515121100.649334-1-michael.bommarito@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit iwl_mld_set_netdetect_info() walks the per-match matching_channels[] bitmap and emits one center_freq per set bit by indexing netdetect_cfg->channels[]: for_each_set_bit(j, (unsigned long *)&matches[i].matching_channels[0], sizeof(matches[i].matching_channels)) { match->channels[match->n_channels] = netdetect_cfg->channels[j]->center_freq; match->n_channels++; } Two problems here. First, the third argument to for_each_set_bit(bit, addr, size) is the number of BITS to walk, not bytes. sizeof(matches[i].matching_channels) is SCAN_OFFLOAD_MATCHING_CHANNELS_LEN = 7 BYTES, so the macro only visits j = 0..6 and silently misses bits 7..55 of the 56-bit bitmap. This is a functional defect (per-match channel reporting is truncated to the first 7 entries of the bitmap). Second, the loop body indexes netdetect_cfg->channels[j] without bounding j against netdetect_cfg->n_channels. netdetect_cfg ->channels is a kmemdup()'ed array of pointers sized at exactly n_channels entries (the user's WoWLAN net-detect channel list). If n_channels < 7 (a 2.4 GHz only configuration, or a small saved- SSID channel allowlist) and the firmware sets a match bit at any position in [n_channels, 6], the indexed load reads past the end of the allocation, and ->center_freq then dereferences whatever that wild pointer fetched. Reproduced under UML+KASAN via a KUnit harness that lifts the iteration logic. With netdetect_cfg->channels sized at 5 entries and matching_channels bit 5 set, the kernel panics on the wild deref: Kernel panic - not syncing: Segfault with no mm RIP: 0033:mld_set_freqs_buggy.constprop.0+0x116/0x1c2 (The selector 0x0033 is UML's user-mode segment; under UML, in-kernel code runs in ring 3 on the host. The trap is a kernel-context page fault on the wild-pointer deref.) Building drivers/net/wireless/intel/iwlwifi/mld/d3.o under x86_64 allmodconfig with the fix applied yields no new warnings. Rewrite the iteration as an explicit indexed loop with an upper bound of min(bitmap-width-in-bits, n_channels). This addresses both issues in one step: bits-correct iteration over the bitmap, and a hard clamp against the channels-table length. Address the two together because applying only the bits-correct iteration without the clamp would widen the OOB exposure from j < 7 to j < 56. A short comment is added because the clamp's purpose (avoiding an OOB pointer fetch from netdetect_cfg->channels) is not obvious from the expression alone, and a future reader could otherwise "simplify" the bound back to the underlying constant. Cc: stable@vger.kernel.org Fixes: d1e879ec600f ("wifi: iwlwifi: add iwlmld sub-driver") Signed-off-by: Michael Bommarito Assisted-by: Claude:claude-opus-4-7 --- drivers/net/wireless/intel/iwlwifi/mld/d3.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mld/d3.c b/drivers/net/wireless/intel/iwlwifi/mld/d3.c index e89ec531cb06..51abf414bb1e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/d3.c @@ -1165,7 +1165,7 @@ iwl_mld_set_netdetect_info(struct iwl_mld *mld, for_each_set_bit(i, &matched_profiles, netdetect_cfg->n_match_sets) { struct cfg80211_wowlan_nd_match *match; - int idx, j, n_channels = 0; + int idx, j, max, n_channels = 0; struct iwl_scan_offload_profile_match *matches = (void *)netdetect_res->matches; @@ -1192,9 +1192,19 @@ iwl_mld_set_netdetect_info(struct iwl_mld *mld, if (netdetect_cfg->n_channels < n_channels) continue; - for_each_set_bit(j, - (unsigned long *)&matches[i].matching_channels[0], - sizeof(matches[i].matching_channels)) { + /* Clamp bit-index iteration to the channels table length: + * a firmware-set bit past n_channels would otherwise index + * past the kmemdup'd netdetect_cfg->channels[] allocation. + */ + max = min_t(int, BITS_PER_BYTE * + sizeof(matches[i].matching_channels), + netdetect_cfg->n_channels); + + for (j = 0; j < max; j++) { + if (!(matches[i].matching_channels[j / BITS_PER_BYTE] & + BIT(j % BITS_PER_BYTE))) + continue; + match->channels[match->n_channels] = netdetect_cfg->channels[j]->center_freq; match->n_channels++; -- 2.53.0