1 // RUN: %clang_analyze_cc1 -std=c++11 -Wno-format-security \ 2 // RUN: -analyzer-checker=core,optin.taint,alpha.security.ArrayBoundV2,debug.ExprInspection \ 3 // RUN: -analyzer-config optin.taint.TaintPropagation:Config=%S/Inputs/taint-generic-config.yaml \ 4 // RUN: -verify %s 5 6 template <typename T> void clang_analyzer_isTainted(T); 7 8 #define BUFSIZE 10 9 int Buffer[BUFSIZE]; 10 11 int scanf(const char*, ...); 12 template <typename T = int> T mySource1(); 13 int mySource3(); 14 15 typedef struct _FILE FILE; 16 extern "C" { 17 extern FILE *stdin; 18 } 19 int fscanf(FILE *stream, const char *format, ...); 20 21 bool isOutOfRange2(const int*); 22 23 void mySink2(int); 24 25 // Test configuration 26 namespace myNamespace { 27 void scanf(const char*, ...); 28 void myScanf(const char*, ...); 29 int mySource3(); 30 31 bool isOutOfRange(const int*); 32 bool isOutOfRange2(const int*); 33 34 void mySink(int, int, int); 35 void mySink2(int); 36 } 37 38 namespace myAnotherNamespace { 39 int mySource3(); 40 41 bool isOutOfRange2(const int*); 42 43 void mySink2(int); 44 } 45 46 void testConfigurationNamespacePropagation1() { 47 int x; 48 // The built-in functions should be matched only for functions in 49 // the global namespace 50 myNamespace::scanf("%d", &x); 51 Buffer[x] = 1; // no-warning 52 53 scanf("%d", &x); 54 Buffer[x] = 1; // expected-warning {{Potential out of bound access }} 55 } 56 57 void testConfigurationNamespacePropagation2() { 58 int x = mySource3(); 59 Buffer[x] = 1; // no-warning 60 61 int y = myNamespace::mySource3(); 62 Buffer[y] = 1; // expected-warning {{Potential out of bound access }} 63 } 64 65 void testConfigurationNamespacePropagation3() { 66 int x = myAnotherNamespace::mySource3(); 67 Buffer[x] = 1; // expected-warning {{Potential out of bound access }} 68 } 69 70 void testConfigurationNamespacePropagation4() { 71 int x; 72 // Configured functions without scope should match for all function. 73 myNamespace::myScanf("%d", &x); 74 Buffer[x] = 1; // expected-warning {{Potential out of bound access }} 75 } 76 77 void testConfigurationNamespaceFilter1() { 78 int x = mySource1(); 79 if (myNamespace::isOutOfRange2(&x)) 80 return; 81 Buffer[x] = 1; // no-warning 82 83 int y = mySource1(); 84 if (isOutOfRange2(&y)) 85 return; 86 Buffer[y] = 1; // expected-warning {{Potential out of bound access }} 87 } 88 89 void testConfigurationNamespaceFilter2() { 90 int x = mySource1(); 91 if (myAnotherNamespace::isOutOfRange2(&x)) 92 return; 93 Buffer[x] = 1; // no-warning 94 } 95 96 void testConfigurationNamespaceFilter3() { 97 int x = mySource1(); 98 if (myNamespace::isOutOfRange(&x)) 99 return; 100 Buffer[x] = 1; // no-warning 101 } 102 103 void testConfigurationNamespaceSink1() { 104 int x = mySource1(); 105 mySink2(x); // no-warning 106 107 int y = mySource1(); 108 myNamespace::mySink2(y); 109 // expected-warning@-1 {{Untrusted data is passed to a user-defined sink}} 110 } 111 112 void testConfigurationNamespaceSink2() { 113 int x = mySource1(); 114 myAnotherNamespace::mySink2(x); 115 // expected-warning@-1 {{Untrusted data is passed to a user-defined sink}} 116 } 117 118 void testConfigurationNamespaceSink3() { 119 int x = mySource1(); 120 myNamespace::mySink(x, 0, 1); 121 // expected-warning@-1 {{Untrusted data is passed to a user-defined sink}} 122 } 123 124 struct Foo { 125 void scanf(const char*, int*); 126 void myMemberScanf(const char*, int*); 127 }; 128 129 void testConfigurationMemberFunc() { 130 int x; 131 Foo foo; 132 foo.scanf("%d", &x); 133 Buffer[x] = 1; // no-warning 134 135 foo.myMemberScanf("%d", &x); 136 Buffer[x] = 1; // expected-warning {{Potential out of bound access }} 137 } 138 139 void testReadingFromStdin(char **p) { 140 int n; 141 fscanf(stdin, "%d", &n); 142 Buffer[n] = 1; // expected-warning {{Potential out of bound access }} 143 } 144 145 namespace gh114270 { 146 class Empty {}; 147 class Aggr { 148 public: 149 int data; 150 }; 151 152 void top() { 153 int Int = mySource1<int>(); 154 clang_analyzer_isTainted(Int); // expected-warning {{YES}} 155 156 Empty E = mySource1<Empty>(); 157 clang_analyzer_isTainted(E); // expected-warning {{YES}} 158 159 Aggr A = mySource1<Aggr>(); 160 clang_analyzer_isTainted(A); // expected-warning {{YES}} 161 clang_analyzer_isTainted(A.data); // expected-warning {{YES}} 162 } 163 } // namespace gh114270 164