https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126436
Bug ID: 126436
Summary: malloc incorrectly succeeds on big sizes with
-fsanitizer=address
Product: gcc
Version: 16.1.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: sanitizer
Assignee: unassigned at gcc dot gnu.org
Reporter: eggert at cs dot ucla.edu
CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
jakub at gcc dot gnu.org, kcc at gcc dot gnu.org
Target Milestone: ---
I ran into this bug when testing a bleeding-edge GNU m4 with gcc (GCC) 16.1.1
20260515 (Red Hat 16.1.1-2) on x86-64. Take the following program
'test-malloc.c':
#include <stdlib.h>
int
main (void)
{
return !!malloc ((size_t) -1 / 2 + 1);
}
and compile and run it in 32-bit mode on a large-enough x86-64 machine, as
follows:
gcc -m32 -fsanitize=address test-malloc.c
./a.out
echo $?
The last line should output "0", but it outputs "1" because the
AddressSanitizer malloc mistakenly succeeds. This malloc should fail on this
platform, because glibc malloc always fails when given sizes larger than
PTRDIFF_MAX, for safety reasons. I believe this has been true since glibc 2.30
(2019).
I do not observe the problem if I omit -fsanitize=address; exit status is 0.
Ironically, the 'gcc -m32' command by default warns that the size is too large.
But the -fsanitize=address calloc succeeds anyway. It's also ironic that in
this particular case, -fsanitize=address is less safe than ordinary
compilation.
Other allocator functions like realloc, calloc, and reallocarray have the same
bug. The AddressSanitizer versions mistakenly check only for size_t overflow;
they should also check for ptrdiff_t overflow.