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

     1  /* Copyright (C) 2004, 2005  Free Software Foundation.
     2  
     3     Ensure builtin __strcpy_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 *strcpy (char *, const char *);
    10  extern int memcmp (const void *, const void *, size_t);
    11  
    12  #include "chk.h"
    13  
    14  LOCAL const char s1[] = "123";
    15  char p[32] = "";
    16  char *s2 = "defg";
    17  char *s3 = "FGH";
    18  char *s4;
    19  size_t l1 = 1;
    20  
    21  void
    22  __attribute__((noinline))
    23  test1 (void)
    24  {
    25    chk_calls = 0;
    26  #ifndef __OPTIMIZE_SIZE__
    27    strcpy_disallowed = 1;
    28  #else
    29    strcpy_disallowed = 0;
    30  #endif
    31  
    32    if (strcpy (p, "abcde") != p || memcmp (p, "abcde", 6))
    33      abort ();
    34    if (strcpy (p + 16, "vwxyz" + 1) != p + 16 || memcmp (p + 16, "wxyz", 5))
    35      abort ();
    36    if (strcpy (p + 1, "") != p + 1 || memcmp (p, "a\0cde", 6))
    37      abort ();  
    38    if (strcpy (p + 3, "fghij") != p + 3 || memcmp (p, "a\0cfghij", 9))
    39      abort ();
    40  
    41    /* Test at least one instance of the __builtin_ style.  We do this
    42       to ensure that it works and that the prototype is correct.  */
    43    if (__builtin_strcpy (p, "abcde") != p || memcmp (p, "abcde", 6))
    44      abort ();
    45  
    46    strcpy_disallowed = 0;
    47    if (chk_calls)
    48      abort ();
    49  }
    50  
    51  #ifndef MAX_OFFSET
    52  #define MAX_OFFSET (sizeof (long long))
    53  #endif
    54  
    55  #ifndef MAX_COPY
    56  #define MAX_COPY (10 * sizeof (long long))
    57  #endif
    58  
    59  #ifndef MAX_EXTRA
    60  #define MAX_EXTRA (sizeof (long long))
    61  #endif
    62  
    63  #define MAX_LENGTH (MAX_OFFSET + MAX_COPY + 1 + MAX_EXTRA)
    64  
    65  /* Use a sequence length that is not divisible by two, to make it more
    66     likely to detect when words are mixed up.  */
    67  #define SEQUENCE_LENGTH 31
    68  
    69  static union {
    70    char buf[MAX_LENGTH];
    71    long long align_int;
    72    long double align_fp;
    73  } u1, u2;
    74  
    75  void
    76  __attribute__((noinline))
    77  test2 (void)
    78  {
    79    int off1, off2, len, i;
    80    char *p, *q, c;
    81  
    82    for (off1 = 0; off1 < MAX_OFFSET; off1++)
    83      for (off2 = 0; off2 < MAX_OFFSET; off2++)
    84        for (len = 1; len < MAX_COPY; len++)
    85  	{
    86  	  for (i = 0, c = 'A'; i < MAX_LENGTH; i++, c++)
    87  	    {
    88  	      u1.buf[i] = 'a';
    89  	      if (c >= 'A' + SEQUENCE_LENGTH)
    90  		c = 'A';
    91  	      u2.buf[i] = c;
    92  	    }
    93  	  u2.buf[off2 + len] = '\0';
    94  
    95  	  p = strcpy (u1.buf + off1, u2.buf + off2);
    96  	  if (p != u1.buf + off1)
    97  	    abort ();
    98  
    99  	  q = u1.buf;
   100  	  for (i = 0; i < off1; i++, q++)
   101  	    if (*q != 'a')
   102  	      abort ();
   103  
   104  	  for (i = 0, c = 'A' + off2; i < len; i++, q++, c++)
   105  	    {
   106  	      if (c >= 'A' + SEQUENCE_LENGTH)
   107  		c = 'A';
   108  	      if (*q != c)
   109  		abort ();
   110  	    }
   111  
   112  	  if (*q++ != '\0')
   113  	    abort ();
   114  	  for (i = 0; i < MAX_EXTRA; i++, q++)
   115  	    if (*q != 'a')
   116  	      abort ();
   117  	}
   118  }
   119  
   120  /* Test whether compile time checking is done where it should
   121     and so is runtime object size checking.  */
   122  void
   123  __attribute__((noinline))
   124  test3 (void)
   125  {
   126    struct A { char buf1[10]; char buf2[10]; } a;
   127    char *r = l1 == 1 ? &a.buf1[5] : &a.buf2[4];
   128    char buf3[20];
   129    int i;
   130    const char *l;
   131  
   132    /* The following calls should do runtime checking
   133       - source length is not known, but destination is.  */
   134    chk_calls = 0;
   135    strcpy (a.buf1 + 2, s3 + 3);
   136    strcpy (r, s3 + 2);
   137    r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
   138    strcpy (r, s2 + 2);
   139    strcpy (r + 2, s3 + 3);
   140    r = buf3;
   141    for (i = 0; i < 4; ++i)
   142      {
   143        if (i == l1 - 1)
   144  	r = &a.buf1[1];
   145        else if (i == l1)
   146  	r = &a.buf2[7];
   147        else if (i == l1 + 1)
   148  	r = &buf3[5];
   149        else if (i == l1 + 2)
   150  	r = &a.buf1[9];
   151      }
   152    strcpy (r, s2 + 4);
   153    if (chk_calls != 5)
   154      abort ();
   155  
   156    /* Following have known destination and known source length,
   157       so if optimizing certainly shouldn't result in the checking
   158       variants.  */
   159    chk_calls = 0;
   160    strcpy (a.buf1 + 2, "");
   161    strcpy (r, "a");
   162    r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
   163    strcpy (r, s1 + 1);
   164    r = buf3;
   165    l = "abc";
   166    for (i = 0; i < 4; ++i)
   167      {
   168        if (i == l1 - 1)
   169  	r = &a.buf1[1], l = "e";
   170        else if (i == l1)
   171  	r = &a.buf2[7], l = "gh";
   172        else if (i == l1 + 1)
   173  	r = &buf3[5], l = "jkl";
   174        else if (i == l1 + 2)
   175  	r = &a.buf1[9], l = "";
   176      }
   177    strcpy (r, "");
   178    /* Here, strlen (l) + 1 is known to be at most 4 and
   179       __builtin_object_size (&buf3[16], 0) is 4, so this doesn't need
   180       runtime checking.  */
   181    strcpy (&buf3[16], l);
   182    /* Unknown destination and source, no checking.  */
   183    strcpy (s4, s3);
   184    if (chk_calls)
   185      abort ();
   186    chk_calls = 0;
   187  }
   188  
   189  /* Test whether runtime and/or compile time checking catches
   190     buffer overflows.  */
   191  void
   192  __attribute__((noinline))
   193  test4 (void)
   194  {
   195    struct A { char buf1[10]; char buf2[10]; } a;
   196    char buf3[20];
   197  
   198    chk_fail_allowed = 1;
   199    /* Runtime checks.  */
   200    if (__builtin_setjmp (chk_fail_buf) == 0)
   201      {
   202        strcpy (&a.buf2[9], s2 + 3);
   203        abort ();
   204      }
   205    if (__builtin_setjmp (chk_fail_buf) == 0)
   206      {
   207        strcpy (&a.buf2[7], s3 + strlen (s3) - 3);
   208        abort ();
   209      }
   210    /* This should be detectable at compile time already.  */
   211    if (__builtin_setjmp (chk_fail_buf) == 0)
   212      {
   213        strcpy (&buf3[19], "a");
   214        abort ();
   215      }
   216    chk_fail_allowed = 0;
   217  }
   218  
   219  void
   220  main_test (void)
   221  {
   222  #ifndef __OPTIMIZE__
   223    /* Object size checking is only intended for -O[s123].  */
   224    return;
   225  #endif
   226    __asm ("" : "=r" (s2) : "0" (s2));
   227    __asm ("" : "=r" (s3) : "0" (s3));
   228    __asm ("" : "=r" (l1) : "0" (l1));
   229    test1 ();
   230    test2 ();
   231    s4 = p;
   232    test3 ();
   233    test4 ();
   234  }