Re: x86: fortify-string.h:63:33: error: '__builtin_memcmp' specified bound exceeds maximum object size

From: Arnd Bergmann
Date: Wed Feb 21 2024 - 11:52:07 EST


On Wed, Feb 21, 2024, at 16:32, Naresh Kamboju wrote:
> The x86 / i386 compilations encountered errors due to additional Kconfigs
> incorporated from the selftests/net/*/config in the Linux next version.
> The issue first appeared with the next-20240213 tag. This problem affects
> the Linux next branch, but not the mainline Linus master branch.
>
> Reported-by: Linux Kernel Functional Testing <lkft@xxxxxxxxxx>
>
> The bisection points to the following commit id,
> # first bad commit: [64259ce2a20ce2dcc585a2cb83d1366fb04a6008] ubsan:
> reintroduce signed overflow sanitizer
>
> Build errors:
> -------------
> In function 'memcmp',
> inlined from 'nft_pipapo_insert' at
> /builds/linux/net/netfilter/nft_set_pipapo.c:1258:7:
> /builds/linux/include/linux/fortify-string.h:63:33: error:
> '__builtin_memcmp' specified bound 18446744071562067968 exceeds
> maximum object size 9223372036854775807 [-Werror=stringop-overread]
> 63 | #define __underlying_memcmp __builtin_memcmp
> | ^
> /builds/linux/include/linux/fortify-string.h:655:16: note: in
> expansion of macro '__underlying_memcmp'
> 655 | return __underlying_memcmp(p, q, size);
> | ^~~~~~~~~~~~~~~~~~~
> cc1: all warnings being treated as errors

The size 18446744071562067968 is equal to (u64)INT_MIN, so something
goes wrong with the length conversion when a negative length
might be passed into memcmp().

I don't see any relevant changes to this file that
are likely causes, but these warnings are sometimes
sensitive to compiler optimization, so it's possible that
some unrelated change such as 7395dfacfff6 ("netfilter:
nf_tables: use timestamp to check for set element timeout")
just changed the inlining behavior in a way such that
either a warning is now detected when it was previously
hidden and the compiler now sees more about the
state, or it seems less about the state and can no longer
prove that this does not happen.

I have so far not seen the same issue in randconfig builds
on today's linux-next with gcc-13.2.0, but I would guess
that a patch like

diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
index aa1d9e93a9a0..c284522f64c4 100644
--- a/net/netfilter/nft_set_pipapo.c
+++ b/net/netfilter/nft_set_pipapo.c
@@ -1252,11 +1252,12 @@ static int nft_pipapo_insert(const struct net *net, const struct nft_set *set,
start_p = start;
end_p = end;
nft_pipapo_for_each_field(f, i, m) {
+ unsigned length = f->groups / NFT_PIPAPO_GROUPS_PER_BYTE(f);
+
if (f->rules >= (unsigned long)NFT_PIPAPO_RULE0_MAX)
return -ENOSPC;

- if (memcmp(start_p, end_p,
- f->groups / NFT_PIPAPO_GROUPS_PER_BYTE(f)) > 0)
+ if (memcmp(start_p, end_p, length)) > 0)
return -EINVAL;

start_p += NFT_PIPAPO_GROUPS_PADDED_SIZE(f);


will hide the issue again.

Arnd