From 662f522032f2b2966b4f03e914ceff0d3d72c54b Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 23 Jun 2026 20:30:55 +0100 Subject: [PATCH] C++: Properly instantiate the new reverse flow feature. --- .../cpp/dataflow/internal/FlowSummaryImpl.qll | 27 +++++++++++++++++ .../ir/dataflow/internal/DataFlowPrivate.qll | 30 ++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll index c942014d094..cb85f8aee0e 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll @@ -6,6 +6,7 @@ private import cpp as Cpp private import codeql.dataflow.internal.FlowSummaryImpl private import codeql.dataflow.internal.AccessPathSyntax as AccessPath private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate +private import semmle.code.cpp.ir.dataflow.internal.DataFlowNodes private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific as DataFlowImplSpecific private import semmle.code.cpp.dataflow.ExternalFlow @@ -20,8 +21,22 @@ module Input implements InputSig { class SinkBase = Void; + class FlowSummaryCallBase = CallInstruction; + predicate callableFromSource(SummarizedCallableBase c) { exists(c.getBlock()) } + FlowSummaryCallBase getASourceCall(SummarizedCallableBase sc) { + result.getStaticCallTarget() = sc + } + + DataFlowCallable getSummarizedCallableAsDataFlowCallable(SummarizedCallableBase c) { + result.asSummarizedCallable() = c + } + + DataFlowCallable getSourceCallEnclosingCallable(FlowSummaryCallBase call) { + result.asSourceCallable() = call.getEnclosingFunction() + } + ArgumentPosition callbackSelfParameterPosition() { result = TDirectPosition(-1) } ReturnKind getStandardReturnValueKind() { result = getReturnValueKind("") } @@ -30,6 +45,10 @@ module Input implements InputSig { arg = repeatStars(result.(NormalReturnKind).getIndirectionIndex()) } + ParameterPosition getFlowSummaryParameterPosition(ReturnKind rk) { + result = TFlowSummaryPosition(rk) + } + string encodeParameterPosition(ParameterPosition pos) { result = pos.toString() } string encodeArgumentPosition(ArgumentPosition pos) { result = pos.toString() } @@ -110,6 +129,14 @@ private module StepsInput implements Impl::Private::StepsInputSig { result.getStaticCallTarget().getUnderlyingCallable() = sc } + Node getSourceOutNode(Input::FlowSummaryCallBase call, ReturnKind rk) { + exists(IndirectReturnOutNode out | result = out | + out.getCallInstruction() = call and + pragma[only_bind_out](rk.(NormalReturnKind).getIndirectionIndex()) = + pragma[only_bind_out](out.getIndirectionIndex()) + ) + } + DataFlowCallable getSourceNodeEnclosingCallable(Input::SourceBase source) { none() } Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponentStack s) { none() } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index 83f240ddae5..f791850bd00 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -561,6 +561,21 @@ class SummaryArgumentNode extends ArgumentNode, FlowSummaryNode { } } +/** An argument node that re-enters return output as input to a flow summary. */ +private class FlowSummaryArgumentNode extends ArgumentNode, FlowSummaryNode { + private CallInstruction callInstruction; + private ReturnKind rk; + + FlowSummaryArgumentNode() { + this.getSummaryNode() = FlowSummaryImpl::Private::summaryArgumentNode(callInstruction, rk) + } + + override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { + call.asCallInstruction() = callInstruction and + pos = TFlowSummaryPosition(rk) + } +} + /** A parameter position represented by an integer. */ class ParameterPosition = Position; @@ -616,6 +631,18 @@ class IndirectionPosition extends Position, TIndirectionPosition { final override int getIndirectionIndex() { result = indirectionIndex } } +class FlowSummaryPosition extends Position, TFlowSummaryPosition { + ReturnKind rk; + + FlowSummaryPosition() { this = TFlowSummaryPosition(rk) } + + override string toString() { result = "write to: " + rk.toString() } + + override int getArgumentIndex() { none() } + + final override int getIndirectionIndex() { result = rk.getIndirectionIndex() } +} + newtype TPosition = TDirectPosition(int argumentIndex) { exists(any(CallInstruction c).getArgument(argumentIndex)) @@ -634,7 +661,8 @@ newtype TPosition = p = f.getParameter(argumentIndex) and indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(p.getUnspecifiedType()) - 1] ) - } + } or + TFlowSummaryPosition(ReturnKind rk) { FlowSummaryImpl::Private::relevantFlowSummaryPosition(rk) } private newtype TReturnKind = TNormalReturnKind(int indirectionIndex) {