https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82656
Bug ID: 82656 Summary: memset buffer overflow not detected after realloc with -fcheck-pointer-bounds Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: major Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- When the buggy program below is compiled without -fcheck-pointer-bounds it triggers a -Wstringop-overflow warning due to the buffer overflow. Running the program then aborts as the buffer overflow is detected. But when the same program is compiled with -fcheck-pointer-bounds -mmpx there is no warning at compile time and the program then runs with the buffer overflow undetected. Since the entire purpose of the -fcheck-pointer-bounds option is to detect invalid pointer accesses this seems like a severe bug (hence the severity of major). I suspect the root cause is the same as that of bug 82655: the signature of __builtin_realloc is different with -fcheck-pointer-bounds than without (the second argument is the pointer bounds in the former case and the allocation size in the latter), but the function attributes are the same between both built-ins. That includes the alloc_size attribute which specifies the argument number of the allocation size. Output without -fcheck-pointer-bounds: $ cat y.c && gcc -O2 -Wall -D_FORTIFY_SOURCE=2 y.c && ./a.out #include <string.h> void* __attribute__ ((noclone, noinline)) f (void *p) { void *q = __builtin_realloc (p, 32); if (!q) return 0; memset (q, 0, 123); return q; } int main (void) { f (__builtin_malloc (1)); } In file included from /usr/include/string.h:635:0, from y.c:1: In function ‘memset’, inlined from ‘f’ at y.c:10:3: /usr/include/bits/string3.h:90:10: warning: ‘__builtin___memset_chk’ writing 123 bytes into a region of size 32 overflows the destination [-Wstringop-overflow=] return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest)); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *** buffer overflow detected ***: ./a.out terminated Contrast that to compiling and running with -fcheck-pointer-bounds: $ gcc -O2 -Wall -D_FORTIFY_SOURCE=2 -fcheck-pointer-bounds -mmpx y.c && ./a.out $