Borsik Gabor | 273e674 | 2019-11-23 22:28:46 +0100 | [diff] [blame] | 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 | |
| 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 | |
| 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 | |
| 54 | void testConfigurationNamespacePropagation3() { |
| 55 | int x = myAnotherNamespace::mySource3(); |
| 56 | Buffer[x] = 1; // expected-warning {{Out of bound memory access }} |
| 57 | } |
| 58 | |
| 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 | |
| 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 | |
| 78 | void testConfigurationNamespaceFilter2() { |
| 79 | int x = mySource1(); |
| 80 | if (myAnotherNamespace::isOutOfRange2(&x)) |
| 81 | return; |
| 82 | Buffer[x] = 1; // no-warning |
| 83 | } |
| 84 | |
| 85 | void testConfigurationNamespaceFilter3() { |
| 86 | int x = mySource1(); |
| 87 | if (myNamespace::isOutOfRange(&x)) |
| 88 | return; |
| 89 | Buffer[x] = 1; // no-warning |
| 90 | } |
| 91 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | } |