[Bug middle-end/70988] missing buffer overflow detection in chained strcat calls
jakub at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Tue May 10 07:43:00 GMT 2016
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70988
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jakub at gcc dot gnu.org
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
At least #c1 is indeed a tree-ssa-strlen.c bug.
It transforms
a = "";
__builtin___strcat_chk (&a, "abc", 4);
__builtin___strcat_chk (&a, "def", 4);
__builtin___strcat_chk (&a, "ghi", 4);
__builtin___strcat_chk (&a, "jkl", 4);
into:
a = "";
__builtin___memcpy_chk (&a, "abc", 4, 4);
_9 = &a + 3;
__builtin___memcpy_chk (_9, "def", 4, 4);
_10 = &a + 6;
__builtin___memcpy_chk (_10, "ghi", 4, 4);
_11 = &a + 9;
__builtin___memcpy_chk (_11, "jkl", 4, 4);
which is wrong, we need to subtract the current known length of the destination
string from the __strcat_chk BOS sizes to get the __memcpy_chk BOS size (and
both have to be integers), otherwise we have to punt on the transformation (BOS
can't be variable). So the above would be:
a = "";
__builtin___memcpy_chk (&a, "abc", 4, 4);
_9 = &a + 3;
__builtin___memcpy_chk (_9, "def", 4, 1);
_10 = &a + 6;
__builtin___memcpy_chk (_10, "ghi", 4, 0);
_11 = &a + 9;
__builtin___memcpy_chk (_11, "jkl", 4, 0);
For known variable length of destination string before __strcat_chk, the
question is if we shouldn't transform it to memcpy instead with if (var_len +
const_size >= strcat_bos) __chk_fail (); but we'd then might run into overflow
issues and from the basic design principle that -D_FORTIFY_SOURCE=2 should
provide only very cheap checks. So maybe use ADD_OVERFLOW too on the addition?
The strcat -> memcpy transformation is important on the other side, would be
bad if we lost it.
More information about the Gcc-bugs
mailing list