Re: [PATCH] wifi: nl80211: Avoid address calculations via out of bounds array indexing

2024-05-07 Thread Nathan Chancellor
On Tue, May 07, 2024 at 12:46:46PM +0200, Johannes Berg wrote:
> On Thu, 2024-04-25 at 11:13 -0700, Nathan Chancellor wrote:
> > On Wed, Apr 24, 2024 at 03:01:01PM -0700, Kees Cook wrote:
> > > 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 
> > > Fixes: e3eac9f32ec0 ("wifi: cfg80211: Annotate struct 
> > > cfg80211_scan_request with __counted_by")
> > > Signed-off-by: Kees Cook 
> > 
> > Tested-by: Nathan Chancellor 
> > 
> 
> How do you get this tested? We have the same, and more, bugs in
> cfg80211_scan_6ghz() which I'm fixing right now, but no idea how to
> actually get the checks done?

You'll need a toolchain with __counted_by support, which I believe is
only clang 18+ at this point (I have prebuilts available at [1]), and
CONFIG_UBSAN_BOUNDS enabled, then they should just pop up in dmesg.

[1]: https://mirrors.edge.kernel.org/pub/tools/llvm/

Cheers,
Nathan



Re: [PATCH] wifi: nl80211: Avoid address calculations via out of bounds array indexing

2024-05-07 Thread Johannes Berg
On Thu, 2024-04-25 at 11:13 -0700, Nathan Chancellor wrote:
> On Wed, Apr 24, 2024 at 03:01:01PM -0700, Kees Cook wrote:
> > 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 
> > Fixes: e3eac9f32ec0 ("wifi: cfg80211: Annotate struct cfg80211_scan_request 
> > with __counted_by")
> > Signed-off-by: Kees Cook 
> 
> Tested-by: Nathan Chancellor 
> 

How do you get this tested? We have the same, and more, bugs in
cfg80211_scan_6ghz() which I'm fixing right now, but no idea how to
actually get the checks done?

johannes



Re: [PATCH] wifi: nl80211: Avoid address calculations via out of bounds array indexing

2024-04-30 Thread Kees Cook
On Tue, Apr 30, 2024 at 12:59:57PM -0700, Jeff Johnson wrote:
> On 4/30/2024 3:01 AM, Johannes Berg wrote:
> > This really doesn't even seem right, shouldn't do pointer arithmetic on
> > void pointers.
> 
> FWIW I argued this in the past in another context and Linus gave his opinion:
> 
> https://lore.kernel.org/all/CAHk-=whFKYMrF6euVvziW+drw7-yi1pYdf=uccnzj8k09do...@mail.gmail.com/

I was going to make the same argument. :) For this case, (void *) is
superior because we need to perform byte-granular arithmetic and we need
to use the implicit cast to the assigned variable's type.

The reason not to use the channels[] array is because we're not addressing
anything in the array -- we're addressing past it. Better to use the
correct allocation base.

-Kees

-- 
Kees Cook



Re: [PATCH] wifi: nl80211: Avoid address calculations via out of bounds array indexing

2024-04-30 Thread Jeff Johnson
On 4/30/2024 3:01 AM, Johannes Berg wrote:
> This really doesn't even seem right, shouldn't do pointer arithmetic on
> void pointers.

FWIW I argued this in the past in another context and Linus gave his opinion:

https://lore.kernel.org/all/CAHk-=whFKYMrF6euVvziW+drw7-yi1pYdf=uccnzj8k09do...@mail.gmail.com/




Re: [PATCH] wifi: nl80211: Avoid address calculations via out of bounds array indexing

2024-04-30 Thread Johannes Berg
On Wed, 2024-04-24 at 15:01 -0700, Kees Cook wrote:
> 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 
> Fixes: e3eac9f32ec0 ("wifi: cfg80211: Annotate struct cfg80211_scan_request 
> with __counted_by")

While I was weighing whether or not to apply this for 6.9 still ...

> + request->n_channels = n_channels;
>  
>   if (n_ssids)
> - request->ssids = (void *)>channels[n_channels];
> + request->ssids = (void *)request + ssids_offset;

This really doesn't even seem right, shouldn't do pointer arithmetic on
void pointers. Same applies below too.

And also if you set n_channels before, perhaps it's actually OK to get a
pointer to *after*? Not sure though.

johannes



Re: [PATCH] wifi: nl80211: Avoid address calculations via out of bounds array indexing

2024-04-25 Thread Nathan Chancellor
On Wed, Apr 24, 2024 at 03:01:01PM -0700, Kees Cook wrote:
> 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 
> Fixes: e3eac9f32ec0 ("wifi: cfg80211: Annotate struct cfg80211_scan_request 
> with __counted_by")
> Signed-off-by: Kees Cook 

Tested-by: Nathan Chancellor 

> ---
> Cc: Johannes Berg 
> Cc: "David S. Miller" 
> Cc: Eric Dumazet 
> Cc: Jakub Kicinski 
> Cc: Paolo Abeni 
> Cc: linux-wirel...@vger.kernel.org
> Cc: net...@vger.kernel.org
> ---
>  net/wireless/nl80211.c | 14 +++---
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> index f391b4055944..f1ed0981147e 100644
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -9163,6 +9163,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 = >wiphy;
>  
> @@ -9208,21 +9209,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 *)>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) {
> -- 
> 2.34.1
>