summaryrefslogtreecommitdiffstats
path: root/clang/test/Analysis/taint-generic.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/Analysis/taint-generic.cpp')
-rw-r--r--clang/test/Analysis/taint-generic.cpp126
1 files changed, 126 insertions, 0 deletions
diff --git a/clang/test/Analysis/taint-generic.cpp b/clang/test/Analysis/taint-generic.cpp
new file mode 100644
index 00000000000..09cd5447194
--- /dev/null
+++ b/clang/test/Analysis/taint-generic.cpp
@@ -0,0 +1,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 }}
+}
OpenPOWER on IntegriCloud