https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79220

            Bug ID: 79220
           Summary: missing -Wstringop-overflow= on a memcpy 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: ---

Both of the two calls to memcpy in the functions in the test case below
trivially overflow the destination, yet only the one in f() is diagnosed.  The
one in g() is not because GCC transforms the memcpy call to assignment. 
Between the two, from a security point, overflowing a buffer with unknown data
is a more serious problem than overwriting it with data already
present/hardcoded in the program.  GCC should avoid performing the
transformation unless the destination is known to be big enough for the write.

$ cat t.c && gcc -O2 -S -Wall -Wextra -Wpedantic
-fdump-tree-optimized=/dev/stdout t.c
#include <string.h>

char d[3];

void f (void)
{
  memcpy (d, "0123456789", 8);
}

void g (const char *s)
{
  memcpy (d, s, 8);
}

;; Function f (f, funcdef_no=14, decl_uid=2196, cgraph_uid=14, symbol_order=15)

f ()
{
  <bb 2> [100.00%]:
  memcpy (&d, "0123456789", 8); [tail call]
  return;

}


t.c: In function ‘f’:
t.c:7:3: warning: ‘memcpy’ writing 8 bytes into a region of size 3 overflows
the destination [-Wstringop-overflow=]
   memcpy (d, "0123456789", 8);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~

;; Function g (g, funcdef_no=15, decl_uid=2199, cgraph_uid=15, symbol_order=16)

g (const char * s)
{
  long unsigned int _3;

  <bb 2> [100.00%]:
  _3 = MEM[(char * {ref-all})s_2(D)];
  MEM[(char * {ref-all})&d] = _3;
  return;

}

Reply via email to