[Bug middle-end/77608] New: missing protection on trivially detectable runtime buffer overflow
msebor at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu Sep 15 19:44:00 GMT 2016
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77608
Bug ID: 77608
Summary: missing protection on trivially detectable runtime
buffer overflow
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: ---
The __builtin_object_size function is documented to return the size of the
smallest or largest, respectively, object referenced by its first argument,
ptr, depending on its second argument. When the size of the object ptr points
to is known at compile time but ptr is the result of pointer arithmetic such
the addition expression where the integer operand is not known,
__builtin_object_size fails instead of returning the (maximum or minimum) size
of the object. This failure in turn disables the protection even in otherwise
obvious cases of buffer overflow.
For example, the call to memcpy in the following program clearly overflows the
destination buffer regardless of the value of i, yet because of the
__builtin_object_size failure, GCC fails to instrument the call and the
overflow is allowed to go undetected.
$ 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)) \
volatile unsigned i;
int main (void)
{
{
char d [3];
P (d + i);
memcpy (d + i, "abcdef", 5);
__builtin_printf ("%.0s", d);
}
}
;; Function main (main, funcdef_no=0, decl_uid=1792, cgraph_uid=0,
symbol_order=1) (executed once)
main ()
{
char d[3];
unsigned int i.0_1;
sizetype _2;
void * _3;
<bb 2>:
__builtin_printf ("%2zd %2zd %2zd %2zd\n", 18446744073709551615,
18446744073709551615, 0, 0);
i.0_1 ={v} i;
_2 = (sizetype) i.0_1;
_3 = &d + _2;
__builtin_memcpy (_3, "abcdef", 5);
__builtin_printf ("%.0s", &d);
d ={v} {CLOBBER};
return 0;
}
-1 -1 0 0
More information about the Gcc-bugs
mailing list