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 
$

Reply via email to