Skip to content

Commit 37490de

Browse files
committed
Data flow: Remove Boolean column from TNodeImplicitRead
1 parent d7614a7 commit 37490de

File tree

1 file changed

+51
-20
lines changed

1 file changed

+51
-20
lines changed

shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll

Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
166166

167167
private newtype TNodeEx =
168168
TNodeNormal(Node n) or
169-
TNodeImplicitRead(Node n, boolean hasRead) {
170-
Config::allowImplicitRead(n, _) and hasRead = [false, true]
171-
} or
169+
TNodeImplicitRead(Node n) { Config::allowImplicitRead(n, _) } or
172170
TParamReturnNode(ParameterNode p, SndLevelScopeOption scope) {
173171
paramReturnNode(_, p, scope, _)
174172
}
@@ -177,25 +175,23 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
177175
string toString() {
178176
result = this.asNode().toString()
179177
or
180-
exists(Node n | this.isImplicitReadNode(n, _) | result = n.toString() + " [Ext]")
178+
exists(Node n | this.isImplicitReadNode(n) | result = n.toString() + " [Ext]")
181179
or
182180
result = this.asParamReturnNode().toString() + " [Return]"
183181
}
184182

185183
Node asNode() { this = TNodeNormal(result) }
186184

187185
/** Gets the corresponding Node if this is a normal node or its post-implicit read node. */
188-
Node asNodeOrImplicitRead() {
189-
this = TNodeNormal(result) or this = TNodeImplicitRead(result, true)
190-
}
186+
Node asNodeOrImplicitRead() { this = TNodeNormal(result) or this = TNodeImplicitRead(result) }
191187

192-
predicate isImplicitReadNode(Node n, boolean hasRead) { this = TNodeImplicitRead(n, hasRead) }
188+
predicate isImplicitReadNode(Node n) { this = TNodeImplicitRead(n) }
193189

194190
ParameterNode asParamReturnNode() { this = TParamReturnNode(result, _) }
195191

196192
Node projectToNode() {
197193
this = TNodeNormal(result) or
198-
this = TNodeImplicitRead(result, _) or
194+
this = TNodeImplicitRead(result) or
199195
this = TParamReturnNode(result, _)
200196
}
201197

@@ -439,13 +435,6 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
439435
stepFilter(node1, node2)
440436
)
441437
or
442-
exists(Node n |
443-
node1.asNode() = n and
444-
node2.isImplicitReadNode(n, false) and
445-
not fullBarrier(node1) and
446-
model = ""
447-
)
448-
or
449438
exists(Node n1, Node n2, SndLevelScopeOption scope |
450439
node1.asNode() = n1 and
451440
node2 = TParamReturnNode(n2, scope) and
@@ -524,9 +513,13 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
524513
stepFilter(node1, node2)
525514
or
526515
exists(Node n |
527-
node2.isImplicitReadNode(n, true) and
528-
node1.isImplicitReadNode(n, _) and
516+
node2.isImplicitReadNode(n) and
529517
Config::allowImplicitRead(n, c)
518+
|
519+
node1.asNode() = n and
520+
not fullBarrier(node1)
521+
or
522+
node1.isImplicitReadNode(n)
530523
)
531524
}
532525

@@ -802,7 +795,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
802795
}
803796

804797
additional predicate sinkNode(NodeEx node, FlowState state) {
805-
fwdFlow(node) and
798+
fwdFlow(pragma[only_bind_into](node)) and
806799
fwdFlowState(state) and
807800
isRelevantSink(node.asNodeOrImplicitRead())
808801
or
@@ -2910,14 +2903,50 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
29102903

29112904
abstract PathNodeImpl getASuccessorImpl(string label);
29122905

2906+
pragma[nomagic]
2907+
PathNodeImpl getAnImplicitReadSuccessorAtSink(string label) {
2908+
exists(PathNodeMid readTarget |
2909+
result = this.getASuccessorImpl(label) and
2910+
localStep(this, readTarget, _) and
2911+
readTarget.getNodeEx().isImplicitReadNode(_)
2912+
|
2913+
// last implicit read, leaving the access path empty
2914+
result = readTarget.projectToSink(_)
2915+
or
2916+
// implicit read, leaving the access path non-empty
2917+
exists(result.getAnImplicitReadSuccessorAtSink(_)) and
2918+
result = readTarget
2919+
)
2920+
}
2921+
29132922
private PathNodeImpl getASuccessorIfHidden(string label) {
29142923
this.isHidden() and
29152924
result = this.getASuccessorImpl(label)
2925+
or
2926+
result = this.getAnImplicitReadSuccessorAtSink(label)
29162927
}
29172928

29182929
private PathNodeImpl getASuccessorFromNonHidden(string label) {
29192930
result = this.getASuccessorImpl(label) and
2920-
not this.isHidden()
2931+
not this.isHidden() and
2932+
// In cases like
2933+
//
2934+
// ```
2935+
// x.Field = taint;
2936+
// Sink(x);
2937+
// ```
2938+
//
2939+
// we only want the direct edge
2940+
//
2941+
// `[post update] x [Field]` -> `x`
2942+
//
2943+
// and not the two edges
2944+
//
2945+
// `[post update] x [Field]` -> `x [Field]`
2946+
// `x [Field]` -> `x`
2947+
//
2948+
// which the restriction below ensures.
2949+
not result = this.getAnImplicitReadSuccessorAtSink(label)
29212950
or
29222951
exists(string l1, string l2 |
29232952
result = this.getASuccessorFromNonHidden(l1).getASuccessorIfHidden(l2) and
@@ -3391,6 +3420,8 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
33913420
private predicate localStepFromHidden(PathNodeImpl n1, PathNodeImpl n2) {
33923421
n2 = localStep(n1) and
33933422
n1.isHidden()
3423+
or
3424+
n2 = n1.getAnImplicitReadSuccessorAtSink(_)
33943425
}
33953426

33963427
bindingset[par, ret]

0 commit comments

Comments
 (0)