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