Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fd807d4

Browse files
author
Robert Marsh
committed
C++: IR dataflow through modeled functions
1 parent c7975e8 commit fd807d4

3 files changed

Lines changed: 57 additions & 5 deletions

File tree

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

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ private import cpp
66
private import semmle.code.cpp.ir.IR
77
private import semmle.code.cpp.controlflow.IRGuards
88
private import semmle.code.cpp.ir.ValueNumbering
9+
private import semmle.code.cpp.models.interfaces.DataFlow
910

1011
/**
1112
* A newtype wrapper to prevent accidental casts between `Node` and
@@ -282,7 +283,58 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
282283
// for variables that have escaped: for soundness, the IR has to assume that
283284
// every write to an unknown address can affect every escaped variable, and
284285
// this assumption shows up as data flowing through partial chi operands.
285-
iTo.getAnOperand().(ChiTotalOperand).getDef() = iFrom
286+
iTo.getAnOperand().(ChiTotalOperand).getDef() = iFrom or
287+
// Flow from argument to return value
288+
iTo = any(CallInstruction call |
289+
exists(int indexIn |
290+
modelFlowToReturnValue(call.getStaticCallTarget(), indexIn) and
291+
iFrom = getACallArgumentOrIndirection(call, indexIn)
292+
)
293+
)
294+
or
295+
// Flow from input argument to output argument
296+
// TODO: This won't work in practice as long as all aliased memory is tracked
297+
// together in a single virtual variable.
298+
iTo = any(WriteSideEffectInstruction outNode |
299+
exists(CallInstruction call, int indexIn, int indexOut |
300+
modelFlowToParameter(call.getStaticCallTarget(), indexIn, indexOut) and
301+
iFrom = getACallArgumentOrIndirection(call, indexIn) and
302+
outNode.getIndex() = indexOut and
303+
outNode.getPrimaryInstruction() = call
304+
)
305+
)
306+
}
307+
308+
/**
309+
* Get an instruction that goes into argument `argumentIndex` of `call`. This
310+
* can be either directly or through one pointer indirection.
311+
*/
312+
private Instruction getACallArgumentOrIndirection(CallInstruction call, int argumentIndex) {
313+
result = call.getPositionalArgument(argumentIndex)
314+
or
315+
exists(ReadSideEffectInstruction readSE |
316+
// TODO: why are read side effect operands imprecise?
317+
result = readSE.getSideEffectOperand().getAnyDef() and
318+
readSE.getPrimaryInstruction() = call and
319+
readSE.getIndex() = argumentIndex
320+
)
321+
}
322+
323+
private predicate modelFlowToParameter(Function f, int parameterIn, int parameterOut) {
324+
exists(FunctionInput modelIn, FunctionOutput modelOut |
325+
f.(DataFlowFunction).hasDataFlow(modelIn, modelOut) and
326+
(modelIn.isParameter(parameterIn) or modelIn.isParameterDeref(parameterIn)) and
327+
modelOut.isParameterDeref(parameterOut)
328+
)
329+
}
330+
331+
private predicate modelFlowToReturnValue(Function f, int parameterIn) {
332+
// Data flow from parameter to return value
333+
exists(FunctionInput modelIn, FunctionOutput modelOut |
334+
f.(DataFlowFunction).hasDataFlow(modelIn, modelOut) and
335+
(modelIn.isParameter(parameterIn) or modelIn.isParameterDeref(parameterIn)) and
336+
(modelOut.isReturnValue() or modelOut.isReturnValueDeref())
337+
)
286338
}
287339

288340
/**

cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,6 @@
2424
| taint.cpp:261:7:261:7 | taint.cpp:258:7:258:12 | AST only |
2525
| taint.cpp:351:7:351:7 | taint.cpp:330:6:330:11 | AST only |
2626
| taint.cpp:352:7:352:7 | taint.cpp:330:6:330:11 | AST only |
27-
| taint.cpp:372:7:372:7 | taint.cpp:365:24:365:29 | AST only |
28-
| taint.cpp:374:7:374:7 | taint.cpp:365:24:365:29 | AST only |
29-
| taint.cpp:382:7:382:7 | taint.cpp:377:23:377:28 | AST only |
30-
| taint.cpp:391:7:391:7 | taint.cpp:385:27:385:32 | AST only |
3127
| taint.cpp:423:7:423:7 | taint.cpp:422:14:422:19 | AST only |
3228
| taint.cpp:424:9:424:17 | taint.cpp:422:14:422:19 | AST only |
3329
| taint.cpp:429:7:429:7 | taint.cpp:428:13:428:18 | IR only |

cpp/ql/test/library-tests/dataflow/taint-tests/test_ir.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,8 @@
1515
| taint.cpp:291:7:291:7 | y | taint.cpp:275:6:275:11 | call to source |
1616
| taint.cpp:337:7:337:7 | t | taint.cpp:330:6:330:11 | call to source |
1717
| taint.cpp:350:7:350:7 | t | taint.cpp:330:6:330:11 | call to source |
18+
| taint.cpp:372:7:372:7 | a | taint.cpp:365:24:365:29 | source |
19+
| taint.cpp:374:7:374:7 | c | taint.cpp:365:24:365:29 | source |
20+
| taint.cpp:382:7:382:7 | a | taint.cpp:377:23:377:28 | source |
21+
| taint.cpp:391:7:391:7 | a | taint.cpp:385:27:385:32 | source |
1822
| taint.cpp:429:7:429:7 | b | taint.cpp:428:13:428:18 | call to source |

0 commit comments

Comments
 (0)