[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