From bb258813a15401eaa1920c442b6dac94617a90ce Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 18 May 2021 11:15:55 +0200 Subject: [PATCH 1/6] Dataflow: Improve performance for dispatch-join in flow-through. --- .../java/dataflow/internal/DataFlowImpl.qll | 317 ++++++++++++------ 1 file changed, 222 insertions(+), 95 deletions(-) diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll index 058d66b1496..c60bb107fdf 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and From 4406b8e33979eed493326c005c0dbc5e5cf6d689 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 19 May 2021 19:22:36 +0200 Subject: [PATCH 2/6] Dataflow: Sync. --- .../cpp/dataflow/internal/DataFlowImpl.qll | 317 ++++++++++++------ .../cpp/dataflow/internal/DataFlowImpl2.qll | 317 ++++++++++++------ .../cpp/dataflow/internal/DataFlowImpl3.qll | 317 ++++++++++++------ .../cpp/dataflow/internal/DataFlowImpl4.qll | 317 ++++++++++++------ .../dataflow/internal/DataFlowImplLocal.qll | 317 ++++++++++++------ .../cpp/ir/dataflow/internal/DataFlowImpl.qll | 317 ++++++++++++------ .../ir/dataflow/internal/DataFlowImpl2.qll | 317 ++++++++++++------ .../ir/dataflow/internal/DataFlowImpl3.qll | 317 ++++++++++++------ .../ir/dataflow/internal/DataFlowImpl4.qll | 317 ++++++++++++------ .../csharp/dataflow/internal/DataFlowImpl.qll | 317 ++++++++++++------ .../dataflow/internal/DataFlowImpl2.qll | 317 ++++++++++++------ .../dataflow/internal/DataFlowImpl3.qll | 317 ++++++++++++------ .../dataflow/internal/DataFlowImpl4.qll | 317 ++++++++++++------ .../dataflow/internal/DataFlowImpl5.qll | 317 ++++++++++++------ .../java/dataflow/internal/DataFlowImpl2.qll | 317 ++++++++++++------ .../java/dataflow/internal/DataFlowImpl3.qll | 317 ++++++++++++------ .../java/dataflow/internal/DataFlowImpl4.qll | 317 ++++++++++++------ .../java/dataflow/internal/DataFlowImpl5.qll | 317 ++++++++++++------ .../java/dataflow/internal/DataFlowImpl6.qll | 317 ++++++++++++------ .../dataflow/new/internal/DataFlowImpl.qll | 317 ++++++++++++------ .../dataflow/new/internal/DataFlowImpl2.qll | 317 ++++++++++++------ .../dataflow/new/internal/DataFlowImpl3.qll | 317 ++++++++++++------ .../dataflow/new/internal/DataFlowImpl4.qll | 317 ++++++++++++------ 23 files changed, 5106 insertions(+), 2185 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index 058d66b1496..c60bb107fdf 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll index 058d66b1496..c60bb107fdf 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll index 058d66b1496..c60bb107fdf 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll index 058d66b1496..c60bb107fdf 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll index 058d66b1496..c60bb107fdf 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index 058d66b1496..c60bb107fdf 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index 058d66b1496..c60bb107fdf 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index 058d66b1496..c60bb107fdf 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index 058d66b1496..c60bb107fdf 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index 058d66b1496..c60bb107fdf 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll index 058d66b1496..c60bb107fdf 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll index 058d66b1496..c60bb107fdf 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll index 058d66b1496..c60bb107fdf 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll index 058d66b1496..c60bb107fdf 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll index 058d66b1496..c60bb107fdf 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll index 058d66b1496..c60bb107fdf 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll index 058d66b1496..c60bb107fdf 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll index 058d66b1496..c60bb107fdf 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll index 058d66b1496..c60bb107fdf 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll index 058d66b1496..c60bb107fdf 100644 --- a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll index 058d66b1496..c60bb107fdf 100644 --- a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll index 058d66b1496..c60bb107fdf 100644 --- a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and diff --git a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll index 058d66b1496..c60bb107fdf 100644 --- a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll @@ -605,6 +605,15 @@ private module Stage1 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Node node, boolean toReturn | + revFlow(node, toReturn, config) and + revFlowInToReturn(call, node, config) and + revFlowIsReturned(call, toReturn, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, config)) and @@ -827,6 +836,16 @@ private module Stage2 { PrevStage::revFlow(node, _, _, apa, config) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -893,13 +912,11 @@ private module Stage2 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -950,17 +967,14 @@ private module Stage2 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -975,7 +989,13 @@ private module Stage2 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1006,6 +1026,25 @@ private module Stage2 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1071,14 +1110,12 @@ private module Stage2 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1126,12 +1163,10 @@ private module Stage2 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1141,7 +1176,12 @@ private module Stage2 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1211,6 +1251,15 @@ private module Stage2 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -1459,6 +1508,16 @@ private module Stage3 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -1532,13 +1591,11 @@ private module Stage3 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -1589,17 +1646,14 @@ private module Stage3 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -1614,7 +1668,13 @@ private module Stage3 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1645,6 +1705,25 @@ private module Stage3 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -1710,14 +1789,12 @@ private module Stage3 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -1765,12 +1842,10 @@ private module Stage3 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -1780,7 +1855,12 @@ private module Stage3 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -1850,6 +1930,15 @@ private module Stage3 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and @@ -2120,8 +2209,6 @@ private module Stage4 { bindingset[innercc, inner, call] private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) { resolveReturn(innercc, inner, call) - or - innercc.(CallContextCall).matchesCall(call) } bindingset[node, cc, config] @@ -2174,6 +2261,16 @@ private module Stage4 { ) } + pragma[nomagic] + private predicate flowThroughOutOfCall( + DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, + Configuration config + ) { + flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and + PrevStage::callMayFlowThroughRev(call, config) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + } + /** * Holds if `node` is reachable with access path `ap` from a source in the * configuration `config`. @@ -2247,13 +2344,11 @@ private module Stage4 { ) or // flow out of a callable - exists(DataFlowCall call | - fwdFlowOut(call, node, any(CcNoCall innercc), cc, argAp, ap, config) - or - exists(Ap argAp0 | - fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) - ) + fwdFlowOutNotFromArg(node, cc, argAp, ap, config) + or + exists(DataFlowCall call, Ap argAp0 | + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) ) } @@ -2304,17 +2399,14 @@ private module Stage4 { ) } - /** - * Holds if flow may exit from `call` at `out` with access path `ap`. The - * inner call context is `innercc`, but `ccOut` is just the call context - * based on the return step. In the case of through-flow `ccOut` is discarded - * and replaced by the outer call context as tracked by `fwdFlowIsEntered`. - */ pragma[nomagic] - private predicate fwdFlowOut( - DataFlowCall call, Node out, Cc innercc, Cc ccOut, ApOption argAp, Ap ap, Configuration config + private predicate fwdFlowOutNotFromArg( + Node out, Cc ccOut, ApOption argAp, Ap ap, Configuration config ) { - exists(ReturnNodeExt ret, boolean allowsFieldFlow, DataFlowCallable inner | + exists( + DataFlowCall call, ReturnNodeExt ret, boolean allowsFieldFlow, CcNoCall innercc, + DataFlowCallable inner + | fwdFlow(ret, innercc, argAp, ap, config) and flowOutOfCall(call, ret, out, allowsFieldFlow, config) and inner = getNodeEnclosingCallable(ret) and @@ -2329,7 +2421,13 @@ private module Stage4 { private predicate fwdFlowOutFromArg( DataFlowCall call, Node out, Ap argAp, Ap ap, Configuration config ) { - fwdFlowOut(call, out, any(CcCall ccc), _, apSome(argAp), ap, config) + exists(ReturnNodeExt ret, boolean allowsFieldFlow, CcCall ccc | + fwdFlow(ret, ccc, apSome(argAp), ap, config) and + flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and + ccc.matchesCall(call) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2360,6 +2458,25 @@ private module Stage4 { fwdFlowConsCand(ap1, c, ap2, config) } + pragma[nomagic] + private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { + exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | + fwdFlow(node, cc, argAp, ap, config) and + fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowIsEntered(call, cc, argAp, argAp0, config) + ) + } + + pragma[nomagic] + private predicate flowThroughIntoCall( + DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + ) { + flowIntoCall(call, node1, node2, allowsFieldFlow, config) and + fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + callMayFlowThroughFwd(call, pragma[only_bind_into](config)) + } + /** * Holds if `node` with access path `ap` is part of a path from a source to a * sink in the configuration `config`. @@ -2425,14 +2542,12 @@ private module Stage4 { ) or // flow into a callable - exists(DataFlowCall call | - revFlowIn(call, node, toReturn, returnAp, ap, config) and - toReturn = false - or - exists(Ap returnAp0 | - revFlowInToReturn(call, node, returnAp0, ap, config) and - revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) - ) + revFlowInNotToReturn(node, returnAp, ap, config) and + toReturn = false + or + exists(DataFlowCall call, Ap returnAp0 | + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) or // flow out of a callable @@ -2480,12 +2595,10 @@ private module Stage4 { } pragma[nomagic] - private predicate revFlowIn( - DataFlowCall call, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap, Configuration config - ) { + private predicate revFlowInNotToReturn(ArgNode arg, ApOption returnAp, Ap ap, Configuration config) { exists(ParamNode p, boolean allowsFieldFlow | - revFlow(p, toReturn, returnAp, ap, config) and - flowIntoCall(call, arg, p, allowsFieldFlow, config) + revFlow(p, false, returnAp, ap, config) and + flowIntoCall(_, arg, p, allowsFieldFlow, config) | ap instanceof ApNil or allowsFieldFlow = true ) @@ -2495,7 +2608,12 @@ private module Stage4 { private predicate revFlowInToReturn( DataFlowCall call, ArgNode arg, Ap returnAp, Ap ap, Configuration config ) { - revFlowIn(call, arg, true, apSome(returnAp), ap, config) + exists(ParamNode p, boolean allowsFieldFlow | + revFlow(p, true, apSome(returnAp), ap, config) and + flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) + | + ap instanceof ApNil or allowsFieldFlow = true + ) } /** @@ -2565,6 +2683,15 @@ private module Stage4 { ) } + pragma[nomagic] + predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { + exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(node, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, node, returnAp0, ap, config) and + revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) + ) + } + predicate stats(boolean fwd, int nodes, int fields, int conscand, int tuples, Configuration config) { fwd = true and nodes = count(Node node | fwdFlow(node, _, _, _, config)) and From 017bf68906ad9418b087ff6c5f40752d8e1140dc Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 25 May 2021 11:40:53 +0200 Subject: [PATCH 3/6] Dataflow: Fix bad join order. --- .../cpp/dataflow/internal/DataFlowImpl.qll | 18 ++++++++++++------ .../cpp/dataflow/internal/DataFlowImpl2.qll | 18 ++++++++++++------ .../cpp/dataflow/internal/DataFlowImpl3.qll | 18 ++++++++++++------ .../cpp/dataflow/internal/DataFlowImpl4.qll | 18 ++++++++++++------ .../dataflow/internal/DataFlowImplLocal.qll | 18 ++++++++++++------ .../cpp/ir/dataflow/internal/DataFlowImpl.qll | 18 ++++++++++++------ .../cpp/ir/dataflow/internal/DataFlowImpl2.qll | 18 ++++++++++++------ .../cpp/ir/dataflow/internal/DataFlowImpl3.qll | 18 ++++++++++++------ .../cpp/ir/dataflow/internal/DataFlowImpl4.qll | 18 ++++++++++++------ .../csharp/dataflow/internal/DataFlowImpl.qll | 18 ++++++++++++------ .../csharp/dataflow/internal/DataFlowImpl2.qll | 18 ++++++++++++------ .../csharp/dataflow/internal/DataFlowImpl3.qll | 18 ++++++++++++------ .../csharp/dataflow/internal/DataFlowImpl4.qll | 18 ++++++++++++------ .../csharp/dataflow/internal/DataFlowImpl5.qll | 18 ++++++++++++------ .../java/dataflow/internal/DataFlowImpl.qll | 18 ++++++++++++------ .../java/dataflow/internal/DataFlowImpl2.qll | 18 ++++++++++++------ .../java/dataflow/internal/DataFlowImpl3.qll | 18 ++++++++++++------ .../java/dataflow/internal/DataFlowImpl4.qll | 18 ++++++++++++------ .../java/dataflow/internal/DataFlowImpl5.qll | 18 ++++++++++++------ .../java/dataflow/internal/DataFlowImpl6.qll | 18 ++++++++++++------ .../dataflow/new/internal/DataFlowImpl.qll | 18 ++++++++++++------ .../dataflow/new/internal/DataFlowImpl2.qll | 18 ++++++++++++------ .../dataflow/new/internal/DataFlowImpl3.qll | 18 ++++++++++++------ .../dataflow/new/internal/DataFlowImpl4.qll | 18 ++++++++++++------ 24 files changed, 288 insertions(+), 144 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index c60bb107fdf..dc9583c6653 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll index c60bb107fdf..dc9583c6653 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll index c60bb107fdf..dc9583c6653 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll index c60bb107fdf..dc9583c6653 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll index c60bb107fdf..dc9583c6653 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index c60bb107fdf..dc9583c6653 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index c60bb107fdf..dc9583c6653 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index c60bb107fdf..dc9583c6653 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index c60bb107fdf..dc9583c6653 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index c60bb107fdf..dc9583c6653 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll index c60bb107fdf..dc9583c6653 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll index c60bb107fdf..dc9583c6653 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll index c60bb107fdf..dc9583c6653 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll index c60bb107fdf..dc9583c6653 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll index c60bb107fdf..dc9583c6653 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll index c60bb107fdf..dc9583c6653 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll index c60bb107fdf..dc9583c6653 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll index c60bb107fdf..dc9583c6653 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll index c60bb107fdf..dc9583c6653 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll index c60bb107fdf..dc9583c6653 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll index c60bb107fdf..dc9583c6653 100644 --- a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll index c60bb107fdf..dc9583c6653 100644 --- a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll index c60bb107fdf..dc9583c6653 100644 --- a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } diff --git a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll index c60bb107fdf..dc9583c6653 100644 --- a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll @@ -1029,9 +1029,11 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -1708,9 +1710,11 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } @@ -2461,9 +2465,11 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, cc, argAp, ap, config) and + fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, node, argAp0, ap, config) and - fwdFlowIsEntered(call, cc, argAp, argAp0, config) + fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + pragma[only_bind_into](config)) ) } From 683f853fa515afe3e4eb5ff29015b21052f86169 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Mon, 31 May 2021 15:14:13 +0200 Subject: [PATCH 4/6] Dataflow: Fix another bad join order. --- .../cpp/dataflow/internal/DataFlowImpl.qll | 21 +++++++++++-------- .../cpp/dataflow/internal/DataFlowImpl2.qll | 21 +++++++++++-------- .../cpp/dataflow/internal/DataFlowImpl3.qll | 21 +++++++++++-------- .../cpp/dataflow/internal/DataFlowImpl4.qll | 21 +++++++++++-------- .../dataflow/internal/DataFlowImplLocal.qll | 21 +++++++++++-------- .../cpp/ir/dataflow/internal/DataFlowImpl.qll | 21 +++++++++++-------- .../ir/dataflow/internal/DataFlowImpl2.qll | 21 +++++++++++-------- .../ir/dataflow/internal/DataFlowImpl3.qll | 21 +++++++++++-------- .../ir/dataflow/internal/DataFlowImpl4.qll | 21 +++++++++++-------- .../csharp/dataflow/internal/DataFlowImpl.qll | 21 +++++++++++-------- .../dataflow/internal/DataFlowImpl2.qll | 21 +++++++++++-------- .../dataflow/internal/DataFlowImpl3.qll | 21 +++++++++++-------- .../dataflow/internal/DataFlowImpl4.qll | 21 +++++++++++-------- .../dataflow/internal/DataFlowImpl5.qll | 21 +++++++++++-------- .../java/dataflow/internal/DataFlowImpl.qll | 21 +++++++++++-------- .../java/dataflow/internal/DataFlowImpl2.qll | 21 +++++++++++-------- .../java/dataflow/internal/DataFlowImpl3.qll | 21 +++++++++++-------- .../java/dataflow/internal/DataFlowImpl4.qll | 21 +++++++++++-------- .../java/dataflow/internal/DataFlowImpl5.qll | 21 +++++++++++-------- .../java/dataflow/internal/DataFlowImpl6.qll | 21 +++++++++++-------- .../dataflow/new/internal/DataFlowImpl.qll | 21 +++++++++++-------- .../dataflow/new/internal/DataFlowImpl2.qll | 21 +++++++++++-------- .../dataflow/new/internal/DataFlowImpl3.qll | 21 +++++++++++-------- .../dataflow/new/internal/DataFlowImpl4.qll | 21 +++++++++++-------- 24 files changed, 288 insertions(+), 216 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index dc9583c6653..d992b601c22 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll index dc9583c6653..d992b601c22 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll index dc9583c6653..d992b601c22 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll index dc9583c6653..d992b601c22 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll index dc9583c6653..d992b601c22 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index dc9583c6653..d992b601c22 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index dc9583c6653..d992b601c22 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index dc9583c6653..d992b601c22 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index dc9583c6653..d992b601c22 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index dc9583c6653..d992b601c22 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll index dc9583c6653..d992b601c22 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll index dc9583c6653..d992b601c22 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll index dc9583c6653..d992b601c22 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll index dc9583c6653..d992b601c22 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll index dc9583c6653..d992b601c22 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll index dc9583c6653..d992b601c22 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll index dc9583c6653..d992b601c22 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll index dc9583c6653..d992b601c22 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll index dc9583c6653..d992b601c22 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll index dc9583c6653..d992b601c22 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll index dc9583c6653..d992b601c22 100644 --- a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll index dc9583c6653..d992b601c22 100644 --- a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll index dc9583c6653..d992b601c22 100644 --- a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** diff --git a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll index dc9583c6653..d992b601c22 100644 --- a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll @@ -841,9 +841,10 @@ private module Stage2 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -1515,9 +1516,10 @@ private module Stage3 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** @@ -2270,9 +2272,10 @@ private module Stage4 { DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, config) and - PrevStage::callMayFlowThroughRev(call, config) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, config) + flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + pragma[only_bind_into](config)) } /** From 4f9a6c151bb6c045d262b4e0da893ddfe562b563 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 1 Jun 2021 10:29:17 +0200 Subject: [PATCH 5/6] Dataflow: Code review fixes. --- .../cpp/dataflow/internal/DataFlowImpl.qll | 87 +++++++++---------- .../cpp/dataflow/internal/DataFlowImpl2.qll | 87 +++++++++---------- .../cpp/dataflow/internal/DataFlowImpl3.qll | 87 +++++++++---------- .../cpp/dataflow/internal/DataFlowImpl4.qll | 87 +++++++++---------- .../dataflow/internal/DataFlowImplLocal.qll | 87 +++++++++---------- .../cpp/ir/dataflow/internal/DataFlowImpl.qll | 87 +++++++++---------- .../ir/dataflow/internal/DataFlowImpl2.qll | 87 +++++++++---------- .../ir/dataflow/internal/DataFlowImpl3.qll | 87 +++++++++---------- .../ir/dataflow/internal/DataFlowImpl4.qll | 87 +++++++++---------- .../csharp/dataflow/internal/DataFlowImpl.qll | 87 +++++++++---------- .../dataflow/internal/DataFlowImpl2.qll | 87 +++++++++---------- .../dataflow/internal/DataFlowImpl3.qll | 87 +++++++++---------- .../dataflow/internal/DataFlowImpl4.qll | 87 +++++++++---------- .../dataflow/internal/DataFlowImpl5.qll | 87 +++++++++---------- .../java/dataflow/internal/DataFlowImpl.qll | 87 +++++++++---------- .../java/dataflow/internal/DataFlowImpl2.qll | 87 +++++++++---------- .../java/dataflow/internal/DataFlowImpl3.qll | 87 +++++++++---------- .../java/dataflow/internal/DataFlowImpl4.qll | 87 +++++++++---------- .../java/dataflow/internal/DataFlowImpl5.qll | 87 +++++++++---------- .../java/dataflow/internal/DataFlowImpl6.qll | 87 +++++++++---------- .../dataflow/new/internal/DataFlowImpl.qll | 87 +++++++++---------- .../dataflow/new/internal/DataFlowImpl2.qll | 87 +++++++++---------- .../dataflow/new/internal/DataFlowImpl3.qll | 87 +++++++++---------- .../dataflow/new/internal/DataFlowImpl4.qll | 87 +++++++++---------- 24 files changed, 1008 insertions(+), 1080 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index d992b601c22..2638d093be4 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll index d992b601c22..2638d093be4 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll index d992b601c22..2638d093be4 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll index d992b601c22..2638d093be4 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll index d992b601c22..2638d093be4 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index d992b601c22..2638d093be4 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index d992b601c22..2638d093be4 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index d992b601c22..2638d093be4 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index d992b601c22..2638d093be4 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index d992b601c22..2638d093be4 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll index d992b601c22..2638d093be4 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll index d992b601c22..2638d093be4 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll index d992b601c22..2638d093be4 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll index d992b601c22..2638d093be4 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll index d992b601c22..2638d093be4 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll index d992b601c22..2638d093be4 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll index d992b601c22..2638d093be4 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll index d992b601c22..2638d093be4 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll index d992b601c22..2638d093be4 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll index d992b601c22..2638d093be4 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll index d992b601c22..2638d093be4 100644 --- a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll index d992b601c22..2638d093be4 100644 --- a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll index d992b601c22..2638d093be4 100644 --- a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } diff --git a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll index d992b601c22..2638d093be4 100644 --- a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll @@ -607,9 +607,9 @@ private module Stage1 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Node node, boolean toReturn | - revFlow(node, toReturn, config) and - revFlowInToReturn(call, node, config) and + exists(ArgNode arg, boolean toReturn | + revFlow(arg, toReturn, config) and + revFlowInToReturn(call, arg, config) and revFlowIsReturned(call, toReturn, config) ) } @@ -838,12 +838,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1029,10 +1028,10 @@ private module Stage2 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1040,11 +1039,11 @@ private module Stage2 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1256,9 +1255,9 @@ private module Stage2 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -1513,12 +1512,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -1711,10 +1709,10 @@ private module Stage3 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -1722,11 +1720,11 @@ private module Stage3 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -1938,9 +1936,9 @@ private module Stage3 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } @@ -2269,12 +2267,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCall call, ReturnNodeExt node1, Node node2, boolean allowsFieldFlow, - Configuration config + DataFlowCall call, ReturnNodeExt ret, Node out, boolean allowsFieldFlow, Configuration config ) { - flowOutOfCall(call, node1, node2, allowsFieldFlow, pragma[only_bind_into](config)) and + flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(node1), _, + PrevStage::parameterMayFlowThrough(_, getNodeEnclosingCallable(ret), _, pragma[only_bind_into](config)) } @@ -2467,10 +2464,10 @@ private module Stage4 { pragma[nomagic] private predicate callMayFlowThroughFwd(DataFlowCall call, Configuration config) { - exists(Ap argAp0, Node node, Cc cc, ApOption argAp, Ap ap | - fwdFlow(node, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, + exists(Ap argAp0, Node out, Cc cc, ApOption argAp, Ap ap | + fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and - fwdFlowOutFromArg(call, node, argAp0, ap, config) and + fwdFlowOutFromArg(call, out, argAp0, ap, config) and fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, pragma[only_bind_into](config)) ) @@ -2478,11 +2475,11 @@ private module Stage4 { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCall call, ArgNode node1, ParamNode node2, boolean allowsFieldFlow, Configuration config + DataFlowCall call, ArgNode arg, ParamNode p, boolean allowsFieldFlow, Configuration config ) { - flowIntoCall(call, node1, node2, allowsFieldFlow, config) and - fwdFlow(node1, _, _, _, pragma[only_bind_into](config)) and - PrevStage::parameterMayFlowThrough(node2, _, _, pragma[only_bind_into](config)) and + flowIntoCall(call, arg, p, allowsFieldFlow, config) and + fwdFlow(arg, _, _, _, pragma[only_bind_into](config)) and + PrevStage::parameterMayFlowThrough(p, _, _, pragma[only_bind_into](config)) and callMayFlowThroughFwd(call, pragma[only_bind_into](config)) } @@ -2694,9 +2691,9 @@ private module Stage4 { pragma[nomagic] predicate callMayFlowThroughRev(DataFlowCall call, Configuration config) { - exists(Ap returnAp0, Node node, boolean toReturn, ApOption returnAp, Ap ap | - revFlow(node, toReturn, returnAp, ap, config) and - revFlowInToReturn(call, node, returnAp0, ap, config) and + exists(Ap returnAp0, ArgNode arg, boolean toReturn, ApOption returnAp, Ap ap | + revFlow(arg, toReturn, returnAp, ap, config) and + revFlowInToReturn(call, arg, returnAp0, ap, config) and revFlowIsReturned(call, toReturn, returnAp, returnAp0, config) ) } From 5d21c64247b7bba2adad03c08cdf8341f68f836d Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 1 Jun 2021 10:49:47 +0200 Subject: [PATCH 6/6] Dataflow: qldoc fix. --- cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll | 4 +++- .../src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll | 4 +++- .../src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll | 4 +++- .../src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll | 4 +++- .../semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll | 4 +++- .../src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll | 4 +++- .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll | 4 +++- .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll | 4 +++- .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll | 4 +++- .../src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll | 4 +++- .../semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll | 4 +++- .../semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll | 4 +++- .../semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll | 4 +++- .../semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll | 4 +++- .../src/semmle/code/java/dataflow/internal/DataFlowImpl.qll | 4 +++- .../src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll | 4 +++- .../src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll | 4 +++- .../src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll | 4 +++- .../src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll | 4 +++- .../src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll | 4 +++- .../src/semmle/python/dataflow/new/internal/DataFlowImpl.qll | 4 +++- .../src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll | 4 +++- .../src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll | 4 +++- .../src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll | 4 +++- 24 files changed, 72 insertions(+), 24 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index 2638d093be4..9b14db7ef88 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll index 2638d093be4..9b14db7ef88 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll index 2638d093be4..9b14db7ef88 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll index 2638d093be4..9b14db7ef88 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll index 2638d093be4..9b14db7ef88 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index 2638d093be4..9b14db7ef88 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index 2638d093be4..9b14db7ef88 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index 2638d093be4..9b14db7ef88 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index 2638d093be4..9b14db7ef88 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index 2638d093be4..9b14db7ef88 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll index 2638d093be4..9b14db7ef88 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll index 2638d093be4..9b14db7ef88 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll index 2638d093be4..9b14db7ef88 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll index 2638d093be4..9b14db7ef88 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll index 2638d093be4..9b14db7ef88 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll index 2638d093be4..9b14db7ef88 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll index 2638d093be4..9b14db7ef88 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll index 2638d093be4..9b14db7ef88 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll index 2638d093be4..9b14db7ef88 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll index 2638d093be4..9b14db7ef88 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll index 2638d093be4..9b14db7ef88 100644 --- a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll index 2638d093be4..9b14db7ef88 100644 --- a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl2.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll index 2638d093be4..9b14db7ef88 100644 --- a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl3.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) { diff --git a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll index 2638d093be4..9b14db7ef88 100644 --- a/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ b/python/ql/src/semmle/python/dataflow/new/internal/DataFlowImpl4.qll @@ -532,7 +532,9 @@ private module Stage1 { } /** - * Holds if an output from `call` is reached in the flow covered by `revFlow`. + * Holds if an output from `call` is reached in the flow covered by `revFlow` + * and data might flow through the target callable resulting in reverse flow + * reaching an argument of `call`. */ pragma[nomagic] private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn, Configuration config) {