diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll index d857cdaa359..59ece3ead6f 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll @@ -750,6 +750,27 @@ module Private { ) } + /** + * Holds if `p` can reach `n` in a summarized callable, using only value-preserving + * local steps. `clearsOrExcepts` records whether any node on the path from `p` to + * `n` either clears or expects contents. + */ + private predicate paramReachesLocal(ParamNode p, Node n, boolean clearsOrExcepts) { + viableParam(_, _, _, p) and + n = p and + clearsOrExcepts = false + or + exists(Node mid, boolean clearsOrExceptsMid | + paramReachesLocal(p, mid, clearsOrExceptsMid) and + summaryLocalStep(mid, n, true) and + if + summaryClearsContent(n, _) or + summaryExpectsContent(n, _) + then clearsOrExcepts = true + else clearsOrExcepts = clearsOrExceptsMid + ) + } + /** * Holds if use-use flow starting from `arg` should be prohibited. * @@ -759,15 +780,11 @@ module Private { */ pragma[nomagic] predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) { - exists(ParamNode p, Node mid, ParameterPosition ppos, Node ret | + exists(ParamNode p, ParameterPosition ppos, Node ret | + paramReachesLocal(p, ret, true) and p = summaryArgParam0(_, arg, sc) and p.isParameterOf(_, pragma[only_bind_into](ppos)) and - summaryLocalStep(p, mid, true) and - summaryLocalStep(mid, ret, true) and isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos)) - | - summaryClearsContent(mid, _) or - summaryExpectsContent(mid, _) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll index d857cdaa359..59ece3ead6f 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll @@ -750,6 +750,27 @@ module Private { ) } + /** + * Holds if `p` can reach `n` in a summarized callable, using only value-preserving + * local steps. `clearsOrExcepts` records whether any node on the path from `p` to + * `n` either clears or expects contents. + */ + private predicate paramReachesLocal(ParamNode p, Node n, boolean clearsOrExcepts) { + viableParam(_, _, _, p) and + n = p and + clearsOrExcepts = false + or + exists(Node mid, boolean clearsOrExceptsMid | + paramReachesLocal(p, mid, clearsOrExceptsMid) and + summaryLocalStep(mid, n, true) and + if + summaryClearsContent(n, _) or + summaryExpectsContent(n, _) + then clearsOrExcepts = true + else clearsOrExcepts = clearsOrExceptsMid + ) + } + /** * Holds if use-use flow starting from `arg` should be prohibited. * @@ -759,15 +780,11 @@ module Private { */ pragma[nomagic] predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) { - exists(ParamNode p, Node mid, ParameterPosition ppos, Node ret | + exists(ParamNode p, ParameterPosition ppos, Node ret | + paramReachesLocal(p, ret, true) and p = summaryArgParam0(_, arg, sc) and p.isParameterOf(_, pragma[only_bind_into](ppos)) and - summaryLocalStep(p, mid, true) and - summaryLocalStep(mid, ret, true) and isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos)) - | - summaryClearsContent(mid, _) or - summaryExpectsContent(mid, _) ) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll index d857cdaa359..59ece3ead6f 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll @@ -750,6 +750,27 @@ module Private { ) } + /** + * Holds if `p` can reach `n` in a summarized callable, using only value-preserving + * local steps. `clearsOrExcepts` records whether any node on the path from `p` to + * `n` either clears or expects contents. + */ + private predicate paramReachesLocal(ParamNode p, Node n, boolean clearsOrExcepts) { + viableParam(_, _, _, p) and + n = p and + clearsOrExcepts = false + or + exists(Node mid, boolean clearsOrExceptsMid | + paramReachesLocal(p, mid, clearsOrExceptsMid) and + summaryLocalStep(mid, n, true) and + if + summaryClearsContent(n, _) or + summaryExpectsContent(n, _) + then clearsOrExcepts = true + else clearsOrExcepts = clearsOrExceptsMid + ) + } + /** * Holds if use-use flow starting from `arg` should be prohibited. * @@ -759,15 +780,11 @@ module Private { */ pragma[nomagic] predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) { - exists(ParamNode p, Node mid, ParameterPosition ppos, Node ret | + exists(ParamNode p, ParameterPosition ppos, Node ret | + paramReachesLocal(p, ret, true) and p = summaryArgParam0(_, arg, sc) and p.isParameterOf(_, pragma[only_bind_into](ppos)) and - summaryLocalStep(p, mid, true) and - summaryLocalStep(mid, ret, true) and isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos)) - | - summaryClearsContent(mid, _) or - summaryExpectsContent(mid, _) ) } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll index d857cdaa359..59ece3ead6f 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll @@ -750,6 +750,27 @@ module Private { ) } + /** + * Holds if `p` can reach `n` in a summarized callable, using only value-preserving + * local steps. `clearsOrExcepts` records whether any node on the path from `p` to + * `n` either clears or expects contents. + */ + private predicate paramReachesLocal(ParamNode p, Node n, boolean clearsOrExcepts) { + viableParam(_, _, _, p) and + n = p and + clearsOrExcepts = false + or + exists(Node mid, boolean clearsOrExceptsMid | + paramReachesLocal(p, mid, clearsOrExceptsMid) and + summaryLocalStep(mid, n, true) and + if + summaryClearsContent(n, _) or + summaryExpectsContent(n, _) + then clearsOrExcepts = true + else clearsOrExcepts = clearsOrExceptsMid + ) + } + /** * Holds if use-use flow starting from `arg` should be prohibited. * @@ -759,15 +780,11 @@ module Private { */ pragma[nomagic] predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) { - exists(ParamNode p, Node mid, ParameterPosition ppos, Node ret | + exists(ParamNode p, ParameterPosition ppos, Node ret | + paramReachesLocal(p, ret, true) and p = summaryArgParam0(_, arg, sc) and p.isParameterOf(_, pragma[only_bind_into](ppos)) and - summaryLocalStep(p, mid, true) and - summaryLocalStep(mid, ret, true) and isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos)) - | - summaryClearsContent(mid, _) or - summaryExpectsContent(mid, _) ) }