1 /* PR target/38902 */
2 /* { dg-do run } */
3 /* { dg-options "-O2 -fstack-protector" } */
4 /* { dg-require-effective-target fstack_protector } */
5
6 #ifdef DEBUG
7 #include <stdio.h>
8 #define debug(format, args...) printf (format , ## args)
9 #else
10 extern int sprintf (char *, const char *, ...);
11 #define debug(format, args...)
12 #endif
13
14 extern void abort (void);
15
16 /*
17
18 Copyright (C) 2009 Canonical, Ltd.
19 Author: Kees Cook <kees@ubuntu.com>
20 License: GPLv3
21
22 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38616
23 https://bugs.launchpad.net/ubuntu/+source/gcc-4.3/+bug/316019
24 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38902
25
26 gcc -O2 -fstack-protector truncate.c -o truncate
27
28 Broken:
29
30 Only the first operation fails, so create a new function for each test.
31 Source must be local (literal or stack)
32
33 __builtin_memmove
34 __builtin_memcpy
35 __builtin_strcpy (optimized to __builtin_memcpy?)
36 sprintf (direct) (optmized to __builtin_strcpy?)
37 sprintf (via %s) (optmized to __builtin_strcpy?)
38
39 OK:
40 __builtin_strcat
41 sprintf (complex format)
42
43 */
44
45 char *heap = "1234567890abcdefghijklmnopqrstuvwxyz";
46
47 int failed = 0;
48
49 #define CHECK(count, a...) \
50 void test##count (void) \
51 { \
52 char *local = "1234567890abcdefghijklmnopqrstuvwxyz"; \
53 char buffer[1024]=""; \
54 a; \
55 if (__builtin_strcmp(buffer, heap) == 0) { \
56 debug("Okay(%d):\n\t%s\n", count, # a); \
57 } \
58 else { \
59 debug("Failed(%d):\n\t%s\n", count, # a); \
60 failed++; \
61 } \
62 }
63
64
65 CHECK( 0, __builtin_memcpy (buffer, "1234567890abcdefghijklmnopqrstuvwxyz", __builtin_strlen("1234567890abcdefghijklmnopqrstuvwxyz")+1); );
66 CHECK( 1, __builtin_memcpy (buffer, local, __builtin_strlen(local)+1); );
67 CHECK( 2, __builtin_memcpy (buffer, heap, __builtin_strlen(heap)+1); );
68
69 CHECK( 3, __builtin_memmove (buffer, "1234567890abcdefghijklmnopqrstuvwxyz", __builtin_strlen("1234567890abcdefghijklmnopqrstuvwxyz")+1); );
70 CHECK( 4, __builtin_memmove (buffer, local, __builtin_strlen(local)+1); );
71 CHECK( 5, __builtin_memmove (buffer, heap, __builtin_strlen(heap)+1); );
72
73 CHECK( 6, __builtin_strcpy (buffer, "1234567890abcdefghijklmnopqrstuvwxyz"); );
74 CHECK( 7, __builtin_strcpy (buffer, local); );
75 CHECK( 8, __builtin_strcpy (buffer, heap); );
76
77 CHECK( 9, sprintf (buffer, "1234567890abcdefghijklmnopqrstuvwxyz"); );
78 CHECK(10, sprintf (buffer, local); );
79 CHECK(11, sprintf (buffer, heap); );
80
81 CHECK(12, sprintf (buffer, "%s", "1234567890abcdefghijklmnopqrstuvwxyz"); );
82 CHECK(13, sprintf (buffer, "%s", local); );
83 CHECK(14, sprintf (buffer, "%s", heap); );
84
85 CHECK(15, __builtin_strcat (buffer, "1234567890abcdefghijklmnopqrstuvwxyz"); );
86 CHECK(16, __builtin_strcat (buffer, local); );
87 CHECK(17, __builtin_strcat (buffer, heap); );
88
mongoose(void)89 void mongoose(void)
90 {
91 char buffer[1024]="";
92 sprintf (buffer, "%s", "1234567890abcdefghijklmnopqrstuvwxyz");;
93 if (__builtin_strcmp(buffer, heap) == 0) {
94 debug("Okay(%d):\n\t%s\n", -1, "sprintf (buffer, \"%s\", \"1234567890abcdefghijklmnopqrstuvwxyz\");");
95 }
96 else {
97 debug("Failed(%d):\n\t%s\n", -1, "sprintf (buffer, \"%s\", \"1234567890abcdefghijklmnopqrstuvwxyz\");");
98 failed++;
99 }
100 }
101
main(int argc,char * argv[])102 int main (int argc, char *argv[])
103 {
104 test0();
105 test1();
106 test2();
107 test3();
108 test4();
109 test5();
110 test6();
111 test7();
112 test8();
113 test9();
114 test10();
115 test11();
116
117 // wtf, why are these different?!
118 test12();
119 mongoose();
120
121 test13();
122 test14();
123 test15();
124 test16();
125 test17();
126
127 if (failed)
128 abort ();
129
130 return 0;
131 }
132