[Bug middle-end/77622] __builtin_object_size incorrect for an out-of-bounds pointer prior to destination object

msebor at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sun Nov 3 20:34:00 GMT 2019


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77622

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2019-11-03
     Ever confirmed|0                           |1
      Known to fail|                            |10.0, 7.3.0, 8.3.0, 9.2.0

--- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> ---
GCC 10 warns but still doesn't instrument the code so the invalid access is
allowed to cause memory corruption at runtime:

$ gcc -O2 -Wall -fdump-tree-optimized=/dev/stdout pr77622.c && ./a.out
pr77622.c: In function ‘f’:
pr77622.c:6:9: warning: array subscript -7 is outside array bounds of ‘char[3]’
[-Warray-bounds]
    6 |   char *p = &d[3] - i;
      |         ^
pr77622.c:4:8: note: while referencing ‘d’
    4 |   char d [3];
      |        ^
pr77622.c:6:9: warning: array subscript -7 is outside array bounds of ‘char[3]’
[-Warray-bounds]
    6 |   char *p = &d[3] - i;
      |         ^
pr77622.c:4:8: note: while referencing ‘d’
    4 |   char d [3];
      |        ^

;; Function f (f, funcdef_no=0, decl_uid=1930, cgraph_uid=1, symbol_order=0)

__attribute__((noinline))
f ()
{
  char d[3];

  <bb 2> [local count: 1073741824]:
  __builtin_memcpy (&MEM <char> [(void *)&d + -7B], "abcdef", 5);
  __builtin_printf ("%.0s", &MEM <char> [(void *)&d + -7B]);
  d ={v} {CLOBBER};
  return;

}



;; Function main (main, funcdef_no=1, decl_uid=1936, cgraph_uid=2,
symbol_order=1) (executed once)

main ()
{
  <bb 2> [local count: 1073741824]:
  f ();
  return 0;

}


Clang doesn't warn about the invalid access like GCC does but it prevents it at
runtime:

$ cat pr77622.c && clang -D_FORTIFY_SOURCE=2 -O2 -Wall pr77622.c && ./a.out
__attribute__ ((noinline))
void f (void)
{
  char d [3];
  int i = 10;
  char *p = &d[3] - i;

  __builtin___memcpy_chk (p, "abcdef", 5, __builtin_object_size (p, 0));

  __builtin_printf ("%.0s", p);
}

int main (void)
{
  f ();
}
*** buffer overflow detected ***: ./a.out terminated
Aborted (core dumped)


More information about the Gcc-bugs mailing list