Merge pull request #5375 from aschackmull/dataflow/unbind

Dataflow: Switch from unbind to pragma[only_bind_into].
This commit is contained in:
Anders Schack-Mulligen
2021-03-16 14:03:54 +01:00
committed by GitHub
23 changed files with 2484 additions and 1978 deletions

View File

@@ -444,8 +444,8 @@ private module Stage1 {
// read
exists(Node mid, Content c |
read(node, c, mid) and
fwdFlowConsCand(c, unbind(config)) and
revFlow(mid, toReturn, config)
fwdFlowConsCand(c, pragma[only_bind_into](config)) and
revFlow(mid, toReturn, pragma[only_bind_into](config))
)
or
// flow into a callable
@@ -471,18 +471,18 @@ private module Stage1 {
pragma[nomagic]
private predicate revFlowConsCand(Content c, Configuration config) {
exists(Node mid, Node node |
fwdFlow(node, unbind(config)) and
fwdFlow(node, pragma[only_bind_into](config)) and
read(node, c, mid) and
fwdFlowConsCand(c, unbind(config)) and
revFlow(mid, _, config)
fwdFlowConsCand(c, pragma[only_bind_into](config)) and
revFlow(pragma[only_bind_into](mid), _, pragma[only_bind_into](config))
)
}
pragma[nomagic]
private predicate revFlowStore(Content c, Node node, boolean toReturn, Configuration config) {
exists(Node mid, TypedContent tc |
revFlow(mid, toReturn, config) and
fwdFlowConsCand(c, unbind(config)) and
revFlow(mid, toReturn, pragma[only_bind_into](config)) and
fwdFlowConsCand(c, pragma[only_bind_into](config)) and
store(node, tc, mid, _) and
c = tc.getContent()
)
@@ -552,8 +552,8 @@ private module Stage1 {
Node node1, Ap ap1, TypedContent tc, Node node2, DataFlowType contentType, Configuration config
) {
exists(Content c |
revFlowIsReadAndStored(c, config) and
revFlow(node2, unbind(config)) and
revFlowIsReadAndStored(c, pragma[only_bind_into](config)) and
revFlow(node2, pragma[only_bind_into](config)) and
store(node1, tc, node2, contentType) and
c = tc.getContent() and
exists(ap1)
@@ -562,8 +562,8 @@ private module Stage1 {
pragma[nomagic]
predicate readStepCand(Node n1, Content c, Node n2, Configuration config) {
revFlowIsReadAndStored(c, config) and
revFlow(n2, unbind(config)) and
revFlowIsReadAndStored(c, pragma[only_bind_into](config)) and
revFlow(n2, pragma[only_bind_into](config)) and
read(n1, c, n2)
}
@@ -626,9 +626,6 @@ private module Stage1 {
/* End: Stage 1 logic. */
}
bindingset[result, b]
private boolean unbindBool(boolean b) { result != b.booleanNot() }
pragma[noinline]
private predicate localFlowStepNodeCand1(Node node1, Node node2, Configuration config) {
Stage1::revFlow(node2, config) and
@@ -864,16 +861,16 @@ private module Stage2 {
)
or
exists(Node mid |
fwdFlow(mid, _, _, ap, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
jumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone()
)
or
exists(Node mid, ApNil nil |
fwdFlow(mid, _, _, nil, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
additionalJumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone() and
@@ -1045,9 +1042,9 @@ private module Stage2 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
localStep(node, mid, false, _, config, _) and
revFlow(mid, toReturn, returnAp, nil, config) and
revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and
ap instanceof ApNil
)
or
@@ -1059,9 +1056,9 @@ private module Stage2 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
additionalJumpStep(node, mid, config) and
revFlow(mid, _, _, nil, config) and
revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and
toReturn = false and
returnAp = apNone() and
ap instanceof ApNil
@@ -1114,9 +1111,10 @@ private module Stage2 {
*/
pragma[nomagic]
private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) {
exists(Node mid |
exists(Node mid, Ap tail0 |
revFlow(mid, _, _, tail, config) and
readStepFwd(_, cons, c, mid, tail, config)
tail = pragma[only_bind_into](tail0) and
readStepFwd(_, cons, c, mid, tail0, config)
)
}
@@ -1182,9 +1180,10 @@ private module Stage2 {
predicate readStepCand(Node node1, Content c, Node node2, Configuration config) {
exists(Ap ap1, Ap ap2 |
revFlow(node2, _, _, ap2, config) and
revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and
readStepFwd(node1, ap1, c, node2, ap2, config) and
revFlowStore(ap1, c, /*unbind*/ unbindBool(ap2), _, _, _, _, _, unbind(config))
revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _,
pragma[only_bind_into](config))
)
}
@@ -1240,8 +1239,8 @@ private predicate flowOutOfCallNodeCand2(
DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config
) {
flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
Stage2::revFlow(node2, config) and
Stage2::revFlow(node1, unbind(config))
Stage2::revFlow(node2, pragma[only_bind_into](config)) and
Stage2::revFlow(node1, pragma[only_bind_into](config))
}
pragma[nomagic]
@@ -1250,8 +1249,8 @@ private predicate flowIntoCallNodeCand2(
Configuration config
) {
flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
Stage2::revFlow(node2, config) and
Stage2::revFlow(node1, unbind(config))
Stage2::revFlow(node2, pragma[only_bind_into](config)) and
Stage2::revFlow(node1, pragma[only_bind_into](config))
}
private module LocalFlowBigStep {
@@ -1306,8 +1305,8 @@ private module LocalFlowBigStep {
pragma[noinline]
private predicate additionalLocalFlowStepNodeCand2(Node node1, Node node2, Configuration config) {
additionalLocalFlowStepNodeCand1(node1, node2, config) and
Stage2::revFlow(node1, _, _, false, config) and
Stage2::revFlow(node2, _, _, false, unbind(config))
Stage2::revFlow(node1, _, _, false, pragma[only_bind_into](config)) and
Stage2::revFlow(node2, _, _, false, pragma[only_bind_into](config))
}
/**
@@ -1324,7 +1323,7 @@ private module LocalFlowBigStep {
) {
not isUnreachableInCall(node2, cc.(LocalCallContextSpecificCall).getCall()) and
(
localFlowEntry(node1, config) and
localFlowEntry(node1, pragma[only_bind_into](config)) and
(
localFlowStepNodeCand1(node1, node2, config) and
preservesValue = true and
@@ -1337,22 +1336,22 @@ private module LocalFlowBigStep {
node1 != node2 and
cc.relevantFor(getNodeEnclosingCallable(node1)) and
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
Stage2::revFlow(node2, unbind(config))
Stage2::revFlow(node2, pragma[only_bind_into](config))
or
exists(Node mid |
localFlowStepPlus(node1, mid, preservesValue, t, config, cc) and
localFlowStepPlus(node1, mid, preservesValue, t, pragma[only_bind_into](config), cc) and
localFlowStepNodeCand1(mid, node2, config) and
not mid instanceof FlowCheckNode and
Stage2::revFlow(node2, unbind(config))
Stage2::revFlow(node2, pragma[only_bind_into](config))
)
or
exists(Node mid |
localFlowStepPlus(node1, mid, _, _, config, cc) and
localFlowStepPlus(node1, mid, _, _, pragma[only_bind_into](config), cc) and
additionalLocalFlowStepNodeCand2(mid, node2, config) and
not mid instanceof FlowCheckNode and
preservesValue = false and
t = getNodeType(node2) and
Stage2::revFlow(node2, unbind(config))
Stage2::revFlow(node2, pragma[only_bind_into](config))
)
)
}
@@ -1459,6 +1458,13 @@ private module Stage3 {
PrevStage::revFlow(node, _, _, apa, config)
}
bindingset[result, apa]
private ApApprox unbindApa(ApApprox apa) {
exists(ApApprox apa0 |
apa = pragma[only_bind_into](apa0) and result = pragma[only_bind_into](apa0)
)
}
/**
* Holds if `node` is reachable with access path `ap` from a source in the
* configuration `config`.
@@ -1470,7 +1476,7 @@ private module Stage3 {
pragma[nomagic]
predicate fwdFlow(Node node, Cc cc, ApOption argAp, Ap ap, Configuration config) {
fwdFlow0(node, cc, argAp, ap, config) and
flowCand(node, unbindBool(getApprox(ap)), config) and
flowCand(node, unbindApa(getApprox(ap)), config) and
filter(node, ap)
}
@@ -1494,16 +1500,16 @@ private module Stage3 {
)
or
exists(Node mid |
fwdFlow(mid, _, _, ap, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
jumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone()
)
or
exists(Node mid, ApNil nil |
fwdFlow(mid, _, _, nil, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
additionalJumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone() and
@@ -1548,7 +1554,7 @@ private module Stage3 {
) {
exists(DataFlowType contentType |
fwdFlow(node1, cc, argAp, ap1, config) and
PrevStage::storeStepCand(node1, unbindBool(getApprox(ap1)), tc, node2, contentType, config) and
PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and
typecheckStore(ap1, contentType)
)
}
@@ -1627,7 +1633,7 @@ private module Stage3 {
) {
exists(ParameterNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindBool(getApprox(ap)), config)
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
}
@@ -1675,9 +1681,9 @@ private module Stage3 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
localStep(node, mid, false, _, config, _) and
revFlow(mid, toReturn, returnAp, nil, config) and
revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and
ap instanceof ApNil
)
or
@@ -1689,9 +1695,9 @@ private module Stage3 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
additionalJumpStep(node, mid, config) and
revFlow(mid, _, _, nil, config) and
revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and
toReturn = false and
returnAp = apNone() and
ap instanceof ApNil
@@ -1744,9 +1750,10 @@ private module Stage3 {
*/
pragma[nomagic]
private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) {
exists(Node mid |
exists(Node mid, Ap tail0 |
revFlow(mid, _, _, tail, config) and
readStepFwd(_, cons, c, mid, tail, config)
tail = pragma[only_bind_into](tail0) and
readStepFwd(_, cons, c, mid, tail0, config)
)
}
@@ -1812,9 +1819,10 @@ private module Stage3 {
predicate readStepCand(Node node1, Content c, Node node2, Configuration config) {
exists(Ap ap1, Ap ap2 |
revFlow(node2, _, _, ap2, config) and
revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and
readStepFwd(node1, ap1, c, node2, ap2, config) and
revFlowStore(ap1, c, /*unbind*/ ap2, _, _, _, _, _, unbind(config))
revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _,
pragma[only_bind_into](config))
)
}
@@ -2125,8 +2133,11 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
localFlowEntry(node, config) and
result = getLocalCallContext(cc, getNodeEnclosingCallable(node))
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
}
private predicate localStep(
@@ -2141,8 +2152,8 @@ private module Stage4 {
Configuration config
) {
flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
PrevStage::revFlow(node2, _, _, _, config) and
PrevStage::revFlow(node1, _, _, _, unbind(config))
PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and
PrevStage::revFlow(node1, _, _, _, pragma[only_bind_into](config))
}
pragma[nomagic]
@@ -2151,8 +2162,8 @@ private module Stage4 {
Configuration config
) {
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
PrevStage::revFlow(node2, _, _, _, config) and
PrevStage::revFlow(node1, _, _, _, unbind(config))
PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and
PrevStage::revFlow(node1, _, _, _, pragma[only_bind_into](config))
}
bindingset[node, ap]
@@ -2167,6 +2178,13 @@ private module Stage4 {
PrevStage::revFlow(node, _, _, apa, config)
}
bindingset[result, apa]
private ApApprox unbindApa(ApApprox apa) {
exists(ApApprox apa0 |
apa = pragma[only_bind_into](apa0) and result = pragma[only_bind_into](apa0)
)
}
/**
* Holds if `node` is reachable with access path `ap` from a source in the
* configuration `config`.
@@ -2178,7 +2196,7 @@ private module Stage4 {
pragma[nomagic]
predicate fwdFlow(Node node, Cc cc, ApOption argAp, Ap ap, Configuration config) {
fwdFlow0(node, cc, argAp, ap, config) and
flowCand(node, getApprox(ap), config) and
flowCand(node, unbindApa(getApprox(ap)), config) and
filter(node, ap)
}
@@ -2202,16 +2220,16 @@ private module Stage4 {
)
or
exists(Node mid |
fwdFlow(mid, _, _, ap, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
jumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone()
)
or
exists(Node mid, ApNil nil |
fwdFlow(mid, _, _, nil, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
additionalJumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone() and
@@ -2256,7 +2274,7 @@ private module Stage4 {
) {
exists(DataFlowType contentType |
fwdFlow(node1, cc, argAp, ap1, config) and
PrevStage::storeStepCand(node1, getApprox(ap1), tc, node2, contentType, config) and
PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and
typecheckStore(ap1, contentType)
)
}
@@ -2335,7 +2353,7 @@ private module Stage4 {
) {
exists(ParameterNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, getApprox(ap), config)
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
}
@@ -2383,9 +2401,9 @@ private module Stage4 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
localStep(node, mid, false, _, config, _) and
revFlow(mid, toReturn, returnAp, nil, config) and
revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and
ap instanceof ApNil
)
or
@@ -2397,9 +2415,9 @@ private module Stage4 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
additionalJumpStep(node, mid, config) and
revFlow(mid, _, _, nil, config) and
revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and
toReturn = false and
returnAp = apNone() and
ap instanceof ApNil
@@ -2452,9 +2470,10 @@ private module Stage4 {
*/
pragma[nomagic]
private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) {
exists(Node mid |
exists(Node mid, Ap tail0 |
revFlow(mid, _, _, tail, config) and
readStepFwd(_, cons, c, mid, tail, config)
tail = pragma[only_bind_into](tail0) and
readStepFwd(_, cons, c, mid, tail0, config)
)
}
@@ -2520,9 +2539,10 @@ private module Stage4 {
predicate readStepCand(Node node1, Content c, Node node2, Configuration config) {
exists(Ap ap1, Ap ap2 |
revFlow(node2, _, _, ap2, config) and
revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and
readStepFwd(node1, ap1, c, node2, ap2, config) and
revFlowStore(ap1, c, /*unbind*/ ap2, _, _, _, _, _, unbind(config))
revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _,
pragma[only_bind_into](config))
)
}
@@ -2574,7 +2594,9 @@ private module Stage4 {
}
bindingset[conf, result]
private Configuration unbind(Configuration conf) { result >= conf and result <= conf }
private Configuration unbindConf(Configuration conf) {
exists(Configuration c | result = pragma[only_bind_into](c) and conf = pragma[only_bind_into](c))
}
private predicate nodeMayUseSummary(Node n, AccessPathApprox apa, Configuration config) {
exists(DataFlowCallable c, AccessPathApprox apa0 |
@@ -2744,13 +2766,13 @@ private newtype TPathNode =
// ... or a step from an existing PathNode to another node.
exists(PathNodeMid mid |
pathStep(mid, node, cc, sc, ap) and
config = mid.getConfiguration() and
Stage4::revFlow(node, _, _, ap.getApprox(), unbind(config))
pragma[only_bind_into](config) = mid.getConfiguration() and
Stage4::revFlow(node, _, _, ap.getApprox(), pragma[only_bind_into](config))
)
} or
TPathNodeSink(Node node, Configuration config) {
config.isSink(node) and
Stage4::revFlow(node, unbind(config)) and
pragma[only_bind_into](config).isSink(node) and
Stage4::revFlow(node, pragma[only_bind_into](config)) and
(
// A sink that is also a source ...
config.isSource(node)
@@ -2758,7 +2780,7 @@ private newtype TPathNode =
// ... or a sink that can be reached from a source
exists(PathNodeMid mid |
pathStep(mid, node, _, _, TAccessPathNil(_)) and
config = unbind(mid.getConfiguration())
pragma[only_bind_into](config) = mid.getConfiguration()
)
)
}
@@ -3055,7 +3077,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
private PathNodeMid getSuccMid() {
pathStep(this, result.getNode(), result.getCallContext(), result.getSummaryCtx(), result.getAp()) and
result.getConfiguration() = unbind(this.getConfiguration())
result.getConfiguration() = unbindConf(this.getConfiguration())
}
override PathNodeImpl getASuccessorImpl() {
@@ -3067,7 +3089,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
mid = getSuccMid() and
mid.getNode() = sink.getNode() and
mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbind(mid.getConfiguration()) and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
result = sink
)
}
@@ -3298,7 +3320,7 @@ private predicate pathThroughCallable0(
) {
exists(CallContext innercc, SummaryCtx sc |
pathIntoCallable(mid, _, cc, innercc, sc, call) and
paramFlowsThrough(kind, innercc, sc, ap, apa, unbind(mid.getConfiguration()))
paramFlowsThrough(kind, innercc, sc, ap, apa, unbindConf(mid.getConfiguration()))
)
}
@@ -3310,7 +3332,7 @@ pragma[noinline]
private predicate pathThroughCallable(PathNodeMid mid, Node out, CallContext cc, AccessPath ap) {
exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
pathThroughCallable0(call, mid, kind, cc, ap, apa) and
out = getAnOutNodeFlow(kind, call, apa, unbind(mid.getConfiguration()))
out = getAnOutNodeFlow(kind, call, apa, unbindConf(mid.getConfiguration()))
)
}
@@ -3433,8 +3455,8 @@ private module FlowExploration {
private predicate callableExtStepFwd(TCallableExt ce1, TCallableExt ce2) {
exists(DataFlowCallable c1, DataFlowCallable c2, Configuration config |
callableStep(c1, c2, config) and
ce1 = TCallable(c1, config) and
ce2 = TCallable(c2, unbind(config))
ce1 = TCallable(c1, pragma[only_bind_into](config)) and
ce2 = TCallable(c2, pragma[only_bind_into](config))
)
or
exists(Node n, Configuration config |

View File

@@ -444,8 +444,8 @@ private module Stage1 {
// read
exists(Node mid, Content c |
read(node, c, mid) and
fwdFlowConsCand(c, unbind(config)) and
revFlow(mid, toReturn, config)
fwdFlowConsCand(c, pragma[only_bind_into](config)) and
revFlow(mid, toReturn, pragma[only_bind_into](config))
)
or
// flow into a callable
@@ -471,18 +471,18 @@ private module Stage1 {
pragma[nomagic]
private predicate revFlowConsCand(Content c, Configuration config) {
exists(Node mid, Node node |
fwdFlow(node, unbind(config)) and
fwdFlow(node, pragma[only_bind_into](config)) and
read(node, c, mid) and
fwdFlowConsCand(c, unbind(config)) and
revFlow(mid, _, config)
fwdFlowConsCand(c, pragma[only_bind_into](config)) and
revFlow(pragma[only_bind_into](mid), _, pragma[only_bind_into](config))
)
}
pragma[nomagic]
private predicate revFlowStore(Content c, Node node, boolean toReturn, Configuration config) {
exists(Node mid, TypedContent tc |
revFlow(mid, toReturn, config) and
fwdFlowConsCand(c, unbind(config)) and
revFlow(mid, toReturn, pragma[only_bind_into](config)) and
fwdFlowConsCand(c, pragma[only_bind_into](config)) and
store(node, tc, mid, _) and
c = tc.getContent()
)
@@ -552,8 +552,8 @@ private module Stage1 {
Node node1, Ap ap1, TypedContent tc, Node node2, DataFlowType contentType, Configuration config
) {
exists(Content c |
revFlowIsReadAndStored(c, config) and
revFlow(node2, unbind(config)) and
revFlowIsReadAndStored(c, pragma[only_bind_into](config)) and
revFlow(node2, pragma[only_bind_into](config)) and
store(node1, tc, node2, contentType) and
c = tc.getContent() and
exists(ap1)
@@ -562,8 +562,8 @@ private module Stage1 {
pragma[nomagic]
predicate readStepCand(Node n1, Content c, Node n2, Configuration config) {
revFlowIsReadAndStored(c, config) and
revFlow(n2, unbind(config)) and
revFlowIsReadAndStored(c, pragma[only_bind_into](config)) and
revFlow(n2, pragma[only_bind_into](config)) and
read(n1, c, n2)
}
@@ -626,9 +626,6 @@ private module Stage1 {
/* End: Stage 1 logic. */
}
bindingset[result, b]
private boolean unbindBool(boolean b) { result != b.booleanNot() }
pragma[noinline]
private predicate localFlowStepNodeCand1(Node node1, Node node2, Configuration config) {
Stage1::revFlow(node2, config) and
@@ -864,16 +861,16 @@ private module Stage2 {
)
or
exists(Node mid |
fwdFlow(mid, _, _, ap, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
jumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone()
)
or
exists(Node mid, ApNil nil |
fwdFlow(mid, _, _, nil, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
additionalJumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone() and
@@ -1045,9 +1042,9 @@ private module Stage2 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
localStep(node, mid, false, _, config, _) and
revFlow(mid, toReturn, returnAp, nil, config) and
revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and
ap instanceof ApNil
)
or
@@ -1059,9 +1056,9 @@ private module Stage2 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
additionalJumpStep(node, mid, config) and
revFlow(mid, _, _, nil, config) and
revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and
toReturn = false and
returnAp = apNone() and
ap instanceof ApNil
@@ -1114,9 +1111,10 @@ private module Stage2 {
*/
pragma[nomagic]
private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) {
exists(Node mid |
exists(Node mid, Ap tail0 |
revFlow(mid, _, _, tail, config) and
readStepFwd(_, cons, c, mid, tail, config)
tail = pragma[only_bind_into](tail0) and
readStepFwd(_, cons, c, mid, tail0, config)
)
}
@@ -1182,9 +1180,10 @@ private module Stage2 {
predicate readStepCand(Node node1, Content c, Node node2, Configuration config) {
exists(Ap ap1, Ap ap2 |
revFlow(node2, _, _, ap2, config) and
revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and
readStepFwd(node1, ap1, c, node2, ap2, config) and
revFlowStore(ap1, c, /*unbind*/ unbindBool(ap2), _, _, _, _, _, unbind(config))
revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _,
pragma[only_bind_into](config))
)
}
@@ -1240,8 +1239,8 @@ private predicate flowOutOfCallNodeCand2(
DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config
) {
flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
Stage2::revFlow(node2, config) and
Stage2::revFlow(node1, unbind(config))
Stage2::revFlow(node2, pragma[only_bind_into](config)) and
Stage2::revFlow(node1, pragma[only_bind_into](config))
}
pragma[nomagic]
@@ -1250,8 +1249,8 @@ private predicate flowIntoCallNodeCand2(
Configuration config
) {
flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
Stage2::revFlow(node2, config) and
Stage2::revFlow(node1, unbind(config))
Stage2::revFlow(node2, pragma[only_bind_into](config)) and
Stage2::revFlow(node1, pragma[only_bind_into](config))
}
private module LocalFlowBigStep {
@@ -1306,8 +1305,8 @@ private module LocalFlowBigStep {
pragma[noinline]
private predicate additionalLocalFlowStepNodeCand2(Node node1, Node node2, Configuration config) {
additionalLocalFlowStepNodeCand1(node1, node2, config) and
Stage2::revFlow(node1, _, _, false, config) and
Stage2::revFlow(node2, _, _, false, unbind(config))
Stage2::revFlow(node1, _, _, false, pragma[only_bind_into](config)) and
Stage2::revFlow(node2, _, _, false, pragma[only_bind_into](config))
}
/**
@@ -1324,7 +1323,7 @@ private module LocalFlowBigStep {
) {
not isUnreachableInCall(node2, cc.(LocalCallContextSpecificCall).getCall()) and
(
localFlowEntry(node1, config) and
localFlowEntry(node1, pragma[only_bind_into](config)) and
(
localFlowStepNodeCand1(node1, node2, config) and
preservesValue = true and
@@ -1337,22 +1336,22 @@ private module LocalFlowBigStep {
node1 != node2 and
cc.relevantFor(getNodeEnclosingCallable(node1)) and
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
Stage2::revFlow(node2, unbind(config))
Stage2::revFlow(node2, pragma[only_bind_into](config))
or
exists(Node mid |
localFlowStepPlus(node1, mid, preservesValue, t, config, cc) and
localFlowStepPlus(node1, mid, preservesValue, t, pragma[only_bind_into](config), cc) and
localFlowStepNodeCand1(mid, node2, config) and
not mid instanceof FlowCheckNode and
Stage2::revFlow(node2, unbind(config))
Stage2::revFlow(node2, pragma[only_bind_into](config))
)
or
exists(Node mid |
localFlowStepPlus(node1, mid, _, _, config, cc) and
localFlowStepPlus(node1, mid, _, _, pragma[only_bind_into](config), cc) and
additionalLocalFlowStepNodeCand2(mid, node2, config) and
not mid instanceof FlowCheckNode and
preservesValue = false and
t = getNodeType(node2) and
Stage2::revFlow(node2, unbind(config))
Stage2::revFlow(node2, pragma[only_bind_into](config))
)
)
}
@@ -1459,6 +1458,13 @@ private module Stage3 {
PrevStage::revFlow(node, _, _, apa, config)
}
bindingset[result, apa]
private ApApprox unbindApa(ApApprox apa) {
exists(ApApprox apa0 |
apa = pragma[only_bind_into](apa0) and result = pragma[only_bind_into](apa0)
)
}
/**
* Holds if `node` is reachable with access path `ap` from a source in the
* configuration `config`.
@@ -1470,7 +1476,7 @@ private module Stage3 {
pragma[nomagic]
predicate fwdFlow(Node node, Cc cc, ApOption argAp, Ap ap, Configuration config) {
fwdFlow0(node, cc, argAp, ap, config) and
flowCand(node, unbindBool(getApprox(ap)), config) and
flowCand(node, unbindApa(getApprox(ap)), config) and
filter(node, ap)
}
@@ -1494,16 +1500,16 @@ private module Stage3 {
)
or
exists(Node mid |
fwdFlow(mid, _, _, ap, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
jumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone()
)
or
exists(Node mid, ApNil nil |
fwdFlow(mid, _, _, nil, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
additionalJumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone() and
@@ -1548,7 +1554,7 @@ private module Stage3 {
) {
exists(DataFlowType contentType |
fwdFlow(node1, cc, argAp, ap1, config) and
PrevStage::storeStepCand(node1, unbindBool(getApprox(ap1)), tc, node2, contentType, config) and
PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and
typecheckStore(ap1, contentType)
)
}
@@ -1627,7 +1633,7 @@ private module Stage3 {
) {
exists(ParameterNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindBool(getApprox(ap)), config)
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
}
@@ -1675,9 +1681,9 @@ private module Stage3 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
localStep(node, mid, false, _, config, _) and
revFlow(mid, toReturn, returnAp, nil, config) and
revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and
ap instanceof ApNil
)
or
@@ -1689,9 +1695,9 @@ private module Stage3 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
additionalJumpStep(node, mid, config) and
revFlow(mid, _, _, nil, config) and
revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and
toReturn = false and
returnAp = apNone() and
ap instanceof ApNil
@@ -1744,9 +1750,10 @@ private module Stage3 {
*/
pragma[nomagic]
private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) {
exists(Node mid |
exists(Node mid, Ap tail0 |
revFlow(mid, _, _, tail, config) and
readStepFwd(_, cons, c, mid, tail, config)
tail = pragma[only_bind_into](tail0) and
readStepFwd(_, cons, c, mid, tail0, config)
)
}
@@ -1812,9 +1819,10 @@ private module Stage3 {
predicate readStepCand(Node node1, Content c, Node node2, Configuration config) {
exists(Ap ap1, Ap ap2 |
revFlow(node2, _, _, ap2, config) and
revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and
readStepFwd(node1, ap1, c, node2, ap2, config) and
revFlowStore(ap1, c, /*unbind*/ ap2, _, _, _, _, _, unbind(config))
revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _,
pragma[only_bind_into](config))
)
}
@@ -2125,8 +2133,11 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
localFlowEntry(node, config) and
result = getLocalCallContext(cc, getNodeEnclosingCallable(node))
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
}
private predicate localStep(
@@ -2141,8 +2152,8 @@ private module Stage4 {
Configuration config
) {
flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
PrevStage::revFlow(node2, _, _, _, config) and
PrevStage::revFlow(node1, _, _, _, unbind(config))
PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and
PrevStage::revFlow(node1, _, _, _, pragma[only_bind_into](config))
}
pragma[nomagic]
@@ -2151,8 +2162,8 @@ private module Stage4 {
Configuration config
) {
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
PrevStage::revFlow(node2, _, _, _, config) and
PrevStage::revFlow(node1, _, _, _, unbind(config))
PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and
PrevStage::revFlow(node1, _, _, _, pragma[only_bind_into](config))
}
bindingset[node, ap]
@@ -2167,6 +2178,13 @@ private module Stage4 {
PrevStage::revFlow(node, _, _, apa, config)
}
bindingset[result, apa]
private ApApprox unbindApa(ApApprox apa) {
exists(ApApprox apa0 |
apa = pragma[only_bind_into](apa0) and result = pragma[only_bind_into](apa0)
)
}
/**
* Holds if `node` is reachable with access path `ap` from a source in the
* configuration `config`.
@@ -2178,7 +2196,7 @@ private module Stage4 {
pragma[nomagic]
predicate fwdFlow(Node node, Cc cc, ApOption argAp, Ap ap, Configuration config) {
fwdFlow0(node, cc, argAp, ap, config) and
flowCand(node, getApprox(ap), config) and
flowCand(node, unbindApa(getApprox(ap)), config) and
filter(node, ap)
}
@@ -2202,16 +2220,16 @@ private module Stage4 {
)
or
exists(Node mid |
fwdFlow(mid, _, _, ap, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
jumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone()
)
or
exists(Node mid, ApNil nil |
fwdFlow(mid, _, _, nil, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
additionalJumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone() and
@@ -2256,7 +2274,7 @@ private module Stage4 {
) {
exists(DataFlowType contentType |
fwdFlow(node1, cc, argAp, ap1, config) and
PrevStage::storeStepCand(node1, getApprox(ap1), tc, node2, contentType, config) and
PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and
typecheckStore(ap1, contentType)
)
}
@@ -2335,7 +2353,7 @@ private module Stage4 {
) {
exists(ParameterNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, getApprox(ap), config)
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
}
@@ -2383,9 +2401,9 @@ private module Stage4 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
localStep(node, mid, false, _, config, _) and
revFlow(mid, toReturn, returnAp, nil, config) and
revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and
ap instanceof ApNil
)
or
@@ -2397,9 +2415,9 @@ private module Stage4 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
additionalJumpStep(node, mid, config) and
revFlow(mid, _, _, nil, config) and
revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and
toReturn = false and
returnAp = apNone() and
ap instanceof ApNil
@@ -2452,9 +2470,10 @@ private module Stage4 {
*/
pragma[nomagic]
private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) {
exists(Node mid |
exists(Node mid, Ap tail0 |
revFlow(mid, _, _, tail, config) and
readStepFwd(_, cons, c, mid, tail, config)
tail = pragma[only_bind_into](tail0) and
readStepFwd(_, cons, c, mid, tail0, config)
)
}
@@ -2520,9 +2539,10 @@ private module Stage4 {
predicate readStepCand(Node node1, Content c, Node node2, Configuration config) {
exists(Ap ap1, Ap ap2 |
revFlow(node2, _, _, ap2, config) and
revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and
readStepFwd(node1, ap1, c, node2, ap2, config) and
revFlowStore(ap1, c, /*unbind*/ ap2, _, _, _, _, _, unbind(config))
revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _,
pragma[only_bind_into](config))
)
}
@@ -2574,7 +2594,9 @@ private module Stage4 {
}
bindingset[conf, result]
private Configuration unbind(Configuration conf) { result >= conf and result <= conf }
private Configuration unbindConf(Configuration conf) {
exists(Configuration c | result = pragma[only_bind_into](c) and conf = pragma[only_bind_into](c))
}
private predicate nodeMayUseSummary(Node n, AccessPathApprox apa, Configuration config) {
exists(DataFlowCallable c, AccessPathApprox apa0 |
@@ -2744,13 +2766,13 @@ private newtype TPathNode =
// ... or a step from an existing PathNode to another node.
exists(PathNodeMid mid |
pathStep(mid, node, cc, sc, ap) and
config = mid.getConfiguration() and
Stage4::revFlow(node, _, _, ap.getApprox(), unbind(config))
pragma[only_bind_into](config) = mid.getConfiguration() and
Stage4::revFlow(node, _, _, ap.getApprox(), pragma[only_bind_into](config))
)
} or
TPathNodeSink(Node node, Configuration config) {
config.isSink(node) and
Stage4::revFlow(node, unbind(config)) and
pragma[only_bind_into](config).isSink(node) and
Stage4::revFlow(node, pragma[only_bind_into](config)) and
(
// A sink that is also a source ...
config.isSource(node)
@@ -2758,7 +2780,7 @@ private newtype TPathNode =
// ... or a sink that can be reached from a source
exists(PathNodeMid mid |
pathStep(mid, node, _, _, TAccessPathNil(_)) and
config = unbind(mid.getConfiguration())
pragma[only_bind_into](config) = mid.getConfiguration()
)
)
}
@@ -3055,7 +3077,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
private PathNodeMid getSuccMid() {
pathStep(this, result.getNode(), result.getCallContext(), result.getSummaryCtx(), result.getAp()) and
result.getConfiguration() = unbind(this.getConfiguration())
result.getConfiguration() = unbindConf(this.getConfiguration())
}
override PathNodeImpl getASuccessorImpl() {
@@ -3067,7 +3089,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
mid = getSuccMid() and
mid.getNode() = sink.getNode() and
mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbind(mid.getConfiguration()) and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
result = sink
)
}
@@ -3298,7 +3320,7 @@ private predicate pathThroughCallable0(
) {
exists(CallContext innercc, SummaryCtx sc |
pathIntoCallable(mid, _, cc, innercc, sc, call) and
paramFlowsThrough(kind, innercc, sc, ap, apa, unbind(mid.getConfiguration()))
paramFlowsThrough(kind, innercc, sc, ap, apa, unbindConf(mid.getConfiguration()))
)
}
@@ -3310,7 +3332,7 @@ pragma[noinline]
private predicate pathThroughCallable(PathNodeMid mid, Node out, CallContext cc, AccessPath ap) {
exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
pathThroughCallable0(call, mid, kind, cc, ap, apa) and
out = getAnOutNodeFlow(kind, call, apa, unbind(mid.getConfiguration()))
out = getAnOutNodeFlow(kind, call, apa, unbindConf(mid.getConfiguration()))
)
}
@@ -3433,8 +3455,8 @@ private module FlowExploration {
private predicate callableExtStepFwd(TCallableExt ce1, TCallableExt ce2) {
exists(DataFlowCallable c1, DataFlowCallable c2, Configuration config |
callableStep(c1, c2, config) and
ce1 = TCallable(c1, config) and
ce2 = TCallable(c2, unbind(config))
ce1 = TCallable(c1, pragma[only_bind_into](config)) and
ce2 = TCallable(c2, pragma[only_bind_into](config))
)
or
exists(Node n, Configuration config |

View File

@@ -444,8 +444,8 @@ private module Stage1 {
// read
exists(Node mid, Content c |
read(node, c, mid) and
fwdFlowConsCand(c, unbind(config)) and
revFlow(mid, toReturn, config)
fwdFlowConsCand(c, pragma[only_bind_into](config)) and
revFlow(mid, toReturn, pragma[only_bind_into](config))
)
or
// flow into a callable
@@ -471,18 +471,18 @@ private module Stage1 {
pragma[nomagic]
private predicate revFlowConsCand(Content c, Configuration config) {
exists(Node mid, Node node |
fwdFlow(node, unbind(config)) and
fwdFlow(node, pragma[only_bind_into](config)) and
read(node, c, mid) and
fwdFlowConsCand(c, unbind(config)) and
revFlow(mid, _, config)
fwdFlowConsCand(c, pragma[only_bind_into](config)) and
revFlow(pragma[only_bind_into](mid), _, pragma[only_bind_into](config))
)
}
pragma[nomagic]
private predicate revFlowStore(Content c, Node node, boolean toReturn, Configuration config) {
exists(Node mid, TypedContent tc |
revFlow(mid, toReturn, config) and
fwdFlowConsCand(c, unbind(config)) and
revFlow(mid, toReturn, pragma[only_bind_into](config)) and
fwdFlowConsCand(c, pragma[only_bind_into](config)) and
store(node, tc, mid, _) and
c = tc.getContent()
)
@@ -552,8 +552,8 @@ private module Stage1 {
Node node1, Ap ap1, TypedContent tc, Node node2, DataFlowType contentType, Configuration config
) {
exists(Content c |
revFlowIsReadAndStored(c, config) and
revFlow(node2, unbind(config)) and
revFlowIsReadAndStored(c, pragma[only_bind_into](config)) and
revFlow(node2, pragma[only_bind_into](config)) and
store(node1, tc, node2, contentType) and
c = tc.getContent() and
exists(ap1)
@@ -562,8 +562,8 @@ private module Stage1 {
pragma[nomagic]
predicate readStepCand(Node n1, Content c, Node n2, Configuration config) {
revFlowIsReadAndStored(c, config) and
revFlow(n2, unbind(config)) and
revFlowIsReadAndStored(c, pragma[only_bind_into](config)) and
revFlow(n2, pragma[only_bind_into](config)) and
read(n1, c, n2)
}
@@ -626,9 +626,6 @@ private module Stage1 {
/* End: Stage 1 logic. */
}
bindingset[result, b]
private boolean unbindBool(boolean b) { result != b.booleanNot() }
pragma[noinline]
private predicate localFlowStepNodeCand1(Node node1, Node node2, Configuration config) {
Stage1::revFlow(node2, config) and
@@ -864,16 +861,16 @@ private module Stage2 {
)
or
exists(Node mid |
fwdFlow(mid, _, _, ap, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
jumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone()
)
or
exists(Node mid, ApNil nil |
fwdFlow(mid, _, _, nil, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
additionalJumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone() and
@@ -1045,9 +1042,9 @@ private module Stage2 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
localStep(node, mid, false, _, config, _) and
revFlow(mid, toReturn, returnAp, nil, config) and
revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and
ap instanceof ApNil
)
or
@@ -1059,9 +1056,9 @@ private module Stage2 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
additionalJumpStep(node, mid, config) and
revFlow(mid, _, _, nil, config) and
revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and
toReturn = false and
returnAp = apNone() and
ap instanceof ApNil
@@ -1114,9 +1111,10 @@ private module Stage2 {
*/
pragma[nomagic]
private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) {
exists(Node mid |
exists(Node mid, Ap tail0 |
revFlow(mid, _, _, tail, config) and
readStepFwd(_, cons, c, mid, tail, config)
tail = pragma[only_bind_into](tail0) and
readStepFwd(_, cons, c, mid, tail0, config)
)
}
@@ -1182,9 +1180,10 @@ private module Stage2 {
predicate readStepCand(Node node1, Content c, Node node2, Configuration config) {
exists(Ap ap1, Ap ap2 |
revFlow(node2, _, _, ap2, config) and
revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and
readStepFwd(node1, ap1, c, node2, ap2, config) and
revFlowStore(ap1, c, /*unbind*/ unbindBool(ap2), _, _, _, _, _, unbind(config))
revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _,
pragma[only_bind_into](config))
)
}
@@ -1240,8 +1239,8 @@ private predicate flowOutOfCallNodeCand2(
DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config
) {
flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
Stage2::revFlow(node2, config) and
Stage2::revFlow(node1, unbind(config))
Stage2::revFlow(node2, pragma[only_bind_into](config)) and
Stage2::revFlow(node1, pragma[only_bind_into](config))
}
pragma[nomagic]
@@ -1250,8 +1249,8 @@ private predicate flowIntoCallNodeCand2(
Configuration config
) {
flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
Stage2::revFlow(node2, config) and
Stage2::revFlow(node1, unbind(config))
Stage2::revFlow(node2, pragma[only_bind_into](config)) and
Stage2::revFlow(node1, pragma[only_bind_into](config))
}
private module LocalFlowBigStep {
@@ -1306,8 +1305,8 @@ private module LocalFlowBigStep {
pragma[noinline]
private predicate additionalLocalFlowStepNodeCand2(Node node1, Node node2, Configuration config) {
additionalLocalFlowStepNodeCand1(node1, node2, config) and
Stage2::revFlow(node1, _, _, false, config) and
Stage2::revFlow(node2, _, _, false, unbind(config))
Stage2::revFlow(node1, _, _, false, pragma[only_bind_into](config)) and
Stage2::revFlow(node2, _, _, false, pragma[only_bind_into](config))
}
/**
@@ -1324,7 +1323,7 @@ private module LocalFlowBigStep {
) {
not isUnreachableInCall(node2, cc.(LocalCallContextSpecificCall).getCall()) and
(
localFlowEntry(node1, config) and
localFlowEntry(node1, pragma[only_bind_into](config)) and
(
localFlowStepNodeCand1(node1, node2, config) and
preservesValue = true and
@@ -1337,22 +1336,22 @@ private module LocalFlowBigStep {
node1 != node2 and
cc.relevantFor(getNodeEnclosingCallable(node1)) and
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
Stage2::revFlow(node2, unbind(config))
Stage2::revFlow(node2, pragma[only_bind_into](config))
or
exists(Node mid |
localFlowStepPlus(node1, mid, preservesValue, t, config, cc) and
localFlowStepPlus(node1, mid, preservesValue, t, pragma[only_bind_into](config), cc) and
localFlowStepNodeCand1(mid, node2, config) and
not mid instanceof FlowCheckNode and
Stage2::revFlow(node2, unbind(config))
Stage2::revFlow(node2, pragma[only_bind_into](config))
)
or
exists(Node mid |
localFlowStepPlus(node1, mid, _, _, config, cc) and
localFlowStepPlus(node1, mid, _, _, pragma[only_bind_into](config), cc) and
additionalLocalFlowStepNodeCand2(mid, node2, config) and
not mid instanceof FlowCheckNode and
preservesValue = false and
t = getNodeType(node2) and
Stage2::revFlow(node2, unbind(config))
Stage2::revFlow(node2, pragma[only_bind_into](config))
)
)
}
@@ -1459,6 +1458,13 @@ private module Stage3 {
PrevStage::revFlow(node, _, _, apa, config)
}
bindingset[result, apa]
private ApApprox unbindApa(ApApprox apa) {
exists(ApApprox apa0 |
apa = pragma[only_bind_into](apa0) and result = pragma[only_bind_into](apa0)
)
}
/**
* Holds if `node` is reachable with access path `ap` from a source in the
* configuration `config`.
@@ -1470,7 +1476,7 @@ private module Stage3 {
pragma[nomagic]
predicate fwdFlow(Node node, Cc cc, ApOption argAp, Ap ap, Configuration config) {
fwdFlow0(node, cc, argAp, ap, config) and
flowCand(node, unbindBool(getApprox(ap)), config) and
flowCand(node, unbindApa(getApprox(ap)), config) and
filter(node, ap)
}
@@ -1494,16 +1500,16 @@ private module Stage3 {
)
or
exists(Node mid |
fwdFlow(mid, _, _, ap, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
jumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone()
)
or
exists(Node mid, ApNil nil |
fwdFlow(mid, _, _, nil, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
additionalJumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone() and
@@ -1548,7 +1554,7 @@ private module Stage3 {
) {
exists(DataFlowType contentType |
fwdFlow(node1, cc, argAp, ap1, config) and
PrevStage::storeStepCand(node1, unbindBool(getApprox(ap1)), tc, node2, contentType, config) and
PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and
typecheckStore(ap1, contentType)
)
}
@@ -1627,7 +1633,7 @@ private module Stage3 {
) {
exists(ParameterNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindBool(getApprox(ap)), config)
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
}
@@ -1675,9 +1681,9 @@ private module Stage3 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
localStep(node, mid, false, _, config, _) and
revFlow(mid, toReturn, returnAp, nil, config) and
revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and
ap instanceof ApNil
)
or
@@ -1689,9 +1695,9 @@ private module Stage3 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
additionalJumpStep(node, mid, config) and
revFlow(mid, _, _, nil, config) and
revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and
toReturn = false and
returnAp = apNone() and
ap instanceof ApNil
@@ -1744,9 +1750,10 @@ private module Stage3 {
*/
pragma[nomagic]
private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) {
exists(Node mid |
exists(Node mid, Ap tail0 |
revFlow(mid, _, _, tail, config) and
readStepFwd(_, cons, c, mid, tail, config)
tail = pragma[only_bind_into](tail0) and
readStepFwd(_, cons, c, mid, tail0, config)
)
}
@@ -1812,9 +1819,10 @@ private module Stage3 {
predicate readStepCand(Node node1, Content c, Node node2, Configuration config) {
exists(Ap ap1, Ap ap2 |
revFlow(node2, _, _, ap2, config) and
revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and
readStepFwd(node1, ap1, c, node2, ap2, config) and
revFlowStore(ap1, c, /*unbind*/ ap2, _, _, _, _, _, unbind(config))
revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _,
pragma[only_bind_into](config))
)
}
@@ -2125,8 +2133,11 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
localFlowEntry(node, config) and
result = getLocalCallContext(cc, getNodeEnclosingCallable(node))
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
}
private predicate localStep(
@@ -2141,8 +2152,8 @@ private module Stage4 {
Configuration config
) {
flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
PrevStage::revFlow(node2, _, _, _, config) and
PrevStage::revFlow(node1, _, _, _, unbind(config))
PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and
PrevStage::revFlow(node1, _, _, _, pragma[only_bind_into](config))
}
pragma[nomagic]
@@ -2151,8 +2162,8 @@ private module Stage4 {
Configuration config
) {
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
PrevStage::revFlow(node2, _, _, _, config) and
PrevStage::revFlow(node1, _, _, _, unbind(config))
PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and
PrevStage::revFlow(node1, _, _, _, pragma[only_bind_into](config))
}
bindingset[node, ap]
@@ -2167,6 +2178,13 @@ private module Stage4 {
PrevStage::revFlow(node, _, _, apa, config)
}
bindingset[result, apa]
private ApApprox unbindApa(ApApprox apa) {
exists(ApApprox apa0 |
apa = pragma[only_bind_into](apa0) and result = pragma[only_bind_into](apa0)
)
}
/**
* Holds if `node` is reachable with access path `ap` from a source in the
* configuration `config`.
@@ -2178,7 +2196,7 @@ private module Stage4 {
pragma[nomagic]
predicate fwdFlow(Node node, Cc cc, ApOption argAp, Ap ap, Configuration config) {
fwdFlow0(node, cc, argAp, ap, config) and
flowCand(node, getApprox(ap), config) and
flowCand(node, unbindApa(getApprox(ap)), config) and
filter(node, ap)
}
@@ -2202,16 +2220,16 @@ private module Stage4 {
)
or
exists(Node mid |
fwdFlow(mid, _, _, ap, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
jumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone()
)
or
exists(Node mid, ApNil nil |
fwdFlow(mid, _, _, nil, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
additionalJumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone() and
@@ -2256,7 +2274,7 @@ private module Stage4 {
) {
exists(DataFlowType contentType |
fwdFlow(node1, cc, argAp, ap1, config) and
PrevStage::storeStepCand(node1, getApprox(ap1), tc, node2, contentType, config) and
PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and
typecheckStore(ap1, contentType)
)
}
@@ -2335,7 +2353,7 @@ private module Stage4 {
) {
exists(ParameterNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, getApprox(ap), config)
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
}
@@ -2383,9 +2401,9 @@ private module Stage4 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
localStep(node, mid, false, _, config, _) and
revFlow(mid, toReturn, returnAp, nil, config) and
revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and
ap instanceof ApNil
)
or
@@ -2397,9 +2415,9 @@ private module Stage4 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
additionalJumpStep(node, mid, config) and
revFlow(mid, _, _, nil, config) and
revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and
toReturn = false and
returnAp = apNone() and
ap instanceof ApNil
@@ -2452,9 +2470,10 @@ private module Stage4 {
*/
pragma[nomagic]
private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) {
exists(Node mid |
exists(Node mid, Ap tail0 |
revFlow(mid, _, _, tail, config) and
readStepFwd(_, cons, c, mid, tail, config)
tail = pragma[only_bind_into](tail0) and
readStepFwd(_, cons, c, mid, tail0, config)
)
}
@@ -2520,9 +2539,10 @@ private module Stage4 {
predicate readStepCand(Node node1, Content c, Node node2, Configuration config) {
exists(Ap ap1, Ap ap2 |
revFlow(node2, _, _, ap2, config) and
revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and
readStepFwd(node1, ap1, c, node2, ap2, config) and
revFlowStore(ap1, c, /*unbind*/ ap2, _, _, _, _, _, unbind(config))
revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _,
pragma[only_bind_into](config))
)
}
@@ -2574,7 +2594,9 @@ private module Stage4 {
}
bindingset[conf, result]
private Configuration unbind(Configuration conf) { result >= conf and result <= conf }
private Configuration unbindConf(Configuration conf) {
exists(Configuration c | result = pragma[only_bind_into](c) and conf = pragma[only_bind_into](c))
}
private predicate nodeMayUseSummary(Node n, AccessPathApprox apa, Configuration config) {
exists(DataFlowCallable c, AccessPathApprox apa0 |
@@ -2744,13 +2766,13 @@ private newtype TPathNode =
// ... or a step from an existing PathNode to another node.
exists(PathNodeMid mid |
pathStep(mid, node, cc, sc, ap) and
config = mid.getConfiguration() and
Stage4::revFlow(node, _, _, ap.getApprox(), unbind(config))
pragma[only_bind_into](config) = mid.getConfiguration() and
Stage4::revFlow(node, _, _, ap.getApprox(), pragma[only_bind_into](config))
)
} or
TPathNodeSink(Node node, Configuration config) {
config.isSink(node) and
Stage4::revFlow(node, unbind(config)) and
pragma[only_bind_into](config).isSink(node) and
Stage4::revFlow(node, pragma[only_bind_into](config)) and
(
// A sink that is also a source ...
config.isSource(node)
@@ -2758,7 +2780,7 @@ private newtype TPathNode =
// ... or a sink that can be reached from a source
exists(PathNodeMid mid |
pathStep(mid, node, _, _, TAccessPathNil(_)) and
config = unbind(mid.getConfiguration())
pragma[only_bind_into](config) = mid.getConfiguration()
)
)
}
@@ -3055,7 +3077,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
private PathNodeMid getSuccMid() {
pathStep(this, result.getNode(), result.getCallContext(), result.getSummaryCtx(), result.getAp()) and
result.getConfiguration() = unbind(this.getConfiguration())
result.getConfiguration() = unbindConf(this.getConfiguration())
}
override PathNodeImpl getASuccessorImpl() {
@@ -3067,7 +3089,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
mid = getSuccMid() and
mid.getNode() = sink.getNode() and
mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbind(mid.getConfiguration()) and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
result = sink
)
}
@@ -3298,7 +3320,7 @@ private predicate pathThroughCallable0(
) {
exists(CallContext innercc, SummaryCtx sc |
pathIntoCallable(mid, _, cc, innercc, sc, call) and
paramFlowsThrough(kind, innercc, sc, ap, apa, unbind(mid.getConfiguration()))
paramFlowsThrough(kind, innercc, sc, ap, apa, unbindConf(mid.getConfiguration()))
)
}
@@ -3310,7 +3332,7 @@ pragma[noinline]
private predicate pathThroughCallable(PathNodeMid mid, Node out, CallContext cc, AccessPath ap) {
exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
pathThroughCallable0(call, mid, kind, cc, ap, apa) and
out = getAnOutNodeFlow(kind, call, apa, unbind(mid.getConfiguration()))
out = getAnOutNodeFlow(kind, call, apa, unbindConf(mid.getConfiguration()))
)
}
@@ -3433,8 +3455,8 @@ private module FlowExploration {
private predicate callableExtStepFwd(TCallableExt ce1, TCallableExt ce2) {
exists(DataFlowCallable c1, DataFlowCallable c2, Configuration config |
callableStep(c1, c2, config) and
ce1 = TCallable(c1, config) and
ce2 = TCallable(c2, unbind(config))
ce1 = TCallable(c1, pragma[only_bind_into](config)) and
ce2 = TCallable(c2, pragma[only_bind_into](config))
)
or
exists(Node n, Configuration config |

View File

@@ -444,8 +444,8 @@ private module Stage1 {
// read
exists(Node mid, Content c |
read(node, c, mid) and
fwdFlowConsCand(c, unbind(config)) and
revFlow(mid, toReturn, config)
fwdFlowConsCand(c, pragma[only_bind_into](config)) and
revFlow(mid, toReturn, pragma[only_bind_into](config))
)
or
// flow into a callable
@@ -471,18 +471,18 @@ private module Stage1 {
pragma[nomagic]
private predicate revFlowConsCand(Content c, Configuration config) {
exists(Node mid, Node node |
fwdFlow(node, unbind(config)) and
fwdFlow(node, pragma[only_bind_into](config)) and
read(node, c, mid) and
fwdFlowConsCand(c, unbind(config)) and
revFlow(mid, _, config)
fwdFlowConsCand(c, pragma[only_bind_into](config)) and
revFlow(pragma[only_bind_into](mid), _, pragma[only_bind_into](config))
)
}
pragma[nomagic]
private predicate revFlowStore(Content c, Node node, boolean toReturn, Configuration config) {
exists(Node mid, TypedContent tc |
revFlow(mid, toReturn, config) and
fwdFlowConsCand(c, unbind(config)) and
revFlow(mid, toReturn, pragma[only_bind_into](config)) and
fwdFlowConsCand(c, pragma[only_bind_into](config)) and
store(node, tc, mid, _) and
c = tc.getContent()
)
@@ -552,8 +552,8 @@ private module Stage1 {
Node node1, Ap ap1, TypedContent tc, Node node2, DataFlowType contentType, Configuration config
) {
exists(Content c |
revFlowIsReadAndStored(c, config) and
revFlow(node2, unbind(config)) and
revFlowIsReadAndStored(c, pragma[only_bind_into](config)) and
revFlow(node2, pragma[only_bind_into](config)) and
store(node1, tc, node2, contentType) and
c = tc.getContent() and
exists(ap1)
@@ -562,8 +562,8 @@ private module Stage1 {
pragma[nomagic]
predicate readStepCand(Node n1, Content c, Node n2, Configuration config) {
revFlowIsReadAndStored(c, config) and
revFlow(n2, unbind(config)) and
revFlowIsReadAndStored(c, pragma[only_bind_into](config)) and
revFlow(n2, pragma[only_bind_into](config)) and
read(n1, c, n2)
}
@@ -626,9 +626,6 @@ private module Stage1 {
/* End: Stage 1 logic. */
}
bindingset[result, b]
private boolean unbindBool(boolean b) { result != b.booleanNot() }
pragma[noinline]
private predicate localFlowStepNodeCand1(Node node1, Node node2, Configuration config) {
Stage1::revFlow(node2, config) and
@@ -864,16 +861,16 @@ private module Stage2 {
)
or
exists(Node mid |
fwdFlow(mid, _, _, ap, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
jumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone()
)
or
exists(Node mid, ApNil nil |
fwdFlow(mid, _, _, nil, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
additionalJumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone() and
@@ -1045,9 +1042,9 @@ private module Stage2 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
localStep(node, mid, false, _, config, _) and
revFlow(mid, toReturn, returnAp, nil, config) and
revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and
ap instanceof ApNil
)
or
@@ -1059,9 +1056,9 @@ private module Stage2 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
additionalJumpStep(node, mid, config) and
revFlow(mid, _, _, nil, config) and
revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and
toReturn = false and
returnAp = apNone() and
ap instanceof ApNil
@@ -1114,9 +1111,10 @@ private module Stage2 {
*/
pragma[nomagic]
private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) {
exists(Node mid |
exists(Node mid, Ap tail0 |
revFlow(mid, _, _, tail, config) and
readStepFwd(_, cons, c, mid, tail, config)
tail = pragma[only_bind_into](tail0) and
readStepFwd(_, cons, c, mid, tail0, config)
)
}
@@ -1182,9 +1180,10 @@ private module Stage2 {
predicate readStepCand(Node node1, Content c, Node node2, Configuration config) {
exists(Ap ap1, Ap ap2 |
revFlow(node2, _, _, ap2, config) and
revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and
readStepFwd(node1, ap1, c, node2, ap2, config) and
revFlowStore(ap1, c, /*unbind*/ unbindBool(ap2), _, _, _, _, _, unbind(config))
revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _,
pragma[only_bind_into](config))
)
}
@@ -1240,8 +1239,8 @@ private predicate flowOutOfCallNodeCand2(
DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config
) {
flowOutOfCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
Stage2::revFlow(node2, config) and
Stage2::revFlow(node1, unbind(config))
Stage2::revFlow(node2, pragma[only_bind_into](config)) and
Stage2::revFlow(node1, pragma[only_bind_into](config))
}
pragma[nomagic]
@@ -1250,8 +1249,8 @@ private predicate flowIntoCallNodeCand2(
Configuration config
) {
flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
Stage2::revFlow(node2, config) and
Stage2::revFlow(node1, unbind(config))
Stage2::revFlow(node2, pragma[only_bind_into](config)) and
Stage2::revFlow(node1, pragma[only_bind_into](config))
}
private module LocalFlowBigStep {
@@ -1306,8 +1305,8 @@ private module LocalFlowBigStep {
pragma[noinline]
private predicate additionalLocalFlowStepNodeCand2(Node node1, Node node2, Configuration config) {
additionalLocalFlowStepNodeCand1(node1, node2, config) and
Stage2::revFlow(node1, _, _, false, config) and
Stage2::revFlow(node2, _, _, false, unbind(config))
Stage2::revFlow(node1, _, _, false, pragma[only_bind_into](config)) and
Stage2::revFlow(node2, _, _, false, pragma[only_bind_into](config))
}
/**
@@ -1324,7 +1323,7 @@ private module LocalFlowBigStep {
) {
not isUnreachableInCall(node2, cc.(LocalCallContextSpecificCall).getCall()) and
(
localFlowEntry(node1, config) and
localFlowEntry(node1, pragma[only_bind_into](config)) and
(
localFlowStepNodeCand1(node1, node2, config) and
preservesValue = true and
@@ -1337,22 +1336,22 @@ private module LocalFlowBigStep {
node1 != node2 and
cc.relevantFor(getNodeEnclosingCallable(node1)) and
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
Stage2::revFlow(node2, unbind(config))
Stage2::revFlow(node2, pragma[only_bind_into](config))
or
exists(Node mid |
localFlowStepPlus(node1, mid, preservesValue, t, config, cc) and
localFlowStepPlus(node1, mid, preservesValue, t, pragma[only_bind_into](config), cc) and
localFlowStepNodeCand1(mid, node2, config) and
not mid instanceof FlowCheckNode and
Stage2::revFlow(node2, unbind(config))
Stage2::revFlow(node2, pragma[only_bind_into](config))
)
or
exists(Node mid |
localFlowStepPlus(node1, mid, _, _, config, cc) and
localFlowStepPlus(node1, mid, _, _, pragma[only_bind_into](config), cc) and
additionalLocalFlowStepNodeCand2(mid, node2, config) and
not mid instanceof FlowCheckNode and
preservesValue = false and
t = getNodeType(node2) and
Stage2::revFlow(node2, unbind(config))
Stage2::revFlow(node2, pragma[only_bind_into](config))
)
)
}
@@ -1459,6 +1458,13 @@ private module Stage3 {
PrevStage::revFlow(node, _, _, apa, config)
}
bindingset[result, apa]
private ApApprox unbindApa(ApApprox apa) {
exists(ApApprox apa0 |
apa = pragma[only_bind_into](apa0) and result = pragma[only_bind_into](apa0)
)
}
/**
* Holds if `node` is reachable with access path `ap` from a source in the
* configuration `config`.
@@ -1470,7 +1476,7 @@ private module Stage3 {
pragma[nomagic]
predicate fwdFlow(Node node, Cc cc, ApOption argAp, Ap ap, Configuration config) {
fwdFlow0(node, cc, argAp, ap, config) and
flowCand(node, unbindBool(getApprox(ap)), config) and
flowCand(node, unbindApa(getApprox(ap)), config) and
filter(node, ap)
}
@@ -1494,16 +1500,16 @@ private module Stage3 {
)
or
exists(Node mid |
fwdFlow(mid, _, _, ap, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
jumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone()
)
or
exists(Node mid, ApNil nil |
fwdFlow(mid, _, _, nil, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
additionalJumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone() and
@@ -1548,7 +1554,7 @@ private module Stage3 {
) {
exists(DataFlowType contentType |
fwdFlow(node1, cc, argAp, ap1, config) and
PrevStage::storeStepCand(node1, unbindBool(getApprox(ap1)), tc, node2, contentType, config) and
PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and
typecheckStore(ap1, contentType)
)
}
@@ -1627,7 +1633,7 @@ private module Stage3 {
) {
exists(ParameterNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, unbindBool(getApprox(ap)), config)
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
}
@@ -1675,9 +1681,9 @@ private module Stage3 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
localStep(node, mid, false, _, config, _) and
revFlow(mid, toReturn, returnAp, nil, config) and
revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and
ap instanceof ApNil
)
or
@@ -1689,9 +1695,9 @@ private module Stage3 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
additionalJumpStep(node, mid, config) and
revFlow(mid, _, _, nil, config) and
revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and
toReturn = false and
returnAp = apNone() and
ap instanceof ApNil
@@ -1744,9 +1750,10 @@ private module Stage3 {
*/
pragma[nomagic]
private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) {
exists(Node mid |
exists(Node mid, Ap tail0 |
revFlow(mid, _, _, tail, config) and
readStepFwd(_, cons, c, mid, tail, config)
tail = pragma[only_bind_into](tail0) and
readStepFwd(_, cons, c, mid, tail0, config)
)
}
@@ -1812,9 +1819,10 @@ private module Stage3 {
predicate readStepCand(Node node1, Content c, Node node2, Configuration config) {
exists(Ap ap1, Ap ap2 |
revFlow(node2, _, _, ap2, config) and
revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and
readStepFwd(node1, ap1, c, node2, ap2, config) and
revFlowStore(ap1, c, /*unbind*/ ap2, _, _, _, _, _, unbind(config))
revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _,
pragma[only_bind_into](config))
)
}
@@ -2125,8 +2133,11 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
localFlowEntry(node, config) and
result = getLocalCallContext(cc, getNodeEnclosingCallable(node))
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
}
private predicate localStep(
@@ -2141,8 +2152,8 @@ private module Stage4 {
Configuration config
) {
flowOutOfCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
PrevStage::revFlow(node2, _, _, _, config) and
PrevStage::revFlow(node1, _, _, _, unbind(config))
PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and
PrevStage::revFlow(node1, _, _, _, pragma[only_bind_into](config))
}
pragma[nomagic]
@@ -2151,8 +2162,8 @@ private module Stage4 {
Configuration config
) {
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
PrevStage::revFlow(node2, _, _, _, config) and
PrevStage::revFlow(node1, _, _, _, unbind(config))
PrevStage::revFlow(node2, _, _, _, pragma[only_bind_into](config)) and
PrevStage::revFlow(node1, _, _, _, pragma[only_bind_into](config))
}
bindingset[node, ap]
@@ -2167,6 +2178,13 @@ private module Stage4 {
PrevStage::revFlow(node, _, _, apa, config)
}
bindingset[result, apa]
private ApApprox unbindApa(ApApprox apa) {
exists(ApApprox apa0 |
apa = pragma[only_bind_into](apa0) and result = pragma[only_bind_into](apa0)
)
}
/**
* Holds if `node` is reachable with access path `ap` from a source in the
* configuration `config`.
@@ -2178,7 +2196,7 @@ private module Stage4 {
pragma[nomagic]
predicate fwdFlow(Node node, Cc cc, ApOption argAp, Ap ap, Configuration config) {
fwdFlow0(node, cc, argAp, ap, config) and
flowCand(node, getApprox(ap), config) and
flowCand(node, unbindApa(getApprox(ap)), config) and
filter(node, ap)
}
@@ -2202,16 +2220,16 @@ private module Stage4 {
)
or
exists(Node mid |
fwdFlow(mid, _, _, ap, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, ap, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
jumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone()
)
or
exists(Node mid, ApNil nil |
fwdFlow(mid, _, _, nil, config) and
flowCand(node, _, unbind(config)) and
fwdFlow(mid, _, _, nil, pragma[only_bind_into](config)) and
flowCand(node, _, pragma[only_bind_into](config)) and
additionalJumpStep(mid, node, config) and
cc = ccNone() and
argAp = apNone() and
@@ -2256,7 +2274,7 @@ private module Stage4 {
) {
exists(DataFlowType contentType |
fwdFlow(node1, cc, argAp, ap1, config) and
PrevStage::storeStepCand(node1, getApprox(ap1), tc, node2, contentType, config) and
PrevStage::storeStepCand(node1, unbindApa(getApprox(ap1)), tc, node2, contentType, config) and
typecheckStore(ap1, contentType)
)
}
@@ -2335,7 +2353,7 @@ private module Stage4 {
) {
exists(ParameterNode p |
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
PrevStage::parameterMayFlowThrough(p, _, getApprox(ap), config)
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
)
}
@@ -2383,9 +2401,9 @@ private module Stage4 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
localStep(node, mid, false, _, config, _) and
revFlow(mid, toReturn, returnAp, nil, config) and
revFlow(mid, toReturn, returnAp, nil, pragma[only_bind_into](config)) and
ap instanceof ApNil
)
or
@@ -2397,9 +2415,9 @@ private module Stage4 {
)
or
exists(Node mid, ApNil nil |
fwdFlow(node, _, _, ap, config) and
fwdFlow(node, _, _, ap, pragma[only_bind_into](config)) and
additionalJumpStep(node, mid, config) and
revFlow(mid, _, _, nil, config) and
revFlow(pragma[only_bind_into](mid), _, _, nil, pragma[only_bind_into](config)) and
toReturn = false and
returnAp = apNone() and
ap instanceof ApNil
@@ -2452,9 +2470,10 @@ private module Stage4 {
*/
pragma[nomagic]
private predicate revFlowConsCand(Ap cons, Content c, Ap tail, Configuration config) {
exists(Node mid |
exists(Node mid, Ap tail0 |
revFlow(mid, _, _, tail, config) and
readStepFwd(_, cons, c, mid, tail, config)
tail = pragma[only_bind_into](tail0) and
readStepFwd(_, cons, c, mid, tail0, config)
)
}
@@ -2520,9 +2539,10 @@ private module Stage4 {
predicate readStepCand(Node node1, Content c, Node node2, Configuration config) {
exists(Ap ap1, Ap ap2 |
revFlow(node2, _, _, ap2, config) and
revFlow(node2, _, _, pragma[only_bind_into](ap2), pragma[only_bind_into](config)) and
readStepFwd(node1, ap1, c, node2, ap2, config) and
revFlowStore(ap1, c, /*unbind*/ ap2, _, _, _, _, _, unbind(config))
revFlowStore(ap1, c, pragma[only_bind_into](ap2), _, _, _, _, _,
pragma[only_bind_into](config))
)
}
@@ -2574,7 +2594,9 @@ private module Stage4 {
}
bindingset[conf, result]
private Configuration unbind(Configuration conf) { result >= conf and result <= conf }
private Configuration unbindConf(Configuration conf) {
exists(Configuration c | result = pragma[only_bind_into](c) and conf = pragma[only_bind_into](c))
}
private predicate nodeMayUseSummary(Node n, AccessPathApprox apa, Configuration config) {
exists(DataFlowCallable c, AccessPathApprox apa0 |
@@ -2744,13 +2766,13 @@ private newtype TPathNode =
// ... or a step from an existing PathNode to another node.
exists(PathNodeMid mid |
pathStep(mid, node, cc, sc, ap) and
config = mid.getConfiguration() and
Stage4::revFlow(node, _, _, ap.getApprox(), unbind(config))
pragma[only_bind_into](config) = mid.getConfiguration() and
Stage4::revFlow(node, _, _, ap.getApprox(), pragma[only_bind_into](config))
)
} or
TPathNodeSink(Node node, Configuration config) {
config.isSink(node) and
Stage4::revFlow(node, unbind(config)) and
pragma[only_bind_into](config).isSink(node) and
Stage4::revFlow(node, pragma[only_bind_into](config)) and
(
// A sink that is also a source ...
config.isSource(node)
@@ -2758,7 +2780,7 @@ private newtype TPathNode =
// ... or a sink that can be reached from a source
exists(PathNodeMid mid |
pathStep(mid, node, _, _, TAccessPathNil(_)) and
config = unbind(mid.getConfiguration())
pragma[only_bind_into](config) = mid.getConfiguration()
)
)
}
@@ -3055,7 +3077,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
private PathNodeMid getSuccMid() {
pathStep(this, result.getNode(), result.getCallContext(), result.getSummaryCtx(), result.getAp()) and
result.getConfiguration() = unbind(this.getConfiguration())
result.getConfiguration() = unbindConf(this.getConfiguration())
}
override PathNodeImpl getASuccessorImpl() {
@@ -3067,7 +3089,7 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
mid = getSuccMid() and
mid.getNode() = sink.getNode() and
mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbind(mid.getConfiguration()) and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
result = sink
)
}
@@ -3298,7 +3320,7 @@ private predicate pathThroughCallable0(
) {
exists(CallContext innercc, SummaryCtx sc |
pathIntoCallable(mid, _, cc, innercc, sc, call) and
paramFlowsThrough(kind, innercc, sc, ap, apa, unbind(mid.getConfiguration()))
paramFlowsThrough(kind, innercc, sc, ap, apa, unbindConf(mid.getConfiguration()))
)
}
@@ -3310,7 +3332,7 @@ pragma[noinline]
private predicate pathThroughCallable(PathNodeMid mid, Node out, CallContext cc, AccessPath ap) {
exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
pathThroughCallable0(call, mid, kind, cc, ap, apa) and
out = getAnOutNodeFlow(kind, call, apa, unbind(mid.getConfiguration()))
out = getAnOutNodeFlow(kind, call, apa, unbindConf(mid.getConfiguration()))
)
}
@@ -3433,8 +3455,8 @@ private module FlowExploration {
private predicate callableExtStepFwd(TCallableExt ce1, TCallableExt ce2) {
exists(DataFlowCallable c1, DataFlowCallable c2, Configuration config |
callableStep(c1, c2, config) and
ce1 = TCallable(c1, config) and
ce2 = TCallable(c2, unbind(config))
ce1 = TCallable(c1, pragma[only_bind_into](config)) and
ce2 = TCallable(c2, pragma[only_bind_into](config))
)
or
exists(Node n, Configuration config |