https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85484
Bug ID: 85484
Summary: missing -Wstringop-overflow for strcpy with a string
of non-const length
Product: gcc
Version: 8.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: msebor at gcc dot gnu.org
Target Milestone: ---
The buffer overflow reported in bug 85476 can be reduced to the test case
below. The overflow is quite obvious and should be easy to detect at
compile-time via the -Wstringop-overflow warning yet GCC does not detect it,
either with or without -D_FORTIFY_SOURCE. That's because __builtin_object_size
that -Wstringop-overflow relies on only deals with constant sizes. But the
non-constant string length and allocation size are both readily available in
the tree-ssa-strlen pass and so the bug can easily be detected there.
$ cat x.c && gcc -O2 -S -Wall -Wextra -Wpedantic -fdump-tree-strlen=/dev/stdout
x.c
void f (char*);
void g (const char *s)
{
unsigned n = __builtin_strlen (s);
char *d = __builtin_alloca (n); // off-by-one error (should be n + 1)
__builtin_strcpy (d, s); // missing -Wstringop-overflow
f (d);
}
void h (const char *s)
{
unsigned n = __builtin_strlen (s);
char *d = __builtin_alloca (n);
__builtin___strcpy_chk (d, s, __builtin_object_size (d, 1));
f (d);
}
;; Function g (g, funcdef_no=0, decl_uid=1960, cgraph_uid=0, symbol_order=0)
g (const char * s)
{
char * d;
long unsigned int _1;
long unsigned int _8;
long unsigned int _10;
<bb 2> [local count: 1073741825]:
_1 = __builtin_strlen (s_3(D));
_8 = _1 & 4294967295;
d_5 = __builtin_alloca (_8);
_10 = _1 + 1;
__builtin_memcpy (d_5, s_3(D), _10);
f (d_5);
return;
}
;; Function h (h, funcdef_no=1, decl_uid=1965, cgraph_uid=1, symbol_order=1)
h (const char * s)
{
char * d;
long unsigned int _1;
long unsigned int _2;
long unsigned int _9;
<bb 2> [local count: 1073741825]:
_1 = __builtin_strlen (s_4(D));
_9 = _1 & 4294967295;
d_6 = __builtin_alloca (_9);
_2 = _1 + 1;
__builtin_memcpy (d_6, s_4(D), _2);
f (d_6);
return;
}