mirror of
https://github.com/github/codeql.git
synced 2025-12-18 09:43:15 +01:00
The virtual-dispatch code for globals was missing any relationship between the union field access and the global variable, which meant it propagated function-pointer flow between any two fields of a global struct. This resulted in false positives from `cpp/tainted-format-string` on projects using SDL, such as WohlSoft/PGE-Project. In addition to fixing that bug, this commit also brings the code up to date with the new style of modeling flow through global variables: `DataFlow::Node.asVariable()`.
36 lines
837 B
C++
36 lines
837 B
C++
#include "shared.h"
|
|
|
|
using SinkFunction = void (*)(int);
|
|
|
|
void notSink(int notSinkParam);
|
|
|
|
void callsSink(int sinkParam) {
|
|
sink(sinkParam);
|
|
}
|
|
|
|
struct {
|
|
SinkFunction sinkPtr, notSinkPtr;
|
|
} globalStruct;
|
|
|
|
union {
|
|
SinkFunction sinkPtr, notSinkPtr;
|
|
} globalUnion;
|
|
|
|
SinkFunction globalSinkPtr;
|
|
|
|
void assignGlobals() {
|
|
globalStruct.sinkPtr = callsSink;
|
|
globalUnion.sinkPtr = callsSink;
|
|
globalSinkPtr = callsSink;
|
|
};
|
|
|
|
void testStruct() {
|
|
globalStruct.sinkPtr(atoi(getenv("TAINTED"))); // should reach sinkParam [NOT DETECTED]
|
|
globalStruct.notSinkPtr(atoi(getenv("TAINTED"))); // shouldn't reach sinkParam
|
|
|
|
globalUnion.sinkPtr(atoi(getenv("TAINTED"))); // should reach sinkParam
|
|
globalUnion.notSinkPtr(atoi(getenv("TAINTED"))); // should reach sinkParam
|
|
|
|
globalSinkPtr(atoi(getenv("TAINTED"))); // should reach sinkParam
|
|
}
|