Commit 4ac40e20 authored by Kees Cook's avatar Kees Cook Committed by Liu Jian
Browse files

wifi: nl80211: Avoid address calculations via out of bounds array indexing

stable inclusion
from stable-v6.6.33
commit ed74398642fcb19f6ff385c35a7d512c6663e17b
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IA6SBS
CVE: CVE-2024-38562

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=ed74398642fcb19f6ff385c35a7d512c6663e17b



--------------------------------

[ Upstream commit 838c7b8f1f278404d9d684c34a8cb26dc41aaaa1 ]

Before request->channels[] can be used, request->n_channels must be set.
Additionally, address calculations for memory after the "channels" array
need to be calculated from the allocation base ("request") rather than
via the first "out of bounds" index of "channels", otherwise run-time
bounds checking will throw a warning.

Reported-by: default avatarNathan Chancellor <nathan@kernel.org>
Fixes: e3eac9f3 ("wifi: cfg80211: Annotate struct cfg80211_scan_request with __counted_by")
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Tested-by: default avatarNathan Chancellor <nathan@kernel.org>
Link: https://msgid.link/20240424220057.work.819-kees@kernel.org


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarLiu Jian <liujian56@huawei.com>
parent 986fcc8f
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -9153,6 +9153,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
	struct wiphy *wiphy;
	int err, tmp, n_ssids = 0, n_channels, i;
	size_t ie_len, size;
	size_t ssids_offset, ie_offset;
	wiphy = &rdev->wiphy;
@@ -9198,21 +9199,20 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
		return -EINVAL;
	size = struct_size(request, channels, n_channels);
	ssids_offset = size;
	size = size_add(size, array_size(sizeof(*request->ssids), n_ssids));
	ie_offset = size;
	size = size_add(size, ie_len);
	request = kzalloc(size, GFP_KERNEL);
	if (!request)
		return -ENOMEM;
	request->n_channels = n_channels;
	if (n_ssids)
		request->ssids = (void *)&request->channels[n_channels];
		request->ssids = (void *)request + ssids_offset;
	request->n_ssids = n_ssids;
	if (ie_len) {
		if (n_ssids)
			request->ie = (void *)(request->ssids + n_ssids);
		else
			request->ie = (void *)(request->channels + n_channels);
	}
	if (ie_len)
		request->ie = (void *)request + ie_offset;
	i = 0;
	if (scan_freqs) {