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