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