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)