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