'-Warray-bounds' is already disabled for gcc-10+. Now that we've merged
bitmap_{read,write), I see the following error when building the kernel
with gcc-9.4 (Ubuntu 20.04.4 LTS) for x86_64 allmodconfig:
drivers/pinctrl/pinctrl-cy8c95x0.c: In function ‘cy8c95x0_read_regs_mask.isra.0’:
include/linux/bitmap.h:756:18: error: array subscript [1, 288230376151711744] is outside array bounds of ‘long unsigned int[1]’ [-Werror=array-bounds]
756 | value_high = map[index + 1] & BITMAP_LAST_WORD_MASK(start + nbits);
| ~~~^~~~~~~~~~~
The immediate reason is that the commit b44759705f7d ("bitmap: make
bitmap_{get,set}_value8() use bitmap_{read,write}()") switched the
bitmap_get_value8() to an alias of bitmap_read(); the same for 'set'.
Now; the code that triggers Warray-bounds, calls the function like this:
#define MAX_BANK 8
#define BANK_SZ 8
#define MAX_LINE (MAX_BANK * BANK_SZ)
DECLARE_BITMAP(tval, MAX_LINE); // 64-bit map: unsigned long tval[1]
read_val |= bitmap_get_value8(tval, i * BANK_SZ) & ~bits;
bitmap_read() is implemented such that it may conditionally dereference
a pointer beyond the boundary like this:
unsigned long offset = start % BITS_PER_LONG;
unsigned long space = BITS_PER_LONG - offset;
if (space >= nbits)
return (map[index] >> offset) & BITMAP_LAST_WORD_MASK(nbits);
value_low = map[index] & BITMAP_FIRST_WORD_MASK(start);
value_high = map[index + 1] & BITMAP_LAST_WORD_MASK(start + nbits);
return (value_low >> offset) | (value_high << space);
In case of bitmap_get_value8(), it's impossible to violate the boundary
because 'space >= nbits' is never the true for byte-aligned 8-bit access.
So, this is clearly a false-positive.
The same type of false-positives break my allmodconfig build in many
places. gcc-8, is clear, however.
Signed-off-by: Yury Norov <[email protected]>
---
It has already been spotted in this thread:
https://lore.kernel.org/linux-kernel//[email protected]/T/#mc833ceac1b05d7156a864dcfe21435d01d77a0d7
And I suggested to use the OPTIMIZER_HIDE_VAR() there. But now that I
see the warning disabled for gcc-10+, it looks simpler to just extend
it to gcc-9+.
---
init/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/init/Kconfig b/init/Kconfig
index 72404c1f2157..febdea2afc3b 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -883,7 +883,7 @@ config GCC10_NO_ARRAY_BOUNDS
config CC_NO_ARRAY_BOUNDS
bool
- default y if CC_IS_GCC && GCC_VERSION >= 100000 && GCC10_NO_ARRAY_BOUNDS
+ default y if CC_IS_GCC && GCC_VERSION >= 90000 && GCC10_NO_ARRAY_BOUNDS
# Currently, disable -Wstringop-overflow for GCC globally.
config GCC_NO_STRINGOP_OVERFLOW
--
2.40.1
On Wed, 22 May 2024 15:58:30 -0700 Yury Norov <[email protected]> wrote:
> '-Warray-bounds' is already disabled for gcc-10+. Now that we've merged
> bitmap_{read,write), I see the following error when building the kernel
> with gcc-9.4 (Ubuntu 20.04.4 LTS) for x86_64 allmodconfig:
>
> drivers/pinctrl/pinctrl-cy8c95x0.c: In function ‘cy8c95x0_read_regs_mask.isra.0’:
> include/linux/bitmap.h:756:18: error: array subscript [1, 288230376151711744] is outside array bounds of ‘long unsigned int[1]’ [-Werror=array-bounds]
> 756 | value_high = map[index + 1] & BITMAP_LAST_WORD_MASK(start + nbits);
> | ~~~^~~~~~~~~~~
>
> The immediate reason is that the commit b44759705f7d ("bitmap: make
> bitmap_{get,set}_value8() use bitmap_{read,write}()") switched the
> bitmap_get_value8() to an alias of bitmap_read(); the same for 'set'.
So it seems that all kernels which contain b44759705f7d should have
this change? If so, and as b44759705f7d appears to be in the net tree
then the net tree is a suitable place to carry this patch?
Or I can send it into Linus this -rc cycle and things will sort themselves out.
Thoughts?
On Thu, May 23, 2024 at 01:00:26PM -0700, Andrew Morton wrote:
> On Wed, 22 May 2024 15:58:30 -0700 Yury Norov <[email protected]> wrote:
>
> > '-Warray-bounds' is already disabled for gcc-10+. Now that we've merged
> > bitmap_{read,write), I see the following error when building the kernel
> > with gcc-9.4 (Ubuntu 20.04.4 LTS) for x86_64 allmodconfig:
> >
> > drivers/pinctrl/pinctrl-cy8c95x0.c: In function ‘cy8c95x0_read_regs_mask.isra.0’:
> > include/linux/bitmap.h:756:18: error: array subscript [1, 288230376151711744] is outside array bounds of ‘long unsigned int[1]’ [-Werror=array-bounds]
> > 756 | value_high = map[index + 1] & BITMAP_LAST_WORD_MASK(start + nbits);
> > | ~~~^~~~~~~~~~~
> >
> > The immediate reason is that the commit b44759705f7d ("bitmap: make
> > bitmap_{get,set}_value8() use bitmap_{read,write}()") switched the
> > bitmap_get_value8() to an alias of bitmap_read(); the same for 'set'.
>
> So it seems that all kernels which contain b44759705f7d should have
> this change? If so, and as b44759705f7d appears to be in the net tree
> then the net tree is a suitable place to carry this patch?
>
> Or I can send it into Linus this -rc cycle and things will sort themselves out.
>
> Thoughts?
This is a real build breaker, so yes - I would like to have the fix in
this -rc. No preference regarding the tree.