Bug 82456 - missing -Wstringop-overread on strcpy reading past the end of an array
Summary: missing -Wstringop-overread on strcpy reading past the end of an array
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 8.0
: P3 normal
Target Milestone: 11.0
Assignee: Martin Sebor
URL:
Keywords: diagnostic
Depends on:
Blocks: Wstringop-overread
  Show dependency treegraph
 
Reported: 2017-10-06 17:48 UTC by Martin Sebor
Modified: 2020-09-14 19:24 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work: 11.0
Known to fail: 10.2.0, 7.3.0, 8.2.0, 9.1.0
Last reconfirmed: 2020-02-10 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2017-10-06 17:48:26 UTC
The -Wstringop-overflow warning is supposed to detect not just writing but also reading past the end of arrays.  The following test case shows a number of instances of the latter bug the warning fails to detect.  (The missing -Warray-bounds is discussed in bug 82455.)

$ cat z.c && gcc -O2 -S -Wall -Wextra z.c
void fcst (char *d)
{
  char a[2] = "0";

  __builtin_strcpy (d, a + 3);   // -Warray-bounds (good)
                                 // missing -Wstringop-overflow
}

void frng (char *d, int i)
{
  char a[2] = "0";

  if (i < 3)
    i = 3;

  __builtin_strcpy (d, a + i);   // both warnings missing
                                 // (array index out of bounds
                                 // and reading past the end)
}

void gcst (char *d)
{
  char a[2] = "0";

  __builtin_strcpy (d, a + 2);   // missing -Wstringop-overflow
                                 // (reading past the end)
}

void grng (char *d, int i)
{
  char a[2] = "0";

  if (i < 2) 
    i = 2;

  __builtin_strcpy (d, a + i);   // missing -Wstringop-overflow
                                 // (reading past the end)
}

z.c: In function ‘fcst’:
z.c:5:3: warning: array subscript is above array bounds [-Warray-bounds]
   __builtin_strcpy (d, a + 3);   // -Warray-bounds (good)
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
Comment 1 Martin Sebor 2019-01-14 23:09:32 UTC
GCC 8.2.0 and 9 issue two warnings, one for each of fcst and frng, but none for gcst or grng, so confirming those are still missing.

See also bug 81437 for a similar (the same?) problem.

$ gcc -O2 -S -Wall z.c
z.c: In function ‘fcst’:
z.c:5:3: warning: array subscript 3 is above array bounds of ‘char[2]’ [-Warray-bounds]
   __builtin_strcpy (d, a + 3);   // -Warray-bounds (good)
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
z.c:5:3: warning: ‘__builtin_strcpy’ offset 3 is out of the bounds [0, 2] of object ‘a’ with type ‘char[2]’ [-Warray-bounds]
z.c:3:8: note: ‘a’ declared here
   char a[2] = "0";
        ^
z.c: In function ‘frng’:
z.c:16:3: warning: ‘__builtin_strcpy’ offset [3, 2147483647] is out of the bounds [0, 2] of object ‘a’ with type ‘char[2]’ [-Warray-bounds]
   __builtin_strcpy (d, a + i);   // both warnings missing
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
z.c:11:8: note: ‘a’ declared here
   char a[2] = "0";
        ^
Comment 2 Martin Sebor 2020-02-10 23:05:27 UTC
No change in 10.0.
Comment 3 Martin Sebor 2020-04-22 21:50:37 UTC
GCC 10 detects all these problems but only with -Warray-bounds (in -Wall) and not by -Wstringop-overflow (enabled by default), so I'm going to leave this open until it's also fixed there.

$ gcc -O2 -S -Wall pr82456.c
pr82456.c: In function ‘fcst’:
pr82456.c:5:3: warning: array subscript 3 is outside array bounds of ‘char[2]’ [-Warray-bounds]
    5 |   __builtin_strcpy (d, a + 3);   // -Warray-bounds (good)
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
pr82456.c:3:8: note: while referencing ‘a’
    3 |   char a[2] = "0";
      |        ^
pr82456.c: In function ‘frng’:
pr82456.c:16:3: warning: ‘__builtin_strcpy’ offset [3, 2147483647] is out of the bounds [0, 2] of object ‘a’ with type ‘char[2]’ [-Warray-bounds]
   16 |   __builtin_strcpy (d, a + i);   // both warnings missing
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
pr82456.c:11:8: note: ‘a’ declared here
   11 |   char a[2] = "0";
      |        ^
pr82456.c: In function ‘gcst’:
pr82456.c:25:3: warning: ‘__builtin_strcpy’ offset 2 is out of the bounds [0, 2] of object ‘a’ with type ‘char[2]’ [-Warray-bounds]
   25 |   __builtin_strcpy (d, a + 2);   // missing -Wstringop-overflow
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
pr82456.c:23:8: note: ‘a’ declared here
   23 |   char a[2] = "0";
      |        ^
pr82456.c: In function ‘grng’:
pr82456.c:36:3: warning: ‘__builtin_strcpy’ offset 2 is out of the bounds [0, 2] of object ‘a’ with type ‘char[2]’ [-Warray-bounds]
   36 |   __builtin_strcpy (d, a + i);   // missing -Wstringop-overflow
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
pr82456.c:31:8: note: ‘a’ declared here
   31 |   char a[2] = "0";
      |        

This was enabled by the commit below:

commit 3942060c4b3168307b9e2870d81e7ca15b49760a
Author: Martin Sebor <msebor@redhat.com>
Date:   Tue Apr 21 10:59:24 2020 -0600

    PR middle-end/94647 - bogus -Warray-bounds on strncpy into a larger member array from a smaller array
    
    gcc/ChangeLog:
    
            PR middle-end/94647
            * gimple-ssa-warn-restrict.c (builtin_access::builtin_access): Correct
            the computation of the lower bound of the source access size.
            (builtin_access::generic_overlap): Remove a hack for setting ranges
            of overlap offsets.
    
    gcc/testsuite/ChangeLog:
    
            PR middle-end/94647
            * c-c++-common/Warray-bounds-2.c: Adjust a test case and add a new one.
            * c-c++-common/Warray-bounds-3.c: Add tests for missing warnings.
            * c-c++-common/Wrestrict.c: Invert bounds in printed ranges.
            * gcc.dg/Warray-bounds-59.c: New test.
            * gcc.dg/Wrestrict-10.c: Add a missing warning.
            * gcc.dg/Wrestrict-5.c: Adjust text of expected warning.
            * gcc.dg/Wrestrict-6.c: Expect to see a range of overlap offsets.
Comment 4 Martin Sebor 2020-09-14 19:24:36 UTC
GCC 11 diagnoses all four instances with the new -Wstringop-overread warning added in g:d14c547abd484d3540b692bb8048c4a6efe92c8b.