https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92334
Bug ID: 92334 Summary: incorrect __builtin_object_size result for negative offsets Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- When the pointer argument to __builtin_object_size() is at a negative offset from the beginning of an object the function seems to return the sum of the absolute value of the offset and the size of the object rather than zero, thus defeating the _FORTIFY_SOURCE protection against out of bounds writes. The -Warray-bounds and -Wstringop-overflow warnings do detect some of these bugs. $ cat z.c && gcc -O2 -S -Wall -fdump-tree-strlen=/dev/stdout z.c void sink (void*); void f (const void *p) { int i = -7; char a[3]; char *q = a + i; __builtin___memcpy_chk (q, p, 10, __builtin_object_size (p, 1)); sink (a); } void g (const void *p) { int i = -7; char a[3]; char *q = a + i; __builtin___memcpy_chk (q, p, 13, __builtin_object_size (p, 1)); sink (a); } z.c: In function ‘f’: z.c:8:9: warning: array subscript -7 is outside array bounds of ‘char[3]’ [-Warray-bounds] 8 | char *q = a + i; | ^ z.c:7:8: note: while referencing ‘a’ 7 | char a[3]; | ^ ;; Function f (f, funcdef_no=0, decl_uid=1932, cgraph_uid=1, symbol_order=0) ;; 1 loops found ;; ;; Loop 0 ;; header 0, latch 1 ;; depth 0, outer -1 ;; nodes: 0 1 2 ;; 2 succs { 1 } f (const void * p) { char a[3]; <bb 2> [local count: 1073741824]: __builtin_memcpy (&MEM <char[3]> [(void *)&a + -7B], p_3(D), 10); sink (&a); a ={v} {CLOBBER}; return; } z.c: In function ‘g’: z.c:20:9: warning: array subscript -7 is outside array bounds of ‘char[3]’ [-Warray-bounds] 20 | char *q = a + i; | ^ z.c:19:8: note: while referencing ‘a’ 19 | char a[3]; | ^ ;; Function g (g, funcdef_no=1, decl_uid=1938, cgraph_uid=2, symbol_order=1) ;; 1 loops found ;; ;; Loop 0 ;; header 0, latch 1 ;; depth 0, outer -1 ;; nodes: 0 1 2 ;; 2 succs { 1 } g (const void * p) { char a[3]; <bb 2> [local count: 1073741824]: __builtin_memcpy (&MEM <char[3]> [(void *)&a + -7B], p_3(D), 13); sink (&a); a ={v} {CLOBBER}; return; } z.c:22:3: warning: ‘__builtin_memcpy’ writing 13 bytes into a region of size 10 overflows the destination [-Wstringop-overflow=] 22 | __builtin___memcpy_chk (q, p, 13, __builtin_object_size (p, 1)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~