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

            Bug ID: 79196
           Summary: [7 Regression] Probably invalid folding of strstr(x,
                    "foo") eq x to memcmp (x, "foo", strlen("foo")
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: marxin at gcc dot gnu.org
                CC: prathamesh3492 at gcc dot gnu.org
  Target Milestone: ---

I found the problem in postgresql database, where:

$ cat /tmp/strcmp.c
#include <string.h>
#include <stdio.h>

int
__attribute__((noinline))
test(char *a)
{
  if (__builtin_strstr (a, "DROP CONVERSION") == a)
    return 0;

  return 1;
}

int main(int argc, char **argv)
{
  return test ("x");
}

gcc /tmp/strcmp.c -O2 -fsanitize=address && ./a.out 
=================================================================
==28435==ERROR: AddressSanitizer: global-buffer-overflow on address
0x0000004008a2 at pc 0x7fc19460a229 bp 0x7ffe1e071c30 sp 0x7ffe1e0713e0
READ of size 15 at 0x0000004008a2 thread T0
    #0 0x7fc19460a228 in __interceptor_memcmp
../../../../libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:626
    #1 0x4007a2 in test (/tmp/a.out+0x4007a2)
    #2 0x7fc1941dd290 in __libc_start_main (/lib64/libc.so.6+0x20290)
    #3 0x4006d9 in _start (/tmp/a.out+0x4006d9)

0x0000004008a2 is located 0 bytes to the right of global variable '*.LC1'
defined in '/tmp/strcmp.c' (0x4008a0) of size 2
  '*.LC1' is ascii string 'x'
SUMMARY: AddressSanitizer: global-buffer-overflow
../../../../libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:626
in __interceptor_memcmp
Shadow bytes around the buggy address:
  0x0000800780c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000800780d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000800780e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000800780f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080078100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f9 f9
=>0x000080078110: f9 f9 f9 f9[02]f9 f9 f9 f9 f9 f9 f9 00 00 00 00
  0x000080078120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080078130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080078140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080078150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x000080078160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

I guess one can't replace strstr where having a shorter first argument should
be valid usage as I've read documentation.
In that case, transforming to memcmp will cause invalid memory reads, as seen
by address sanitizer.

Started with r243633.

Reply via email to