File: taint-generic.cpp

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,998,520 kB
  • sloc: cpp: 6,951,680; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,009; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,167; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (138 lines) | stat: -rw-r--r-- 3,431 bytes parent folder | download | duplicates (4)
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
127
128
129
130
131
132
133
134
135
136
137
138
// 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();

typedef struct _FILE FILE;
extern "C" {
extern FILE *stdin;
}
int fscanf(FILE *stream, const char *format, ...);

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 {{Potential out of bound access }}
}

void testConfigurationNamespacePropagation2() {
  int x = mySource3();
  Buffer[x] = 1; // no-warning

  int y = myNamespace::mySource3();
  Buffer[y] = 1; // expected-warning {{Potential out of bound access }}
}

void testConfigurationNamespacePropagation3() {
  int x = myAnotherNamespace::mySource3();
  Buffer[x] = 1; // expected-warning {{Potential out of bound access }}
}

void testConfigurationNamespacePropagation4() {
  int x;
  // Configured functions without scope should match for all function.
  myNamespace::myScanf("%d", &x);
  Buffer[x] = 1; // expected-warning {{Potential out of bound 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 {{Potential out of bound 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 {{Potential out of bound access }}
}

void testReadingFromStdin(char **p) {
  int n;
  fscanf(stdin, "%d", &n);
  Buffer[n] = 1; // expected-warning {{Potential out of bound access }}
}