modernc.org/ccgo/v3@v3.16.14/lib/testdata/gcc-9.1.0/gcc/testsuite/gcc.c-torture/execute/builtins/strncat-chk.c (about)

     1  /* Copyright (C) 2004, 2005  Free Software Foundation.
     2  
     3     Ensure builtin __strncat_chk performs correctly.  */
     4  
     5  extern void abort (void);
     6  typedef __SIZE_TYPE__ size_t;
     7  extern size_t strlen (const char *);
     8  extern void *memcpy (void *, const void *, size_t);
     9  extern char *strcat (char *, const char *);
    10  extern char *strncat (char *, const char *, size_t);
    11  extern int memcmp (const void *, const void *, size_t);
    12  extern char *strcpy (char *, const char *);
    13  extern int strcmp (const char *, const char *);
    14  extern void *memset (void *, int, size_t);
    15  
    16  #include "chk.h"
    17  
    18  const char s1[] = "123";
    19  char p[32] = "";
    20  char *s2 = "defg";
    21  char *s3 = "FGH";
    22  char *s4;
    23  size_t l1 = 1;
    24  char *s5;
    25  int x = 123;
    26  
    27  void
    28  __attribute__((noinline))
    29  test1 (void)
    30  {
    31    const char *const s1 = "hello world";
    32    const char *const s2 = "";
    33    const char *s3;
    34    char dst[64], *d2;
    35  
    36    /* Following strncat calls should be all optimized out.  */
    37    chk_calls = 0;
    38    strncat_disallowed = 1;
    39    strcat_disallowed = 1;
    40    strcpy (dst, s1);
    41    if (strncat (dst, "", 100) != dst || strcmp (dst, s1))
    42      abort ();
    43    strcpy (dst, s1);
    44    if (strncat (dst, s2, 100) != dst || strcmp (dst, s1))
    45      abort ();
    46    strcpy (dst, s1); d2 = dst;
    47    if (strncat (++d2, s2, 100) != dst+1 || d2 != dst+1 || strcmp (dst, s1))
    48      abort ();
    49    strcpy (dst, s1); d2 = dst;
    50    if (strncat (++d2+5, s2, 100) != dst+6 || d2 != dst+1 || strcmp (dst, s1))
    51      abort ();
    52    strcpy (dst, s1); d2 = dst;
    53    if (strncat (++d2+5, s1+11, 100) != dst+6 || d2 != dst+1 || strcmp (dst, s1))
    54      abort ();
    55    strcpy (dst, s1); d2 = dst;
    56    if (strncat (++d2+5, s1, 0) != dst+6 || d2 != dst+1 || strcmp (dst, s1))
    57      abort ();
    58    strcpy (dst, s1); d2 = dst; s3 = s1;
    59    if (strncat (++d2+5, ++s3, 0) != dst+6 || d2 != dst+1 || strcmp (dst, s1)
    60        || s3 != s1 + 1)
    61      abort ();
    62    strcpy (dst, s1); d2 = dst;
    63    if (strncat (++d2+5, "", ++x) != dst+6 || d2 != dst+1 || x != 124
    64        || strcmp (dst, s1))
    65      abort ();
    66    if (chk_calls)
    67      abort ();
    68    strcat_disallowed = 0;
    69  
    70    /* These __strncat_chk calls should be optimized into __strcat_chk,
    71       as strlen (src) <= len.  */
    72    strcpy (dst, s1);
    73    if (strncat (dst, "foo", 3) != dst || strcmp (dst, "hello worldfoo"))
    74      abort ();
    75    strcpy (dst, s1);
    76    if (strncat (dst, "foo", 100) != dst || strcmp (dst, "hello worldfoo"))
    77      abort ();
    78    strcpy (dst, s1);
    79    if (strncat (dst, s1, 100) != dst || strcmp (dst, "hello worldhello world"))
    80      abort ();
    81    if (chk_calls != 3)
    82      abort ();
    83  
    84    chk_calls = 0;
    85    /* The following calls have side-effects in dest, so are not checked.  */
    86    strcpy (dst, s1); d2 = dst;
    87    if (__builtin___strncat_chk (++d2, s1, 100, os (++d2)) != dst+1
    88        || d2 != dst+1 || strcmp (dst, "hello worldhello world"))
    89      abort ();
    90    strcpy (dst, s1); d2 = dst;
    91    if (__builtin___strncat_chk (++d2+5, s1, 100, os (++d2+5)) != dst+6
    92        || d2 != dst+1 || strcmp (dst, "hello worldhello world"))
    93      abort ();
    94    strcpy (dst, s1); d2 = dst;
    95    if (__builtin___strncat_chk (++d2+5, s1+5, 100, os (++d2+5)) != dst+6
    96        || d2 != dst+1 || strcmp (dst, "hello world world"))
    97      abort ();
    98    if (chk_calls)
    99      abort ();
   100  
   101    chk_calls = 0;
   102    strcat_disallowed = 1;
   103  
   104    /* Test at least one instance of the __builtin_ style.  We do this
   105       to ensure that it works and that the prototype is correct.  */
   106    strcpy (dst, s1);
   107    if (__builtin_strncat (dst, "", 100) != dst || strcmp (dst, s1))
   108      abort ();
   109  
   110    if (chk_calls)
   111      abort ();
   112    strncat_disallowed = 0;
   113    strcat_disallowed = 0;
   114  }
   115  
   116  /* Test whether compile time checking is done where it should
   117     and so is runtime object size checking.  */
   118  void
   119  __attribute__((noinline))
   120  test2 (void)
   121  {
   122    struct A { char buf1[10]; char buf2[10]; } a;
   123    char *r = l1 == 1 ? &a.buf1[5] : &a.buf2[4];
   124    char buf3[20];
   125    int i;
   126  
   127    /* The following calls should do runtime checking.  */
   128    memset (&a, '\0', sizeof (a));
   129    s5 = (char *) &a;
   130    __asm __volatile ("" : : "r" (s5) : "memory");
   131    chk_calls = 0;
   132    strncat (a.buf1 + 2, s3 + 3, l1 - 1);
   133    strncat (r, s3 + 2, l1);
   134    r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
   135    memset (r, '\0', 3);
   136    __asm __volatile ("" : : "r" (r) : "memory");
   137    strncat (r, s2 + 2, l1 + 1);
   138    strncat (r + 2, s3 + 3, l1 - 1);
   139    r = buf3;
   140    for (i = 0; i < 4; ++i)
   141      {
   142        if (i == l1 - 1)
   143  	r = &a.buf1[1];
   144        else if (i == l1)
   145  	r = &a.buf2[7];
   146        else if (i == l1 + 1)
   147  	r = &buf3[5];
   148        else if (i == l1 + 2)
   149  	r = &a.buf1[9];
   150      }
   151    strncat (r, s2 + 4, l1);
   152    if (chk_calls != 5)
   153      abort ();
   154  
   155    /* Following have known destination and known source length,
   156       but we don't know the length of dest string, so runtime checking
   157       is needed too.  */
   158    memset (&a, '\0', sizeof (a));
   159    chk_calls = 0;
   160    s5 = (char *) &a;
   161    __asm __volatile ("" : : "r" (s5) : "memory");
   162    strncat (a.buf1 + 2, "a", 5);
   163    strncat (r, "def", 0);
   164    r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
   165    memset (r, '\0', 3);
   166    __asm __volatile ("" : : "r" (r) : "memory");
   167    strncat (r, s1 + 1, 2);
   168    if (chk_calls != 2)
   169      abort ();
   170    chk_calls = 0;
   171    strcat_disallowed = 1;
   172    /* Unknown destination and source, no checking.  */
   173    strncat (s4, s3, l1 + 1);
   174    strcat_disallowed = 0;
   175    if (chk_calls)
   176      abort ();
   177  }
   178  
   179  /* Test whether runtime and/or compile time checking catches
   180     buffer overflows.  */
   181  void
   182  __attribute__((noinline))
   183  test3 (void)
   184  {
   185    struct A { char buf1[10]; char buf2[10]; } a;
   186    char buf3[20];
   187  
   188    memset (&a, '\0', sizeof (a));
   189    memset (buf3, '\0', sizeof (buf3));
   190    s5 = (char *) &a;
   191    __asm __volatile ("" : : "r" (s5) : "memory");
   192    s5 = buf3;
   193    __asm __volatile ("" : : "r" (s5) : "memory");
   194    chk_fail_allowed = 1;
   195    /* Runtime checks.  */
   196    if (__builtin_setjmp (chk_fail_buf) == 0)
   197      {
   198        strncat (&a.buf2[9], s2 + 3, 4);
   199        abort ();
   200      }
   201    if (__builtin_setjmp (chk_fail_buf) == 0)
   202      {
   203        strncat (&a.buf2[7], s3 + strlen (s3) - 3, 3);
   204        abort ();
   205      }
   206    if (__builtin_setjmp (chk_fail_buf) == 0)
   207      {
   208        strncat (&buf3[19], "abcde", 1);
   209        abort ();
   210      }
   211    chk_fail_allowed = 0;
   212  }
   213  
   214  void
   215  main_test (void)
   216  {
   217  #ifndef __OPTIMIZE__
   218    /* Object size checking is only intended for -O[s123].  */
   219    return;
   220  #endif
   221    __asm ("" : "=r" (s2) : "0" (s2));
   222    __asm ("" : "=r" (s3) : "0" (s3));
   223    __asm ("" : "=r" (l1) : "0" (l1));
   224    s4 = p;
   225    test1 ();
   226    memset (p, '\0', sizeof (p));
   227    test2 ();
   228    test3 ();
   229  }