Building the Linux kernel with Clang and LLVM
 help / color / mirror / Atom feed
* [PATCH] arch_numa: Avoid false positive fortify warning in setup_node_to_cpumask_map()
@ 2026-08-12  5:22 Nathan Chancellor
  2026-08-12  5:47 ` Andrew Morton
  0 siblings, 1 reply; 3+ messages in thread
From: Nathan Chancellor @ 2026-08-12  5:22 UTC (permalink / raw)
  To: Mike Rapoport, Andrew Morton
  Cc: Nick Desaulniers, Bill Wendling, Justin Stitt, linux-mm,
	linux-kernel, llvm, stable, Nathan Chancellor

When building ARCH=riscv using clang with CONFIG_FORTIFY_SOURCE and
CONFIG_UBSAN_BOUNDS enabled, CONFIG_NR_CPUS > 64, and the default value
of 2 for CONFIG_NODES_SHIFT, there is a compiletime warning from the
fortify routines.

  In file included from mm/arch_numa.c:11:
  In file included from include/linux/acpi.h:14:
  In file included from include/linux/resource_ext.h:11:
  In file included from include/linux/slab.h:17:
  In file included from include/linux/gfp.h:7:
  In file included from include/linux/mmzone.h:8:
  In file included from include/linux/spinlock.h:60:
  In file included from include/linux/interrupt_rc.h:17:
  In file included from include/linux/smp.h:13:
  In file included from include/linux/cpumask.h:11:
  In file included from include/linux/bitmap.h:13:
  In file included from include/linux/string.h:383:
  include/linux/fortify-string.h:430:4: warning: call to '__write_overflow_field' declared with 'warning' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Wattribue-warning]
    430 |                         __write_overflow_field(p_size_field, size);
        |                         ^
  include/linux/fortify-string.h:430:4: note: called by function 'fortify_memset_chk(unsigned long, unsigned long, unsigned long)'
  include/linux/bitmap.h:248:3: note: inlined by function 'setup_node_to_cpumask_map'
    248 |                 memset(dst, 0, len);
        |                 ^
  include/linux/fortify-string.h:462:25: note: expanded from macro 'memset'
    462 | #define memset(p, c, s) __fortify_memset_chk(p, c, s,                   \
        |                         ^
  include/linux/fortify-string.h:453:2: note: expanded from macro '__fortify_memset_chk'
    453 |         fortify_memset_chk(__fortify_size, p_size, p_size_field),       \
        |         ^
  include/linux/fortify-string.h:430:4: note: use '-gline-directives-only' (implied by '-g1') or higher for more accurate inlining chain locations
    430 |                         __write_overflow_field(p_size_field, size);
        |                         ^
  1 warning generated.

In this configuration, MAX_NUMNODES is 4. clang unrolls the for loop in
setup_node_to_cpumask_map() past this, which triggers the fortify check
when accessing node_to_cpumask_map on the theoretical fifth loop
iteration because it would be an out of bounds write.

Make it clear to clang that nr_node_ids is bounded by MAX_NUMNODES due
to the logic in setup_nr_node_ids() by early returning in
setup_node_to_cpumask_map() should that condition be violated.

Cc: stable@vger.kernel.org # all applicable
Closes: https://github.com/ClangBuiltLinux/linux/issues/2174
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
---
This is based on mm-unstable due to the move of arch_numa.c from mm/ to
drivers/base/ living there. I have CC'd stable because this warning
appears in my testing back to at least 6.1 but I see no reason why it
should not apply to all trees. No fixes tag since this is a layered
problem that just happens to appear under certain conditions.

Another alternative would be using the __assume macro to say something
like

  __assume(nr_node_ids <= MAX_NUMNODES);

but that seems a little more fragile.
---
 mm/arch_numa.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/mm/arch_numa.c b/mm/arch_numa.c
index 442ea239bba7..bd7772b05bcf 100644
--- a/mm/arch_numa.c
+++ b/mm/arch_numa.c
@@ -105,6 +105,18 @@ static void __init setup_node_to_cpumask_map(void)
 	if (nr_node_ids == MAX_NUMNODES)
 		setup_nr_node_ids();
 
+	/*
+	 * This check should never be true but it makes it clear to compilers
+	 * that node_to_cpumask_map is bound by nr_node_ids, avoiding false
+	 * positive fortify warnings when accessing node_to_cpumask_map in the
+	 * for loop below.
+	 */
+	if (unlikely(nr_node_ids > MAX_NUMNODES)) {
+		pr_err("nr_node_ids (%u) is larger than MAX_NUMNODES (%d)",
+		       nr_node_ids, MAX_NUMNODES);
+		return;
+	}
+
 	/* allocate and clear the mapping */
 	for (node = 0; node < nr_node_ids; node++) {
 		alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);

---
base-commit: 47870fb9b0e3bd20b45e3a069b4c766f3dcb721a
change-id: 20260811-arch_numa-avoid-fortify-warning-66af87403412

Best regards,
--  
Cheers,
Nathan


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] arch_numa: Avoid false positive fortify warning in setup_node_to_cpumask_map()
  2026-08-12  5:22 [PATCH] arch_numa: Avoid false positive fortify warning in setup_node_to_cpumask_map() Nathan Chancellor
@ 2026-08-12  5:47 ` Andrew Morton
  2026-08-13  1:32   ` Nathan Chancellor
  0 siblings, 1 reply; 3+ messages in thread
From: Andrew Morton @ 2026-08-12  5:47 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: Mike Rapoport, Nick Desaulniers, Bill Wendling, Justin Stitt,
	linux-mm, linux-kernel, llvm, stable, Kees Cook

On Tue, 11 Aug 2026 22:22:42 -0700 Nathan Chancellor <nathan@kernel.org> wrote:

> When building ARCH=riscv using clang with CONFIG_FORTIFY_SOURCE and
> CONFIG_UBSAN_BOUNDS enabled, CONFIG_NR_CPUS > 64, and the default value
> of 2 for CONFIG_NODES_SHIFT, there is a compiletime warning from the
> fortify routines.

(cc Kees)

>   In file included from mm/arch_numa.c:11:
>   In file included from include/linux/acpi.h:14:
>   In file included from include/linux/resource_ext.h:11:
>   In file included from include/linux/slab.h:17:
>   In file included from include/linux/gfp.h:7:
>   In file included from include/linux/mmzone.h:8:
>   In file included from include/linux/spinlock.h:60:
>   In file included from include/linux/interrupt_rc.h:17:
>   In file included from include/linux/smp.h:13:
>   In file included from include/linux/cpumask.h:11:
>   In file included from include/linux/bitmap.h:13:
>   In file included from include/linux/string.h:383:
>   include/linux/fortify-string.h:430:4: warning: call to '__write_overflow_field' declared with 'warning' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Wattribue-warning]
>     430 |                         __write_overflow_field(p_size_field, size);
>         |                         ^
>   include/linux/fortify-string.h:430:4: note: called by function 'fortify_memset_chk(unsigned long, unsigned long, unsigned long)'
>   include/linux/bitmap.h:248:3: note: inlined by function 'setup_node_to_cpumask_map'
>     248 |                 memset(dst, 0, len);
>         |                 ^
>   include/linux/fortify-string.h:462:25: note: expanded from macro 'memset'
>     462 | #define memset(p, c, s) __fortify_memset_chk(p, c, s,                   \
>         |                         ^
>   include/linux/fortify-string.h:453:2: note: expanded from macro '__fortify_memset_chk'
>     453 |         fortify_memset_chk(__fortify_size, p_size, p_size_field),       \
>         |         ^
>   include/linux/fortify-string.h:430:4: note: use '-gline-directives-only' (implied by '-g1') or higher for more accurate inlining chain locations
>     430 |                         __write_overflow_field(p_size_field, size);
>         |                         ^
>   1 warning generated.
> 
> In this configuration, MAX_NUMNODES is 4. clang unrolls the for loop in
> setup_node_to_cpumask_map() past this, which triggers the fortify check
> when accessing node_to_cpumask_map on the theoretical fifth loop
> iteration because it would be an out of bounds write.
> 
> Make it clear to clang that nr_node_ids is bounded by MAX_NUMNODES due
> to the logic in setup_nr_node_ids() by early returning in
> setup_node_to_cpumask_map() should that condition be violated.
> 
> Cc: stable@vger.kernel.org # all applicable
> Closes: https://github.com/ClangBuiltLinux/linux/issues/2174
> Signed-off-by: Nathan Chancellor <nathan@kernel.org>
> ---
> This is based on mm-unstable due to the move of arch_numa.c from mm/ to
> drivers/base/ living there. I have CC'd stable because this warning
> appears in my testing back to at least 6.1 but I see no reason why it
> should not apply to all trees. No fixes tag since this is a layered
> problem that just happens to appear under certain conditions.
> 
> Another alternative would be using the __assume macro to say something
> like
> 
>   __assume(nr_node_ids <= MAX_NUMNODES);
> 
> but that seems a little more fragile.
> ---
>  mm/arch_numa.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/mm/arch_numa.c b/mm/arch_numa.c
> index 442ea239bba7..bd7772b05bcf 100644
> --- a/mm/arch_numa.c
> +++ b/mm/arch_numa.c
> @@ -105,6 +105,18 @@ static void __init setup_node_to_cpumask_map(void)
>  	if (nr_node_ids == MAX_NUMNODES)
>  		setup_nr_node_ids();
>  
> +	/*
> +	 * This check should never be true but it makes it clear to compilers
> +	 * that node_to_cpumask_map is bound by nr_node_ids, avoiding false
> +	 * positive fortify warnings when accessing node_to_cpumask_map in the
> +	 * for loop below.
> +	 */
> +	if (unlikely(nr_node_ids > MAX_NUMNODES)) {
> +		pr_err("nr_node_ids (%u) is larger than MAX_NUMNODES (%d)",

Sashiko wants a \n there.

> +		       nr_node_ids, MAX_NUMNODES);

Lord only knows why nr_node_ids is unsigned but MAX_NUMNODES is signed.

lgtm otherwise.

> +		return;
> +	}
> +


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] arch_numa: Avoid false positive fortify warning in setup_node_to_cpumask_map()
  2026-08-12  5:47 ` Andrew Morton
@ 2026-08-13  1:32   ` Nathan Chancellor
  0 siblings, 0 replies; 3+ messages in thread
From: Nathan Chancellor @ 2026-08-13  1:32 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Mike Rapoport, Nick Desaulniers, Bill Wendling, Justin Stitt,
	linux-mm, linux-kernel, llvm, stable, Kees Cook

On Tue, Aug 11, 2026 at 10:47:46PM -0700, Andrew Morton wrote:
> (cc Kees)

Thanks, should have done that originally, I cc'd him on the original
issue.

> Sashiko wants a \n there.

Thanks, will send v2 with this tomorrow.

> Lord only knows why nr_node_ids is unsigned but MAX_NUMNODES is signed.

I can change the specifier for MAX_NUMNODES to unsigned as well (even if
it is technically signed due to the signed '1' literal in its
definition) since it should never be negative, up to you.

-- 
Cheers,
Nathan

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-08-13  1:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-12  5:22 [PATCH] arch_numa: Avoid false positive fortify warning in setup_node_to_cpumask_map() Nathan Chancellor
2026-08-12  5:47 ` Andrew Morton
2026-08-13  1:32   ` Nathan Chancellor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox