[Bug middle-end/77622] New: __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
Fri Sep 16 16:59:00 GMT 2016
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77622
Bug ID: 77622
Summary: __builtin_object_size incorrect for an out-of-bounds
pointer prior to destination object
Product: gcc
Version: 7.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 __builtin_object_size intrinsic is passed a pointer that's derived
from the address of an object but points past its end it returns zero in all
types. This makes it possible for _FORTIFY_SOURCE to detect writing past the
end of the destination buffer.
However, when the function is passed a similarly derived pointer that points
before the beginning of the object it instead returns a positive value,
preventing GCC from emitting the checking calls, and allowing buffer overflows
to go undetected.
The test case below shows these two cases.
$ cat x.c && /build/gcc-trunk-git/gcc/xgcc -B /build/gcc-trunk-git/gcc -O2
-Wall -Wextra -Wpedantic -fdump-tree-optimized=/dev/stdout x.c && ./a.out
#define bos(dest) __builtin_object_size (dest, 0)
#define memcpy(dest, src, n) \
__builtin___memcpy_chk (dest, src, n, bos (dest))
#define P(x) \
__builtin_printf ("%2zd %2zd %2zd %2zd\n", \
__builtin_object_size (x, 0), \
__builtin_object_size (x, 1), \
__builtin_object_size (x, 2), \
__builtin_object_size (x, 3)) \
int main (void)
{
char d [3];
int i = 10;
char *p;
{
p = &d[3] - i;
P (p);
memcpy (p, "abcdef", 5);
__builtin_printf ("%.0s", p);
}
{
p = &d[3] + i;
P (p);
memcpy (p, "abcdef", 5);
__builtin_printf ("%.0s", p);
}
}
x.c: In function ‘main’:
x.c:19:7: warning: array subscript is below array bounds [-Warray-bounds]
p = &d[3] - i;
~~^~~~~~~~~~~
x.c:19:7: warning: array subscript is below array bounds [-Warray-bounds]
x.c:29:7: warning: array subscript is above array bounds [-Warray-bounds]
p = &d[3] + i;
~~^~~~~~~~~~~
x.c:29:7: warning: array subscript is above array bounds [-Warray-bounds]
;; Function main (main, funcdef_no=0, decl_uid=1791, cgraph_uid=0,
symbol_order=0) (executed once)
main ()
{
char d[3];
<bb 2>:
__builtin_printf ("%2zd %2zd %2zd %2zd\n", 10, 10, 10, 10);
__builtin_memcpy (&MEM[(void *)&d + -7B], "abcdef", 5);
__builtin_printf ("%.0s", &MEM[(void *)&d + -7B]);
__builtin_printf ("%2zd %2zd %2zd %2zd\n", 0, 0, 0, 0);
__builtin___memcpy_chk (&MEM[(void *)&d + 13B], "abcdef", 5, 0);
__builtin_printf ("%.0s", &MEM[(void *)&d + 13B]);
d ={v} {CLOBBER};
return 0;
}
x.c:3:3: warning: call to __builtin___memcpy_chk will always overflow
destination buffer
__builtin___memcpy_chk (dest, src, n, bos (dest))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
x.c:33:5: note: in expansion of macro ‘memcpy’
memcpy (p, "abcdef", 5);
^~~~~~
10 10 10 10
0 0 0 0
*** buffer overflow detected ***: ./a.out terminated
More information about the Gcc-bugs
mailing list