1 /* Test whether buffer overflow warnings for __*_chk builtins
2    are emitted properly.  */
3 /* { dg-do compile } */
4 /* { dg-options "-O2 -Wno-format -std=gnu99 -ftrack-macro-expansion=0 -fno-tree-dse" } */
5 // { dg-skip-if "packed attribute missing for t" { "epiphany-*-*" } }
6 
7 extern void abort (void);
8 
9 #include "../gcc.c-torture/execute/builtins/chk.h"
10 
11 #define va_list    __builtin_va_list
12 #define va_start   __builtin_va_start
13 #define va_end     __builtin_va_end
14 
15 volatile void *vx;
16 char buf1[20];
17 int x;
18 
19 void
test(int arg,...)20 test (int arg, ...)
21 {
22   char buf2[20];
23   va_list ap;
24   char *p = &buf1[10], *q;
25 
26   memcpy (&buf2[19], "ab", 1);
27   memcpy (&buf2[19], "ab", 2); /* { dg-warning "writing 2 bytes into a region of size 1" "memcpy" } */
28   vx = mempcpy (&buf2[19], "ab", 1);
29   vx = mempcpy (&buf2[19], "ab", 2); /* { dg-warning "writing 2 " "mempcpy" } */
30   memmove (&buf2[18], &buf1[10], 2);
31   memmove (&buf2[18], &buf1[10], 3); /* { dg-warning "writing 3 " "memmove" } */
32   memset (&buf2[16], 'a', 4);
33   memset (&buf2[15], 'b', 6); /* { dg-warning "writing 6 " "memset" } */
34   strcpy (&buf2[18], "a");
35   strcpy (&buf2[18], "ab"); /* { dg-warning "writing 3 " "strcpy" } */
36   vx = stpcpy (&buf2[18], "a");
37   vx = stpcpy (&buf2[18], "ab"); /* { dg-warning "writing 3" "stpcpy" } */
38   strncpy (&buf2[18], "a", 2);
39 
40   /* Both warnings below are equally meaningful.  */
41   strncpy (&buf2[18], "a", 3); /* { dg-warning "(writing 3 bytes into a region of size 2|specified bound 3 exceeds destination size 2)" "strncpy" } */
42 
43   strncpy (&buf2[18], "abc", 2);
44   strncpy (&buf2[18], "abc", 3); /* { dg-warning "writing 3 " "strncpy" } */
45   memset (buf2, '\0', sizeof (buf2));
46   strcat (&buf2[18], "a");
47   memset (buf2, '\0', sizeof (buf2));
48   strcat (&buf2[18], "ab"); /* { dg-warning "writing 3 " "strcat" } */
49   sprintf (&buf2[18], "%s", buf1);
50   sprintf (&buf2[18], "%s", "a");
51   sprintf (&buf2[18], "%s", "ab"); /* { dg-warning "writing 3 " "sprintf" } */
52   sprintf (&buf2[18], "a");
53   sprintf (&buf2[18], "ab"); /* { dg-warning "writing 3 " "sprintf" } */
54   snprintf (&buf2[18], 2, "%d", x);
55   /* N argument to snprintf is the size of the buffer.
56      Although this particular call wouldn't overflow buf2,
57      incorrect buffer size was passed to it and therefore
58      we want a warning and runtime failure.  */
59   snprintf (&buf2[18], 3, "%d", x); /* { dg-warning "specified bound 3 exceeds destination size 2" "snprintf" } */
60   va_start (ap, arg);
61   vsprintf (&buf2[18], "a", ap);
62   va_end (ap);
63 
64   va_start (ap, arg);
65   vsprintf (&buf2[18], "ab", ap); /* { dg-warning "writing 3" "vsprintf" } */
66   va_end (ap);
67   va_start (ap, arg);
68   vsnprintf (&buf2[18], 2, "%s", ap);
69   va_end (ap);
70   va_start (ap, arg);
71   /* See snprintf above.  */
72   vsnprintf (&buf2[18], 3, "%s", ap); /* { dg-warning "specified bound 3 exceeds destination size 2" "vsnprintf" } */
73   va_end (ap);
74 
75   p = p + 10;
76   memset (p, 'd', 0);
77   q = strcpy (p, ""); /* { dg-warning "writing 1 " "strcpy" } */
78 
79   /* This invokes undefined behavior, since we are past the end of buf1.  */
80   p = p + 10;
81   memset (p, 'd', 1); /* { dg-warning "writing 1 " "memset" } */
82 
83   memset (q, 'd', 0);
84   memset (q, 'd', 1); /* { dg-warning "writing 1 " "memset" } */
85   q = q - 10;
86   memset (q, 'd', 10);
87 }
88 
89 char *str = "ABCDEFG";
90 typedef struct { char b[16]; } H;
91 
92 /* Some brown paper bag bugs found in real applications.
93    This test is here merely for amusement.  */
94 
95 void
test2(const H h)96 test2 (const H h)
97 {
98   char c;
99   strncpy (&c, str, 3); /* { dg-warning "(writing 3 bytes into a region of size 1|specified bound 3 exceeds destination size 1)" "strncpy" } */
100 
101   struct { char b[4]; } x;
102   sprintf (x.b, "%s", "ABCD"); /* { dg-warning "writing 5" "sprintf" } */
103 
104   unsigned int i;
105   memcpy (&i, &h, sizeof (h)); /* { dg-warning "writing 16 " "memcpy" } */
106 
107   unsigned char buf[21];
108   memset (buf + 16, 0, 8); /* { dg-warning "writing 8 " "memset" } */
109 
110   typedef struct { __INT32_TYPE__ i, j, k, l; } S;
111   S *s[3];
112   memset (s, 0, sizeof (S) * 3); /* { dg-warning "writing 48 " "memset" } */
113 
114   struct T { char a[8]; char b[4]; char c[10]; } t;
115   stpcpy (t.c,"Testing..."); /* { dg-warning "writing" "stpcpy" } */
116 
117   char b1[7];
118   char b2[4];
119   memset (b1, 0, sizeof (b1));
120   memset (b2, 0, sizeof (b1)); /* { dg-warning "writing 7" "memset" } */
121 }
122