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

Skip to content

Commit 52a7471

Browse files
author
Robert Marsh
committed
C++: Move sources into DefaultTaintTracking
1 parent 39b400c commit 52a7471

1 file changed

Lines changed: 46 additions & 1 deletion

File tree

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

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,32 @@ private predicate predictableInstruction(Instruction instr) {
1818
predictableInstruction(instr.(UnaryInstruction).getUnary())
1919
}
2020

21+
private predicate userInputInstruction(Instruction instr) {
22+
exists(CallInstruction ci, WriteSideEffectInstruction wsei |
23+
userInputArgument(ci.getConvertedResultExpression(), wsei.getIndex()) and
24+
instr = wsei and
25+
wsei.getPrimaryInstruction() = ci
26+
)
27+
or
28+
userInputReturned(instr.getConvertedResultExpression())
29+
or
30+
instr.getConvertedResultExpression() instanceof EnvironmentRead
31+
or
32+
instr
33+
.(LoadInstruction)
34+
.getSourceAddress()
35+
.(VariableAddressInstruction)
36+
.getASTVariable()
37+
.hasName("argv") and
38+
instr.getEnclosingFunction().hasGlobalName("main")
39+
}
40+
2141
private class DefaultTaintTrackingCfg extends DataFlow::Configuration {
2242
DefaultTaintTrackingCfg() { this = "DefaultTaintTrackingCfg" }
2343

24-
override predicate isSource(DataFlow::Node source) { isUserInput(source.asExpr(), _) }
44+
override predicate isSource(DataFlow::Node source) {
45+
userInputInstruction(source.asInstruction())
46+
}
2547

2648
override predicate isSink(DataFlow::Node sink) { any() }
2749

@@ -87,6 +109,10 @@ private predicate instructionTaintStep(Instruction i1, Instruction i2) {
87109
// This is part of the translation of `a[i]`, where we want taint to flow
88110
// from `a`.
89111
i2.(PointerAddInstruction).getLeft() = i1
112+
or
113+
i2.(ChiInstruction).getPartial() = i1
114+
or
115+
i2.(ChiInstruction).getTotal() = i1
90116
// TODO: Flow from argument to return of known functions: Port missing parts
91117
// of `returnArgument` to the `interfaces.Taint` and `interfaces.DataFlow`
92118
// libraries.
@@ -102,6 +128,8 @@ private predicate instructionTaintStep(Instruction i1, Instruction i2) {
102128
predicate tainted(Expr source, Element tainted) {
103129
exists(DefaultTaintTrackingCfg cfg, DataFlow::Node sink |
104130
cfg.hasFlow(DataFlow::exprNode(source), sink)
131+
or
132+
cfg.hasFlow(DataFlow::definitionByReferenceNode(source), sink)
105133
|
106134
// TODO: is it more appropriate to use asConvertedExpr here and avoid
107135
// `getConversion*`? Or will that cause us to miss some cases where there's
@@ -128,6 +156,23 @@ predicate tainted(Expr source, Element tainted) {
128156
// For compatibility, send flow into a `NotExpr` even if it's part of a
129157
// short-circuiting condition and thus might get skipped.
130158
tainted.(NotExpr).getOperand() = sink.asExpr()
159+
or
160+
// For compatibility, send flow from argument read side effects to their
161+
// corresponding argument expression
162+
exists(IndirectReadSideEffectInstruction read |
163+
read.getAnOperand().(SideEffectOperand).getAnyDef() = sink.asInstruction() and
164+
read.getArgumentDef().getUnconvertedResultExpression() = tainted
165+
)
166+
or
167+
exists(BufferReadSideEffectInstruction read |
168+
read.getAnOperand().(SideEffectOperand).getAnyDef() = sink.asInstruction() and
169+
read.getArgumentDef().getUnconvertedResultExpression() = tainted
170+
)
171+
or
172+
exists(SizedBufferReadSideEffectInstruction read |
173+
read.getAnOperand().(SideEffectOperand).getAnyDef() = sink.asInstruction() and
174+
read.getArgumentDef().getUnconvertedResultExpression() = tainted
175+
)
131176
)
132177
}
133178

0 commit comments

Comments
 (0)