On Mon, Apr 21, 2025 at 01:41:57PM -0700, Kees Cook wrote:
> The nested loop in iwl_mld_send_proto_offload() confuses Clang into
> thinking there could be final loop iteration past the end of the "nsc"
> array (which is only 4 entries). The FORTIFY checking in memcmp()
> (via ipv6_addr_cmp()) notices this (due to the available bytes in the
> out-of-bounds position of &nsc[4] being 0), and errors out, failing
> the build. For some reason (likely due to architectural loop unrolling
> configurations), this is only exposed on ARM builds currently. Due to
> Clang's lack of inline tracking[1], the warning is not very helpful:
> 
> include/linux/fortify-string.h:719:4: error: call to '__read_overflow' 
> declared with 'error' attribute: detected read beyond size of object (1st 
> parameter)
>   719 |                         __read_overflow();
>       |                         ^
> 1 error generated.
> 
> But this was tracked down to iwl_mld_send_proto_offload()'s
> ipv6_addr_cmp() call.
> 
> An upstream Clang bug has been filed[2] to track this, but for now.
> Fix the build by explicitly bounding the inner loop by "n_nsc", which
> is what "c" is already limited to.
> 
> Reported-by: Nathan Chancellor <nat...@kernel.org>
> Closes: https://github.com/ClangBuiltLinux/linux/issues/2076
> Link: https://github.com/llvm/llvm-project/pull/73552 [1]
> Link: https://github.com/llvm/llvm-project/issues/136603 [2]
> Signed-off-by: Kees Cook <k...@kernel.org>
> ---
> Cc: Miri Korenblit <miriam.rachel.korenb...@intel.com>
> Cc: Johannes Berg <johannes.b...@intel.com>
> Cc: Yedidya Benshimol <yedidya.ben.shi...@intel.com>
> Cc: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
> Cc: Avraham Stern <avraham.st...@intel.com>
> Cc: Daniel Gabay <daniel.ga...@intel.com>
> Cc: <linux-wirel...@vger.kernel.org>
> ---
>  drivers/net/wireless/intel/iwlwifi/mld/d3.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wireless/intel/iwlwifi/mld/d3.c 
> b/drivers/net/wireless/intel/iwlwifi/mld/d3.c
> index 2c6e8ecd93b7..1daca1ef02b2 100644
> --- a/drivers/net/wireless/intel/iwlwifi/mld/d3.c
> +++ b/drivers/net/wireless/intel/iwlwifi/mld/d3.c
> @@ -1754,7 +1754,7 @@ iwl_mld_send_proto_offload(struct iwl_mld *mld,
>  
>               addrconf_addr_solict_mult(&wowlan_data->target_ipv6_addrs[i],
>                                         &solicited_addr);
> -             for (j = 0; j < c; j++)
> +             for (j = 0; j < c && j < n_nsc; j++)
>                       if (ipv6_addr_cmp(&nsc[j].dest_ipv6_addr,
>                                         &solicited_addr) == 0)
>                               break;
> -- 
> 2.34.1
> 

I might be going crazy but this does not appear to actually resolve the
warning for me, at least with allmodconfig:

  $ git cite
  a33b5a08cbbd ("Merge tag 'sched_ext-for-6.15-rc3-fixes' of 
git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext")

  $ make -skj"$(nproc)" ARCH=arm LLVM=1 clean allmodconfig 
drivers/net/wireless/intel/iwlwifi/mld/d3.o
  In file included from drivers/net/wireless/intel/iwlwifi/mld/d3.c:5:
  ...
  In file included from include/linux/string.h:392:
  include/linux/fortify-string.h:719:4: error: call to '__read_overflow' 
declared with 'error' attribute: detected read beyond size of object (1st 
parameter)
    719 |                         __read_overflow();
        |                         ^
  1 error generated.

  $ b4 -q shazam 20250421204153.work.935-k...@kernel.org
  ...

  $ make -skj"$(nproc)" ARCH=arm LLVM=1 clean allmodconfig 
drivers/net/wireless/intel/iwlwifi/mld/d3.o
  In file included from drivers/net/wireless/intel/iwlwifi/mld/d3.c:5:
  ...
  In file included from include/linux/string.h:392:
  include/linux/fortify-string.h:719:4: error: call to '__read_overflow' 
declared with 'error' attribute: detected read beyond size of object (1st 
parameter)
    719 |                         __read_overflow();
        |                         ^
  1 error generated.

However, if I apply the diff at the bottom of the message, it does...

  $ git stash pop

  $ make -skj"$(nproc)" ARCH=arm LLVM=1 clean allmodconfig 
drivers/net/wireless/intel/iwlwifi/mld/d3.o

It is possible there is something else going on with allmodconfig like
KASAN or GCOV that causes this but I did not look too closely yet

Cheers,
Nathan

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/d3.c 
b/drivers/net/wireless/intel/iwlwifi/mld/d3.c
index fba6a7b1bb5c..7ce01ad3608e 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/d3.c
@@ -1757,7 +1757,7 @@ iwl_mld_send_proto_offload(struct iwl_mld *mld,
 
                addrconf_addr_solict_mult(&wowlan_data->target_ipv6_addrs[i],
                                          &solicited_addr);
-               for (j = 0; j < c && j < n_nsc; j++)
+               for (j = 0; j < n_nsc && j < c; j++)
                        if (ipv6_addr_cmp(&nsc[j].dest_ipv6_addr,
                                          &solicited_addr) == 0)
                                break;

Reply via email to