[Bug middle-end/77784] New: duplicate warning for snprintf for n > object size
msebor at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Sep 28 16:48:00 GMT 2016
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77784
Bug ID: 77784
Summary: duplicate warning for snprintf for n > object size
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: ---
As mentioned in bug 77762#2, with both the -Wformat-length option used and
_FORTIFY_SOURCE defined (and with optimization enabled), GCC now prints two
warnings for calls to functions like snprintf (which normally calls
__builtin___snprintf_chk). Only one warning should be printed.
$ cat zzz.c && /build/gcc-trunk-svn/gcc/xgcc -B /build/gcc-trunk-svn/gcc -S
-Wall -Wformat-length=1 zzz.c
char d [2];
void f (const char *s)
{
__builtin___snprintf_chk (d, 4, 0, 2, s);
}
zzz.c: In function ‘f’:
zzz.c:5:3: warning: specified size 4 exceeds the size 2 of the destination
object [-Wformat-length=]
__builtin___snprintf_chk (d, 4, 0, 2, s);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
zzz.c:5:3: warning: call to __builtin___snprintf_chk will always overflow
destination buffer
As also pointed out in bug 77762 and as the following program shows, the latter
warning is misleading because a buffer overflow need not actually take place
and the call may be valid. This is just a minor detail when the default
implementation of the __snprintf_chk function is used that calls abort in this
case, but printing a more accurate message becomes important when an alternate
implementation is used that does not abort (as is sometimes done in operating
system kernels, for example).
$ cat zzz.c && /build/gcc-trunk-svn/gcc/xgcc -B /build/gcc-trunk-svn/gcc -Wall
-Wformat -Wextra -Wpedantic -Wformat-length=1 zzz.c && ./a.out
typedef __SIZE_TYPE__ size_t;
char d [2];
int main (void)
{
char s[] = "x";
__builtin___snprintf_chk (d, 4, 0, 2, s);
}
int __snprintf_chk (char *s, size_t maxlen, int flag, size_t os,
const char *fmt, ...)
{
__builtin_printf ("%s(%p, %zu, %i, %zu, \"%s\"...)\n",
__func__, s, maxlen, flag, os, fmt);
return __builtin_puts (fmt);
}
zzz.c: In function ‘main’:
zzz.c:8:3: warning: specified size 4 exceeds the size 2 of the destination
object [-Wformat-length=]
__builtin___snprintf_chk (d, 4, 0, 2, s);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
zzz.c:8:3: warning: call to __builtin___snprintf_chk will always overflow
destination buffer
__snprintf_chk(0x601049, 4, 0, 2, "x"...)
x
More information about the Gcc-bugs
mailing list