mirror of
https://github.com/github/codeql.git
synced 2025-12-18 09:43:15 +01:00
487 lines
6.8 KiB
C++
487 lines
6.8 KiB
C++
int source();
|
|
void sink(...) {};
|
|
|
|
void arithAssignments(int source1, int clean1) {
|
|
sink(clean1); // clean
|
|
clean1 += source1;
|
|
clean1 += 1;
|
|
sink(clean1); // tainted
|
|
|
|
clean1 = source1 = 1;
|
|
sink(clean1); // clean
|
|
source1 = clean1 = source();
|
|
source1++;
|
|
++source1;
|
|
source1 += 1;
|
|
sink(source1); // tainted
|
|
sink(++source1); // tainted
|
|
}
|
|
|
|
// --- globals ---
|
|
|
|
int increment(int x) {return x + 1;}
|
|
int zero(int x) {return 0;}
|
|
|
|
int global1 = 0;
|
|
int global2 = source();
|
|
int global3 = global2 + 1;
|
|
int global4 = increment(source());
|
|
int global5 = zero(source());
|
|
int global6, global7, global8, global9, global10;
|
|
|
|
void do_source()
|
|
{
|
|
global6 = 0;
|
|
global7 = source();
|
|
global8 = global7 + 1;
|
|
global9 = increment(source());
|
|
global10 = zero(source());
|
|
|
|
sink(global6);
|
|
sink(global7); // tainted
|
|
sink(global8); // tainted
|
|
sink(global9); // tainted
|
|
sink(global10);
|
|
}
|
|
|
|
void do_sink()
|
|
{
|
|
sink(global1);
|
|
sink(global2); // tainted [NOT DETECTED]
|
|
sink(global3); // tainted [NOT DETECTED]
|
|
sink(global4); // tainted [NOT DETECTED]
|
|
sink(global5);
|
|
sink(global6);
|
|
sink(global7); // tainted [NOT DETECTED]
|
|
sink(global8); // tainted [NOT DETECTED]
|
|
sink(global9); // tainted [NOT DETECTED]
|
|
sink(global10);
|
|
}
|
|
|
|
void global_test()
|
|
{
|
|
do_source();
|
|
do_sink();
|
|
}
|
|
|
|
// --- class fields ---
|
|
|
|
class MyClass {
|
|
public:
|
|
MyClass() : a(0), b(source()) {
|
|
c = source();
|
|
d = 0;
|
|
}
|
|
|
|
void myMethod() {
|
|
d = source();
|
|
}
|
|
|
|
int a, b, c, d;
|
|
};
|
|
|
|
void class_field_test() {
|
|
MyClass mc1, mc2;
|
|
|
|
mc1.myMethod();
|
|
|
|
sink(mc1.a);
|
|
sink(mc1.b); // tainted
|
|
sink(mc1.c); // tainted
|
|
sink(mc1.d); // tainted
|
|
sink(mc2.a);
|
|
sink(mc2.b); // tainted
|
|
sink(mc2.c); // tainted
|
|
sink(mc2.d);
|
|
}
|
|
|
|
// --- arrays ---
|
|
|
|
void array_test(int i) {
|
|
int arr1[10] = {0};
|
|
int arr2[10] = {0};
|
|
int arr3[10] = {0};
|
|
|
|
arr1[5] = source();
|
|
arr2[i] = source();
|
|
arr3[5] = 0;
|
|
|
|
sink(arr1[5]); // tainted
|
|
sink(arr1[i]); // tainted
|
|
sink(arr2[5]); // tainted
|
|
sink(arr2[i]); // tainted
|
|
sink(arr3[5]);
|
|
sink(arr3[i]);
|
|
}
|
|
|
|
// --- pointers ---
|
|
|
|
void pointer_test() {
|
|
int t1 = source();
|
|
int t2 = 1;
|
|
int t3 = 1;
|
|
int *p1 = &t1;
|
|
int *p2 = &t2;
|
|
int *p3 = &t3;
|
|
|
|
*p2 = source();
|
|
|
|
sink(*p1); // tainted
|
|
sink(*p2); // tainted
|
|
sink(*p3);
|
|
|
|
p3 = &t1;
|
|
sink(*p3); // tainted
|
|
|
|
*p3 = 0;
|
|
sink(*p3); // [FALSE POSITIVE]
|
|
}
|
|
|
|
// --- return values ---
|
|
|
|
int select(int i, int a, int b) {
|
|
if (i == 1) {
|
|
return a;
|
|
} else {
|
|
return b;
|
|
}
|
|
}
|
|
|
|
void fn_test(int i) {
|
|
sink(select(i, 1, source())); // tainted
|
|
}
|
|
|
|
// --- strings ---
|
|
|
|
char *strcpy(char *destination, const char *source);
|
|
char *strcat(char *destination, const char *source);
|
|
|
|
namespace strings
|
|
{
|
|
char *source(); // char* source
|
|
|
|
void strings_test1() {
|
|
char *tainted = source();
|
|
char buffer[1024] = {0};
|
|
|
|
sink(source()); // tainted
|
|
sink(tainted); // tainted
|
|
|
|
strcpy(buffer, "Hello, ");
|
|
sink(buffer);
|
|
strcat(buffer, tainted);
|
|
sink(buffer); // tainted
|
|
}
|
|
}
|
|
|
|
// --- pass by reference ---
|
|
|
|
namespace refs {
|
|
void callee(int *p) {
|
|
sink(*p); // tainted
|
|
}
|
|
|
|
void caller() {
|
|
int x = source();
|
|
callee(&x);
|
|
}
|
|
}
|
|
|
|
void *memcpy(void *dest, void *src, int len);
|
|
|
|
void test_memcpy(int *source) {
|
|
int x;
|
|
memcpy(&x, source, sizeof(int));
|
|
sink(x); // tainted
|
|
}
|
|
|
|
// --- std::swap ---
|
|
|
|
#include "swap.h"
|
|
|
|
|
|
|
|
void test_swap() {
|
|
int x, y;
|
|
|
|
x = source();
|
|
y = 0;
|
|
|
|
sink(x); // tainted
|
|
sink(y); // clean
|
|
|
|
std::swap(x, y);
|
|
|
|
sink(x); // clean [FALSE POSITIVE]
|
|
sink(y); // tainted
|
|
}
|
|
|
|
// --- lambdas ---
|
|
|
|
void test_lambdas()
|
|
{
|
|
int t = source();
|
|
int u = 0;
|
|
int v = 0;
|
|
int w = 0;
|
|
|
|
auto a = [t, u]() -> int {
|
|
sink(t); // tainted
|
|
sink(u); // clean
|
|
return t;
|
|
};
|
|
sink(a()); // tainted
|
|
|
|
auto b = [&] {
|
|
sink(t); // tainted
|
|
sink(u); // clean
|
|
v = source(); // (v is reference captured)
|
|
};
|
|
b();
|
|
sink(v); // tainted [NOT DETECTED]
|
|
|
|
auto c = [=] {
|
|
sink(t); // tainted
|
|
sink(u); // clean
|
|
};
|
|
c();
|
|
|
|
auto d = [](int a, int b) {
|
|
sink(a); // tainted
|
|
sink(b); // clean
|
|
};
|
|
d(t, u);
|
|
|
|
auto e = [](int &a, int &b, int &c) {
|
|
sink(a); // tainted
|
|
sink(b); // clean
|
|
c = source();
|
|
};
|
|
e(t, u, w);
|
|
sink(w); // tainted
|
|
}
|
|
|
|
// --- taint through return value ---
|
|
|
|
int id(int x)
|
|
{
|
|
return x;
|
|
}
|
|
|
|
void test_return()
|
|
{
|
|
int x, y, z, t;
|
|
|
|
t = source();
|
|
x = 0;
|
|
y = 0;
|
|
z = 0;
|
|
|
|
sink(t); // tainted
|
|
sink(x);
|
|
sink(y);
|
|
sink(z);
|
|
|
|
x = id(t);
|
|
y = id(id(t));
|
|
z = id(z);
|
|
|
|
sink(t); // tainted
|
|
sink(x); // tainted
|
|
sink(y); // tainted
|
|
sink(z);
|
|
}
|
|
|
|
// --- taint through parameters ---
|
|
|
|
void myAssign1(int &a, int &b)
|
|
{
|
|
a = b;
|
|
}
|
|
|
|
void myAssign2(int &a, int b)
|
|
{
|
|
a = b;
|
|
}
|
|
|
|
void myAssign3(int *a, int b)
|
|
{
|
|
*a = b;
|
|
}
|
|
|
|
void myAssign4(int *a, int b)
|
|
{
|
|
int c;
|
|
|
|
c = b + 1;
|
|
*a = c;
|
|
}
|
|
|
|
void myNotAssign(int &a, int &b)
|
|
{
|
|
a = a + 1;
|
|
b = b + 1;
|
|
}
|
|
|
|
void test_outparams()
|
|
{
|
|
int t, a, b, c, d, e;
|
|
|
|
t = source();
|
|
a = 0;
|
|
b = 0;
|
|
c = 0;
|
|
d = 0;
|
|
e = 0;
|
|
|
|
sink(t); // tainted
|
|
sink(a);
|
|
sink(b);
|
|
sink(c);
|
|
sink(d);
|
|
sink(e);
|
|
|
|
myAssign1(a, t);
|
|
myAssign2(b, t);
|
|
myAssign3(&c, t);
|
|
myAssign4(&d, t);
|
|
myNotAssign(e, t);
|
|
|
|
sink(t); // tainted
|
|
sink(a); // tainted
|
|
sink(b); // tainted
|
|
sink(c); // tainted
|
|
sink(d); // tainted
|
|
sink(e);
|
|
}
|
|
|
|
// --- strdup ---
|
|
|
|
typedef unsigned long size_t;
|
|
char *strdup(const char *s1);
|
|
char *strndup(const char *s1, size_t n);
|
|
wchar_t* wcsdup(const wchar_t* s1);
|
|
|
|
void test_strdup(char *source)
|
|
{
|
|
char *a, *b, *c;
|
|
|
|
a = strdup(source);
|
|
b = strdup("hello, world");
|
|
c = strndup(source, 100);
|
|
sink(a); // tainted
|
|
sink(b);
|
|
sink(c); // tainted
|
|
}
|
|
|
|
void test_strndup(int source)
|
|
{
|
|
char *a;
|
|
|
|
a = strndup("hello, world", source);
|
|
sink(a); // tainted
|
|
}
|
|
|
|
void test_wcsdup(wchar_t *source)
|
|
{
|
|
wchar_t *a, *b;
|
|
|
|
a = wcsdup(source);
|
|
b = wcsdup(L"hello, world");
|
|
sink(a); // tainted
|
|
sink(b);
|
|
}
|
|
|
|
// --- qualifiers ---
|
|
|
|
class MyClass2 {
|
|
public:
|
|
MyClass2(int value);
|
|
void setMember(int value);
|
|
int getMember();
|
|
|
|
int member;
|
|
};
|
|
|
|
class MyClass3 {
|
|
public:
|
|
MyClass3(const char *string);
|
|
void setString(const char *string);
|
|
const char *getString();
|
|
|
|
const char *buffer;
|
|
};
|
|
|
|
void test_qualifiers()
|
|
{
|
|
MyClass2 a(0), b(0), *c;
|
|
MyClass3 d("");
|
|
|
|
sink(a);
|
|
sink(a.getMember());
|
|
a.setMember(source());
|
|
sink(a); // tainted
|
|
sink(a.getMember()); // tainted
|
|
|
|
sink(b);
|
|
sink(b.getMember());
|
|
b.member = source();
|
|
sink(b); // tainted
|
|
sink(b.member); // tainted
|
|
sink(b.getMember());
|
|
|
|
c = new MyClass2(0);
|
|
|
|
sink(c);
|
|
sink(c->getMember());
|
|
c->setMember(source());
|
|
sink(c); // tainted (deref)
|
|
sink(c->getMember()); // tainted
|
|
|
|
delete c;
|
|
|
|
sink(d);
|
|
sink(d.getString());
|
|
d.setString(strings::source());
|
|
sink(d); // tainted
|
|
sink(d.getString()); // tainted
|
|
}
|
|
|
|
// --- non-standard swap ---
|
|
|
|
void swop(int &a, int &b)
|
|
{
|
|
int c = a;
|
|
a = b;
|
|
b = c;
|
|
}
|
|
|
|
void test_swop() {
|
|
int x, y;
|
|
|
|
x = source();
|
|
y = 0;
|
|
|
|
sink(x); // tainted
|
|
sink(y); // clean
|
|
|
|
swop(x, y);
|
|
|
|
sink(x); // clean [FALSE POSITIVE]
|
|
sink(y); // tainted
|
|
}
|
|
|
|
// --- getdelim ---
|
|
|
|
struct FILE;
|
|
|
|
int getdelim(char ** lineptr, size_t * n, int delimiter, FILE *stream);
|
|
|
|
void test_getdelim(FILE* source1) {
|
|
char* line = nullptr;
|
|
size_t n;
|
|
getdelim(&line, &n, '\n', source1);
|
|
|
|
sink(line);
|
|
}
|