From 607a1e46dae1ad4169b8ff7f76e453c3598e91c2 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 28 Apr 2025 20:02:44 +0100 Subject: [PATCH 01/10] Shared: Generate value-preserving summaries when possible. --- .../internal/ModelGeneratorImpl.qll | 191 +++++++++++++----- .../modelgenerator/internal/ModelPrinting.qll | 8 +- 2 files changed, 150 insertions(+), 49 deletions(-) diff --git a/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll b/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll index b9592964f931..1856908206f2 100644 --- a/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll +++ b/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll @@ -11,6 +11,7 @@ private import codeql.dataflow.internal.ContentDataFlowImpl private import codeql.dataflow.internal.DataFlowImplCommon as DataFlowImplCommon private import codeql.util.Location private import ModelPrinting +private import codeql.util.Unit /** * Provides language-specific model generator parameters. @@ -464,14 +465,22 @@ module MakeModelGenerator< override string toString() { result = "TaintStore(" + step + ")" } } - /** - * A data flow configuration for tracking flow through APIs. - * The sources are the parameters of an API and the sinks are the return values (excluding `this`) and parameters. - * - * This can be used to generate Flow summaries for APIs from parameter to return. - */ - private module PropagateFlowConfig implements DataFlow::StateConfigSig { - class FlowState = TaintState; + private signature module PropagateFlowConfigInputSig { + class FlowState; + + FlowState initialState(); + + default predicate isAdditionalFlowStep( + DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2 + ) { + none() + } + } + + private module PropagateFlowConfig + implements DataFlow::StateConfigSig + { + import PropagateFlowConfigInput predicate isSource(DataFlow::Node source, FlowState state) { source instanceof DataFlow::ParameterNode and @@ -480,7 +489,7 @@ module MakeModelGenerator< c instanceof DataFlowSummaryTargetApi and not isUninterestingForHeuristicDataFlowModels(c) ) and - state.(TaintRead).getStep() = 0 + state = initialState() } predicate isSink(DataFlow::Node sink, FlowState state) { @@ -494,6 +503,31 @@ module MakeModelGenerator< not exists(captureQualifierFlow(getAsExprEnclosingCallable(sink))) } + predicate isAdditionalFlowStep = PropagateFlowConfigInput::isAdditionalFlowStep/4; + + predicate isBarrier(DataFlow::Node n) { + exists(Type t | t = n.(NodeExtended).getType() and not isRelevantType(t)) + } + + DataFlow::FlowFeature getAFeature() { + result instanceof DataFlow::FeatureEqualSourceSinkCallContext + } + } + + /** + * A module used to construct a data flow configuration for tracking taint- + * flow through APIs. + * The sources are the parameters of an API and the sinks are the return + * values (excluding `this`) and parameters. + * + * This can be used to generate flow summaries for APIs from parameter to + * return. + */ + module PropagateFlowConfigInputTaintInput implements PropagateFlowConfigInputSig { + class FlowState = TaintState; + + FlowState initialState() { result.(TaintRead).getStep() = 0 } + predicate isAdditionalFlowStep( DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2 ) { @@ -515,51 +549,107 @@ module MakeModelGenerator< state1.(TaintRead).getStep() + 1 = state2.(TaintRead).getStep() ) } + } - predicate isBarrier(DataFlow::Node n) { - exists(Type t | t = n.(NodeExtended).getType() and not isRelevantType(t)) - } + /** + * A data flow configuration for tracking taint-flow through APIs. + * The sources are the parameters of an API and the sinks are the return + * values (excluding `this`) and parameters. + * + * This can be used to generate flow summaries for APIs from parameter to + * return. + */ + private module PropagateTaintFlowConfig = + PropagateFlowConfig; - DataFlow::FlowFeature getAFeature() { - result instanceof DataFlow::FeatureEqualSourceSinkCallContext - } + module PropagateTaintFlow = TaintTracking::GlobalWithState; + + /** + * A module used to construct a data flow configuration for tracking + * data flow through APIs. + * The sources are the parameters of an API and the sinks are the return + * values (excluding `this`) and parameters. + * + * This can be used to generate value-preserving flow summaries for APIs + * from parameter to return. + */ + module PropagateFlowConfigInputDataFlowInput implements PropagateFlowConfigInputSig { + class FlowState = Unit; + + FlowState initialState() { any() } } - module PropagateFlow = TaintTracking::GlobalWithState; + /** + * A data flow configuration for tracking data flow through APIs. + * The sources are the parameters of an API and the sinks are the return + * values (excluding `this`) and parameters. + * + * This can be used to generate flow summaries for APIs from parameter to + * return. + */ + private module PropagateDataFlowConfig = + PropagateFlowConfig; + + module PropagateDataFlow = DataFlow::GlobalWithState; /** - * Gets the summary model(s) of `api`, if there is flow from parameters to return value or parameter. + * Holds if there should be a summary of `api` specifying flow from `p` + * to `returnNodeExt`. */ - string captureThroughFlow0( + predicate captureThroughFlow0( DataFlowSummaryTargetApi api, DataFlow::ParameterNode p, ReturnNodeExt returnNodeExt ) { - exists(string input, string output | - getEnclosingCallable(p) = api and - getEnclosingCallable(returnNodeExt) = api and - input = parameterNodeAsInput(p) and - output = getOutput(returnNodeExt) and - input != output and - result = ModelPrinting::asLiftedTaintModel(api, input, output) - ) + captureThroughFlow0(api, p, _, returnNodeExt, _, _) + } + + /** + * Holds if there should be a summary of `api` specifying flow + * from `p` (with summary component `input`) to `returnNodeExt` (with + * summary component `output`). + * + * `preservesValue` is true if the summary is value-preserving, or `false` + * otherwise. + */ + private predicate captureThroughFlow0( + DataFlowSummaryTargetApi api, DataFlow::ParameterNode p, string input, + ReturnNodeExt returnNodeExt, string output, boolean preservesValue + ) { + ( + PropagateDataFlow::flow(p, returnNodeExt) and preservesValue = true + or + not PropagateDataFlow::flow(p, returnNodeExt) and + PropagateTaintFlow::flow(p, returnNodeExt) and + preservesValue = false + ) and + getEnclosingCallable(p) = api and + getEnclosingCallable(returnNodeExt) = api and + input = parameterNodeAsInput(p) and + output = getOutput(returnNodeExt) and + input != output } /** * Gets the summary model(s) of `api`, if there is flow from parameters to return value or parameter. + * + * `preservesValue` is `true` if the summary is value-preserving, and `false` otherwise. */ - private string captureThroughFlow(DataFlowSummaryTargetApi api) { - exists(DataFlow::ParameterNode p, ReturnNodeExt returnNodeExt | - PropagateFlow::flow(p, returnNodeExt) and - result = captureThroughFlow0(api, p, returnNodeExt) + private string captureThroughFlow(DataFlowSummaryTargetApi api, boolean preservesValue) { + exists(string input, string output | + preservesValue = max(boolean b | captureThroughFlow0(api, _, input, _, output, b)) and + result = ModelPrinting::asLiftedTaintModel(api, input, output, preservesValue) ) } /** * Gets the summary model(s) of `api`, if there is flow from parameters to the * return value or parameter or if `api` is a fluent API. + * + * `preservesValue` is `true` if the summary is value-preserving, and `false` otherwise. */ - string captureFlow(DataFlowSummaryTargetApi api) { - result = captureQualifierFlow(api) or - result = captureThroughFlow(api) + string captureHeuristicFlow(DataFlowSummaryTargetApi api, boolean preservesValue) { + result = captureQualifierFlow(api) and preservesValue = true + or + result = captureThroughFlow(api, preservesValue) } /** @@ -569,7 +659,7 @@ module MakeModelGenerator< */ string captureNoFlow(DataFlowSummaryTargetApi api) { not exists(DataFlowSummaryTargetApi api0 | - exists(captureFlow(api0)) and api0.lift() = api.lift() + exists(captureFlow(api0, _)) and api0.lift() = api.lift() ) and api.isRelevant() and result = ModelPrinting::asNeutralSummaryModel(api) @@ -1024,12 +1114,13 @@ module MakeModelGenerator< /** * Gets the content based summary model(s) of the API `api` (if there is flow from a parameter to * the return value or a parameter). `lift` is true, if the model should be lifted, otherwise false. + * `preservesValue` is `true` if the summary is value-preserving, and `false` otherwise. * * Models are lifted to the best type in case the read and store access paths do not * contain a field or synthetic field access. */ - string captureFlow(ContentDataFlowSummaryTargetApi api, boolean lift) { - exists(string input, string output, boolean preservesValue | + string captureFlow(ContentDataFlowSummaryTargetApi api, boolean lift, boolean preservesValue) { + exists(string input, string output | captureFlow0(api, input, output, _, lift) and preservesValue = max(boolean p | captureFlow0(api, input, output, p, lift)) and result = ContentModelPrinting::asModel(api, input, output, preservesValue, lift) @@ -1046,17 +1137,25 @@ module MakeModelGenerator< * generate flow summaries using the heuristic based summary generator. */ string captureFlow(DataFlowSummaryTargetApi api, boolean lift) { - result = ContentSensitive::captureFlow(api, lift) - or - not exists(DataFlowSummaryTargetApi api0 | - (api0 = api or api.lift() = api0) and - exists(ContentSensitive::captureFlow(api0, false)) + exists(boolean preservesValue | + result = ContentSensitive::captureFlow(api, lift, preservesValue) or - api0.lift() = api.lift() and - exists(ContentSensitive::captureFlow(api0, true)) - ) and - result = Heuristic::captureFlow(api) and - lift = true + not exists(DataFlowSummaryTargetApi api0 | + // If the heuristic summary is value-preserving then we keep both + // summaries. However, if we can generate any content-sensitive + // summary (value-preserving or not) then we don't include any taint- + // based heuristic summary. + preservesValue = false + | + (api0 = api or api.lift() = api0) and + exists(ContentSensitive::captureFlow(api0, false, _)) + or + api0.lift() = api.lift() and + exists(ContentSensitive::captureFlow(api0, true, _)) + ) and + result = Heuristic::captureHeuristicFlow(api, preservesValue) and + lift = true + ) } /** diff --git a/shared/mad/codeql/mad/modelgenerator/internal/ModelPrinting.qll b/shared/mad/codeql/mad/modelgenerator/internal/ModelPrinting.qll index 0ab92f7032b4..0bce2ed50d17 100644 --- a/shared/mad/codeql/mad/modelgenerator/internal/ModelPrinting.qll +++ b/shared/mad/codeql/mad/modelgenerator/internal/ModelPrinting.qll @@ -86,9 +86,11 @@ module ModelPrintingImpl { /** * Gets the lifted taint summary model for `api` with `input` and `output`. */ - bindingset[input, output] - string asLiftedTaintModel(Printing::SummaryApi api, string input, string output) { - result = asModel(api, input, output, false, true) + bindingset[input, output, preservesValue] + string asLiftedTaintModel( + Printing::SummaryApi api, string input, string output, boolean preservesValue + ) { + result = asModel(api, input, output, preservesValue, true) } /** From cd4737970000ce235be368c9a2bb0fb31de2317a Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 29 Apr 2025 13:18:01 +0100 Subject: [PATCH 02/10] C#: Fixup queries and accept test changes. --- .../CaptureContentSummaryModels.ql | 2 +- .../debug/CaptureSummaryModelsPartialPath.ql | 2 +- .../debug/CaptureSummaryModelsPath.ql | 10 ++-- .../dataflow/CaptureContentSummaryModels.ql | 2 +- .../dataflow/CaptureHeuristicSummaryModels.ql | 2 +- .../modelgenerator/dataflow/Summaries.cs | 46 +++++++++---------- 6 files changed, 32 insertions(+), 32 deletions(-) diff --git a/csharp/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql b/csharp/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql index 039c96a9a0bc..c108029e3df3 100644 --- a/csharp/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql +++ b/csharp/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql @@ -9,5 +9,5 @@ import internal.CaptureModels from DataFlowSummaryTargetApi api, string flow -where flow = ContentSensitive::captureFlow(api, _) +where flow = ContentSensitive::captureFlow(api, _, _) select flow order by flow diff --git a/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql b/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql index beb14cd8e627..979a129e5652 100644 --- a/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql +++ b/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql @@ -14,7 +14,7 @@ import PartialFlow::PartialPathGraph int explorationLimit() { result = 3 } -module PartialFlow = Heuristic::PropagateFlow::FlowExplorationFwd; +module PartialFlow = Heuristic::PropagateTaintFlow::FlowExplorationFwd; from PartialFlow::PartialPathNode source, PartialFlow::PartialPathNode sink, diff --git a/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql b/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql index e3de78767eaa..9d51b60ec2ec 100644 --- a/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql +++ b/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql @@ -11,15 +11,15 @@ import csharp import utils.modelgenerator.internal.CaptureModels import Heuristic -import PropagateFlow::PathGraph +import PropagateTaintFlow::PathGraph from - PropagateFlow::PathNode source, PropagateFlow::PathNode sink, DataFlowSummaryTargetApi api, - DataFlow::Node p, DataFlow::Node returnNodeExt + PropagateTaintFlow::PathNode source, PropagateTaintFlow::PathNode sink, + DataFlowSummaryTargetApi api, DataFlow::Node p, DataFlow::Node returnNodeExt where - PropagateFlow::flowPath(source, sink) and + PropagateTaintFlow::flowPath(source, sink) and p = source.getNode() and returnNodeExt = sink.getNode() and - exists(captureThroughFlow0(api, p, returnNodeExt)) + captureThroughFlow0(api, p, returnNodeExt) select sink.getNode(), source, sink, "There is flow from $@ to the $@.", source.getNode(), "parameter", sink.getNode(), "return value" diff --git a/csharp/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.ql b/csharp/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.ql index 0d9e4cd52d9f..fe575790af0e 100644 --- a/csharp/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.ql +++ b/csharp/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.ql @@ -3,7 +3,7 @@ import utils.modelgenerator.internal.CaptureModels import utils.test.InlineMadTest module InlineMadTestConfig implements InlineMadTestConfigSig { - string getCapturedModel(Callable c) { result = ContentSensitive::captureFlow(c, _) } + string getCapturedModel(Callable c) { result = ContentSensitive::captureFlow(c, _, _) } string getKind() { result = "contentbased-summary" } } diff --git a/csharp/ql/test/utils/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql b/csharp/ql/test/utils/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql index 24cb66e427e7..d8e71b5e7208 100644 --- a/csharp/ql/test/utils/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql +++ b/csharp/ql/test/utils/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql @@ -3,7 +3,7 @@ import utils.modelgenerator.internal.CaptureModels import utils.test.InlineMadTest module InlineMadTestConfig implements InlineMadTestConfigSig { - string getCapturedModel(Callable c) { result = Heuristic::captureFlow(c) } + string getCapturedModel(Callable c) { result = Heuristic::captureHeuristicFlow(c, _) } string getKind() { result = "heuristic-summary" } } diff --git a/csharp/ql/test/utils/modelgenerator/dataflow/Summaries.cs b/csharp/ql/test/utils/modelgenerator/dataflow/Summaries.cs index f1dbc02512ab..382739b348e1 100644 --- a/csharp/ql/test/utils/modelgenerator/dataflow/Summaries.cs +++ b/csharp/ql/test/utils/modelgenerator/dataflow/Summaries.cs @@ -19,22 +19,22 @@ public BasicFlow ReturnThis(object input) return this; } - // heuristic-summary=Models;BasicFlow;false;ReturnParam0;(System.String,System.Object);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=Models;BasicFlow;false;ReturnParam0;(System.String,System.Object);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=Models;BasicFlow;false;ReturnParam0;(System.String,System.Object);;Argument[0];ReturnValue;value;dfc-generated public string ReturnParam0(string input0, object input1) { return input0; } - // heuristic-summary=Models;BasicFlow;false;ReturnParam1;(System.String,System.Object);;Argument[1];ReturnValue;taint;df-generated + // heuristic-summary=Models;BasicFlow;false;ReturnParam1;(System.String,System.Object);;Argument[1];ReturnValue;value;df-generated // contentbased-summary=Models;BasicFlow;false;ReturnParam1;(System.String,System.Object);;Argument[1];ReturnValue;value;dfc-generated public object ReturnParam1(string input0, object input1) { return input1; } - // heuristic-summary=Models;BasicFlow;false;ReturnParamMultiple;(System.Object,System.Object);;Argument[0];ReturnValue;taint;df-generated - // heuristic-summary=Models;BasicFlow;false;ReturnParamMultiple;(System.Object,System.Object);;Argument[1];ReturnValue;taint;df-generated + // heuristic-summary=Models;BasicFlow;false;ReturnParamMultiple;(System.Object,System.Object);;Argument[0];ReturnValue;value;df-generated + // heuristic-summary=Models;BasicFlow;false;ReturnParamMultiple;(System.Object,System.Object);;Argument[1];ReturnValue;value;df-generated // contentbased-summary=Models;BasicFlow;false;ReturnParamMultiple;(System.Object,System.Object);;Argument[0];ReturnValue;value;dfc-generated // contentbased-summary=Models;BasicFlow;false;ReturnParamMultiple;(System.Object,System.Object);;Argument[1];ReturnValue;value;dfc-generated public object ReturnParamMultiple(object input0, object input1) @@ -133,35 +133,35 @@ public List ReturnFieldInAList() return new List { tainted }; } - // SPURIOUS-heuristic-summary=Models;CollectionFlow;false;ReturnComplexTypeArray;(System.String[]);;Argument[0].Element;ReturnValue;taint;df-generated + // SPURIOUS-heuristic-summary=Models;CollectionFlow;false;ReturnComplexTypeArray;(System.String[]);;Argument[0].Element;ReturnValue;value;df-generated // contentbased-summary=Models;CollectionFlow;false;ReturnComplexTypeArray;(System.String[]);;Argument[0];ReturnValue;value;dfc-generated public string[] ReturnComplexTypeArray(string[] a) { return a; } - // SPURIOUS-heuristic-summary=Models;CollectionFlow;false;ReturnBulkTypeList;(System.Collections.Generic.List);;Argument[0].Element;ReturnValue;taint;df-generated + // SPURIOUS-heuristic-summary=Models;CollectionFlow;false;ReturnBulkTypeList;(System.Collections.Generic.List);;Argument[0].Element;ReturnValue;value;df-generated // contentbased-summary=Models;CollectionFlow;false;ReturnBulkTypeList;(System.Collections.Generic.List);;Argument[0];ReturnValue;value;dfc-generated public List ReturnBulkTypeList(List a) { return a; } - // SPURIOUS-heuristic-summary=Models;CollectionFlow;false;ReturnComplexTypeDictionary;(System.Collections.Generic.Dictionary);;Argument[0].Element;ReturnValue;taint;df-generated + // SPURIOUS-heuristic-summary=Models;CollectionFlow;false;ReturnComplexTypeDictionary;(System.Collections.Generic.Dictionary);;Argument[0].Element;ReturnValue;value;df-generated // contentbased-summary=Models;CollectionFlow;false;ReturnComplexTypeDictionary;(System.Collections.Generic.Dictionary);;Argument[0];ReturnValue;value;dfc-generated public Dictionary ReturnComplexTypeDictionary(Dictionary a) { return a; } - // SPURIOUS-heuristic-summary=Models;CollectionFlow;false;ReturnUntypedArray;(System.Array);;Argument[0].Element;ReturnValue;taint;df-generated + // SPURIOUS-heuristic-summary=Models;CollectionFlow;false;ReturnUntypedArray;(System.Array);;Argument[0].Element;ReturnValue;value;df-generated // contentbased-summary=Models;CollectionFlow;false;ReturnUntypedArray;(System.Array);;Argument[0];ReturnValue;value;dfc-generated public Array ReturnUntypedArray(Array a) { return a; } - // SPURIOUS-heuristic-summary=Models;CollectionFlow;false;ReturnUntypedList;(System.Collections.IList);;Argument[0].Element;ReturnValue;taint;df-generated + // SPURIOUS-heuristic-summary=Models;CollectionFlow;false;ReturnUntypedList;(System.Collections.IList);;Argument[0].Element;ReturnValue;value;df-generated // contentbased-summary=Models;CollectionFlow;false;ReturnUntypedList;(System.Collections.IList);;Argument[0];ReturnValue;value;dfc-generated public IList ReturnUntypedList(IList a) { @@ -202,7 +202,7 @@ public IEnumerableFlow(string s) tainted = s; } - // SPURIOUS-heuristic-summary=Models;IEnumerableFlow;false;ReturnIEnumerable;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;df-generated + // SPURIOUS-heuristic-summary=Models;IEnumerableFlow;false;ReturnIEnumerable;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;value;df-generated // contentbased-summary=Models;IEnumerableFlow;false;ReturnIEnumerable;(System.Collections.Generic.IEnumerable);;Argument[0];ReturnValue;value;dfc-generated public IEnumerable ReturnIEnumerable(IEnumerable input) { @@ -256,7 +256,7 @@ public List ReturnFieldInGenericList() return new List { tainted }; } - // heuristic-summary=Models;GenericFlow;false;ReturnGenericParam;(S);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=Models;GenericFlow;false;ReturnGenericParam;(S);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=Models;GenericFlow;false;ReturnGenericParam;(S);;Argument[0];ReturnValue;value;dfc-generated public S ReturnGenericParam(S input) { @@ -280,7 +280,7 @@ public void AddToGenericList(List input, S data) public abstract class BaseClassFlow { - // heuristic-summary=Models;BaseClassFlow;true;ReturnParam;(System.Object);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=Models;BaseClassFlow;true;ReturnParam;(System.Object);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=Models;BaseClassFlow;true;ReturnParam;(System.Object);;Argument[0];ReturnValue;value;dfc-generated public virtual object ReturnParam(object input) { @@ -290,7 +290,7 @@ public virtual object ReturnParam(object input) public class DerivedClass1Flow : BaseClassFlow { - // heuristic-summary=Models;DerivedClass1Flow;false;ReturnParam1;(System.String,System.String);;Argument[1];ReturnValue;taint;df-generated + // heuristic-summary=Models;DerivedClass1Flow;false;ReturnParam1;(System.String,System.String);;Argument[1];ReturnValue;value;df-generated // contentbased-summary=Models;DerivedClass1Flow;false;ReturnParam1;(System.String,System.String);;Argument[1];ReturnValue;value;dfc-generated public string ReturnParam1(string input0, string input1) { @@ -300,14 +300,14 @@ public string ReturnParam1(string input0, string input1) public class DerivedClass2Flow : BaseClassFlow { - // heuristic-summary=Models;BaseClassFlow;true;ReturnParam;(System.Object);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=Models;BaseClassFlow;true;ReturnParam;(System.Object);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=Models;BaseClassFlow;true;ReturnParam;(System.Object);;Argument[0];ReturnValue;value;dfc-generated public override object ReturnParam(object input) { return input; } - // heuristic-summary=Models;DerivedClass2Flow;false;ReturnParam0;(System.String,System.Int32);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=Models;DerivedClass2Flow;false;ReturnParam0;(System.String,System.Int32);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=Models;DerivedClass2Flow;false;ReturnParam0;(System.String,System.Int32);;Argument[0];ReturnValue;value;dfc-generated public string ReturnParam0(string input0, int input1) { @@ -327,7 +327,7 @@ public OperatorFlow(object o) } // Flow Summary. - // heuristic-summary=Models;OperatorFlow;false;op_Addition;(Models.OperatorFlow,Models.OperatorFlow);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=Models;OperatorFlow;false;op_Addition;(Models.OperatorFlow,Models.OperatorFlow);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=Models;OperatorFlow;false;op_Addition;(Models.OperatorFlow,Models.OperatorFlow);;Argument[0];ReturnValue;value;dfc-generated public static OperatorFlow operator +(OperatorFlow a, OperatorFlow b) { @@ -368,7 +368,7 @@ public override bool Equals(object obj) return boolTainted; } - // heuristic-summary=Models;EqualsGetHashCodeNoFlow;false;Equals;(System.String);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=Models;EqualsGetHashCodeNoFlow;false;Equals;(System.String);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=Models;EqualsGetHashCodeNoFlow;false;Equals;(System.String);;Argument[0];ReturnValue;value;dfc-generated public string Equals(string s) { @@ -606,7 +606,7 @@ public abstract class BasePublic public class AImplBasePublic : BasePublic { - // heuristic-summary=Models;Inheritance+BasePublic;true;Id;(System.String);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=Models;Inheritance+BasePublic;true;Id;(System.String);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=Models;Inheritance+BasePublic;true;Id;(System.String);;Argument[0];ReturnValue;value;dfc-generated public override string Id(string x) { @@ -636,7 +636,7 @@ private abstract class C : IPublic2 public class BImpl : B { - // heuristic-summary=Models;Inheritance+IPublic1;true;Id;(System.String);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=Models;Inheritance+IPublic1;true;Id;(System.String);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=Models;Inheritance+IPublic1;true;Id;(System.String);;Argument[0];ReturnValue;value;dfc-generated public override string Id(string x) { @@ -646,7 +646,7 @@ public override string Id(string x) private class CImpl : C { - // heuristic-summary=Models;Inheritance+IPublic2;true;Id;(System.String);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=Models;Inheritance+IPublic2;true;Id;(System.String);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=Models;Inheritance+IPublic2;true;Id;(System.String);;Argument[0];ReturnValue;value;dfc-generated public override string Id(string x) { @@ -1035,14 +1035,14 @@ public override object GetValue() public class ParameterModifiers { // contentbased-summary=Models;ParameterModifiers;false;Copy;(System.Object,System.Object);;Argument[0];Argument[1];value;dfc-generated - // heuristic-summary=Models;ParameterModifiers;false;Copy;(System.Object,System.Object);;Argument[0];Argument[1];taint;df-generated + // heuristic-summary=Models;ParameterModifiers;false;Copy;(System.Object,System.Object);;Argument[0];Argument[1];value;df-generated public void Copy(object key, out object value) { value = key; } // contentbased-summary=Models;ParameterModifiers;false;CopyToRef;(System.Object,System.Object);;Argument[0];Argument[1];value;dfc-generated - // heuristic-summary=Models;ParameterModifiers;false;CopyToRef;(System.Object,System.Object);;Argument[0];Argument[1];taint;df-generated + // heuristic-summary=Models;ParameterModifiers;false;CopyToRef;(System.Object,System.Object);;Argument[0];Argument[1];value;df-generated public void CopyToRef(object key, ref object value) { value = key; @@ -1062,7 +1062,7 @@ public void RefParamUse(ref object value) } // contentbased-summary=Models;ParameterModifiers;false;InReturn;(System.Object);;Argument[0];ReturnValue;value;dfc-generated - // heuristic-summary=Models;ParameterModifiers;false;InReturn;(System.Object);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=Models;ParameterModifiers;false;InReturn;(System.Object);;Argument[0];ReturnValue;value;df-generated public object InReturn(in object v) { return v; From 07641e48ab693478c95448e565b2807ae631e781 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 29 Apr 2025 13:18:16 +0100 Subject: [PATCH 03/10] Java: Fixup queries and accept test changes. --- .../modelgenerator/CaptureContentSummaryModels.ql | 2 +- .../debug/CaptureSummaryModelsPartialPath.ql | 2 +- .../modelgenerator/debug/CaptureSummaryModelsPath.ql | 10 +++++----- .../dataflow/CaptureContentSummaryModels.ql | 2 +- .../dataflow/CaptureHeuristicSummaryModels.ql | 2 +- .../utils/modelgenerator/dataflow/p/FinalClass.java | 2 +- .../modelgenerator/dataflow/p/ImmutablePojo.java | 2 +- .../utils/modelgenerator/dataflow/p/Inheritance.java | 12 ++++++------ .../modelgenerator/dataflow/p/InnerClasses.java | 4 ++-- .../utils/modelgenerator/dataflow/p/MultiPaths.java | 2 +- .../modelgenerator/dataflow/p/MultipleImpl2.java | 2 +- .../modelgenerator/dataflow/p/MultipleImpls.java | 2 +- .../utils/modelgenerator/dataflow/p/ParamFlow.java | 6 +++--- 13 files changed, 25 insertions(+), 25 deletions(-) diff --git a/java/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql b/java/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql index b1340e2c0d33..6d209a4c50d7 100644 --- a/java/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql +++ b/java/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql @@ -9,5 +9,5 @@ import internal.CaptureModels from DataFlowSummaryTargetApi api, string flow -where flow = ContentSensitive::captureFlow(api, _) +where flow = ContentSensitive::captureFlow(api, _, _) select flow order by flow diff --git a/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql b/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql index 8895fdaefbb3..16d202f27888 100644 --- a/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql +++ b/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql @@ -15,7 +15,7 @@ import PartialFlow::PartialPathGraph int explorationLimit() { result = 3 } -module PartialFlow = Heuristic::PropagateFlow::FlowExplorationFwd; +module PartialFlow = Heuristic::PropagateTaintFlow::FlowExplorationFwd; from PartialFlow::PartialPathNode source, PartialFlow::PartialPathNode sink, diff --git a/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql b/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql index 8f6bf1c1f531..57468f6ac051 100644 --- a/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql +++ b/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql @@ -12,15 +12,15 @@ import java import semmle.code.java.dataflow.DataFlow import utils.modelgenerator.internal.CaptureModels import Heuristic -import PropagateFlow::PathGraph +import PropagateTaintFlow::PathGraph from - PropagateFlow::PathNode source, PropagateFlow::PathNode sink, DataFlowSummaryTargetApi api, - DataFlow::Node p, DataFlow::Node returnNodeExt + PropagateTaintFlow::PathNode source, PropagateTaintFlow::PathNode sink, + DataFlowSummaryTargetApi api, DataFlow::Node p, DataFlow::Node returnNodeExt where - PropagateFlow::flowPath(source, sink) and + PropagateTaintFlow::flowPath(source, sink) and p = source.getNode() and returnNodeExt = sink.getNode() and - exists(captureThroughFlow0(api, p, returnNodeExt)) + captureThroughFlow0(api, p, returnNodeExt) select sink.getNode(), source, sink, "There is flow from $@ to the $@.", source.getNode(), "parameter", sink.getNode(), "return value" diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.ql b/java/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.ql index 8dd23714fb79..1ee494a849a2 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.ql +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.ql @@ -3,7 +3,7 @@ import utils.modelgenerator.internal.CaptureModels import utils.test.InlineMadTest module InlineMadTestConfig implements InlineMadTestConfigSig { - string getCapturedModel(Callable c) { result = ContentSensitive::captureFlow(c, _) } + string getCapturedModel(Callable c) { result = ContentSensitive::captureFlow(c, _, _) } string getKind() { result = "contentbased-summary" } } diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql b/java/ql/test/utils/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql index 45485a8009a5..6b07aa87da8d 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql @@ -3,7 +3,7 @@ import utils.modelgenerator.internal.CaptureModels import utils.test.InlineMadTest module InlineMadTestConfig implements InlineMadTestConfigSig { - string getCapturedModel(Callable c) { result = Heuristic::captureFlow(c) } + string getCapturedModel(Callable c) { result = Heuristic::captureHeuristicFlow(c, _) } string getKind() { result = "heuristic-summary" } } diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java b/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java index 993248f9bf80..431140c51541 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/FinalClass.java @@ -4,7 +4,7 @@ public final class FinalClass { private static final String C = "constant"; - // heuristic-summary=p;FinalClass;false;returnsInput;(String);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=p;FinalClass;false;returnsInput;(String);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=p;FinalClass;false;returnsInput;(String);;Argument[0];ReturnValue;value;dfc-generated public String returnsInput(String input) { return input; diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java b/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java index 711d49cc1fc3..0f784ae859f8 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/ImmutablePojo.java @@ -24,7 +24,7 @@ public long getX() { return x; } - // heuristic-summary=p;ImmutablePojo;false;or;(String);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=p;ImmutablePojo;false;or;(String);;Argument[0];ReturnValue;value;df-generated // heuristic-summary=p;ImmutablePojo;false;or;(String);;Argument[this];ReturnValue;taint;df-generated // contentbased-summary=p;ImmutablePojo;false;or;(String);;Argument[0];ReturnValue;value;dfc-generated // contentbased-summary=p;ImmutablePojo;false;or;(String);;Argument[this].SyntheticField[p.ImmutablePojo.value];ReturnValue;value;dfc-generated diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/Inheritance.java b/java/ql/test/utils/modelgenerator/dataflow/p/Inheritance.java index 4253ee0d6ead..096c186cdc8a 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/Inheritance.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/Inheritance.java @@ -10,7 +10,7 @@ public abstract class BasePublic { } public class AImplBasePrivateImpl extends BasePrivate { - // heuristic-summary=p;Inheritance$AImplBasePrivateImpl;true;id;(String);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=p;Inheritance$AImplBasePrivateImpl;true;id;(String);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=p;Inheritance$AImplBasePrivateImpl;true;id;(String);;Argument[0];ReturnValue;value;dfc-generated @Override public String id(String s) { @@ -19,7 +19,7 @@ public String id(String s) { } public class AImplBasePublic extends BasePublic { - // heuristic-summary=p;Inheritance$BasePublic;true;id;(String);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=p;Inheritance$BasePublic;true;id;(String);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=p;Inheritance$BasePublic;true;id;(String);;Argument[0];ReturnValue;value;dfc-generated @Override public String id(String s) { @@ -60,7 +60,7 @@ private abstract class E implements IPrivate2 { } public class BImpl extends B { - // heuristic-summary=p;Inheritance$IPublic1;true;id;(String);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=p;Inheritance$IPublic1;true;id;(String);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=p;Inheritance$IPublic1;true;id;(String);;Argument[0];ReturnValue;value;dfc-generated @Override public String id(String s) { @@ -69,7 +69,7 @@ public String id(String s) { } public class CImpl extends C { - // heuristic-summary=p;Inheritance$C;true;id;(String);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=p;Inheritance$C;true;id;(String);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=p;Inheritance$C;true;id;(String);;Argument[0];ReturnValue;value;dfc-generated @Override public String id(String s) { @@ -78,7 +78,7 @@ public String id(String s) { } public class DImpl extends D { - // heuristic-summary=p;Inheritance$IPublic2;true;id;(String);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=p;Inheritance$IPublic2;true;id;(String);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=p;Inheritance$IPublic2;true;id;(String);;Argument[0];ReturnValue;value;dfc-generated @Override public String id(String s) { @@ -87,7 +87,7 @@ public String id(String s) { } public class EImpl extends E { - // heuristic-summary=p;Inheritance$EImpl;true;id;(String);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=p;Inheritance$EImpl;true;id;(String);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=p;Inheritance$EImpl;true;id;(String);;Argument[0];ReturnValue;value;dfc-generated @Override public String id(String s) { diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/InnerClasses.java b/java/ql/test/utils/modelgenerator/dataflow/p/InnerClasses.java index 283bcfd5c6e2..e0db1227b48f 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/InnerClasses.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/InnerClasses.java @@ -9,14 +9,14 @@ public String no(String input) { } public class CaptureMe { - // heuristic-summary=p;InnerClasses$CaptureMe;true;yesCm;(String);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=p;InnerClasses$CaptureMe;true;yesCm;(String);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=p;InnerClasses$CaptureMe;true;yesCm;(String);;Argument[0];ReturnValue;value;dfc-generated public String yesCm(String input) { return input; } } - // heuristic-summary=p;InnerClasses;true;yes;(String);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=p;InnerClasses;true;yes;(String);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=p;InnerClasses;true;yes;(String);;Argument[0];ReturnValue;value;dfc-generated public String yes(String input) { return input; diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/MultiPaths.java b/java/ql/test/utils/modelgenerator/dataflow/p/MultiPaths.java index 11d2f8f76f83..fb03061eaaf7 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/MultiPaths.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/MultiPaths.java @@ -2,7 +2,7 @@ public class MultiPaths { - // heuristic-summary=p;MultiPaths;true;cond;(String,String);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=p;MultiPaths;true;cond;(String,String);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=p;MultiPaths;true;cond;(String,String);;Argument[0];ReturnValue;value;dfc-generated public String cond(String x, String other) { if (x == other) { diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java index d0fd31613d65..7256e5345baa 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpl2.java @@ -16,7 +16,7 @@ public Object m(Object value) { } public class Impl2 implements IInterface { - // heuristic-summary=p;MultipleImpl2$IInterface;true;m;(Object);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=p;MultipleImpl2$IInterface;true;m;(Object);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=p;MultipleImpl2$IInterface;true;m;(Object);;Argument[0];ReturnValue;value;dfc-generated public Object m(Object value) { return value; diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java index 5bdbb47fa483..60e16fbeb165 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/MultipleImpls.java @@ -9,7 +9,7 @@ public static interface Strategy { } public static class Strat1 implements Strategy { - // heuristic-summary=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];ReturnValue;value;dfc-generated public String doSomething(String value) { return value; diff --git a/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java b/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java index 81b9602e5577..4c9d7427d75d 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java +++ b/java/ql/test/utils/modelgenerator/dataflow/p/ParamFlow.java @@ -7,7 +7,7 @@ public class ParamFlow { - // heuristic-summary=p;ParamFlow;true;returnsInput;(String);;Argument[0];ReturnValue;taint;df-generated + // heuristic-summary=p;ParamFlow;true;returnsInput;(String);;Argument[0];ReturnValue;value;df-generated // contentbased-summary=p;ParamFlow;true;returnsInput;(String);;Argument[0];ReturnValue;value;dfc-generated public String returnsInput(String input) { return input; @@ -18,8 +18,8 @@ public int ignorePrimitiveReturnValue(String input) { return input.length(); } - // heuristic-summary=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[0];ReturnValue;taint;df-generated - // heuristic-summary=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[1];ReturnValue;taint;df-generated + // heuristic-summary=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[0];ReturnValue;value;df-generated + // heuristic-summary=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[1];ReturnValue;value;df-generated // contentbased-summary=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[0];ReturnValue;value;dfc-generated // contentbased-summary=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[1];ReturnValue;value;dfc-generated public String returnMultipleParameters(String one, String two) { From 775197372c8d0055e43c7479b5e6cdd56bf122a7 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 29 Apr 2025 13:18:27 +0100 Subject: [PATCH 04/10] Rust: Fixup queries. --- .../modelgenerator/CaptureContentSummaryModels.ql | 2 +- .../debug/CaptureSummaryModelsPartialPath.ql | 2 +- .../modelgenerator/debug/CaptureSummaryModelsPath.ql | 10 +++++----- .../utils-tests/modelgenerator/CaptureSummaryModels.ql | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/rust/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql b/rust/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql index da90465197e5..a19a1b2398c7 100644 --- a/rust/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql +++ b/rust/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql @@ -9,5 +9,5 @@ import internal.CaptureModels from DataFlowSummaryTargetApi api, string flow -where flow = ContentSensitive::captureFlow(api, _) +where flow = ContentSensitive::captureFlow(api, _, _) select flow order by flow diff --git a/rust/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql b/rust/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql index eb0cd638b534..49b8d56fdff0 100644 --- a/rust/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql +++ b/rust/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql @@ -14,7 +14,7 @@ import PartialFlow::PartialPathGraph int explorationLimit() { result = 3 } -module PartialFlow = Heuristic::PropagateFlow::FlowExplorationFwd; +module PartialFlow = Heuristic::PropagateTaintFlow::FlowExplorationFwd; from PartialFlow::PartialPathNode source, PartialFlow::PartialPathNode sink, diff --git a/rust/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql b/rust/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql index 1ddec1ff618b..611faae5b410 100644 --- a/rust/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql +++ b/rust/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql @@ -11,15 +11,15 @@ private import codeql.rust.dataflow.DataFlow import utils.modelgenerator.internal.CaptureModels import Heuristic -import PropagateFlow::PathGraph +import PropagateTaintFlow::PathGraph from - PropagateFlow::PathNode source, PropagateFlow::PathNode sink, DataFlowSummaryTargetApi api, - DataFlow::Node p, DataFlow::Node returnNodeExt + PropagateTaintFlow::PathNode source, PropagateTaintFlow::PathNode sink, + DataFlowSummaryTargetApi api, DataFlow::Node p, DataFlow::Node returnNodeExt where - PropagateFlow::flowPath(source, sink) and + PropagateTaintFlow::flowPath(source, sink) and p = source.getNode() and returnNodeExt = sink.getNode() and - exists(captureThroughFlow0(api, p, returnNodeExt)) + captureThroughFlow0(api, p, returnNodeExt) select sink.getNode(), source, sink, "There is flow from $@ to the $@.", source.getNode(), "parameter", sink.getNode(), "return value" diff --git a/rust/ql/test/utils-tests/modelgenerator/CaptureSummaryModels.ql b/rust/ql/test/utils-tests/modelgenerator/CaptureSummaryModels.ql index 002689a20390..2ea8bd1ce6de 100644 --- a/rust/ql/test/utils-tests/modelgenerator/CaptureSummaryModels.ql +++ b/rust/ql/test/utils-tests/modelgenerator/CaptureSummaryModels.ql @@ -3,7 +3,7 @@ import utils.modelgenerator.internal.CaptureModels import utils.test.InlineMadTest module InlineMadTestConfig implements InlineMadTestConfigSig { - string getCapturedModel(Function f) { result = ContentSensitive::captureFlow(f, _) } + string getCapturedModel(Function f) { result = ContentSensitive::captureFlow(f, _, _) } string getKind() { result = "summary" } } From d8eafbb9e2807e237651534e1a3b82edf2536e02 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 29 Apr 2025 15:04:25 +0100 Subject: [PATCH 05/10] C++: Fixup queries and accept test changes. --- .../CaptureContentSummaryModels.ql | 2 +- .../dataflow/CaptureContentSummaryModels.ql | 2 +- .../dataflow/CaptureHeuristicSummaryModels.ql | 2 +- .../modelgenerator/dataflow/summaries.cpp | 46 +++++++++---------- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/cpp/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql b/cpp/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql index 8dc0c3d7f6b1..d49ace967ca8 100644 --- a/cpp/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql +++ b/cpp/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql @@ -9,5 +9,5 @@ import internal.CaptureModels from DataFlowSummaryTargetApi api, string flow -where flow = ContentSensitive::captureFlow(api, _) +where flow = ContentSensitive::captureFlow(api, _, _) select flow order by flow diff --git a/cpp/ql/test/library-tests/dataflow/modelgenerator/dataflow/CaptureContentSummaryModels.ql b/cpp/ql/test/library-tests/dataflow/modelgenerator/dataflow/CaptureContentSummaryModels.ql index 0156eaaeb988..a73cc1631989 100644 --- a/cpp/ql/test/library-tests/dataflow/modelgenerator/dataflow/CaptureContentSummaryModels.ql +++ b/cpp/ql/test/library-tests/dataflow/modelgenerator/dataflow/CaptureContentSummaryModels.ql @@ -3,7 +3,7 @@ import utils.modelgenerator.internal.CaptureModels import InlineModelsAsDataTest module InlineMadTestConfig implements InlineMadTestConfigSig { - string getCapturedModel(MadRelevantFunction c) { result = ContentSensitive::captureFlow(c, _) } + string getCapturedModel(MadRelevantFunction c) { result = ContentSensitive::captureFlow(c, _, _) } string getKind() { result = "contentbased-summary" } } diff --git a/cpp/ql/test/library-tests/dataflow/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql b/cpp/ql/test/library-tests/dataflow/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql index 3ab1dc6c4710..14423e8c078c 100644 --- a/cpp/ql/test/library-tests/dataflow/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql +++ b/cpp/ql/test/library-tests/dataflow/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql @@ -3,7 +3,7 @@ import utils.modelgenerator.internal.CaptureModels import InlineModelsAsDataTest module InlineMadTestConfig implements InlineMadTestConfigSig { - string getCapturedModel(MadRelevantFunction c) { result = Heuristic::captureFlow(c) } + string getCapturedModel(MadRelevantFunction c) { result = Heuristic::captureHeuristicFlow(c, _) } string getKind() { result = "heuristic-summary" } } diff --git a/cpp/ql/test/library-tests/dataflow/modelgenerator/dataflow/summaries.cpp b/cpp/ql/test/library-tests/dataflow/modelgenerator/dataflow/summaries.cpp index 74869a69994e..d4f96f67ff35 100644 --- a/cpp/ql/test/library-tests/dataflow/modelgenerator/dataflow/summaries.cpp +++ b/cpp/ql/test/library-tests/dataflow/modelgenerator/dataflow/summaries.cpp @@ -10,32 +10,32 @@ namespace Models { //No model as destructors are excluded from model generation. ~BasicFlow() = default; - //heuristic-summary=Models;BasicFlow;true;returnThis;(int *);;Argument[-1];ReturnValue[*];taint;df-generated + //heuristic-summary=Models;BasicFlow;true;returnThis;(int *);;Argument[-1];ReturnValue[*];value;df-generated //contentbased-summary=Models;BasicFlow;true;returnThis;(int *);;Argument[-1];ReturnValue[*];value;dfc-generated BasicFlow* returnThis(int* input) { return this; } - //heuristic-summary=Models;BasicFlow;true;returnParam0;(int *,int *);;Argument[0];ReturnValue;taint;df-generated - //heuristic-summary=Models;BasicFlow;true;returnParam0;(int *,int *);;Argument[*0];ReturnValue[*];taint;df-generated + //heuristic-summary=Models;BasicFlow;true;returnParam0;(int *,int *);;Argument[0];ReturnValue;value;df-generated + //heuristic-summary=Models;BasicFlow;true;returnParam0;(int *,int *);;Argument[*0];ReturnValue[*];value;df-generated //contentbased-summary=Models;BasicFlow;true;returnParam0;(int *,int *);;Argument[0];ReturnValue;value;dfc-generated //contentbased-summary=Models;BasicFlow;true;returnParam0;(int *,int *);;Argument[*0];ReturnValue[*];value;dfc-generated int* returnParam0(int* input0, int* input1) { return input0; } - //heuristic-summary=Models;BasicFlow;true;returnParam1;(int *,int *);;Argument[1];ReturnValue;taint;df-generated - //heuristic-summary=Models;BasicFlow;true;returnParam1;(int *,int *);;Argument[*1];ReturnValue[*];taint;df-generated + //heuristic-summary=Models;BasicFlow;true;returnParam1;(int *,int *);;Argument[1];ReturnValue;value;df-generated + //heuristic-summary=Models;BasicFlow;true;returnParam1;(int *,int *);;Argument[*1];ReturnValue[*];value;df-generated //contentbased-summary=Models;BasicFlow;true;returnParam1;(int *,int *);;Argument[1];ReturnValue;value;dfc-generated //contentbased-summary=Models;BasicFlow;true;returnParam1;(int *,int *);;Argument[*1];ReturnValue[*];value;dfc-generated int* returnParam1(int* input0, int* input1) { return input1; } - //heuristic-summary=Models;BasicFlow;true;returnParamMultiple;(bool,int *,int *);;Argument[1];ReturnValue;taint;df-generated - //heuristic-summary=Models;BasicFlow;true;returnParamMultiple;(bool,int *,int *);;Argument[*1];ReturnValue[*];taint;df-generated - //heuristic-summary=Models;BasicFlow;true;returnParamMultiple;(bool,int *,int *);;Argument[2];ReturnValue;taint;df-generated - //heuristic-summary=Models;BasicFlow;true;returnParamMultiple;(bool,int *,int *);;Argument[*2];ReturnValue[*];taint;df-generated + //heuristic-summary=Models;BasicFlow;true;returnParamMultiple;(bool,int *,int *);;Argument[1];ReturnValue;value;df-generated + //heuristic-summary=Models;BasicFlow;true;returnParamMultiple;(bool,int *,int *);;Argument[*1];ReturnValue[*];value;df-generated + //heuristic-summary=Models;BasicFlow;true;returnParamMultiple;(bool,int *,int *);;Argument[2];ReturnValue;value;df-generated + //heuristic-summary=Models;BasicFlow;true;returnParamMultiple;(bool,int *,int *);;Argument[*2];ReturnValue[*];value;df-generated //contentbased-summary=Models;BasicFlow;true;returnParamMultiple;(bool,int *,int *);;Argument[1];ReturnValue;value;dfc-generated //contentbased-summary=Models;BasicFlow;true;returnParamMultiple;(bool,int *,int *);;Argument[*1];ReturnValue[*];value;dfc-generated //contentbased-summary=Models;BasicFlow;true;returnParamMultiple;(bool,int *,int *);;Argument[2];ReturnValue;value;dfc-generated @@ -46,9 +46,9 @@ namespace Models { //heuristic-summary=Models;BasicFlow;true;returnSubstring;(const char *,char *);;Argument[0];Argument[*1];taint;df-generated //heuristic-summary=Models;BasicFlow;true;returnSubstring;(const char *,char *);;Argument[0];ReturnValue[*];taint;df-generated - //heuristic-summary=Models;BasicFlow;true;returnSubstring;(const char *,char *);;Argument[*0];ReturnValue[*];taint;df-generated - //heuristic-summary=Models;BasicFlow;true;returnSubstring;(const char *,char *);;Argument[1];ReturnValue;taint;df-generated - //heuristic-summary=Models;BasicFlow;true;returnSubstring;(const char *,char *);;Argument[*0];Argument[*1];taint;df-generated + //heuristic-summary=Models;BasicFlow;true;returnSubstring;(const char *,char *);;Argument[*0];ReturnValue[*];value;df-generated + //heuristic-summary=Models;BasicFlow;true;returnSubstring;(const char *,char *);;Argument[1];ReturnValue;value;df-generated + //heuristic-summary=Models;BasicFlow;true;returnSubstring;(const char *,char *);;Argument[*0];Argument[*1];value;df-generated //contentbased-summary=Models;BasicFlow;true;returnSubstring;(const char *,char *);;Argument[0];Argument[*1];taint;dfc-generated //contentbased-summary=Models;BasicFlow;true;returnSubstring;(const char *,char *);;Argument[0];ReturnValue[*];taint;dfc-generated //contentbased-summary=Models;BasicFlow;true;returnSubstring;(const char *,char *);;Argument[*0];ReturnValue[*];value;dfc-generated @@ -79,14 +79,14 @@ namespace Models { struct TemplatedFlow { T tainted; - //heuristic-summary=Models;TemplatedFlow;true;template_returnThis;(T);;Argument[-1];ReturnValue[*];taint;df-generated + //heuristic-summary=Models;TemplatedFlow;true;template_returnThis;(T);;Argument[-1];ReturnValue[*];value;df-generated //contentbased-summary=Models;TemplatedFlow;true;template_returnThis;(T);;Argument[-1];ReturnValue[*];value;dfc-generated TemplatedFlow* template_returnThis(T input) { return this; } - //heuristic-summary=Models;TemplatedFlow;true;template_returnParam0;(T *,T *);;Argument[0];ReturnValue;taint;df-generated - //heuristic-summary=Models;TemplatedFlow;true;template_returnParam0;(T *,T *);;Argument[*0];ReturnValue[*];taint;df-generated + //heuristic-summary=Models;TemplatedFlow;true;template_returnParam0;(T *,T *);;Argument[0];ReturnValue;value;df-generated + //heuristic-summary=Models;TemplatedFlow;true;template_returnParam0;(T *,T *);;Argument[*0];ReturnValue[*];value;df-generated //contentbased-summary=Models;TemplatedFlow;true;template_returnParam0;(T *,T *);;Argument[0];ReturnValue;value;dfc-generated //contentbased-summary=Models;TemplatedFlow;true;template_returnParam0;(T *,T *);;Argument[*0];ReturnValue[*];value;dfc-generated T* template_returnParam0(T* input0, T* input1) { @@ -105,8 +105,8 @@ namespace Models { return tainted; } - //heuristic-summary=Models;TemplatedFlow;true;templated_function;(U *,T *);;Argument[0];ReturnValue;taint;df-generated - //heuristic-summary=Models;TemplatedFlow;true;templated_function;(U *,T *);;Argument[*0];ReturnValue[*];taint;df-generated + //heuristic-summary=Models;TemplatedFlow;true;templated_function;(U *,T *);;Argument[0];ReturnValue;value;df-generated + //heuristic-summary=Models;TemplatedFlow;true;templated_function;(U *,T *);;Argument[*0];ReturnValue[*];value;df-generated //contentbased-summary=Models;TemplatedFlow;true;templated_function;(U *,T *);;Argument[0];ReturnValue;value;dfc-generated //contentbased-summary=Models;TemplatedFlow;true;templated_function;(U *,T *);;Argument[*0];ReturnValue[*];value;dfc-generated template @@ -130,7 +130,7 @@ namespace Models { } //heuristic-summary=;;true;toplevel_function;(int *);;Argument[0];ReturnValue;taint;df-generated -//heuristic-summary=;;true;toplevel_function;(int *);;Argument[*0];ReturnValue;taint;df-generated +//heuristic-summary=;;true;toplevel_function;(int *);;Argument[*0];ReturnValue;value;df-generated //heuristic-summary=;;true;toplevel_function;(int *);;Argument[0];Argument[*0];taint;df-generated //contentbased-summary=;;true;toplevel_function;(int *);;Argument[0];Argument[*0];taint;dfc-generated //contentbased-summary=;;true;toplevel_function;(int *);;Argument[0];ReturnValue;taint;dfc-generated @@ -145,13 +145,13 @@ static int static_toplevel_function(int* p) { } struct NonFinalStruct { - //heuristic-summary=;NonFinalStruct;true;public_not_final_member_function;(int);;Argument[0];ReturnValue;taint;df-generated + //heuristic-summary=;NonFinalStruct;true;public_not_final_member_function;(int);;Argument[0];ReturnValue;value;df-generated //contentbased-summary=;NonFinalStruct;true;public_not_final_member_function;(int);;Argument[0];ReturnValue;value;dfc-generated virtual int public_not_final_member_function(int x) { return x; } - //heuristic-summary=;NonFinalStruct;false;public_final_member_function;(int);;Argument[0];ReturnValue;taint;df-generated + //heuristic-summary=;NonFinalStruct;false;public_final_member_function;(int);;Argument[0];ReturnValue;value;df-generated //contentbased-summary=;NonFinalStruct;false;public_final_member_function;(int);;Argument[0];ReturnValue;value;dfc-generated virtual int public_final_member_function(int x) final { return x; @@ -171,13 +171,13 @@ struct NonFinalStruct { }; struct FinalStruct final { - //heuristic-summary=;FinalStruct;false;public_not_final_member_function_2;(int);;Argument[0];ReturnValue;taint;df-generated + //heuristic-summary=;FinalStruct;false;public_not_final_member_function_2;(int);;Argument[0];ReturnValue;value;df-generated //contentbased-summary=;FinalStruct;false;public_not_final_member_function_2;(int);;Argument[0];ReturnValue;value;dfc-generated virtual int public_not_final_member_function_2(int x) { return x; } - //heuristic-summary=;FinalStruct;false;public_final_member_function_2;(int);;Argument[0];ReturnValue;taint;df-generated + //heuristic-summary=;FinalStruct;false;public_final_member_function_2;(int);;Argument[0];ReturnValue;value;df-generated //contentbased-summary=;FinalStruct;false;public_final_member_function_2;(int);;Argument[0];ReturnValue;value;dfc-generated virtual int public_final_member_function_2(int x) final { return x; @@ -211,7 +211,7 @@ struct HasInt { //contentbased-summary=;;true;copy_struct;(HasInt *,const HasInt *);;Argument[*1];Argument[*0];value;dfc-generated //heuristic-summary=;;true;copy_struct;(HasInt *,const HasInt *);;Argument[1];Argument[*0];taint;df-generated //heuristic-summary=;;true;copy_struct;(HasInt *,const HasInt *);;Argument[1];Argument[*1];taint;df-generated -//heuristic-summary=;;true;copy_struct;(HasInt *,const HasInt *);;Argument[*1];Argument[*0];taint;df-generated +//heuristic-summary=;;true;copy_struct;(HasInt *,const HasInt *);;Argument[*1];Argument[*0];value;df-generated int copy_struct(HasInt *out, const HasInt *in) { *out = *in; return 1; From 54f0eed2c67e96568896fc0728867bbebf0e21b2 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 2 May 2025 13:54:58 +0100 Subject: [PATCH 06/10] Shared: Rename 'asLiftedTaintModel' to 'asLiftedModel'. --- .../codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll | 2 +- shared/mad/codeql/mad/modelgenerator/internal/ModelPrinting.qll | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll b/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll index 0c9e4349dfa2..34ea0dae6e67 100644 --- a/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll +++ b/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll @@ -562,7 +562,7 @@ module MakeModelGeneratorFactory< private string captureThroughFlow(DataFlowSummaryTargetApi api, boolean preservesValue) { exists(string input, string output | preservesValue = max(boolean b | captureThroughFlow0(api, _, input, _, output, b)) and - result = ModelPrintingSummary::asLiftedTaintModel(api, input, output, preservesValue) + result = ModelPrintingSummary::asLiftedModel(api, input, output, preservesValue) ) } diff --git a/shared/mad/codeql/mad/modelgenerator/internal/ModelPrinting.qll b/shared/mad/codeql/mad/modelgenerator/internal/ModelPrinting.qll index 23bca7e930bb..d4fbd9062b63 100644 --- a/shared/mad/codeql/mad/modelgenerator/internal/ModelPrinting.qll +++ b/shared/mad/codeql/mad/modelgenerator/internal/ModelPrinting.qll @@ -97,7 +97,7 @@ module ModelPrintingImpl { * Gets the lifted taint summary model for `api` with `input` and `output`. */ bindingset[input, output, preservesValue] - string asLiftedTaintModel( + string asLiftedModel( Printing::SummaryApi api, string input, string output, boolean preservesValue ) { result = asModel(api, input, output, preservesValue, true) From 4d2f2b89e76a4ef97e4d9a989e0df78cd0b14442 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 2 May 2025 14:02:41 +0100 Subject: [PATCH 07/10] Shared/Java/C#/Rust/C++: Rename 'captureHeuristicFlow' to 'captureFlow'. --- .../dataflow/CaptureHeuristicSummaryModels.ql | 2 +- .../modelgenerator/debug/CaptureSummaryModelsPath.ql | 9 ++++----- .../dataflow/CaptureHeuristicSummaryModels.ql | 2 +- .../modelgenerator/debug/CaptureSummaryModelsPath.ql | 9 ++++----- .../dataflow/CaptureHeuristicSummaryModels.ql | 2 +- .../modelgenerator/debug/CaptureSummaryModelsPath.ql | 9 ++++----- .../mad/modelgenerator/internal/ModelGeneratorImpl.qll | 4 ++-- 7 files changed, 17 insertions(+), 20 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql b/cpp/ql/test/library-tests/dataflow/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql index 6c35b568f965..ec9cb3400df5 100644 --- a/cpp/ql/test/library-tests/dataflow/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql +++ b/cpp/ql/test/library-tests/dataflow/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql @@ -4,7 +4,7 @@ import SummaryModels import InlineModelsAsDataTest module InlineMadTestConfig implements InlineMadTestConfigSig { - string getCapturedModel(MadRelevantFunction c) { result = Heuristic::captureHeuristicFlow(c, _) } + string getCapturedModel(MadRelevantFunction c) { result = Heuristic::captureFlow(c, _) } string getKind() { result = "heuristic-summary" } } diff --git a/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql b/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql index fa7921d9b63b..096aea1790e6 100644 --- a/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql +++ b/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql @@ -11,16 +11,15 @@ import csharp import utils.modelgenerator.internal.CaptureModels import SummaryModels -import Heuristic -import PropagateTaintFlow::PathGraph +import Heuristic::PropagateTaintFlow::PathGraph from - PropagateTaintFlow::PathNode source, PropagateTaintFlow::PathNode sink, + Heuristic::PropagateTaintFlow::PathNode source, Heuristic::PropagateTaintFlow::PathNode sink, DataFlowSummaryTargetApi api, DataFlow::Node p, DataFlow::Node returnNodeExt where - PropagateTaintFlow::flowPath(source, sink) and + Heuristic::PropagateTaintFlow::flowPath(source, sink) and p = source.getNode() and returnNodeExt = sink.getNode() and - captureThroughFlow0(api, p, returnNodeExt) + Heuristic::captureThroughFlow0(api, p, returnNodeExt) select sink.getNode(), source, sink, "There is flow from $@ to the $@.", source.getNode(), "parameter", sink.getNode(), "return value" diff --git a/csharp/ql/test/utils/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql b/csharp/ql/test/utils/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql index c21a53dd844b..cf52ff8cf25b 100644 --- a/csharp/ql/test/utils/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql +++ b/csharp/ql/test/utils/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql @@ -4,7 +4,7 @@ import SummaryModels import utils.test.InlineMadTest module InlineMadTestConfig implements InlineMadTestConfigSig { - string getCapturedModel(Callable c) { result = Heuristic::captureHeuristicFlow(c, _) } + string getCapturedModel(Callable c) { result = Heuristic::captureFlow(c, _) } string getKind() { result = "heuristic-summary" } } diff --git a/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql b/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql index d4f3c49e14ee..20559f00cbfe 100644 --- a/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql +++ b/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql @@ -12,16 +12,15 @@ import java import semmle.code.java.dataflow.DataFlow import utils.modelgenerator.internal.CaptureModels import SummaryModels -import Heuristic -import PropagateTaintFlow::PathGraph +import Heuristic::PropagateTaintFlow::PathGraph from - PropagateTaintFlow::PathNode source, PropagateTaintFlow::PathNode sink, + Heuristic::PropagateTaintFlow::PathNode source, Heuristic::PropagateTaintFlow::PathNode sink, DataFlowSummaryTargetApi api, DataFlow::Node p, DataFlow::Node returnNodeExt where - PropagateTaintFlow::flowPath(source, sink) and + Heuristic::PropagateTaintFlow::flowPath(source, sink) and p = source.getNode() and returnNodeExt = sink.getNode() and - captureThroughFlow0(api, p, returnNodeExt) + Heuristic::captureThroughFlow0(api, p, returnNodeExt) select sink.getNode(), source, sink, "There is flow from $@ to the $@.", source.getNode(), "parameter", sink.getNode(), "return value" diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql b/java/ql/test/utils/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql index 7b40492d35a3..ae1b25a28143 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureHeuristicSummaryModels.ql @@ -4,7 +4,7 @@ import SummaryModels import utils.test.InlineMadTest module InlineMadTestConfig implements InlineMadTestConfigSig { - string getCapturedModel(Callable c) { result = Heuristic::captureHeuristicFlow(c, _) } + string getCapturedModel(Callable c) { result = Heuristic::captureFlow(c, _) } string getKind() { result = "heuristic-summary" } } diff --git a/rust/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql b/rust/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql index 8ae02ce1d696..7c7a54aea513 100644 --- a/rust/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql +++ b/rust/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql @@ -11,16 +11,15 @@ private import codeql.rust.dataflow.DataFlow import utils.modelgenerator.internal.CaptureModels import SummaryModels -import Heuristic -import PropagateTaintFlow::PathGraph +import Heuristic::PropagateTaintFlow::PathGraph from - PropagateTaintFlow::PathNode source, PropagateTaintFlow::PathNode sink, + Heuristic::PropagateTaintFlow::PathNode source, Heuristic::PropagateTaintFlow::PathNode sink, DataFlowSummaryTargetApi api, DataFlow::Node p, DataFlow::Node returnNodeExt where - PropagateTaintFlow::flowPath(source, sink) and + Heuristic::PropagateTaintFlow::flowPath(source, sink) and p = source.getNode() and returnNodeExt = sink.getNode() and - captureThroughFlow0(api, p, returnNodeExt) + Heuristic::captureThroughFlow0(api, p, returnNodeExt) select sink.getNode(), source, sink, "There is flow from $@ to the $@.", source.getNode(), "parameter", sink.getNode(), "return value" diff --git a/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll b/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll index 34ea0dae6e67..1eed895cc879 100644 --- a/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll +++ b/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll @@ -572,7 +572,7 @@ module MakeModelGeneratorFactory< * * `preservesValue` is `true` if the summary is value-preserving, and `false` otherwise. */ - string captureHeuristicFlow(DataFlowSummaryTargetApi api, boolean preservesValue) { + string captureFlow(DataFlowSummaryTargetApi api, boolean preservesValue) { result = captureQualifierFlow(api) and preservesValue = true or result = captureThroughFlow(api, preservesValue) @@ -988,7 +988,7 @@ module MakeModelGeneratorFactory< api0.lift() = api.lift() and exists(ContentSensitive::captureFlow(api0, true, _)) ) and - result = Heuristic::captureHeuristicFlow(api, preservesValue) and + result = Heuristic::captureFlow(api, preservesValue) and lift = true ) } From 37bc2bf5b30e24a1302aad10476d4614b96c595c Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 2 May 2025 16:51:15 +0100 Subject: [PATCH 08/10] Shared: Deduplicate flow summaries. --- .../internal/ModelGeneratorImpl.qll | 83 ++++++++++++------- 1 file changed, 52 insertions(+), 31 deletions(-) diff --git a/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll b/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll index 1eed895cc879..6623373b2816 100644 --- a/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll +++ b/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll @@ -345,12 +345,14 @@ module MakeModelGeneratorFactory< /** * Gets the summary model of `api`, if it follows the `fluent` programming pattern (returns `this`). */ - private string captureQualifierFlow(DataFlowSummaryTargetApi api) { + private string captureQualifierFlow(DataFlowSummaryTargetApi api, string input, string output) { exists(ReturnNodeExt ret | api = returnNodeEnclosingCallable(ret) and isOwnInstanceAccessNode(ret) ) and - result = ModelPrintingSummary::asLiftedValueModel(api, qualifierString(), "ReturnValue") + input = qualifierString() and + output = "ReturnValue" and + result = ModelPrintingSummary::asLiftedValueModel(api, input, output) } private int accessPathLimit0() { result = 2 } @@ -430,7 +432,7 @@ module MakeModelGeneratorFactory< predicate isSink(DataFlow::Node sink) { sink instanceof ReturnNodeExt and not isOwnInstanceAccessNode(sink) and - not exists(captureQualifierFlow(getAsExprEnclosingCallable(sink))) + not exists(captureQualifierFlow(getAsExprEnclosingCallable(sink), _, _)) } predicate isAdditionalFlowStep = PropagateFlowConfigInput::isAdditionalFlowStep/4; @@ -559,11 +561,24 @@ module MakeModelGeneratorFactory< * * `preservesValue` is `true` if the summary is value-preserving, and `false` otherwise. */ - private string captureThroughFlow(DataFlowSummaryTargetApi api, boolean preservesValue) { - exists(string input, string output | - preservesValue = max(boolean b | captureThroughFlow0(api, _, input, _, output, b)) and - result = ModelPrintingSummary::asLiftedModel(api, input, output, preservesValue) - ) + private string captureThroughFlow( + DataFlowSummaryTargetApi api, string input, string output, boolean preservesValue + ) { + preservesValue = max(boolean b | captureThroughFlow0(api, _, input, _, output, b)) and + result = ModelPrintingSummary::asLiftedModel(api, input, output, preservesValue) + } + + /** + * Gets the summary model(s) of `api`, if there is flow `input` to + * `output`. `preservesValue` is `true` if the summary is value- + * preserving, and `false` otherwise. + */ + string captureFlow( + DataFlowSummaryTargetApi api, string input, string output, boolean preservesValue + ) { + result = captureQualifierFlow(api, input, output) and preservesValue = true + or + result = captureThroughFlow(api, input, output, preservesValue) } /** @@ -573,9 +588,7 @@ module MakeModelGeneratorFactory< * `preservesValue` is `true` if the summary is value-preserving, and `false` otherwise. */ string captureFlow(DataFlowSummaryTargetApi api, boolean preservesValue) { - result = captureQualifierFlow(api) and preservesValue = true - or - result = captureThroughFlow(api, preservesValue) + result = captureFlow(api, _, _, preservesValue) } /** @@ -947,19 +960,20 @@ module MakeModelGeneratorFactory< } /** - * Gets the content based summary model(s) of the API `api` (if there is flow from a parameter to - * the return value or a parameter). `lift` is true, if the model should be lifted, otherwise false. + * Gets the content based summary model(s) of the API `api` (if there is flow from `input` to + * `output`). `lift` is true, if the model should be lifted, otherwise false. * `preservesValue` is `true` if the summary is value-preserving, and `false` otherwise. * * Models are lifted to the best type in case the read and store access paths do not * contain a field or synthetic field access. */ - string captureFlow(ContentDataFlowSummaryTargetApi api, boolean lift, boolean preservesValue) { - exists(string input, string output | - captureFlow0(api, input, output, _, lift) and - preservesValue = max(boolean p | captureFlow0(api, input, output, p, lift)) and - result = ContentModelPrinting::asModel(api, input, output, preservesValue, lift) - ) + string captureFlow( + ContentDataFlowSummaryTargetApi api, string input, string output, boolean lift, + boolean preservesValue + ) { + captureFlow0(api, input, output, _, lift) and + preservesValue = max(boolean p | captureFlow0(api, input, output, p, lift)) and + result = ContentModelPrinting::asModel(api, input, output, preservesValue, lift) } } @@ -972,23 +986,30 @@ module MakeModelGeneratorFactory< * generate flow summaries using the heuristic based summary generator. */ string captureFlow(DataFlowSummaryTargetApi api, boolean lift) { - exists(boolean preservesValue | - result = ContentSensitive::captureFlow(api, lift, preservesValue) - or - not exists(DataFlowSummaryTargetApi api0 | - // If the heuristic summary is value-preserving then we keep both - // summaries. However, if we can generate any content-sensitive - // summary (value-preserving or not) then we don't include any taint- - // based heuristic summary. - preservesValue = false + result = ContentSensitive::captureFlow(api, _, _, lift, _) + or + exists(boolean preservesValue, string input, string output | + not exists( + DataFlowSummaryTargetApi api0, string input0, string output0, boolean preservesValue0 + | + // If the heuristic summary is taint-based, and we can generate a content-sensitive + // summary that is value-preserving then we omit generating any heuristic summary. + preservesValue = false and + preservesValue0 = true + or + // However, if they're both value-preserving (or both taint-based) then we only + // generate a heuristic summary if we didn't generate a content-sensitive summary. + preservesValue = preservesValue0 and + input0 = input and + output0 = output | (api0 = api or api.lift() = api0) and - exists(ContentSensitive::captureFlow(api0, false, _)) + exists(ContentSensitive::captureFlow(api0, input0, output0, false, preservesValue0)) or api0.lift() = api.lift() and - exists(ContentSensitive::captureFlow(api0, true, _)) + exists(ContentSensitive::captureFlow(api0, input0, output0, true, preservesValue0)) ) and - result = Heuristic::captureFlow(api, preservesValue) and + result = Heuristic::captureFlow(api, input, output, preservesValue) and lift = true ) } From bce5f2539f7c2bdf6feaef9810188dc133cb8416 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 2 May 2025 16:52:05 +0100 Subject: [PATCH 09/10] C++/C#/Java/Rust: Fixup tests. --- .../src/utils/modelgenerator/CaptureContentSummaryModels.ql | 2 +- .../modelgenerator/dataflow/CaptureContentSummaryModels.ql | 4 +++- .../src/utils/modelgenerator/CaptureContentSummaryModels.ql | 2 +- .../modelgenerator/dataflow/CaptureContentSummaryModels.ql | 2 +- .../src/utils/modelgenerator/CaptureContentSummaryModels.ql | 2 +- .../modelgenerator/dataflow/CaptureContentSummaryModels.ql | 2 +- .../src/utils/modelgenerator/CaptureContentSummaryModels.ql | 2 +- .../test/utils-tests/modelgenerator/CaptureSummaryModels.ql | 2 +- 8 files changed, 10 insertions(+), 8 deletions(-) diff --git a/cpp/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql b/cpp/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql index c9ded7484662..a15a584e13d0 100644 --- a/cpp/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql +++ b/cpp/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql @@ -10,5 +10,5 @@ import internal.CaptureModels import SummaryModels from DataFlowSummaryTargetApi api, string flow -where flow = ContentSensitive::captureFlow(api, _, _) +where flow = ContentSensitive::captureFlow(api, _, _, _, _) select flow order by flow diff --git a/cpp/ql/test/library-tests/dataflow/modelgenerator/dataflow/CaptureContentSummaryModels.ql b/cpp/ql/test/library-tests/dataflow/modelgenerator/dataflow/CaptureContentSummaryModels.ql index a7d6e0ad4ec5..37990554258b 100644 --- a/cpp/ql/test/library-tests/dataflow/modelgenerator/dataflow/CaptureContentSummaryModels.ql +++ b/cpp/ql/test/library-tests/dataflow/modelgenerator/dataflow/CaptureContentSummaryModels.ql @@ -4,7 +4,9 @@ import SummaryModels import InlineModelsAsDataTest module InlineMadTestConfig implements InlineMadTestConfigSig { - string getCapturedModel(MadRelevantFunction c) { result = ContentSensitive::captureFlow(c, _, _) } + string getCapturedModel(MadRelevantFunction c) { + result = ContentSensitive::captureFlow(c, _, _, _, _) + } string getKind() { result = "contentbased-summary" } } diff --git a/csharp/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql b/csharp/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql index cc36c15d6ad1..6030960a1a78 100644 --- a/csharp/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql +++ b/csharp/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql @@ -10,5 +10,5 @@ import internal.CaptureModels import SummaryModels from DataFlowSummaryTargetApi api, string flow -where flow = ContentSensitive::captureFlow(api, _, _) +where flow = ContentSensitive::captureFlow(api, _, _, _, _) select flow order by flow diff --git a/csharp/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.ql b/csharp/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.ql index 7a385bc70ac5..a52b96b02327 100644 --- a/csharp/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.ql +++ b/csharp/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.ql @@ -4,7 +4,7 @@ import SummaryModels import utils.test.InlineMadTest module InlineMadTestConfig implements InlineMadTestConfigSig { - string getCapturedModel(Callable c) { result = ContentSensitive::captureFlow(c, _, _) } + string getCapturedModel(Callable c) { result = ContentSensitive::captureFlow(c, _, _, _, _) } string getKind() { result = "contentbased-summary" } } diff --git a/java/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql b/java/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql index 3eec61cc8d49..39e8cd9a0a4a 100644 --- a/java/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql +++ b/java/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql @@ -10,5 +10,5 @@ import internal.CaptureModels import SummaryModels from DataFlowSummaryTargetApi api, string flow -where flow = ContentSensitive::captureFlow(api, _, _) +where flow = ContentSensitive::captureFlow(api, _, _, _, _) select flow order by flow diff --git a/java/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.ql b/java/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.ql index 1954bc8cd960..aecabe429019 100644 --- a/java/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.ql +++ b/java/ql/test/utils/modelgenerator/dataflow/CaptureContentSummaryModels.ql @@ -4,7 +4,7 @@ import SummaryModels import utils.test.InlineMadTest module InlineMadTestConfig implements InlineMadTestConfigSig { - string getCapturedModel(Callable c) { result = ContentSensitive::captureFlow(c, _, _) } + string getCapturedModel(Callable c) { result = ContentSensitive::captureFlow(c, _, _, _, _) } string getKind() { result = "contentbased-summary" } } diff --git a/rust/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql b/rust/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql index e88efe80b8e5..9dd63e06ea72 100644 --- a/rust/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql +++ b/rust/ql/src/utils/modelgenerator/CaptureContentSummaryModels.ql @@ -10,5 +10,5 @@ import internal.CaptureModels import SummaryModels from DataFlowSummaryTargetApi api, string flow -where flow = ContentSensitive::captureFlow(api, _, _) +where flow = ContentSensitive::captureFlow(api, _, _, _, _) select flow order by flow diff --git a/rust/ql/test/utils-tests/modelgenerator/CaptureSummaryModels.ql b/rust/ql/test/utils-tests/modelgenerator/CaptureSummaryModels.ql index c68b3b18b8c9..fe5e532394b4 100644 --- a/rust/ql/test/utils-tests/modelgenerator/CaptureSummaryModels.ql +++ b/rust/ql/test/utils-tests/modelgenerator/CaptureSummaryModels.ql @@ -4,7 +4,7 @@ import SummaryModels import utils.test.InlineMadTest module InlineMadTestConfig implements InlineMadTestConfigSig { - string getCapturedModel(Function f) { result = ContentSensitive::captureFlow(f, _, _) } + string getCapturedModel(Function f) { result = ContentSensitive::captureFlow(f, _, _, _, _) } string getKind() { result = "summary" } } From 64371688d7fd70eddc0076806efb14bfe5a7e2c8 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 8 May 2025 10:16:09 -0400 Subject: [PATCH 10/10] Shared: Fix QLDoc to make QL4QL happy. --- .../codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll b/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll index 6623373b2816..331bcbc8b65d 100644 --- a/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll +++ b/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll @@ -344,6 +344,8 @@ module MakeModelGeneratorFactory< /** * Gets the summary model of `api`, if it follows the `fluent` programming pattern (returns `this`). + * + * The strings `input` and `output` represent the qualifier and the return value, respectively. */ private string captureQualifierFlow(DataFlowSummaryTargetApi api, string input, string output) { exists(ReturnNodeExt ret |