Bug 82645 - missing -Wstringop-overflow on strncpy overflowing a member array
Summary: missing -Wstringop-overflow on strncpy overflowing a member array
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 8.0
: P3 normal
Target Milestone: 8.4
Assignee: Martin Sebor
URL:
Keywords: diagnostic
Depends on:
Blocks: Wstringop-overflow
  Show dependency treegraph
 
Reported: 2017-10-21 01:52 UTC by Martin Sebor
Modified: 2019-09-05 15:18 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work: 8.1.0
Known to fail: 7.2.0
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2017-10-21 01:52:30 UTC
GCC fails to issue -Wstringop-overflow for the buffer overflow in the following test case unless it's compiled with -D_FORTIFY_SOURCE=2.  The root cause is that compute_builtin_object_size() fails.  Ironically, removing the call to sink (p->a) causes the warning to appear even without -D_FORTIFY_SOURCE=2.

As an aside, the byte count in the warning issued by GCC 8 (but not 7) with -D_FORTIFY_SOURCE=2 is off by 1.  The correct range (between 7 and INT_MAX) is shown in the warning without the sink() call:

    writing between 7 and 2147483647 bytes into a region of size 5 overflows the destination 

$ (set -x && cat y.c && gcc -O2 -Wall y.c && gcc -D_FORTIFY_SOURCE=2 -O2 -Wall y.c)
+ cat y.c
#include <string.h>

struct S { char a[5]; void (*pf)(void); };

void __attribute__ ((weak))
sink (const char *s)
{
  __builtin_printf ("%.7s\n", s);
}

void __attribute__ ((weak))
g (struct S *p, int n)
{
  if (n < 7) n = 7;

  strncpy (p->a, "123456", n);   // missing -Wstringop-overflow without -D_FORTIFY_SOURCE
  sink (p->a);                   // removing this call triggers the warning
}

int main (void)
{
  struct S s = { };
  g (&s, 7);
}
+ gcc -O2 -Wall y.c
+ gcc -D_FORTIFY_SOURCE=2 -O2 -Wall y.c
In file included from /usr/include/string.h:635:0,
                 from y.c:1:
In function ‘strncpy’,
    inlined from ‘g’ at y.c:16:3:
/usr/include/bits/string3.h:126:10: warning: ‘__builtin___strncpy_chk’ writing 6 bytes into a region of size 5 overflows the destination [-Wstringop-overflow=]
   return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Comment 1 Martin Sebor 2019-09-01 21:43:52 UTC
This was fixed via r254630 in GCC 8: PR c/81117 - Improve buffer overflow checking in strncpy.