Skip to content

Commit 6cdca29

Browse files
committed
C++: Flow through read side effects
Until we have better tracking of indirections, these flow rules conflate pointers and their contents.
1 parent c24bced commit 6cdca29

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ private predicate instructionTaintStep(Instruction i1, Instruction i2) {
166166
i2 = any(CallInstruction call |
167167
exists(int indexIn |
168168
modelTaintToReturnValue(call.getStaticCallTarget(), indexIn) and
169-
i1 = call.getPositionalArgument(indexIn)
169+
i1 = getACallArgumentOrIndirection(call, indexIn)
170170
)
171171
)
172172
or
@@ -178,13 +178,28 @@ private predicate instructionTaintStep(Instruction i1, Instruction i2) {
178178
i2 = any(WriteSideEffectInstruction outNode |
179179
exists(CallInstruction call, int indexIn, int indexOut |
180180
modelTaintToParameter(call.getStaticCallTarget(), indexIn, indexOut) and
181-
i1 = call.getPositionalArgument(indexIn) and
181+
i1 = getACallArgumentOrIndirection(call, indexIn) and
182182
outNode.getIndex() = indexOut and
183183
outNode.getPrimaryInstruction() = call
184184
)
185185
)
186186
}
187187

188+
/**
189+
* Get an instruction that goes into argument `argumentIndex` of `call`. This
190+
* can be either directly or through one pointer indirection.
191+
*/
192+
private Instruction getACallArgumentOrIndirection(CallInstruction call, int argumentIndex) {
193+
result = call.getPositionalArgument(argumentIndex)
194+
or
195+
exists(ReadSideEffectInstruction readSE |
196+
// TODO: why are read side effect operands imprecise?
197+
result = readSE.getSideEffectOperand().getAnyDef() and
198+
readSE.getPrimaryInstruction() = call and
199+
readSE.getIndex() = argumentIndex
200+
)
201+
}
202+
188203
private predicate modelTaintToParameter(Function f, int parameterIn, int parameterOut) {
189204
exists(FunctionInput modelIn, FunctionOutput modelOut |
190205
f.(TaintFunction).hasTaintFlow(modelIn, modelOut) and

cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@
2525
| defaulttainttracking.cpp:22:20:22:25 | call to getenv | defaulttainttracking.cpp:22:8:22:33 | (const char *)... |
2626
| defaulttainttracking.cpp:22:20:22:25 | call to getenv | defaulttainttracking.cpp:22:20:22:25 | call to getenv |
2727
| defaulttainttracking.cpp:22:20:22:25 | call to getenv | defaulttainttracking.cpp:22:20:22:32 | (const char *)... |
28+
| defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:32:11:32:26 | p#0 |
2829
| defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:38:11:38:21 | env_pointer |
2930
| defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:38:25:38:30 | call to getenv |
3031
| defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:38:25:38:37 | (void *)... |
32+
| defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:39:22:39:22 | a |
33+
| defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:39:26:39:34 | call to inet_addr |
3134
| defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:39:50:39:61 | & ... |
35+
| defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:40:10:40:10 | a |

0 commit comments

Comments
 (0)