1 // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.security.taint,core,alpha.security.ArrayBoundV2 -analyzer-config alpha.security.taint.TaintPropagation:Config=%S/Inputs/taint-generic-config.yaml -Wno-format-security -verify -std=c++11 %s
2
3 #define BUFSIZE 10
4 int Buffer[BUFSIZE];
5
6 int scanf(const char*, ...);
7 int mySource1();
8 int mySource3();
9
10 bool isOutOfRange2(const int*);
11
12 void mySink2(int);
13
14 // Test configuration
15 namespace myNamespace {
16 void scanf(const char*, ...);
17 void myScanf(const char*, ...);
18 int mySource3();
19
20 bool isOutOfRange(const int*);
21 bool isOutOfRange2(const int*);
22
23 void mySink(int, int, int);
24 void mySink2(int);
25 }
26
27 namespace myAnotherNamespace {
28 int mySource3();
29
30 bool isOutOfRange2(const int*);
31
32 void mySink2(int);
33 }
34
testConfigurationNamespacePropagation1()35 void testConfigurationNamespacePropagation1() {
36 int x;
37 // The built-in functions should be matched only for functions in
38 // the global namespace
39 myNamespace::scanf("%d", &x);
40 Buffer[x] = 1; // no-warning
41
42 scanf("%d", &x);
43 Buffer[x] = 1; // expected-warning {{Out of bound memory access }}
44 }
45
testConfigurationNamespacePropagation2()46 void testConfigurationNamespacePropagation2() {
47 int x = mySource3();
48 Buffer[x] = 1; // no-warning
49
50 int y = myNamespace::mySource3();
51 Buffer[y] = 1; // expected-warning {{Out of bound memory access }}
52 }
53
testConfigurationNamespacePropagation3()54 void testConfigurationNamespacePropagation3() {
55 int x = myAnotherNamespace::mySource3();
56 Buffer[x] = 1; // expected-warning {{Out of bound memory access }}
57 }
58
testConfigurationNamespacePropagation4()59 void testConfigurationNamespacePropagation4() {
60 int x;
61 // Configured functions without scope should match for all function.
62 myNamespace::myScanf("%d", &x);
63 Buffer[x] = 1; // expected-warning {{Out of bound memory access }}
64 }
65
testConfigurationNamespaceFilter1()66 void testConfigurationNamespaceFilter1() {
67 int x = mySource1();
68 if (myNamespace::isOutOfRange2(&x))
69 return;
70 Buffer[x] = 1; // no-warning
71
72 int y = mySource1();
73 if (isOutOfRange2(&y))
74 return;
75 Buffer[y] = 1; // expected-warning {{Out of bound memory access }}
76 }
77
testConfigurationNamespaceFilter2()78 void testConfigurationNamespaceFilter2() {
79 int x = mySource1();
80 if (myAnotherNamespace::isOutOfRange2(&x))
81 return;
82 Buffer[x] = 1; // no-warning
83 }
84
testConfigurationNamespaceFilter3()85 void testConfigurationNamespaceFilter3() {
86 int x = mySource1();
87 if (myNamespace::isOutOfRange(&x))
88 return;
89 Buffer[x] = 1; // no-warning
90 }
91
testConfigurationNamespaceSink1()92 void testConfigurationNamespaceSink1() {
93 int x = mySource1();
94 mySink2(x); // no-warning
95
96 int y = mySource1();
97 myNamespace::mySink2(y);
98 // expected-warning@-1 {{Untrusted data is passed to a user-defined sink}}
99 }
100
testConfigurationNamespaceSink2()101 void testConfigurationNamespaceSink2() {
102 int x = mySource1();
103 myAnotherNamespace::mySink2(x);
104 // expected-warning@-1 {{Untrusted data is passed to a user-defined sink}}
105 }
106
testConfigurationNamespaceSink3()107 void testConfigurationNamespaceSink3() {
108 int x = mySource1();
109 myNamespace::mySink(x, 0, 1);
110 // expected-warning@-1 {{Untrusted data is passed to a user-defined sink}}
111 }
112
113 struct Foo {
114 void scanf(const char*, int*);
115 void myMemberScanf(const char*, int*);
116 };
117
testConfigurationMemberFunc()118 void testConfigurationMemberFunc() {
119 int x;
120 Foo foo;
121 foo.scanf("%d", &x);
122 Buffer[x] = 1; // no-warning
123
124 foo.myMemberScanf("%d", &x);
125 Buffer[x] = 1; // expected-warning {{Out of bound memory access }}
126 }
127