summaryrefslogtreecommitdiffstats
path: root/clang/test/Analysis
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/Analysis')
-rwxr-xr-xclang/test/Analysis/Inputs/taint-generic-config.yaml41
-rw-r--r--clang/test/Analysis/taint-generic.cpp126
2 files changed, 167 insertions, 0 deletions
diff --git a/clang/test/Analysis/Inputs/taint-generic-config.yaml b/clang/test/Analysis/Inputs/taint-generic-config.yaml
index 4605dd1c2ef..39b52ccc32e 100755
--- a/clang/test/Analysis/Inputs/taint-generic-config.yaml
+++ b/clang/test/Analysis/Inputs/taint-generic-config.yaml
@@ -9,12 +9,29 @@ Propagations:
- Name: mySource2
DstArgs: [0]
+ # int x = myNamespace::mySource3(); // x is tainted
+ - Name: mySource3
+ Scope: "myNamespace::"
+ DstArgs: [-1]
+
+ # int x = myAnotherNamespace::mySource3(); // x is tainted
+ - Name: mySource3
+ Scope: "myAnotherNamespace::"
+ DstArgs: [-1]
+
# int x, y;
# myScanf("%d %d", &x, &y); // x and y are tainted
- Name: myScanf
VariadicType: Dst
VariadicIndex: 1
+ # int x, y;
+ # Foo::myScanf("%d %d", &x, &y); // x and y are tainted
+ - Name: myMemberScanf
+ Scope: "Foo::"
+ VariadicType: Dst
+ VariadicIndex: 1
+
# int x; // x is tainted
# int y;
# myPropagator(x, &y); // y is tainted
@@ -40,6 +57,18 @@ Filters:
- Name: isOutOfRange
Args: [0]
+ # int x; // x is tainted
+ # myNamespace::isOutOfRange(&x); // x is not tainted anymore
+ - Name: isOutOfRange2
+ Scope: "myNamespace::"
+ Args: [0]
+
+ # int x; // x is tainted
+ # myAnotherNamespace::isOutOfRange(&x); // x is not tainted anymore
+ - Name: isOutOfRange2
+ Scope: "myAnotherNamespace::"
+ Args: [0]
+
# A list of sink functions
Sinks:
# int x, y; // x and y are tainted
@@ -48,3 +77,15 @@ Sinks:
# mySink(0, x, 1); // It won't warn
- Name: mySink
Args: [0, 2]
+
+ # int x; // x is tainted
+ # myNamespace::mySink(x); // It will warn
+ - Name: mySink2
+ Scope: "myNamespace::"
+ Args: [0]
+
+ # int x; // x is tainted
+ # myAnotherNamespace::mySink(x); // It will warn
+ - Name: mySink2
+ Scope: "myAnotherNamespace::"
+ Args: [0]
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