aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2024-04-24 15:01:01 -0700
committerJohannes Berg <johannes.berg@intel.com>2024-05-03 09:20:26 +0200
commit838c7b8f1f278404d9d684c34a8cb26dc41aaaa1 (patch)
treedda74becf98e11f5e06e983067f2ebca3c0dc75a
parent3d913719df14c28c4d3819e7e6d150760222bda4 (diff)
downloadwireless-for-next.tar.gz
wifi: nl80211: Avoid address calculations via out of bounds array indexingHEADmainfor-next
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: Nathan Chancellor <nathan@kernel.org> Fixes: e3eac9f32ec0 ("wifi: cfg80211: Annotate struct cfg80211_scan_request with __counted_by") Signed-off-by: Kees Cook <keescook@chromium.org> Tested-by: Nathan Chancellor <nathan@kernel.org> Link: https://msgid.link/20240424220057.work.819-kees@kernel.org Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/wireless/nl80211.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 30ff9a47081348..65c416e8d25eb9 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -9162,6 +9162,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;
@@ -9207,21 +9208,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) {