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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-code

--- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> ---
The is a bug in the object size pass that has existed since its introduction. 
The addr_object_size() computes the size of the extern object based on its
type, not taking into consideration that, as an extension, GCC allows flexible
array members to be initialized to more elements than would otherwise fit into
the struct.  To avoid this, the function needs to conservatively fail for
uninitialized extern structs with a flexible array member.

The modified test case below illustrates it.  With _FORTIFY_SOURCE defined, it
aborts.

$ cat pr92815.c && gcc -O2 -Wall -c pr92815.c && gcc -D_FORTIFY_SOURCE=2 -DMAIN
-O2 -Wall pr92815.c pr92815.o && ./a.out
#include <string.h>

struct S { int n; char ax[]; };

#if MAIN
extern struct S s;
__attribute__ ((noipa)) void g (void)
{
  strcpy (s.ax, "123");
}
int main (void) { g (); }
#else
struct S s = { 5, { 1, 2, 3, 4, 5 } };
#endif

In file included from /usr/include/string.h:494,
                 from pr92815.c:1:
In function ‘strcpy’,
    inlined from ‘g’ at pr92815.c:9:3:
/usr/include/bits/string_fortified.h:90:10: warning: ‘__builtin___strcpy_chk’
writing 4 bytes into a region of size 0 [-Wstringop-overflow=]
   90 |   return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pr92815.c: In function ‘g’:
pr92815.c:6:17: note: at offset 0 to object ‘s’ with size 4 declared here
    6 | extern struct S s;
      |                 ^
In file included from /usr/include/string.h:494,
                 from pr92815.c:1:
In function ‘strcpy’,
    inlined from ‘g’ at pr92815.c:9:3:
/usr/include/bits/string_fortified.h:90:10: warning: ‘__builtin___memcpy_chk’
offset [4, 7] is out of the bounds [0, 4] of object ‘s’ with type ‘struct S’
[-Warray-bounds]
   90 |   return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pr92815.c: In function ‘g’:
pr92815.c:6:17: note: ‘s’ declared here
    6 | extern struct S s;
      |                 ^
*** buffer overflow detected ***: ./a.out terminated
Aborted (core dumped)

Reply via email to