mirror of
https://github.com/github/codeql.git
synced 2025-12-26 21:56:39 +01:00
The conflicts came from how `this` is now a parameter but not a `Parameter` on `master`. Conflicts: cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/defaulttainttracking.cpp cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/test_diff.expected cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected cpp/ql/test/library-tests/dataflow/fields/ir-flow.expected cpp/ql/test/library-tests/syntax-zoo/dataflow-ir-consistency.expected
152 lines
2.7 KiB
C++
152 lines
2.7 KiB
C++
#include "shared.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) {
|
|
|
|
|
|
|
|
sink(_strdup(getenv("VAR")));
|
|
sink(strdup(getenv("VAR")));
|
|
sink(unmodeled_function(getenv("VAR")));
|
|
|
|
char untainted_buf[100] = "";
|
|
char buf[100] = "VAR = ";
|
|
sink(strcat(buf, getenv("VAR")));
|
|
|
|
sink(buf);
|
|
sink(untainted_buf); // the two buffers would be conflated if we added flow through all partial chi inputs
|
|
|
|
return 0;
|
|
}
|
|
|
|
typedef unsigned int inet_addr_retval;
|
|
inet_addr_retval inet_addr(const char *dotted_address);
|
|
void sink(inet_addr_retval);
|
|
|
|
void test_indirect_arg_to_model() {
|
|
// This test is non-sensical but carefully arranged so we get data flow into
|
|
// inet_addr not through the function argument but through its associated
|
|
// read side effect.
|
|
void *env_pointer = getenv("VAR"); // env_pointer is tainted, not its data.
|
|
inet_addr_retval a = inet_addr((const char *)&env_pointer);
|
|
sink(a);
|
|
}
|
|
|
|
class B {
|
|
public:
|
|
virtual void f(const char*) = 0;
|
|
};
|
|
|
|
class D1 : public B {};
|
|
|
|
class D2 : public D1 {
|
|
public:
|
|
void f(const char* p) override {}
|
|
};
|
|
|
|
class D3 : public D2 {
|
|
public:
|
|
void f(const char* p) override {
|
|
sink(p);
|
|
}
|
|
};
|
|
|
|
void test_dynamic_cast() {
|
|
B* b = new D3();
|
|
b->f(getenv("VAR")); // tainted
|
|
|
|
((D2*)b)->f(getenv("VAR")); // tainted
|
|
static_cast<D2*>(b)->f(getenv("VAR")); // tainted
|
|
dynamic_cast<D2*>(b)->f(getenv("VAR")); // tainted
|
|
reinterpret_cast<D2*>(b)->f(getenv("VAR")); // tainted
|
|
|
|
B* b2 = new D2();
|
|
b2->f(getenv("VAR"));
|
|
|
|
((D2*)b2)->f(getenv("VAR"));
|
|
static_cast<D2*>(b2)->f(getenv("VAR"));
|
|
dynamic_cast<D2*>(b2)->f(getenv("VAR"));
|
|
reinterpret_cast<D2*>(b2)->f(getenv("VAR"));
|
|
|
|
dynamic_cast<D3*>(b2)->f(getenv("VAR")); // tainted [FALSE POSITIVE]
|
|
}
|
|
|
|
namespace std {
|
|
template< class T >
|
|
T&& move( T&& t ) noexcept;
|
|
}
|
|
|
|
void test_std_move() {
|
|
sink(std::move(getenv("VAR")));
|
|
}
|
|
|
|
void flow_to_outparam(char ** ret, char *arg) {
|
|
*ret = arg;
|
|
}
|
|
|
|
void test_outparams() {
|
|
char *p2 = nullptr;
|
|
flow_to_outparam(&p2, getenv("VAR"));
|
|
sink(p2); // tainted
|
|
}
|
|
|
|
|
|
|
|
|
|
struct XY {
|
|
int x;
|
|
int y;
|
|
};
|
|
|
|
void taint_y(XY *xyp) {
|
|
int tainted = getenv("VAR")[0];
|
|
xyp->y = tainted;
|
|
}
|
|
|
|
void test_conflated_fields3() {
|
|
XY xy;
|
|
xy.x = 0;
|
|
taint_y(&xy);
|
|
sink(xy.x); // not tainted
|
|
}
|
|
|
|
struct Point {
|
|
int x;
|
|
int y;
|
|
|
|
void callSink() {
|
|
sink(this->x); // tainted
|
|
sink(this->y); // not tainted
|
|
}
|
|
};
|
|
|
|
void test_conflated_fields1() {
|
|
Point p;
|
|
p.x = getenv("VAR")[0];
|
|
sink(p.x); // tainted
|
|
sink(p.y); // not tainted
|
|
p.callSink();
|
|
}
|
|
|
|
void taint_x(Point *pp) {
|
|
pp->x = getenv("VAR")[0];
|
|
}
|
|
|
|
void y_to_sink(Point *pp) {
|
|
sink(pp->y); // not tainted
|
|
}
|
|
|
|
void test_conflated_fields2() {
|
|
Point p;
|
|
taint_x(&p);
|
|
y_to_sink(&p);
|
|
}
|