mirror of
https://github.com/github/codeql.git
synced 2026-04-26 01:05:15 +02:00
Data flow: Sync files
This commit is contained in:
@@ -211,10 +211,7 @@ private predicate fullBarrier(Node node, Configuration config) {
|
||||
* Holds if data can flow in one local step from `node1` to `node2`.
|
||||
*/
|
||||
private predicate localFlowStep(Node node1, Node node2, Configuration config) {
|
||||
(
|
||||
simpleLocalFlowStep(node1, node2) or
|
||||
reverseStepThroughInputOutputAlias(node1, node2)
|
||||
) and
|
||||
simpleLocalFlowStepExt(node1, node2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
@@ -237,7 +234,7 @@ private predicate additionalLocalFlowStep(Node node1, Node node2, Configuration
|
||||
* Holds if data can flow from `node1` to `node2` in a way that discards call contexts.
|
||||
*/
|
||||
private predicate jumpStep(Node node1, Node node2, Configuration config) {
|
||||
jumpStep(node1, node2) and
|
||||
jumpStepCached(node1, node2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
@@ -388,7 +385,7 @@ private module Stage1 {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
|
||||
exists(ArgumentNode arg |
|
||||
exists(ArgumentNodeExt arg |
|
||||
fwdFlow(arg, cc, config) and
|
||||
viableParamArg(call, _, arg)
|
||||
)
|
||||
@@ -515,7 +512,7 @@ private module Stage1 {
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
|
||||
DataFlowCall call, ParameterNodeExt p, ArgumentNodeExt arg, Configuration config
|
||||
) {
|
||||
viableParamArg(call, p, arg) and
|
||||
fwdFlow(arg, config)
|
||||
@@ -523,16 +520,16 @@ private module Stage1 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIn(
|
||||
DataFlowCall call, ArgumentNode arg, boolean toReturn, Configuration config
|
||||
DataFlowCall call, ArgumentNodeExt arg, boolean toReturn, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
revFlow(p, toReturn, config) and
|
||||
viableParamArgNodeCandFwd1(call, p, arg, config)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(DataFlowCall call, ArgumentNode arg, Configuration config) {
|
||||
private predicate revFlowInToReturn(DataFlowCall call, ArgumentNodeExt arg, Configuration config) {
|
||||
revFlowIn(call, arg, true, config)
|
||||
}
|
||||
|
||||
@@ -597,7 +594,9 @@ private module Stage1 {
|
||||
* Holds if flow may enter through `p` and reach a return node making `p` a
|
||||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
predicate parameterMayFlowThrough(
|
||||
ParameterNodeExt p, DataFlowCallable c, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
@@ -663,7 +662,7 @@ private predicate flowOutOfCallNodeCand1(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate viableParamArgNodeCand1(
|
||||
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
|
||||
DataFlowCall call, ParameterNodeExt p, ArgumentNodeExt arg, Configuration config
|
||||
) {
|
||||
Stage1::viableParamArgNodeCandFwd1(call, p, arg, config) and
|
||||
Stage1::revFlow(arg, config)
|
||||
@@ -675,7 +674,7 @@ private predicate viableParamArgNodeCand1(
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate flowIntoCallNodeCand1(
|
||||
DataFlowCall call, ArgumentNode arg, ParameterNode p, Configuration config
|
||||
DataFlowCall call, ArgumentNodeExt arg, ParameterNodeExt p, Configuration config
|
||||
) {
|
||||
viableParamArgNodeCand1(call, p, arg, config) and
|
||||
Stage1::revFlow(p, config) and
|
||||
@@ -735,7 +734,7 @@ private predicate flowOutOfCallNodeCand1(
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate flowIntoCallNodeCand1(
|
||||
DataFlowCall call, ArgumentNode arg, ParameterNode p, boolean allowsFieldFlow,
|
||||
DataFlowCall call, ArgumentNodeExt arg, ParameterNodeExt p, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowIntoCallNodeCand1(call, arg, p, config) and
|
||||
@@ -944,10 +943,10 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
DataFlowCall call, ParameterNodeExt p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ArgumentNode arg, boolean allowsFieldFlow |
|
||||
exists(ArgumentNodeExt arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
|
||||
@@ -992,7 +991,7 @@ private module Stage2 {
|
||||
private predicate fwdFlowIsEntered(
|
||||
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
|
||||
PrevStage::parameterMayFlowThrough(p, _, getApprox(ap), config)
|
||||
)
|
||||
@@ -1133,10 +1132,10 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIn(
|
||||
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
DataFlowCall call, ArgumentNodeExt arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ParameterNode p, boolean allowsFieldFlow |
|
||||
exists(ParameterNodeExt p, boolean allowsFieldFlow |
|
||||
revFlow(p, toReturn, returnAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
@@ -1146,7 +1145,7 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(
|
||||
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
|
||||
DataFlowCall call, ArgumentNodeExt arg, Ap returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
|
||||
}
|
||||
@@ -1199,13 +1198,15 @@ private module Stage2 {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate parameterFlow(
|
||||
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
ParameterNodeExt p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
) {
|
||||
revFlow(p, true, apSome(ap0), ap, config) and
|
||||
c = getNodeEnclosingCallable(p)
|
||||
}
|
||||
|
||||
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
predicate parameterMayFlowThrough(
|
||||
ParameterNodeExt p, DataFlowCallable c, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
|
||||
parameterFlow(p, ap, ap0, c, config) and
|
||||
c = getNodeEnclosingCallable(ret) and
|
||||
@@ -1245,7 +1246,7 @@ private predicate flowOutOfCallNodeCand2(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowIntoCallNodeCand2(
|
||||
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
|
||||
DataFlowCall call, ArgumentNodeExt node1, ParameterNodeExt node2, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
|
||||
@@ -1260,8 +1261,8 @@ private module LocalFlowBigStep {
|
||||
*/
|
||||
private class FlowCheckNode extends Node {
|
||||
FlowCheckNode() {
|
||||
this instanceof CastNode or
|
||||
clearsContent(this, _)
|
||||
castNode(this) or
|
||||
clearsContentCached(this, _)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1275,7 +1276,7 @@ private module LocalFlowBigStep {
|
||||
config.isSource(node) or
|
||||
jumpStep(_, node, config) or
|
||||
additionalJumpStep(_, node, config) or
|
||||
node instanceof ParameterNode or
|
||||
node instanceof ParameterNodeExt or
|
||||
node instanceof OutNodeExt or
|
||||
store(_, _, node, _) or
|
||||
read(_, _, node) or
|
||||
@@ -1321,21 +1322,21 @@ private module LocalFlowBigStep {
|
||||
Node node1, Node node2, boolean preservesValue, DataFlowType t, Configuration config,
|
||||
LocalCallContext cc
|
||||
) {
|
||||
not isUnreachableInCall(node2, cc.(LocalCallContextSpecificCall).getCall()) and
|
||||
not isUnreachableInCallCached(node2, cc.(LocalCallContextSpecificCall).getCall()) and
|
||||
(
|
||||
localFlowEntry(node1, pragma[only_bind_into](config)) and
|
||||
(
|
||||
localFlowStepNodeCand1(node1, node2, config) and
|
||||
preservesValue = true and
|
||||
t = getNodeType(node1)
|
||||
t = getNodeDataFlowType(node1)
|
||||
or
|
||||
additionalLocalFlowStepNodeCand2(node1, node2, config) and
|
||||
preservesValue = false and
|
||||
t = getNodeType(node2)
|
||||
t = getNodeDataFlowType(node2)
|
||||
) and
|
||||
node1 != node2 and
|
||||
cc.relevantFor(getNodeEnclosingCallable(node1)) and
|
||||
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
|
||||
not isUnreachableInCallCached(node1, cc.(LocalCallContextSpecificCall).getCall()) and
|
||||
Stage2::revFlow(node2, pragma[only_bind_into](config))
|
||||
or
|
||||
exists(Node mid |
|
||||
@@ -1350,7 +1351,7 @@ private module LocalFlowBigStep {
|
||||
additionalLocalFlowStepNodeCand2(mid, node2, config) and
|
||||
not mid instanceof FlowCheckNode and
|
||||
preservesValue = false and
|
||||
t = getNodeType(node2) and
|
||||
t = getNodeDataFlowType(node2) and
|
||||
Stage2::revFlow(node2, pragma[only_bind_into](config))
|
||||
)
|
||||
)
|
||||
@@ -1384,7 +1385,7 @@ private module Stage3 {
|
||||
private ApApprox getApprox(Ap ap) { result = ap.toBoolNonEmpty() }
|
||||
|
||||
private ApNil getApNil(Node node) {
|
||||
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeType(node))
|
||||
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeDataFlowType(node))
|
||||
}
|
||||
|
||||
bindingset[tc, tail]
|
||||
@@ -1443,7 +1444,9 @@ private module Stage3 {
|
||||
bindingset[node, ap]
|
||||
private predicate filter(Node node, Ap ap) {
|
||||
not ap.isClearedAt(node) and
|
||||
if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
|
||||
else any()
|
||||
}
|
||||
|
||||
bindingset[ap, contentType]
|
||||
@@ -1583,10 +1586,10 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
DataFlowCall call, ParameterNodeExt p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ArgumentNode arg, boolean allowsFieldFlow |
|
||||
exists(ArgumentNodeExt arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
|
||||
@@ -1631,7 +1634,7 @@ private module Stage3 {
|
||||
private predicate fwdFlowIsEntered(
|
||||
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
|
||||
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
|
||||
)
|
||||
@@ -1772,10 +1775,10 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIn(
|
||||
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
DataFlowCall call, ArgumentNodeExt arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ParameterNode p, boolean allowsFieldFlow |
|
||||
exists(ParameterNodeExt p, boolean allowsFieldFlow |
|
||||
revFlow(p, toReturn, returnAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
@@ -1785,7 +1788,7 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(
|
||||
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
|
||||
DataFlowCall call, ArgumentNodeExt arg, Ap returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
|
||||
}
|
||||
@@ -1838,13 +1841,15 @@ private module Stage3 {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate parameterFlow(
|
||||
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
ParameterNodeExt p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
) {
|
||||
revFlow(p, true, apSome(ap0), ap, config) and
|
||||
c = getNodeEnclosingCallable(p)
|
||||
}
|
||||
|
||||
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
predicate parameterMayFlowThrough(
|
||||
ParameterNodeExt p, DataFlowCallable c, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
|
||||
parameterFlow(p, ap, ap0, c, config) and
|
||||
c = getNodeEnclosingCallable(ret) and
|
||||
@@ -2088,7 +2093,7 @@ private module Stage4 {
|
||||
private ApApprox getApprox(Ap ap) { result = ap.getFront() }
|
||||
|
||||
private ApNil getApNil(Node node) {
|
||||
PrevStage::revFlow(node, _) and result = TNil(getNodeType(node))
|
||||
PrevStage::revFlow(node, _) and result = TNil(getNodeDataFlowType(node))
|
||||
}
|
||||
|
||||
bindingset[tc, tail]
|
||||
@@ -2155,7 +2160,7 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowIntoCall(
|
||||
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
|
||||
DataFlowCall call, ArgumentNodeExt node1, ParameterNodeExt node2, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
|
||||
@@ -2300,10 +2305,10 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
DataFlowCall call, ParameterNodeExt p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ArgumentNode arg, boolean allowsFieldFlow |
|
||||
exists(ArgumentNodeExt arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
|
||||
@@ -2348,7 +2353,7 @@ private module Stage4 {
|
||||
private predicate fwdFlowIsEntered(
|
||||
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
|
||||
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
|
||||
)
|
||||
@@ -2489,10 +2494,10 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIn(
|
||||
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
DataFlowCall call, ArgumentNodeExt arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ParameterNode p, boolean allowsFieldFlow |
|
||||
exists(ParameterNodeExt p, boolean allowsFieldFlow |
|
||||
revFlow(p, toReturn, returnAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
@@ -2502,7 +2507,7 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(
|
||||
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
|
||||
DataFlowCall call, ArgumentNodeExt arg, Ap returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
|
||||
}
|
||||
@@ -2555,13 +2560,15 @@ private module Stage4 {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate parameterFlow(
|
||||
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
ParameterNodeExt p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
) {
|
||||
revFlow(p, true, apSome(ap0), ap, config) and
|
||||
c = getNodeEnclosingCallable(p)
|
||||
}
|
||||
|
||||
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
predicate parameterMayFlowThrough(
|
||||
ParameterNodeExt p, DataFlowCallable c, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
|
||||
parameterFlow(p, ap, ap0, c, config) and
|
||||
c = getNodeEnclosingCallable(ret) and
|
||||
@@ -2606,7 +2613,7 @@ private predicate nodeMayUseSummary(Node n, AccessPathApprox apa, Configuration
|
||||
|
||||
private newtype TSummaryCtx =
|
||||
TSummaryCtxNone() or
|
||||
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
|
||||
TSummaryCtxSome(ParameterNodeExt p, AccessPath ap) {
|
||||
Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), _)
|
||||
}
|
||||
|
||||
@@ -2627,7 +2634,7 @@ private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
|
||||
|
||||
/** A summary context from which a flow summary can be generated. */
|
||||
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
||||
private ParameterNode p;
|
||||
private ParameterNodeExt p;
|
||||
private AccessPath ap;
|
||||
|
||||
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
|
||||
@@ -2758,7 +2765,7 @@ private newtype TPathNode =
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
sc instanceof SummaryCtxNone and
|
||||
ap = TAccessPathNil(getNodeType(node))
|
||||
ap = TAccessPathNil(getNodeDataFlowType(node))
|
||||
or
|
||||
// ... or a step from an existing PathNode to another node.
|
||||
exists(PathNodeMid mid |
|
||||
@@ -2979,7 +2986,7 @@ class PathNode extends TPathNode {
|
||||
Configuration getConfiguration() { none() }
|
||||
|
||||
private predicate isHidden() {
|
||||
nodeIsHidden(this.getNode()) and
|
||||
hiddenNode(this.getNode()) and
|
||||
not this.isSource() and
|
||||
not this instanceof PathNodeSink
|
||||
}
|
||||
@@ -3148,7 +3155,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
|
||||
cc instanceof CallContextAny and
|
||||
sc instanceof SummaryCtxNone and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
ap = TAccessPathNil(getNodeType(node))
|
||||
ap = TAccessPathNil(getNodeDataFlowType(node))
|
||||
or
|
||||
exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and
|
||||
sc = mid.getSummaryCtx()
|
||||
@@ -3235,7 +3242,7 @@ pragma[noinline]
|
||||
private predicate pathIntoArg(
|
||||
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
|
||||
) {
|
||||
exists(ArgumentNode arg |
|
||||
exists(ArgumentNodeExt arg |
|
||||
arg = mid.getNode() and
|
||||
cc = mid.getCallContext() and
|
||||
arg.argumentOf(call, i) and
|
||||
@@ -3248,7 +3255,7 @@ pragma[noinline]
|
||||
private predicate parameterCand(
|
||||
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
Stage4::revFlow(p, _, _, apa, config) and
|
||||
p.isParameterOf(callable, i)
|
||||
)
|
||||
@@ -3272,7 +3279,7 @@ private predicate pathIntoCallable0(
|
||||
* respectively.
|
||||
*/
|
||||
private predicate pathIntoCallable(
|
||||
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
|
||||
PathNodeMid mid, ParameterNodeExt p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
|
||||
DataFlowCall call
|
||||
) {
|
||||
exists(int i, DataFlowCallable callable, AccessPath ap |
|
||||
@@ -3568,7 +3575,7 @@ private module FlowExploration {
|
||||
|
||||
private newtype TSummaryCtx1 =
|
||||
TSummaryCtx1None() or
|
||||
TSummaryCtx1Param(ParameterNode p)
|
||||
TSummaryCtx1Param(ParameterNodeExt p)
|
||||
|
||||
private newtype TSummaryCtx2 =
|
||||
TSummaryCtx2None() or
|
||||
@@ -3591,7 +3598,7 @@ private module FlowExploration {
|
||||
cc instanceof CallContextAny and
|
||||
sc1 = TSummaryCtx1None() and
|
||||
sc2 = TSummaryCtx2None() and
|
||||
ap = TPartialNil(getNodeType(node)) and
|
||||
ap = TPartialNil(getNodeDataFlowType(node)) and
|
||||
not fullBarrier(node, config) and
|
||||
exists(config.explorationLimit())
|
||||
or
|
||||
@@ -3611,7 +3618,7 @@ private module FlowExploration {
|
||||
or
|
||||
exists(PartialPathNodeRev mid |
|
||||
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
|
||||
not clearsContent(node, ap.getHead()) and
|
||||
not clearsContentCached(node, ap.getHead()) and
|
||||
not fullBarrier(node, config) and
|
||||
distSink(getNodeEnclosingCallable(node), config) <= config.explorationLimit()
|
||||
)
|
||||
@@ -3625,9 +3632,9 @@ private module FlowExploration {
|
||||
exists(PartialPathNodeFwd mid |
|
||||
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
|
||||
not fullBarrier(node, config) and
|
||||
not clearsContent(node, ap.getHead().getContent()) and
|
||||
not clearsContentCached(node, ap.getHead().getContent()) and
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getNodeType(node), ap.getType())
|
||||
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
|
||||
else any()
|
||||
)
|
||||
}
|
||||
@@ -3783,7 +3790,7 @@ private module FlowExploration {
|
||||
PartialPathNodeFwd mid, Node node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2,
|
||||
PartialAccessPath ap, Configuration config
|
||||
) {
|
||||
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall()) and
|
||||
not isUnreachableInCallCached(node, cc.(CallContextSpecificCall).getCall()) and
|
||||
(
|
||||
localFlowStep(mid.getNode(), node, config) and
|
||||
cc = mid.getCallContext() and
|
||||
@@ -3797,7 +3804,7 @@ private module FlowExploration {
|
||||
sc1 = mid.getSummaryCtx1() and
|
||||
sc2 = mid.getSummaryCtx2() and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getNodeType(node)) and
|
||||
ap = TPartialNil(getNodeDataFlowType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
or
|
||||
@@ -3813,7 +3820,7 @@ private module FlowExploration {
|
||||
sc1 = TSummaryCtx1None() and
|
||||
sc2 = TSummaryCtx2None() and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getNodeType(node)) and
|
||||
ap = TPartialNil(getNodeDataFlowType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
or
|
||||
partialPathStoreStep(mid, _, _, node, ap) and
|
||||
@@ -3827,7 +3834,7 @@ private module FlowExploration {
|
||||
sc1 = mid.getSummaryCtx1() and
|
||||
sc2 = mid.getSummaryCtx2() and
|
||||
apConsFwd(ap, tc, ap0, config) and
|
||||
compatibleTypes(ap.getType(), getNodeType(node))
|
||||
compatibleTypes(ap.getType(), getNodeDataFlowType(node))
|
||||
)
|
||||
or
|
||||
partialPathIntoCallable(mid, node, _, cc, sc1, sc2, _, ap, config)
|
||||
@@ -3924,7 +3931,7 @@ private module FlowExploration {
|
||||
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ArgumentNode arg |
|
||||
exists(ArgumentNodeExt arg |
|
||||
arg = mid.getNode() and
|
||||
cc = mid.getCallContext() and
|
||||
arg.argumentOf(call, i) and
|
||||
@@ -3943,7 +3950,7 @@ private module FlowExploration {
|
||||
}
|
||||
|
||||
private predicate partialPathIntoCallable(
|
||||
PartialPathNodeFwd mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
|
||||
PartialPathNodeFwd mid, ParameterNodeExt p, CallContext outercc, CallContextCall innercc,
|
||||
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
|
||||
Configuration config
|
||||
) {
|
||||
@@ -3980,7 +3987,7 @@ private module FlowExploration {
|
||||
DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, CallContext cc,
|
||||
PartialAccessPath ap, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
|
||||
exists(ParameterNodeExt p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
|
||||
partialPathIntoCallable(mid, p, cc, innercc, sc1, sc2, call, _, config) and
|
||||
paramFlowsThroughInPartialPath(kind, innercc, sc1, sc2, ap, config)
|
||||
)
|
||||
@@ -4037,7 +4044,7 @@ private module FlowExploration {
|
||||
apConsRev(ap, c, ap0, config)
|
||||
)
|
||||
or
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
mid.getNode() = p and
|
||||
viableParamArg(_, p, node) and
|
||||
sc1 = mid.getSummaryCtx1() and
|
||||
@@ -4115,7 +4122,7 @@ private module FlowExploration {
|
||||
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(PartialPathNodeRev mid, ParameterNode p |
|
||||
exists(PartialPathNodeRev mid, ParameterNodeExt p |
|
||||
mid.getNode() = p and
|
||||
p.isParameterOf(_, pos) and
|
||||
sc1 = mid.getSummaryCtx1() and
|
||||
@@ -4138,7 +4145,7 @@ private module FlowExploration {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revPartialPathThroughCallable(
|
||||
PartialPathNodeRev mid, ArgumentNode node, RevPartialAccessPath ap, Configuration config
|
||||
PartialPathNodeRev mid, ArgumentNodeExt node, RevPartialAccessPath ap, Configuration config
|
||||
) {
|
||||
exists(DataFlowCall call, int pos |
|
||||
revPartialPathThroughCallable0(call, mid, pos, ap, config) and
|
||||
|
||||
@@ -211,10 +211,7 @@ private predicate fullBarrier(Node node, Configuration config) {
|
||||
* Holds if data can flow in one local step from `node1` to `node2`.
|
||||
*/
|
||||
private predicate localFlowStep(Node node1, Node node2, Configuration config) {
|
||||
(
|
||||
simpleLocalFlowStep(node1, node2) or
|
||||
reverseStepThroughInputOutputAlias(node1, node2)
|
||||
) and
|
||||
simpleLocalFlowStepExt(node1, node2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
@@ -237,7 +234,7 @@ private predicate additionalLocalFlowStep(Node node1, Node node2, Configuration
|
||||
* Holds if data can flow from `node1` to `node2` in a way that discards call contexts.
|
||||
*/
|
||||
private predicate jumpStep(Node node1, Node node2, Configuration config) {
|
||||
jumpStep(node1, node2) and
|
||||
jumpStepCached(node1, node2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
@@ -388,7 +385,7 @@ private module Stage1 {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
|
||||
exists(ArgumentNode arg |
|
||||
exists(ArgumentNodeExt arg |
|
||||
fwdFlow(arg, cc, config) and
|
||||
viableParamArg(call, _, arg)
|
||||
)
|
||||
@@ -515,7 +512,7 @@ private module Stage1 {
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
|
||||
DataFlowCall call, ParameterNodeExt p, ArgumentNodeExt arg, Configuration config
|
||||
) {
|
||||
viableParamArg(call, p, arg) and
|
||||
fwdFlow(arg, config)
|
||||
@@ -523,16 +520,16 @@ private module Stage1 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIn(
|
||||
DataFlowCall call, ArgumentNode arg, boolean toReturn, Configuration config
|
||||
DataFlowCall call, ArgumentNodeExt arg, boolean toReturn, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
revFlow(p, toReturn, config) and
|
||||
viableParamArgNodeCandFwd1(call, p, arg, config)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(DataFlowCall call, ArgumentNode arg, Configuration config) {
|
||||
private predicate revFlowInToReturn(DataFlowCall call, ArgumentNodeExt arg, Configuration config) {
|
||||
revFlowIn(call, arg, true, config)
|
||||
}
|
||||
|
||||
@@ -597,7 +594,9 @@ private module Stage1 {
|
||||
* Holds if flow may enter through `p` and reach a return node making `p` a
|
||||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
predicate parameterMayFlowThrough(
|
||||
ParameterNodeExt p, DataFlowCallable c, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
@@ -663,7 +662,7 @@ private predicate flowOutOfCallNodeCand1(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate viableParamArgNodeCand1(
|
||||
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
|
||||
DataFlowCall call, ParameterNodeExt p, ArgumentNodeExt arg, Configuration config
|
||||
) {
|
||||
Stage1::viableParamArgNodeCandFwd1(call, p, arg, config) and
|
||||
Stage1::revFlow(arg, config)
|
||||
@@ -675,7 +674,7 @@ private predicate viableParamArgNodeCand1(
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate flowIntoCallNodeCand1(
|
||||
DataFlowCall call, ArgumentNode arg, ParameterNode p, Configuration config
|
||||
DataFlowCall call, ArgumentNodeExt arg, ParameterNodeExt p, Configuration config
|
||||
) {
|
||||
viableParamArgNodeCand1(call, p, arg, config) and
|
||||
Stage1::revFlow(p, config) and
|
||||
@@ -735,7 +734,7 @@ private predicate flowOutOfCallNodeCand1(
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate flowIntoCallNodeCand1(
|
||||
DataFlowCall call, ArgumentNode arg, ParameterNode p, boolean allowsFieldFlow,
|
||||
DataFlowCall call, ArgumentNodeExt arg, ParameterNodeExt p, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowIntoCallNodeCand1(call, arg, p, config) and
|
||||
@@ -944,10 +943,10 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
DataFlowCall call, ParameterNodeExt p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ArgumentNode arg, boolean allowsFieldFlow |
|
||||
exists(ArgumentNodeExt arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
|
||||
@@ -992,7 +991,7 @@ private module Stage2 {
|
||||
private predicate fwdFlowIsEntered(
|
||||
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
|
||||
PrevStage::parameterMayFlowThrough(p, _, getApprox(ap), config)
|
||||
)
|
||||
@@ -1133,10 +1132,10 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIn(
|
||||
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
DataFlowCall call, ArgumentNodeExt arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ParameterNode p, boolean allowsFieldFlow |
|
||||
exists(ParameterNodeExt p, boolean allowsFieldFlow |
|
||||
revFlow(p, toReturn, returnAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
@@ -1146,7 +1145,7 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(
|
||||
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
|
||||
DataFlowCall call, ArgumentNodeExt arg, Ap returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
|
||||
}
|
||||
@@ -1199,13 +1198,15 @@ private module Stage2 {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate parameterFlow(
|
||||
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
ParameterNodeExt p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
) {
|
||||
revFlow(p, true, apSome(ap0), ap, config) and
|
||||
c = getNodeEnclosingCallable(p)
|
||||
}
|
||||
|
||||
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
predicate parameterMayFlowThrough(
|
||||
ParameterNodeExt p, DataFlowCallable c, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
|
||||
parameterFlow(p, ap, ap0, c, config) and
|
||||
c = getNodeEnclosingCallable(ret) and
|
||||
@@ -1245,7 +1246,7 @@ private predicate flowOutOfCallNodeCand2(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowIntoCallNodeCand2(
|
||||
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
|
||||
DataFlowCall call, ArgumentNodeExt node1, ParameterNodeExt node2, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
|
||||
@@ -1260,8 +1261,8 @@ private module LocalFlowBigStep {
|
||||
*/
|
||||
private class FlowCheckNode extends Node {
|
||||
FlowCheckNode() {
|
||||
this instanceof CastNode or
|
||||
clearsContent(this, _)
|
||||
castNode(this) or
|
||||
clearsContentCached(this, _)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1275,7 +1276,7 @@ private module LocalFlowBigStep {
|
||||
config.isSource(node) or
|
||||
jumpStep(_, node, config) or
|
||||
additionalJumpStep(_, node, config) or
|
||||
node instanceof ParameterNode or
|
||||
node instanceof ParameterNodeExt or
|
||||
node instanceof OutNodeExt or
|
||||
store(_, _, node, _) or
|
||||
read(_, _, node) or
|
||||
@@ -1321,21 +1322,21 @@ private module LocalFlowBigStep {
|
||||
Node node1, Node node2, boolean preservesValue, DataFlowType t, Configuration config,
|
||||
LocalCallContext cc
|
||||
) {
|
||||
not isUnreachableInCall(node2, cc.(LocalCallContextSpecificCall).getCall()) and
|
||||
not isUnreachableInCallCached(node2, cc.(LocalCallContextSpecificCall).getCall()) and
|
||||
(
|
||||
localFlowEntry(node1, pragma[only_bind_into](config)) and
|
||||
(
|
||||
localFlowStepNodeCand1(node1, node2, config) and
|
||||
preservesValue = true and
|
||||
t = getNodeType(node1)
|
||||
t = getNodeDataFlowType(node1)
|
||||
or
|
||||
additionalLocalFlowStepNodeCand2(node1, node2, config) and
|
||||
preservesValue = false and
|
||||
t = getNodeType(node2)
|
||||
t = getNodeDataFlowType(node2)
|
||||
) and
|
||||
node1 != node2 and
|
||||
cc.relevantFor(getNodeEnclosingCallable(node1)) and
|
||||
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
|
||||
not isUnreachableInCallCached(node1, cc.(LocalCallContextSpecificCall).getCall()) and
|
||||
Stage2::revFlow(node2, pragma[only_bind_into](config))
|
||||
or
|
||||
exists(Node mid |
|
||||
@@ -1350,7 +1351,7 @@ private module LocalFlowBigStep {
|
||||
additionalLocalFlowStepNodeCand2(mid, node2, config) and
|
||||
not mid instanceof FlowCheckNode and
|
||||
preservesValue = false and
|
||||
t = getNodeType(node2) and
|
||||
t = getNodeDataFlowType(node2) and
|
||||
Stage2::revFlow(node2, pragma[only_bind_into](config))
|
||||
)
|
||||
)
|
||||
@@ -1384,7 +1385,7 @@ private module Stage3 {
|
||||
private ApApprox getApprox(Ap ap) { result = ap.toBoolNonEmpty() }
|
||||
|
||||
private ApNil getApNil(Node node) {
|
||||
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeType(node))
|
||||
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeDataFlowType(node))
|
||||
}
|
||||
|
||||
bindingset[tc, tail]
|
||||
@@ -1443,7 +1444,9 @@ private module Stage3 {
|
||||
bindingset[node, ap]
|
||||
private predicate filter(Node node, Ap ap) {
|
||||
not ap.isClearedAt(node) and
|
||||
if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
|
||||
else any()
|
||||
}
|
||||
|
||||
bindingset[ap, contentType]
|
||||
@@ -1583,10 +1586,10 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
DataFlowCall call, ParameterNodeExt p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ArgumentNode arg, boolean allowsFieldFlow |
|
||||
exists(ArgumentNodeExt arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
|
||||
@@ -1631,7 +1634,7 @@ private module Stage3 {
|
||||
private predicate fwdFlowIsEntered(
|
||||
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
|
||||
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
|
||||
)
|
||||
@@ -1772,10 +1775,10 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIn(
|
||||
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
DataFlowCall call, ArgumentNodeExt arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ParameterNode p, boolean allowsFieldFlow |
|
||||
exists(ParameterNodeExt p, boolean allowsFieldFlow |
|
||||
revFlow(p, toReturn, returnAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
@@ -1785,7 +1788,7 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(
|
||||
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
|
||||
DataFlowCall call, ArgumentNodeExt arg, Ap returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
|
||||
}
|
||||
@@ -1838,13 +1841,15 @@ private module Stage3 {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate parameterFlow(
|
||||
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
ParameterNodeExt p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
) {
|
||||
revFlow(p, true, apSome(ap0), ap, config) and
|
||||
c = getNodeEnclosingCallable(p)
|
||||
}
|
||||
|
||||
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
predicate parameterMayFlowThrough(
|
||||
ParameterNodeExt p, DataFlowCallable c, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
|
||||
parameterFlow(p, ap, ap0, c, config) and
|
||||
c = getNodeEnclosingCallable(ret) and
|
||||
@@ -2088,7 +2093,7 @@ private module Stage4 {
|
||||
private ApApprox getApprox(Ap ap) { result = ap.getFront() }
|
||||
|
||||
private ApNil getApNil(Node node) {
|
||||
PrevStage::revFlow(node, _) and result = TNil(getNodeType(node))
|
||||
PrevStage::revFlow(node, _) and result = TNil(getNodeDataFlowType(node))
|
||||
}
|
||||
|
||||
bindingset[tc, tail]
|
||||
@@ -2155,7 +2160,7 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowIntoCall(
|
||||
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
|
||||
DataFlowCall call, ArgumentNodeExt node1, ParameterNodeExt node2, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
|
||||
@@ -2300,10 +2305,10 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
DataFlowCall call, ParameterNodeExt p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ArgumentNode arg, boolean allowsFieldFlow |
|
||||
exists(ArgumentNodeExt arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
|
||||
@@ -2348,7 +2353,7 @@ private module Stage4 {
|
||||
private predicate fwdFlowIsEntered(
|
||||
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
|
||||
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
|
||||
)
|
||||
@@ -2489,10 +2494,10 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIn(
|
||||
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
DataFlowCall call, ArgumentNodeExt arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ParameterNode p, boolean allowsFieldFlow |
|
||||
exists(ParameterNodeExt p, boolean allowsFieldFlow |
|
||||
revFlow(p, toReturn, returnAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
@@ -2502,7 +2507,7 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(
|
||||
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
|
||||
DataFlowCall call, ArgumentNodeExt arg, Ap returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
|
||||
}
|
||||
@@ -2555,13 +2560,15 @@ private module Stage4 {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate parameterFlow(
|
||||
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
ParameterNodeExt p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
) {
|
||||
revFlow(p, true, apSome(ap0), ap, config) and
|
||||
c = getNodeEnclosingCallable(p)
|
||||
}
|
||||
|
||||
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
predicate parameterMayFlowThrough(
|
||||
ParameterNodeExt p, DataFlowCallable c, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
|
||||
parameterFlow(p, ap, ap0, c, config) and
|
||||
c = getNodeEnclosingCallable(ret) and
|
||||
@@ -2606,7 +2613,7 @@ private predicate nodeMayUseSummary(Node n, AccessPathApprox apa, Configuration
|
||||
|
||||
private newtype TSummaryCtx =
|
||||
TSummaryCtxNone() or
|
||||
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
|
||||
TSummaryCtxSome(ParameterNodeExt p, AccessPath ap) {
|
||||
Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), _)
|
||||
}
|
||||
|
||||
@@ -2627,7 +2634,7 @@ private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
|
||||
|
||||
/** A summary context from which a flow summary can be generated. */
|
||||
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
||||
private ParameterNode p;
|
||||
private ParameterNodeExt p;
|
||||
private AccessPath ap;
|
||||
|
||||
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
|
||||
@@ -2758,7 +2765,7 @@ private newtype TPathNode =
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
sc instanceof SummaryCtxNone and
|
||||
ap = TAccessPathNil(getNodeType(node))
|
||||
ap = TAccessPathNil(getNodeDataFlowType(node))
|
||||
or
|
||||
// ... or a step from an existing PathNode to another node.
|
||||
exists(PathNodeMid mid |
|
||||
@@ -2979,7 +2986,7 @@ class PathNode extends TPathNode {
|
||||
Configuration getConfiguration() { none() }
|
||||
|
||||
private predicate isHidden() {
|
||||
nodeIsHidden(this.getNode()) and
|
||||
hiddenNode(this.getNode()) and
|
||||
not this.isSource() and
|
||||
not this instanceof PathNodeSink
|
||||
}
|
||||
@@ -3148,7 +3155,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
|
||||
cc instanceof CallContextAny and
|
||||
sc instanceof SummaryCtxNone and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
ap = TAccessPathNil(getNodeType(node))
|
||||
ap = TAccessPathNil(getNodeDataFlowType(node))
|
||||
or
|
||||
exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and
|
||||
sc = mid.getSummaryCtx()
|
||||
@@ -3235,7 +3242,7 @@ pragma[noinline]
|
||||
private predicate pathIntoArg(
|
||||
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
|
||||
) {
|
||||
exists(ArgumentNode arg |
|
||||
exists(ArgumentNodeExt arg |
|
||||
arg = mid.getNode() and
|
||||
cc = mid.getCallContext() and
|
||||
arg.argumentOf(call, i) and
|
||||
@@ -3248,7 +3255,7 @@ pragma[noinline]
|
||||
private predicate parameterCand(
|
||||
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
Stage4::revFlow(p, _, _, apa, config) and
|
||||
p.isParameterOf(callable, i)
|
||||
)
|
||||
@@ -3272,7 +3279,7 @@ private predicate pathIntoCallable0(
|
||||
* respectively.
|
||||
*/
|
||||
private predicate pathIntoCallable(
|
||||
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
|
||||
PathNodeMid mid, ParameterNodeExt p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
|
||||
DataFlowCall call
|
||||
) {
|
||||
exists(int i, DataFlowCallable callable, AccessPath ap |
|
||||
@@ -3568,7 +3575,7 @@ private module FlowExploration {
|
||||
|
||||
private newtype TSummaryCtx1 =
|
||||
TSummaryCtx1None() or
|
||||
TSummaryCtx1Param(ParameterNode p)
|
||||
TSummaryCtx1Param(ParameterNodeExt p)
|
||||
|
||||
private newtype TSummaryCtx2 =
|
||||
TSummaryCtx2None() or
|
||||
@@ -3591,7 +3598,7 @@ private module FlowExploration {
|
||||
cc instanceof CallContextAny and
|
||||
sc1 = TSummaryCtx1None() and
|
||||
sc2 = TSummaryCtx2None() and
|
||||
ap = TPartialNil(getNodeType(node)) and
|
||||
ap = TPartialNil(getNodeDataFlowType(node)) and
|
||||
not fullBarrier(node, config) and
|
||||
exists(config.explorationLimit())
|
||||
or
|
||||
@@ -3611,7 +3618,7 @@ private module FlowExploration {
|
||||
or
|
||||
exists(PartialPathNodeRev mid |
|
||||
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
|
||||
not clearsContent(node, ap.getHead()) and
|
||||
not clearsContentCached(node, ap.getHead()) and
|
||||
not fullBarrier(node, config) and
|
||||
distSink(getNodeEnclosingCallable(node), config) <= config.explorationLimit()
|
||||
)
|
||||
@@ -3625,9 +3632,9 @@ private module FlowExploration {
|
||||
exists(PartialPathNodeFwd mid |
|
||||
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
|
||||
not fullBarrier(node, config) and
|
||||
not clearsContent(node, ap.getHead().getContent()) and
|
||||
not clearsContentCached(node, ap.getHead().getContent()) and
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getNodeType(node), ap.getType())
|
||||
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
|
||||
else any()
|
||||
)
|
||||
}
|
||||
@@ -3783,7 +3790,7 @@ private module FlowExploration {
|
||||
PartialPathNodeFwd mid, Node node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2,
|
||||
PartialAccessPath ap, Configuration config
|
||||
) {
|
||||
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall()) and
|
||||
not isUnreachableInCallCached(node, cc.(CallContextSpecificCall).getCall()) and
|
||||
(
|
||||
localFlowStep(mid.getNode(), node, config) and
|
||||
cc = mid.getCallContext() and
|
||||
@@ -3797,7 +3804,7 @@ private module FlowExploration {
|
||||
sc1 = mid.getSummaryCtx1() and
|
||||
sc2 = mid.getSummaryCtx2() and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getNodeType(node)) and
|
||||
ap = TPartialNil(getNodeDataFlowType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
or
|
||||
@@ -3813,7 +3820,7 @@ private module FlowExploration {
|
||||
sc1 = TSummaryCtx1None() and
|
||||
sc2 = TSummaryCtx2None() and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getNodeType(node)) and
|
||||
ap = TPartialNil(getNodeDataFlowType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
or
|
||||
partialPathStoreStep(mid, _, _, node, ap) and
|
||||
@@ -3827,7 +3834,7 @@ private module FlowExploration {
|
||||
sc1 = mid.getSummaryCtx1() and
|
||||
sc2 = mid.getSummaryCtx2() and
|
||||
apConsFwd(ap, tc, ap0, config) and
|
||||
compatibleTypes(ap.getType(), getNodeType(node))
|
||||
compatibleTypes(ap.getType(), getNodeDataFlowType(node))
|
||||
)
|
||||
or
|
||||
partialPathIntoCallable(mid, node, _, cc, sc1, sc2, _, ap, config)
|
||||
@@ -3924,7 +3931,7 @@ private module FlowExploration {
|
||||
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ArgumentNode arg |
|
||||
exists(ArgumentNodeExt arg |
|
||||
arg = mid.getNode() and
|
||||
cc = mid.getCallContext() and
|
||||
arg.argumentOf(call, i) and
|
||||
@@ -3943,7 +3950,7 @@ private module FlowExploration {
|
||||
}
|
||||
|
||||
private predicate partialPathIntoCallable(
|
||||
PartialPathNodeFwd mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
|
||||
PartialPathNodeFwd mid, ParameterNodeExt p, CallContext outercc, CallContextCall innercc,
|
||||
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
|
||||
Configuration config
|
||||
) {
|
||||
@@ -3980,7 +3987,7 @@ private module FlowExploration {
|
||||
DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, CallContext cc,
|
||||
PartialAccessPath ap, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
|
||||
exists(ParameterNodeExt p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
|
||||
partialPathIntoCallable(mid, p, cc, innercc, sc1, sc2, call, _, config) and
|
||||
paramFlowsThroughInPartialPath(kind, innercc, sc1, sc2, ap, config)
|
||||
)
|
||||
@@ -4037,7 +4044,7 @@ private module FlowExploration {
|
||||
apConsRev(ap, c, ap0, config)
|
||||
)
|
||||
or
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
mid.getNode() = p and
|
||||
viableParamArg(_, p, node) and
|
||||
sc1 = mid.getSummaryCtx1() and
|
||||
@@ -4115,7 +4122,7 @@ private module FlowExploration {
|
||||
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(PartialPathNodeRev mid, ParameterNode p |
|
||||
exists(PartialPathNodeRev mid, ParameterNodeExt p |
|
||||
mid.getNode() = p and
|
||||
p.isParameterOf(_, pos) and
|
||||
sc1 = mid.getSummaryCtx1() and
|
||||
@@ -4138,7 +4145,7 @@ private module FlowExploration {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revPartialPathThroughCallable(
|
||||
PartialPathNodeRev mid, ArgumentNode node, RevPartialAccessPath ap, Configuration config
|
||||
PartialPathNodeRev mid, ArgumentNodeExt node, RevPartialAccessPath ap, Configuration config
|
||||
) {
|
||||
exists(DataFlowCall call, int pos |
|
||||
revPartialPathThroughCallable0(call, mid, pos, ap, config) and
|
||||
|
||||
@@ -211,10 +211,7 @@ private predicate fullBarrier(Node node, Configuration config) {
|
||||
* Holds if data can flow in one local step from `node1` to `node2`.
|
||||
*/
|
||||
private predicate localFlowStep(Node node1, Node node2, Configuration config) {
|
||||
(
|
||||
simpleLocalFlowStep(node1, node2) or
|
||||
reverseStepThroughInputOutputAlias(node1, node2)
|
||||
) and
|
||||
simpleLocalFlowStepExt(node1, node2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
@@ -237,7 +234,7 @@ private predicate additionalLocalFlowStep(Node node1, Node node2, Configuration
|
||||
* Holds if data can flow from `node1` to `node2` in a way that discards call contexts.
|
||||
*/
|
||||
private predicate jumpStep(Node node1, Node node2, Configuration config) {
|
||||
jumpStep(node1, node2) and
|
||||
jumpStepCached(node1, node2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
@@ -388,7 +385,7 @@ private module Stage1 {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
|
||||
exists(ArgumentNode arg |
|
||||
exists(ArgumentNodeExt arg |
|
||||
fwdFlow(arg, cc, config) and
|
||||
viableParamArg(call, _, arg)
|
||||
)
|
||||
@@ -515,7 +512,7 @@ private module Stage1 {
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
|
||||
DataFlowCall call, ParameterNodeExt p, ArgumentNodeExt arg, Configuration config
|
||||
) {
|
||||
viableParamArg(call, p, arg) and
|
||||
fwdFlow(arg, config)
|
||||
@@ -523,16 +520,16 @@ private module Stage1 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIn(
|
||||
DataFlowCall call, ArgumentNode arg, boolean toReturn, Configuration config
|
||||
DataFlowCall call, ArgumentNodeExt arg, boolean toReturn, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
revFlow(p, toReturn, config) and
|
||||
viableParamArgNodeCandFwd1(call, p, arg, config)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(DataFlowCall call, ArgumentNode arg, Configuration config) {
|
||||
private predicate revFlowInToReturn(DataFlowCall call, ArgumentNodeExt arg, Configuration config) {
|
||||
revFlowIn(call, arg, true, config)
|
||||
}
|
||||
|
||||
@@ -597,7 +594,9 @@ private module Stage1 {
|
||||
* Holds if flow may enter through `p` and reach a return node making `p` a
|
||||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
predicate parameterMayFlowThrough(
|
||||
ParameterNodeExt p, DataFlowCallable c, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
@@ -663,7 +662,7 @@ private predicate flowOutOfCallNodeCand1(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate viableParamArgNodeCand1(
|
||||
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
|
||||
DataFlowCall call, ParameterNodeExt p, ArgumentNodeExt arg, Configuration config
|
||||
) {
|
||||
Stage1::viableParamArgNodeCandFwd1(call, p, arg, config) and
|
||||
Stage1::revFlow(arg, config)
|
||||
@@ -675,7 +674,7 @@ private predicate viableParamArgNodeCand1(
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate flowIntoCallNodeCand1(
|
||||
DataFlowCall call, ArgumentNode arg, ParameterNode p, Configuration config
|
||||
DataFlowCall call, ArgumentNodeExt arg, ParameterNodeExt p, Configuration config
|
||||
) {
|
||||
viableParamArgNodeCand1(call, p, arg, config) and
|
||||
Stage1::revFlow(p, config) and
|
||||
@@ -735,7 +734,7 @@ private predicate flowOutOfCallNodeCand1(
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate flowIntoCallNodeCand1(
|
||||
DataFlowCall call, ArgumentNode arg, ParameterNode p, boolean allowsFieldFlow,
|
||||
DataFlowCall call, ArgumentNodeExt arg, ParameterNodeExt p, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowIntoCallNodeCand1(call, arg, p, config) and
|
||||
@@ -944,10 +943,10 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
DataFlowCall call, ParameterNodeExt p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ArgumentNode arg, boolean allowsFieldFlow |
|
||||
exists(ArgumentNodeExt arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
|
||||
@@ -992,7 +991,7 @@ private module Stage2 {
|
||||
private predicate fwdFlowIsEntered(
|
||||
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
|
||||
PrevStage::parameterMayFlowThrough(p, _, getApprox(ap), config)
|
||||
)
|
||||
@@ -1133,10 +1132,10 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIn(
|
||||
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
DataFlowCall call, ArgumentNodeExt arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ParameterNode p, boolean allowsFieldFlow |
|
||||
exists(ParameterNodeExt p, boolean allowsFieldFlow |
|
||||
revFlow(p, toReturn, returnAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
@@ -1146,7 +1145,7 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(
|
||||
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
|
||||
DataFlowCall call, ArgumentNodeExt arg, Ap returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
|
||||
}
|
||||
@@ -1199,13 +1198,15 @@ private module Stage2 {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate parameterFlow(
|
||||
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
ParameterNodeExt p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
) {
|
||||
revFlow(p, true, apSome(ap0), ap, config) and
|
||||
c = getNodeEnclosingCallable(p)
|
||||
}
|
||||
|
||||
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
predicate parameterMayFlowThrough(
|
||||
ParameterNodeExt p, DataFlowCallable c, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
|
||||
parameterFlow(p, ap, ap0, c, config) and
|
||||
c = getNodeEnclosingCallable(ret) and
|
||||
@@ -1245,7 +1246,7 @@ private predicate flowOutOfCallNodeCand2(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowIntoCallNodeCand2(
|
||||
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
|
||||
DataFlowCall call, ArgumentNodeExt node1, ParameterNodeExt node2, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
|
||||
@@ -1260,8 +1261,8 @@ private module LocalFlowBigStep {
|
||||
*/
|
||||
private class FlowCheckNode extends Node {
|
||||
FlowCheckNode() {
|
||||
this instanceof CastNode or
|
||||
clearsContent(this, _)
|
||||
castNode(this) or
|
||||
clearsContentCached(this, _)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1275,7 +1276,7 @@ private module LocalFlowBigStep {
|
||||
config.isSource(node) or
|
||||
jumpStep(_, node, config) or
|
||||
additionalJumpStep(_, node, config) or
|
||||
node instanceof ParameterNode or
|
||||
node instanceof ParameterNodeExt or
|
||||
node instanceof OutNodeExt or
|
||||
store(_, _, node, _) or
|
||||
read(_, _, node) or
|
||||
@@ -1321,21 +1322,21 @@ private module LocalFlowBigStep {
|
||||
Node node1, Node node2, boolean preservesValue, DataFlowType t, Configuration config,
|
||||
LocalCallContext cc
|
||||
) {
|
||||
not isUnreachableInCall(node2, cc.(LocalCallContextSpecificCall).getCall()) and
|
||||
not isUnreachableInCallCached(node2, cc.(LocalCallContextSpecificCall).getCall()) and
|
||||
(
|
||||
localFlowEntry(node1, pragma[only_bind_into](config)) and
|
||||
(
|
||||
localFlowStepNodeCand1(node1, node2, config) and
|
||||
preservesValue = true and
|
||||
t = getNodeType(node1)
|
||||
t = getNodeDataFlowType(node1)
|
||||
or
|
||||
additionalLocalFlowStepNodeCand2(node1, node2, config) and
|
||||
preservesValue = false and
|
||||
t = getNodeType(node2)
|
||||
t = getNodeDataFlowType(node2)
|
||||
) and
|
||||
node1 != node2 and
|
||||
cc.relevantFor(getNodeEnclosingCallable(node1)) and
|
||||
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
|
||||
not isUnreachableInCallCached(node1, cc.(LocalCallContextSpecificCall).getCall()) and
|
||||
Stage2::revFlow(node2, pragma[only_bind_into](config))
|
||||
or
|
||||
exists(Node mid |
|
||||
@@ -1350,7 +1351,7 @@ private module LocalFlowBigStep {
|
||||
additionalLocalFlowStepNodeCand2(mid, node2, config) and
|
||||
not mid instanceof FlowCheckNode and
|
||||
preservesValue = false and
|
||||
t = getNodeType(node2) and
|
||||
t = getNodeDataFlowType(node2) and
|
||||
Stage2::revFlow(node2, pragma[only_bind_into](config))
|
||||
)
|
||||
)
|
||||
@@ -1384,7 +1385,7 @@ private module Stage3 {
|
||||
private ApApprox getApprox(Ap ap) { result = ap.toBoolNonEmpty() }
|
||||
|
||||
private ApNil getApNil(Node node) {
|
||||
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeType(node))
|
||||
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeDataFlowType(node))
|
||||
}
|
||||
|
||||
bindingset[tc, tail]
|
||||
@@ -1443,7 +1444,9 @@ private module Stage3 {
|
||||
bindingset[node, ap]
|
||||
private predicate filter(Node node, Ap ap) {
|
||||
not ap.isClearedAt(node) and
|
||||
if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
|
||||
else any()
|
||||
}
|
||||
|
||||
bindingset[ap, contentType]
|
||||
@@ -1583,10 +1586,10 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
DataFlowCall call, ParameterNodeExt p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ArgumentNode arg, boolean allowsFieldFlow |
|
||||
exists(ArgumentNodeExt arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
|
||||
@@ -1631,7 +1634,7 @@ private module Stage3 {
|
||||
private predicate fwdFlowIsEntered(
|
||||
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
|
||||
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
|
||||
)
|
||||
@@ -1772,10 +1775,10 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIn(
|
||||
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
DataFlowCall call, ArgumentNodeExt arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ParameterNode p, boolean allowsFieldFlow |
|
||||
exists(ParameterNodeExt p, boolean allowsFieldFlow |
|
||||
revFlow(p, toReturn, returnAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
@@ -1785,7 +1788,7 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(
|
||||
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
|
||||
DataFlowCall call, ArgumentNodeExt arg, Ap returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
|
||||
}
|
||||
@@ -1838,13 +1841,15 @@ private module Stage3 {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate parameterFlow(
|
||||
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
ParameterNodeExt p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
) {
|
||||
revFlow(p, true, apSome(ap0), ap, config) and
|
||||
c = getNodeEnclosingCallable(p)
|
||||
}
|
||||
|
||||
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
predicate parameterMayFlowThrough(
|
||||
ParameterNodeExt p, DataFlowCallable c, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
|
||||
parameterFlow(p, ap, ap0, c, config) and
|
||||
c = getNodeEnclosingCallable(ret) and
|
||||
@@ -2088,7 +2093,7 @@ private module Stage4 {
|
||||
private ApApprox getApprox(Ap ap) { result = ap.getFront() }
|
||||
|
||||
private ApNil getApNil(Node node) {
|
||||
PrevStage::revFlow(node, _) and result = TNil(getNodeType(node))
|
||||
PrevStage::revFlow(node, _) and result = TNil(getNodeDataFlowType(node))
|
||||
}
|
||||
|
||||
bindingset[tc, tail]
|
||||
@@ -2155,7 +2160,7 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowIntoCall(
|
||||
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
|
||||
DataFlowCall call, ArgumentNodeExt node1, ParameterNodeExt node2, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
|
||||
@@ -2300,10 +2305,10 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
DataFlowCall call, ParameterNodeExt p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ArgumentNode arg, boolean allowsFieldFlow |
|
||||
exists(ArgumentNodeExt arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
|
||||
@@ -2348,7 +2353,7 @@ private module Stage4 {
|
||||
private predicate fwdFlowIsEntered(
|
||||
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
|
||||
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
|
||||
)
|
||||
@@ -2489,10 +2494,10 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIn(
|
||||
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
DataFlowCall call, ArgumentNodeExt arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ParameterNode p, boolean allowsFieldFlow |
|
||||
exists(ParameterNodeExt p, boolean allowsFieldFlow |
|
||||
revFlow(p, toReturn, returnAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
@@ -2502,7 +2507,7 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(
|
||||
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
|
||||
DataFlowCall call, ArgumentNodeExt arg, Ap returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
|
||||
}
|
||||
@@ -2555,13 +2560,15 @@ private module Stage4 {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate parameterFlow(
|
||||
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
ParameterNodeExt p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
) {
|
||||
revFlow(p, true, apSome(ap0), ap, config) and
|
||||
c = getNodeEnclosingCallable(p)
|
||||
}
|
||||
|
||||
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
predicate parameterMayFlowThrough(
|
||||
ParameterNodeExt p, DataFlowCallable c, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
|
||||
parameterFlow(p, ap, ap0, c, config) and
|
||||
c = getNodeEnclosingCallable(ret) and
|
||||
@@ -2606,7 +2613,7 @@ private predicate nodeMayUseSummary(Node n, AccessPathApprox apa, Configuration
|
||||
|
||||
private newtype TSummaryCtx =
|
||||
TSummaryCtxNone() or
|
||||
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
|
||||
TSummaryCtxSome(ParameterNodeExt p, AccessPath ap) {
|
||||
Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), _)
|
||||
}
|
||||
|
||||
@@ -2627,7 +2634,7 @@ private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
|
||||
|
||||
/** A summary context from which a flow summary can be generated. */
|
||||
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
||||
private ParameterNode p;
|
||||
private ParameterNodeExt p;
|
||||
private AccessPath ap;
|
||||
|
||||
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
|
||||
@@ -2758,7 +2765,7 @@ private newtype TPathNode =
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
sc instanceof SummaryCtxNone and
|
||||
ap = TAccessPathNil(getNodeType(node))
|
||||
ap = TAccessPathNil(getNodeDataFlowType(node))
|
||||
or
|
||||
// ... or a step from an existing PathNode to another node.
|
||||
exists(PathNodeMid mid |
|
||||
@@ -2979,7 +2986,7 @@ class PathNode extends TPathNode {
|
||||
Configuration getConfiguration() { none() }
|
||||
|
||||
private predicate isHidden() {
|
||||
nodeIsHidden(this.getNode()) and
|
||||
hiddenNode(this.getNode()) and
|
||||
not this.isSource() and
|
||||
not this instanceof PathNodeSink
|
||||
}
|
||||
@@ -3148,7 +3155,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
|
||||
cc instanceof CallContextAny and
|
||||
sc instanceof SummaryCtxNone and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
ap = TAccessPathNil(getNodeType(node))
|
||||
ap = TAccessPathNil(getNodeDataFlowType(node))
|
||||
or
|
||||
exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and
|
||||
sc = mid.getSummaryCtx()
|
||||
@@ -3235,7 +3242,7 @@ pragma[noinline]
|
||||
private predicate pathIntoArg(
|
||||
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
|
||||
) {
|
||||
exists(ArgumentNode arg |
|
||||
exists(ArgumentNodeExt arg |
|
||||
arg = mid.getNode() and
|
||||
cc = mid.getCallContext() and
|
||||
arg.argumentOf(call, i) and
|
||||
@@ -3248,7 +3255,7 @@ pragma[noinline]
|
||||
private predicate parameterCand(
|
||||
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
Stage4::revFlow(p, _, _, apa, config) and
|
||||
p.isParameterOf(callable, i)
|
||||
)
|
||||
@@ -3272,7 +3279,7 @@ private predicate pathIntoCallable0(
|
||||
* respectively.
|
||||
*/
|
||||
private predicate pathIntoCallable(
|
||||
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
|
||||
PathNodeMid mid, ParameterNodeExt p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
|
||||
DataFlowCall call
|
||||
) {
|
||||
exists(int i, DataFlowCallable callable, AccessPath ap |
|
||||
@@ -3568,7 +3575,7 @@ private module FlowExploration {
|
||||
|
||||
private newtype TSummaryCtx1 =
|
||||
TSummaryCtx1None() or
|
||||
TSummaryCtx1Param(ParameterNode p)
|
||||
TSummaryCtx1Param(ParameterNodeExt p)
|
||||
|
||||
private newtype TSummaryCtx2 =
|
||||
TSummaryCtx2None() or
|
||||
@@ -3591,7 +3598,7 @@ private module FlowExploration {
|
||||
cc instanceof CallContextAny and
|
||||
sc1 = TSummaryCtx1None() and
|
||||
sc2 = TSummaryCtx2None() and
|
||||
ap = TPartialNil(getNodeType(node)) and
|
||||
ap = TPartialNil(getNodeDataFlowType(node)) and
|
||||
not fullBarrier(node, config) and
|
||||
exists(config.explorationLimit())
|
||||
or
|
||||
@@ -3611,7 +3618,7 @@ private module FlowExploration {
|
||||
or
|
||||
exists(PartialPathNodeRev mid |
|
||||
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
|
||||
not clearsContent(node, ap.getHead()) and
|
||||
not clearsContentCached(node, ap.getHead()) and
|
||||
not fullBarrier(node, config) and
|
||||
distSink(getNodeEnclosingCallable(node), config) <= config.explorationLimit()
|
||||
)
|
||||
@@ -3625,9 +3632,9 @@ private module FlowExploration {
|
||||
exists(PartialPathNodeFwd mid |
|
||||
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
|
||||
not fullBarrier(node, config) and
|
||||
not clearsContent(node, ap.getHead().getContent()) and
|
||||
not clearsContentCached(node, ap.getHead().getContent()) and
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getNodeType(node), ap.getType())
|
||||
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
|
||||
else any()
|
||||
)
|
||||
}
|
||||
@@ -3783,7 +3790,7 @@ private module FlowExploration {
|
||||
PartialPathNodeFwd mid, Node node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2,
|
||||
PartialAccessPath ap, Configuration config
|
||||
) {
|
||||
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall()) and
|
||||
not isUnreachableInCallCached(node, cc.(CallContextSpecificCall).getCall()) and
|
||||
(
|
||||
localFlowStep(mid.getNode(), node, config) and
|
||||
cc = mid.getCallContext() and
|
||||
@@ -3797,7 +3804,7 @@ private module FlowExploration {
|
||||
sc1 = mid.getSummaryCtx1() and
|
||||
sc2 = mid.getSummaryCtx2() and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getNodeType(node)) and
|
||||
ap = TPartialNil(getNodeDataFlowType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
or
|
||||
@@ -3813,7 +3820,7 @@ private module FlowExploration {
|
||||
sc1 = TSummaryCtx1None() and
|
||||
sc2 = TSummaryCtx2None() and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getNodeType(node)) and
|
||||
ap = TPartialNil(getNodeDataFlowType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
or
|
||||
partialPathStoreStep(mid, _, _, node, ap) and
|
||||
@@ -3827,7 +3834,7 @@ private module FlowExploration {
|
||||
sc1 = mid.getSummaryCtx1() and
|
||||
sc2 = mid.getSummaryCtx2() and
|
||||
apConsFwd(ap, tc, ap0, config) and
|
||||
compatibleTypes(ap.getType(), getNodeType(node))
|
||||
compatibleTypes(ap.getType(), getNodeDataFlowType(node))
|
||||
)
|
||||
or
|
||||
partialPathIntoCallable(mid, node, _, cc, sc1, sc2, _, ap, config)
|
||||
@@ -3924,7 +3931,7 @@ private module FlowExploration {
|
||||
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ArgumentNode arg |
|
||||
exists(ArgumentNodeExt arg |
|
||||
arg = mid.getNode() and
|
||||
cc = mid.getCallContext() and
|
||||
arg.argumentOf(call, i) and
|
||||
@@ -3943,7 +3950,7 @@ private module FlowExploration {
|
||||
}
|
||||
|
||||
private predicate partialPathIntoCallable(
|
||||
PartialPathNodeFwd mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
|
||||
PartialPathNodeFwd mid, ParameterNodeExt p, CallContext outercc, CallContextCall innercc,
|
||||
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
|
||||
Configuration config
|
||||
) {
|
||||
@@ -3980,7 +3987,7 @@ private module FlowExploration {
|
||||
DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, CallContext cc,
|
||||
PartialAccessPath ap, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
|
||||
exists(ParameterNodeExt p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
|
||||
partialPathIntoCallable(mid, p, cc, innercc, sc1, sc2, call, _, config) and
|
||||
paramFlowsThroughInPartialPath(kind, innercc, sc1, sc2, ap, config)
|
||||
)
|
||||
@@ -4037,7 +4044,7 @@ private module FlowExploration {
|
||||
apConsRev(ap, c, ap0, config)
|
||||
)
|
||||
or
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
mid.getNode() = p and
|
||||
viableParamArg(_, p, node) and
|
||||
sc1 = mid.getSummaryCtx1() and
|
||||
@@ -4115,7 +4122,7 @@ private module FlowExploration {
|
||||
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(PartialPathNodeRev mid, ParameterNode p |
|
||||
exists(PartialPathNodeRev mid, ParameterNodeExt p |
|
||||
mid.getNode() = p and
|
||||
p.isParameterOf(_, pos) and
|
||||
sc1 = mid.getSummaryCtx1() and
|
||||
@@ -4138,7 +4145,7 @@ private module FlowExploration {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revPartialPathThroughCallable(
|
||||
PartialPathNodeRev mid, ArgumentNode node, RevPartialAccessPath ap, Configuration config
|
||||
PartialPathNodeRev mid, ArgumentNodeExt node, RevPartialAccessPath ap, Configuration config
|
||||
) {
|
||||
exists(DataFlowCall call, int pos |
|
||||
revPartialPathThroughCallable0(call, mid, pos, ap, config) and
|
||||
|
||||
@@ -211,10 +211,7 @@ private predicate fullBarrier(Node node, Configuration config) {
|
||||
* Holds if data can flow in one local step from `node1` to `node2`.
|
||||
*/
|
||||
private predicate localFlowStep(Node node1, Node node2, Configuration config) {
|
||||
(
|
||||
simpleLocalFlowStep(node1, node2) or
|
||||
reverseStepThroughInputOutputAlias(node1, node2)
|
||||
) and
|
||||
simpleLocalFlowStepExt(node1, node2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
@@ -237,7 +234,7 @@ private predicate additionalLocalFlowStep(Node node1, Node node2, Configuration
|
||||
* Holds if data can flow from `node1` to `node2` in a way that discards call contexts.
|
||||
*/
|
||||
private predicate jumpStep(Node node1, Node node2, Configuration config) {
|
||||
jumpStep(node1, node2) and
|
||||
jumpStepCached(node1, node2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
@@ -388,7 +385,7 @@ private module Stage1 {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc, Configuration config) {
|
||||
exists(ArgumentNode arg |
|
||||
exists(ArgumentNodeExt arg |
|
||||
fwdFlow(arg, cc, config) and
|
||||
viableParamArg(call, _, arg)
|
||||
)
|
||||
@@ -515,7 +512,7 @@ private module Stage1 {
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
|
||||
DataFlowCall call, ParameterNodeExt p, ArgumentNodeExt arg, Configuration config
|
||||
) {
|
||||
viableParamArg(call, p, arg) and
|
||||
fwdFlow(arg, config)
|
||||
@@ -523,16 +520,16 @@ private module Stage1 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIn(
|
||||
DataFlowCall call, ArgumentNode arg, boolean toReturn, Configuration config
|
||||
DataFlowCall call, ArgumentNodeExt arg, boolean toReturn, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
revFlow(p, toReturn, config) and
|
||||
viableParamArgNodeCandFwd1(call, p, arg, config)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(DataFlowCall call, ArgumentNode arg, Configuration config) {
|
||||
private predicate revFlowInToReturn(DataFlowCall call, ArgumentNodeExt arg, Configuration config) {
|
||||
revFlowIn(call, arg, true, config)
|
||||
}
|
||||
|
||||
@@ -597,7 +594,9 @@ private module Stage1 {
|
||||
* Holds if flow may enter through `p` and reach a return node making `p` a
|
||||
* candidate for the origin of a summary.
|
||||
*/
|
||||
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
predicate parameterMayFlowThrough(
|
||||
ParameterNodeExt p, DataFlowCallable c, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
returnFlowCallableNodeCand(c, kind, config) and
|
||||
@@ -663,7 +662,7 @@ private predicate flowOutOfCallNodeCand1(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate viableParamArgNodeCand1(
|
||||
DataFlowCall call, ParameterNode p, ArgumentNode arg, Configuration config
|
||||
DataFlowCall call, ParameterNodeExt p, ArgumentNodeExt arg, Configuration config
|
||||
) {
|
||||
Stage1::viableParamArgNodeCandFwd1(call, p, arg, config) and
|
||||
Stage1::revFlow(arg, config)
|
||||
@@ -675,7 +674,7 @@ private predicate viableParamArgNodeCand1(
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate flowIntoCallNodeCand1(
|
||||
DataFlowCall call, ArgumentNode arg, ParameterNode p, Configuration config
|
||||
DataFlowCall call, ArgumentNodeExt arg, ParameterNodeExt p, Configuration config
|
||||
) {
|
||||
viableParamArgNodeCand1(call, p, arg, config) and
|
||||
Stage1::revFlow(p, config) and
|
||||
@@ -735,7 +734,7 @@ private predicate flowOutOfCallNodeCand1(
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate flowIntoCallNodeCand1(
|
||||
DataFlowCall call, ArgumentNode arg, ParameterNode p, boolean allowsFieldFlow,
|
||||
DataFlowCall call, ArgumentNodeExt arg, ParameterNodeExt p, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowIntoCallNodeCand1(call, arg, p, config) and
|
||||
@@ -944,10 +943,10 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
DataFlowCall call, ParameterNodeExt p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ArgumentNode arg, boolean allowsFieldFlow |
|
||||
exists(ArgumentNodeExt arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
|
||||
@@ -992,7 +991,7 @@ private module Stage2 {
|
||||
private predicate fwdFlowIsEntered(
|
||||
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
|
||||
PrevStage::parameterMayFlowThrough(p, _, getApprox(ap), config)
|
||||
)
|
||||
@@ -1133,10 +1132,10 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIn(
|
||||
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
DataFlowCall call, ArgumentNodeExt arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ParameterNode p, boolean allowsFieldFlow |
|
||||
exists(ParameterNodeExt p, boolean allowsFieldFlow |
|
||||
revFlow(p, toReturn, returnAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
@@ -1146,7 +1145,7 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(
|
||||
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
|
||||
DataFlowCall call, ArgumentNodeExt arg, Ap returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
|
||||
}
|
||||
@@ -1199,13 +1198,15 @@ private module Stage2 {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate parameterFlow(
|
||||
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
ParameterNodeExt p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
) {
|
||||
revFlow(p, true, apSome(ap0), ap, config) and
|
||||
c = getNodeEnclosingCallable(p)
|
||||
}
|
||||
|
||||
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
predicate parameterMayFlowThrough(
|
||||
ParameterNodeExt p, DataFlowCallable c, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
|
||||
parameterFlow(p, ap, ap0, c, config) and
|
||||
c = getNodeEnclosingCallable(ret) and
|
||||
@@ -1245,7 +1246,7 @@ private predicate flowOutOfCallNodeCand2(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowIntoCallNodeCand2(
|
||||
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
|
||||
DataFlowCall call, ArgumentNodeExt node1, ParameterNodeExt node2, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow, config) and
|
||||
@@ -1260,8 +1261,8 @@ private module LocalFlowBigStep {
|
||||
*/
|
||||
private class FlowCheckNode extends Node {
|
||||
FlowCheckNode() {
|
||||
this instanceof CastNode or
|
||||
clearsContent(this, _)
|
||||
castNode(this) or
|
||||
clearsContentCached(this, _)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1275,7 +1276,7 @@ private module LocalFlowBigStep {
|
||||
config.isSource(node) or
|
||||
jumpStep(_, node, config) or
|
||||
additionalJumpStep(_, node, config) or
|
||||
node instanceof ParameterNode or
|
||||
node instanceof ParameterNodeExt or
|
||||
node instanceof OutNodeExt or
|
||||
store(_, _, node, _) or
|
||||
read(_, _, node) or
|
||||
@@ -1321,21 +1322,21 @@ private module LocalFlowBigStep {
|
||||
Node node1, Node node2, boolean preservesValue, DataFlowType t, Configuration config,
|
||||
LocalCallContext cc
|
||||
) {
|
||||
not isUnreachableInCall(node2, cc.(LocalCallContextSpecificCall).getCall()) and
|
||||
not isUnreachableInCallCached(node2, cc.(LocalCallContextSpecificCall).getCall()) and
|
||||
(
|
||||
localFlowEntry(node1, pragma[only_bind_into](config)) and
|
||||
(
|
||||
localFlowStepNodeCand1(node1, node2, config) and
|
||||
preservesValue = true and
|
||||
t = getNodeType(node1)
|
||||
t = getNodeDataFlowType(node1)
|
||||
or
|
||||
additionalLocalFlowStepNodeCand2(node1, node2, config) and
|
||||
preservesValue = false and
|
||||
t = getNodeType(node2)
|
||||
t = getNodeDataFlowType(node2)
|
||||
) and
|
||||
node1 != node2 and
|
||||
cc.relevantFor(getNodeEnclosingCallable(node1)) and
|
||||
not isUnreachableInCall(node1, cc.(LocalCallContextSpecificCall).getCall()) and
|
||||
not isUnreachableInCallCached(node1, cc.(LocalCallContextSpecificCall).getCall()) and
|
||||
Stage2::revFlow(node2, pragma[only_bind_into](config))
|
||||
or
|
||||
exists(Node mid |
|
||||
@@ -1350,7 +1351,7 @@ private module LocalFlowBigStep {
|
||||
additionalLocalFlowStepNodeCand2(mid, node2, config) and
|
||||
not mid instanceof FlowCheckNode and
|
||||
preservesValue = false and
|
||||
t = getNodeType(node2) and
|
||||
t = getNodeDataFlowType(node2) and
|
||||
Stage2::revFlow(node2, pragma[only_bind_into](config))
|
||||
)
|
||||
)
|
||||
@@ -1384,7 +1385,7 @@ private module Stage3 {
|
||||
private ApApprox getApprox(Ap ap) { result = ap.toBoolNonEmpty() }
|
||||
|
||||
private ApNil getApNil(Node node) {
|
||||
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeType(node))
|
||||
PrevStage::revFlow(node, _) and result = TFrontNil(getNodeDataFlowType(node))
|
||||
}
|
||||
|
||||
bindingset[tc, tail]
|
||||
@@ -1443,7 +1444,9 @@ private module Stage3 {
|
||||
bindingset[node, ap]
|
||||
private predicate filter(Node node, Ap ap) {
|
||||
not ap.isClearedAt(node) and
|
||||
if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any()
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
|
||||
else any()
|
||||
}
|
||||
|
||||
bindingset[ap, contentType]
|
||||
@@ -1583,10 +1586,10 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
DataFlowCall call, ParameterNodeExt p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ArgumentNode arg, boolean allowsFieldFlow |
|
||||
exists(ArgumentNodeExt arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
|
||||
@@ -1631,7 +1634,7 @@ private module Stage3 {
|
||||
private predicate fwdFlowIsEntered(
|
||||
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
|
||||
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
|
||||
)
|
||||
@@ -1772,10 +1775,10 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIn(
|
||||
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
DataFlowCall call, ArgumentNodeExt arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ParameterNode p, boolean allowsFieldFlow |
|
||||
exists(ParameterNodeExt p, boolean allowsFieldFlow |
|
||||
revFlow(p, toReturn, returnAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
@@ -1785,7 +1788,7 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(
|
||||
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
|
||||
DataFlowCall call, ArgumentNodeExt arg, Ap returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
|
||||
}
|
||||
@@ -1838,13 +1841,15 @@ private module Stage3 {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate parameterFlow(
|
||||
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
ParameterNodeExt p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
) {
|
||||
revFlow(p, true, apSome(ap0), ap, config) and
|
||||
c = getNodeEnclosingCallable(p)
|
||||
}
|
||||
|
||||
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
predicate parameterMayFlowThrough(
|
||||
ParameterNodeExt p, DataFlowCallable c, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
|
||||
parameterFlow(p, ap, ap0, c, config) and
|
||||
c = getNodeEnclosingCallable(ret) and
|
||||
@@ -2088,7 +2093,7 @@ private module Stage4 {
|
||||
private ApApprox getApprox(Ap ap) { result = ap.getFront() }
|
||||
|
||||
private ApNil getApNil(Node node) {
|
||||
PrevStage::revFlow(node, _) and result = TNil(getNodeType(node))
|
||||
PrevStage::revFlow(node, _) and result = TNil(getNodeDataFlowType(node))
|
||||
}
|
||||
|
||||
bindingset[tc, tail]
|
||||
@@ -2155,7 +2160,7 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowIntoCall(
|
||||
DataFlowCall call, ArgumentNode node1, ParameterNode node2, boolean allowsFieldFlow,
|
||||
DataFlowCall call, ArgumentNodeExt node1, ParameterNodeExt node2, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow, config) and
|
||||
@@ -2300,10 +2305,10 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fwdFlowIn(
|
||||
DataFlowCall call, ParameterNode p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
DataFlowCall call, ParameterNodeExt p, Cc outercc, Cc innercc, ApOption argAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ArgumentNode arg, boolean allowsFieldFlow |
|
||||
exists(ArgumentNodeExt arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, getNodeEnclosingCallable(p), outercc)
|
||||
@@ -2348,7 +2353,7 @@ private module Stage4 {
|
||||
private predicate fwdFlowIsEntered(
|
||||
DataFlowCall call, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
fwdFlowIn(call, p, cc, _, argAp, ap, config) and
|
||||
PrevStage::parameterMayFlowThrough(p, _, unbindApa(getApprox(ap)), config)
|
||||
)
|
||||
@@ -2489,10 +2494,10 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowIn(
|
||||
DataFlowCall call, ArgumentNode arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
DataFlowCall call, ArgumentNodeExt arg, boolean toReturn, ApOption returnAp, Ap ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ParameterNode p, boolean allowsFieldFlow |
|
||||
exists(ParameterNodeExt p, boolean allowsFieldFlow |
|
||||
revFlow(p, toReturn, returnAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
@@ -2502,7 +2507,7 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revFlowInToReturn(
|
||||
DataFlowCall call, ArgumentNode arg, Ap returnAp, Ap ap, Configuration config
|
||||
DataFlowCall call, ArgumentNodeExt arg, Ap returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlowIn(call, arg, true, apSome(returnAp), ap, config)
|
||||
}
|
||||
@@ -2555,13 +2560,15 @@ private module Stage4 {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate parameterFlow(
|
||||
ParameterNode p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
ParameterNodeExt p, Ap ap, Ap ap0, DataFlowCallable c, Configuration config
|
||||
) {
|
||||
revFlow(p, true, apSome(ap0), ap, config) and
|
||||
c = getNodeEnclosingCallable(p)
|
||||
}
|
||||
|
||||
predicate parameterMayFlowThrough(ParameterNode p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
predicate parameterMayFlowThrough(
|
||||
ParameterNodeExt p, DataFlowCallable c, Ap ap, Configuration config
|
||||
) {
|
||||
exists(ReturnNodeExt ret, Ap ap0, ReturnKindExt kind, int pos |
|
||||
parameterFlow(p, ap, ap0, c, config) and
|
||||
c = getNodeEnclosingCallable(ret) and
|
||||
@@ -2606,7 +2613,7 @@ private predicate nodeMayUseSummary(Node n, AccessPathApprox apa, Configuration
|
||||
|
||||
private newtype TSummaryCtx =
|
||||
TSummaryCtxNone() or
|
||||
TSummaryCtxSome(ParameterNode p, AccessPath ap) {
|
||||
TSummaryCtxSome(ParameterNodeExt p, AccessPath ap) {
|
||||
Stage4::parameterMayFlowThrough(p, _, ap.getApprox(), _)
|
||||
}
|
||||
|
||||
@@ -2627,7 +2634,7 @@ private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone {
|
||||
|
||||
/** A summary context from which a flow summary can be generated. */
|
||||
private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
|
||||
private ParameterNode p;
|
||||
private ParameterNodeExt p;
|
||||
private AccessPath ap;
|
||||
|
||||
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
|
||||
@@ -2758,7 +2765,7 @@ private newtype TPathNode =
|
||||
config.isSource(node) and
|
||||
cc instanceof CallContextAny and
|
||||
sc instanceof SummaryCtxNone and
|
||||
ap = TAccessPathNil(getNodeType(node))
|
||||
ap = TAccessPathNil(getNodeDataFlowType(node))
|
||||
or
|
||||
// ... or a step from an existing PathNode to another node.
|
||||
exists(PathNodeMid mid |
|
||||
@@ -2979,7 +2986,7 @@ class PathNode extends TPathNode {
|
||||
Configuration getConfiguration() { none() }
|
||||
|
||||
private predicate isHidden() {
|
||||
nodeIsHidden(this.getNode()) and
|
||||
hiddenNode(this.getNode()) and
|
||||
not this.isSource() and
|
||||
not this instanceof PathNodeSink
|
||||
}
|
||||
@@ -3148,7 +3155,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
|
||||
cc instanceof CallContextAny and
|
||||
sc instanceof SummaryCtxNone and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
ap = TAccessPathNil(getNodeType(node))
|
||||
ap = TAccessPathNil(getNodeDataFlowType(node))
|
||||
or
|
||||
exists(TypedContent tc | pathStoreStep(mid, node, ap.pop(tc), tc, cc)) and
|
||||
sc = mid.getSummaryCtx()
|
||||
@@ -3235,7 +3242,7 @@ pragma[noinline]
|
||||
private predicate pathIntoArg(
|
||||
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
|
||||
) {
|
||||
exists(ArgumentNode arg |
|
||||
exists(ArgumentNodeExt arg |
|
||||
arg = mid.getNode() and
|
||||
cc = mid.getCallContext() and
|
||||
arg.argumentOf(call, i) and
|
||||
@@ -3248,7 +3255,7 @@ pragma[noinline]
|
||||
private predicate parameterCand(
|
||||
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
Stage4::revFlow(p, _, _, apa, config) and
|
||||
p.isParameterOf(callable, i)
|
||||
)
|
||||
@@ -3272,7 +3279,7 @@ private predicate pathIntoCallable0(
|
||||
* respectively.
|
||||
*/
|
||||
private predicate pathIntoCallable(
|
||||
PathNodeMid mid, ParameterNode p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
|
||||
PathNodeMid mid, ParameterNodeExt p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
|
||||
DataFlowCall call
|
||||
) {
|
||||
exists(int i, DataFlowCallable callable, AccessPath ap |
|
||||
@@ -3568,7 +3575,7 @@ private module FlowExploration {
|
||||
|
||||
private newtype TSummaryCtx1 =
|
||||
TSummaryCtx1None() or
|
||||
TSummaryCtx1Param(ParameterNode p)
|
||||
TSummaryCtx1Param(ParameterNodeExt p)
|
||||
|
||||
private newtype TSummaryCtx2 =
|
||||
TSummaryCtx2None() or
|
||||
@@ -3591,7 +3598,7 @@ private module FlowExploration {
|
||||
cc instanceof CallContextAny and
|
||||
sc1 = TSummaryCtx1None() and
|
||||
sc2 = TSummaryCtx2None() and
|
||||
ap = TPartialNil(getNodeType(node)) and
|
||||
ap = TPartialNil(getNodeDataFlowType(node)) and
|
||||
not fullBarrier(node, config) and
|
||||
exists(config.explorationLimit())
|
||||
or
|
||||
@@ -3611,7 +3618,7 @@ private module FlowExploration {
|
||||
or
|
||||
exists(PartialPathNodeRev mid |
|
||||
revPartialPathStep(mid, node, sc1, sc2, ap, config) and
|
||||
not clearsContent(node, ap.getHead()) and
|
||||
not clearsContentCached(node, ap.getHead()) and
|
||||
not fullBarrier(node, config) and
|
||||
distSink(getNodeEnclosingCallable(node), config) <= config.explorationLimit()
|
||||
)
|
||||
@@ -3625,9 +3632,9 @@ private module FlowExploration {
|
||||
exists(PartialPathNodeFwd mid |
|
||||
partialPathStep(mid, node, cc, sc1, sc2, ap, config) and
|
||||
not fullBarrier(node, config) and
|
||||
not clearsContent(node, ap.getHead().getContent()) and
|
||||
not clearsContentCached(node, ap.getHead().getContent()) and
|
||||
if node instanceof CastingNode
|
||||
then compatibleTypes(getNodeType(node), ap.getType())
|
||||
then compatibleTypes(getNodeDataFlowType(node), ap.getType())
|
||||
else any()
|
||||
)
|
||||
}
|
||||
@@ -3783,7 +3790,7 @@ private module FlowExploration {
|
||||
PartialPathNodeFwd mid, Node node, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2,
|
||||
PartialAccessPath ap, Configuration config
|
||||
) {
|
||||
not isUnreachableInCall(node, cc.(CallContextSpecificCall).getCall()) and
|
||||
not isUnreachableInCallCached(node, cc.(CallContextSpecificCall).getCall()) and
|
||||
(
|
||||
localFlowStep(mid.getNode(), node, config) and
|
||||
cc = mid.getCallContext() and
|
||||
@@ -3797,7 +3804,7 @@ private module FlowExploration {
|
||||
sc1 = mid.getSummaryCtx1() and
|
||||
sc2 = mid.getSummaryCtx2() and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getNodeType(node)) and
|
||||
ap = TPartialNil(getNodeDataFlowType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
or
|
||||
@@ -3813,7 +3820,7 @@ private module FlowExploration {
|
||||
sc1 = TSummaryCtx1None() and
|
||||
sc2 = TSummaryCtx2None() and
|
||||
mid.getAp() instanceof PartialAccessPathNil and
|
||||
ap = TPartialNil(getNodeType(node)) and
|
||||
ap = TPartialNil(getNodeDataFlowType(node)) and
|
||||
config = mid.getConfiguration()
|
||||
or
|
||||
partialPathStoreStep(mid, _, _, node, ap) and
|
||||
@@ -3827,7 +3834,7 @@ private module FlowExploration {
|
||||
sc1 = mid.getSummaryCtx1() and
|
||||
sc2 = mid.getSummaryCtx2() and
|
||||
apConsFwd(ap, tc, ap0, config) and
|
||||
compatibleTypes(ap.getType(), getNodeType(node))
|
||||
compatibleTypes(ap.getType(), getNodeDataFlowType(node))
|
||||
)
|
||||
or
|
||||
partialPathIntoCallable(mid, node, _, cc, sc1, sc2, _, ap, config)
|
||||
@@ -3924,7 +3931,7 @@ private module FlowExploration {
|
||||
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ArgumentNode arg |
|
||||
exists(ArgumentNodeExt arg |
|
||||
arg = mid.getNode() and
|
||||
cc = mid.getCallContext() and
|
||||
arg.argumentOf(call, i) and
|
||||
@@ -3943,7 +3950,7 @@ private module FlowExploration {
|
||||
}
|
||||
|
||||
private predicate partialPathIntoCallable(
|
||||
PartialPathNodeFwd mid, ParameterNode p, CallContext outercc, CallContextCall innercc,
|
||||
PartialPathNodeFwd mid, ParameterNodeExt p, CallContext outercc, CallContextCall innercc,
|
||||
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
|
||||
Configuration config
|
||||
) {
|
||||
@@ -3980,7 +3987,7 @@ private module FlowExploration {
|
||||
DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, CallContext cc,
|
||||
PartialAccessPath ap, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
|
||||
exists(ParameterNodeExt p, CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2 |
|
||||
partialPathIntoCallable(mid, p, cc, innercc, sc1, sc2, call, _, config) and
|
||||
paramFlowsThroughInPartialPath(kind, innercc, sc1, sc2, ap, config)
|
||||
)
|
||||
@@ -4037,7 +4044,7 @@ private module FlowExploration {
|
||||
apConsRev(ap, c, ap0, config)
|
||||
)
|
||||
or
|
||||
exists(ParameterNode p |
|
||||
exists(ParameterNodeExt p |
|
||||
mid.getNode() = p and
|
||||
viableParamArg(_, p, node) and
|
||||
sc1 = mid.getSummaryCtx1() and
|
||||
@@ -4115,7 +4122,7 @@ private module FlowExploration {
|
||||
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(PartialPathNodeRev mid, ParameterNode p |
|
||||
exists(PartialPathNodeRev mid, ParameterNodeExt p |
|
||||
mid.getNode() = p and
|
||||
p.isParameterOf(_, pos) and
|
||||
sc1 = mid.getSummaryCtx1() and
|
||||
@@ -4138,7 +4145,7 @@ private module FlowExploration {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate revPartialPathThroughCallable(
|
||||
PartialPathNodeRev mid, ArgumentNode node, RevPartialAccessPath ap, Configuration config
|
||||
PartialPathNodeRev mid, ArgumentNodeExt node, RevPartialAccessPath ap, Configuration config
|
||||
) {
|
||||
exists(DataFlowCall call, int pos |
|
||||
revPartialPathThroughCallable0(call, mid, pos, ap, config) and
|
||||
|
||||
Reference in New Issue
Block a user