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 10extern int sprintf (char *, const char *, ...); 11#define debug(format, args...) 12#endif 13 14extern void abort (void); 15 16/* 17 18Copyright (C) 2009 Canonical, Ltd. 19Author: Kees Cook <kees@ubuntu.com> 20License: GPLv3 21 22http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38616 23https://bugs.launchpad.net/ubuntu/+source/gcc-4.3/+bug/316019 24http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38902 25 26gcc -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 45char *heap = "1234567890abcdefghijklmnopqrstuvwxyz"; 46 47int failed = 0; 48 49#define CHECK(count, a...) \ 50void 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 65CHECK( 0, __builtin_memcpy (buffer, "1234567890abcdefghijklmnopqrstuvwxyz", __builtin_strlen("1234567890abcdefghijklmnopqrstuvwxyz")+1); ); 66CHECK( 1, __builtin_memcpy (buffer, local, __builtin_strlen(local)+1); ); 67CHECK( 2, __builtin_memcpy (buffer, heap, __builtin_strlen(heap)+1); ); 68 69CHECK( 3, __builtin_memmove (buffer, "1234567890abcdefghijklmnopqrstuvwxyz", __builtin_strlen("1234567890abcdefghijklmnopqrstuvwxyz")+1); ); 70CHECK( 4, __builtin_memmove (buffer, local, __builtin_strlen(local)+1); ); 71CHECK( 5, __builtin_memmove (buffer, heap, __builtin_strlen(heap)+1); ); 72 73CHECK( 6, __builtin_strcpy (buffer, "1234567890abcdefghijklmnopqrstuvwxyz"); ); 74CHECK( 7, __builtin_strcpy (buffer, local); ); 75CHECK( 8, __builtin_strcpy (buffer, heap); ); 76 77CHECK( 9, sprintf (buffer, "1234567890abcdefghijklmnopqrstuvwxyz"); ); 78CHECK(10, sprintf (buffer, local); ); 79CHECK(11, sprintf (buffer, heap); ); 80 81CHECK(12, sprintf (buffer, "%s", "1234567890abcdefghijklmnopqrstuvwxyz"); ); 82CHECK(13, sprintf (buffer, "%s", local); ); 83CHECK(14, sprintf (buffer, "%s", heap); ); 84 85CHECK(15, __builtin_strcat (buffer, "1234567890abcdefghijklmnopqrstuvwxyz"); ); 86CHECK(16, __builtin_strcat (buffer, local); ); 87CHECK(17, __builtin_strcat (buffer, heap); ); 88 89void 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 102int 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