Skip to content

Commit 52b1fb7

Browse files
committed
C++: use models in TaintTrackingUtil
1 parent 11683fa commit 52b1fb7

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
private import semmle.code.cpp.ir.IR
22
private import semmle.code.cpp.ir.dataflow.DataFlow
3+
private import ModelUtil
4+
private import semmle.code.cpp.models.interfaces.DataFlow
35

46
/**
57
* Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
@@ -45,6 +47,8 @@ private predicate localInstructionTaintStep(Instruction nodeFrom, Instruction no
4547
)
4648
or
4749
nodeTo.(LoadInstruction).getSourceAddress() = nodeFrom
50+
or
51+
modeledInstructionTaintStep(nodeFrom, nodeTo)
4852
}
4953

5054
/**
@@ -82,3 +86,31 @@ predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
8286
* but not in local taint.
8387
*/
8488
predicate defaultTaintBarrier(DataFlow::Node node) { none() }
89+
90+
/**
91+
* Holds if taint can flow from `instrIn` to `instrOut` through a call to a
92+
* modeled function.
93+
*/
94+
predicate modeledInstructionTaintStep(Instruction instrIn, Instruction instrOut) {
95+
exists(CallInstruction call, TaintFunction func, FunctionInput modelIn, FunctionOutput modelOut |
96+
instrIn = callInput(call, modelIn) and
97+
instrOut = callOutput(call, modelOut) and
98+
call.getStaticCallTarget() = func and
99+
func.hasTaintFlow(modelIn, modelOut)
100+
)
101+
or
102+
// Taint flow from one argument to another and data flow from an argument to a
103+
// return value. This happens in functions like `strcat` and `memcpy`. We
104+
// could model this flow in two separate steps, but that would add reverse
105+
// flow from the write side-effect to the call instruction, which may not be
106+
// desirable.
107+
exists(CallInstruction call, Function func, FunctionInput modelIn, OutParameterDeref modelMidOut, int indexMid, InParameter modelMidIn, OutReturnValue modelOut |
108+
instrIn = callInput(call, modelIn) and
109+
instrOut = callOutput(call, modelOut) and
110+
call.getStaticCallTarget() = func and
111+
func.(TaintFunction).hasTaintFlow(modelIn, modelMidOut) and
112+
func.(DataFlowFunction).hasDataFlow(modelMidIn, modelOut) and
113+
modelMidOut.isParameterDeref(indexMid) and
114+
modelMidIn.isParameter(indexMid)
115+
)
116+
}

0 commit comments

Comments
 (0)