Merge pull request #19443 from MathiasVP/generate-more-value-preserving-summaries-2

Shared: Generate more value-preserving flow summaries
This commit is contained in:
Mathias Vorreiter Pedersen
2025-05-14 09:12:28 +01:00
committed by GitHub
35 changed files with 331 additions and 209 deletions

View File

@@ -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

View File

@@ -189,15 +189,15 @@ module ModelGeneratorCommonInput implements ModelGeneratorCommonInputSig<Cpp::Lo
)
}
string parameterAccess(Parameter p) { parameterContentAccessImpl(p, result) }
string parameterApproximateAccess(Parameter p) { parameterContentAccessImpl(p, result) }
string parameterContentAccess(Parameter p) { parameterContentAccessImpl(p, result) }
string parameterExactAccess(Parameter p) { parameterContentAccessImpl(p, result) }
bindingset[c]
string paramReturnNodeAsOutput(Callable c, DataFlowPrivate::Position pos) {
string paramReturnNodeAsExactOutput(Callable c, DataFlowPrivate::Position pos) {
exists(Parameter p |
p.isSourceParameterOf(c, pos) and
result = parameterAccess(p)
result = parameterExactAccess(p)
)
or
pos.getArgumentIndex() = -1 and
@@ -206,8 +206,8 @@ module ModelGeneratorCommonInput implements ModelGeneratorCommonInputSig<Cpp::Lo
}
bindingset[c]
string paramReturnNodeAsContentOutput(Callable c, DataFlowPrivate::ParameterPosition pos) {
result = paramReturnNodeAsOutput(c, pos)
string paramReturnNodeAsApproximateOutput(Callable c, DataFlowPrivate::ParameterPosition pos) {
result = paramReturnNodeAsExactOutput(c, pos)
}
pragma[nomagic]

View File

@@ -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" }
}

View File

@@ -4,7 +4,7 @@ import SummaryModels
import InlineModelsAsDataTest
module InlineMadTestConfig implements InlineMadTestConfigSig {
string getCapturedModel(MadRelevantFunction c) { result = Heuristic::captureFlow(c) }
string getCapturedModel(MadRelevantFunction c) { result = Heuristic::captureFlow(c, _) }
string getKind() { result = "heuristic-summary" }
}

View File

@@ -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<T>;true;template_returnThis;(T);;Argument[-1];ReturnValue[*];taint;df-generated
//heuristic-summary=Models;TemplatedFlow<T>;true;template_returnThis;(T);;Argument[-1];ReturnValue[*];value;df-generated
//contentbased-summary=Models;TemplatedFlow<T>;true;template_returnThis;(T);;Argument[-1];ReturnValue[*];value;dfc-generated
TemplatedFlow<T>* template_returnThis(T input) {
return this;
}
//heuristic-summary=Models;TemplatedFlow<T>;true;template_returnParam0;(T *,T *);;Argument[0];ReturnValue;taint;df-generated
//heuristic-summary=Models;TemplatedFlow<T>;true;template_returnParam0;(T *,T *);;Argument[*0];ReturnValue[*];taint;df-generated
//heuristic-summary=Models;TemplatedFlow<T>;true;template_returnParam0;(T *,T *);;Argument[0];ReturnValue;value;df-generated
//heuristic-summary=Models;TemplatedFlow<T>;true;template_returnParam0;(T *,T *);;Argument[*0];ReturnValue[*];value;df-generated
//contentbased-summary=Models;TemplatedFlow<T>;true;template_returnParam0;(T *,T *);;Argument[0];ReturnValue;value;dfc-generated
//contentbased-summary=Models;TemplatedFlow<T>;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<T>;true;templated_function<U>;(U *,T *);;Argument[0];ReturnValue;taint;df-generated
//heuristic-summary=Models;TemplatedFlow<T>;true;templated_function<U>;(U *,T *);;Argument[*0];ReturnValue[*];taint;df-generated
//heuristic-summary=Models;TemplatedFlow<T>;true;templated_function<U>;(U *,T *);;Argument[0];ReturnValue;value;df-generated
//heuristic-summary=Models;TemplatedFlow<T>;true;templated_function<U>;(U *,T *);;Argument[*0];ReturnValue[*];value;df-generated
//contentbased-summary=Models;TemplatedFlow<T>;true;templated_function<U>;(U *,T *);;Argument[0];ReturnValue;value;dfc-generated
//contentbased-summary=Models;TemplatedFlow<T>;true;templated_function<U>;(U *,T *);;Argument[*0];ReturnValue[*];value;dfc-generated
template<typename U>
@@ -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 @@ protected:
};
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;

View File

@@ -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

View File

@@ -15,7 +15,7 @@ import PartialFlow::PartialPathGraph
int explorationLimit() { result = 3 }
module PartialFlow = Heuristic::PropagateFlow::FlowExplorationFwd<explorationLimit/0>;
module PartialFlow = Heuristic::PropagateTaintFlow::FlowExplorationFwd<explorationLimit/0>;
from
PartialFlow::PartialPathNode source, PartialFlow::PartialPathNode sink,

View File

@@ -11,16 +11,15 @@
import csharp
import utils.modelgenerator.internal.CaptureModels
import SummaryModels
import Heuristic
import PropagateFlow::PathGraph
import Heuristic::PropagateTaintFlow::PathGraph
from
PropagateFlow::PathNode source, PropagateFlow::PathNode sink, DataFlowSummaryTargetApi api,
DataFlow::Node p, DataFlow::Node returnNodeExt
Heuristic::PropagateTaintFlow::PathNode source, Heuristic::PropagateTaintFlow::PathNode sink,
DataFlowSummaryTargetApi api, DataFlow::Node p, DataFlow::Node returnNodeExt
where
PropagateFlow::flowPath(source, sink) and
Heuristic::PropagateTaintFlow::flowPath(source, sink) and
p = source.getNode() and
returnNodeExt = sink.getNode() and
exists(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"

View File

@@ -124,13 +124,13 @@ module ModelGeneratorCommonInput implements ModelGeneratorCommonInputSig<Locatio
string qualifierString() { result = "Argument[this]" }
string parameterAccess(CS::Parameter p) {
string parameterApproximateAccess(CS::Parameter p) {
if Collections::isCollectionType(p.getType())
then result = "Argument[" + p.getPosition() + "].Element"
else result = "Argument[" + p.getPosition() + "]"
}
string parameterContentAccess(CS::Parameter p) { result = "Argument[" + p.getPosition() + "]" }
string parameterExactAccess(CS::Parameter p) { result = "Argument[" + p.getPosition() + "]" }
private signature string parameterAccessSig(Parameter p);
@@ -145,13 +145,13 @@ module ModelGeneratorCommonInput implements ModelGeneratorCommonInputSig<Locatio
}
bindingset[c]
string paramReturnNodeAsOutput(CS::Callable c, ParameterPosition pos) {
result = ParamReturnNodeAsOutput<parameterAccess/1>::paramReturnNodeAsOutput(c, pos)
string paramReturnNodeAsApproximateOutput(CS::Callable c, ParameterPosition pos) {
result = ParamReturnNodeAsOutput<parameterApproximateAccess/1>::paramReturnNodeAsOutput(c, pos)
}
bindingset[c]
string paramReturnNodeAsContentOutput(Callable c, ParameterPosition pos) {
result = ParamReturnNodeAsOutput<parameterContentAccess/1>::paramReturnNodeAsOutput(c, pos)
string paramReturnNodeAsExactOutput(Callable c, ParameterPosition pos) {
result = ParamReturnNodeAsOutput<parameterExactAccess/1>::paramReturnNodeAsOutput(c, pos)
}
ParameterPosition getReturnKindParamPosition(ReturnKind kind) {

View File

@@ -39,7 +39,7 @@ private predicate localTypeParameter(Callable callable, TypeParameter tp) {
*/
private predicate parameter(Callable callable, string input, TypeParameter tp) {
exists(Parameter p |
input = ModelGeneratorInput::parameterAccess(p) and
input = ModelGeneratorInput::parameterApproximateAccess(p) and
p = callable.getAParameter() and
(
// Parameter of type tp

View File

@@ -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" }
}

View File

@@ -4,7 +4,7 @@ import SummaryModels
import utils.test.InlineMadTest
module InlineMadTestConfig implements InlineMadTestConfigSig {
string getCapturedModel(Callable c) { result = Heuristic::captureFlow(c) }
string getCapturedModel(Callable c) { result = Heuristic::captureFlow(c, _) }
string getKind() { result = "heuristic-summary" }
}

View File

@@ -19,22 +19,22 @@ public class BasicFlow
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 class CollectionFlow
return new List<string> { tainted };
}
// SPURIOUS-heuristic-summary=Models;CollectionFlow;false;ReturnComplexTypeArray;(System.String[]);;Argument[0].Element;ReturnValue;taint;df-generated
// heuristic-summary=Models;CollectionFlow;false;ReturnComplexTypeArray;(System.String[]);;Argument[0];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<System.Byte>);;Argument[0].Element;ReturnValue;taint;df-generated
// heuristic-summary=Models;CollectionFlow;false;ReturnBulkTypeList;(System.Collections.Generic.List<System.Byte>);;Argument[0];ReturnValue;value;df-generated
// contentbased-summary=Models;CollectionFlow;false;ReturnBulkTypeList;(System.Collections.Generic.List<System.Byte>);;Argument[0];ReturnValue;value;dfc-generated
public List<byte> ReturnBulkTypeList(List<byte> a)
{
return a;
}
// SPURIOUS-heuristic-summary=Models;CollectionFlow;false;ReturnComplexTypeDictionary;(System.Collections.Generic.Dictionary<System.Int32,System.String>);;Argument[0].Element;ReturnValue;taint;df-generated
// heuristic-summary=Models;CollectionFlow;false;ReturnComplexTypeDictionary;(System.Collections.Generic.Dictionary<System.Int32,System.String>);;Argument[0];ReturnValue;value;df-generated
// contentbased-summary=Models;CollectionFlow;false;ReturnComplexTypeDictionary;(System.Collections.Generic.Dictionary<System.Int32,System.String>);;Argument[0];ReturnValue;value;dfc-generated
public Dictionary<int, string> ReturnComplexTypeDictionary(Dictionary<int, string> a)
{
return a;
}
// SPURIOUS-heuristic-summary=Models;CollectionFlow;false;ReturnUntypedArray;(System.Array);;Argument[0].Element;ReturnValue;taint;df-generated
// heuristic-summary=Models;CollectionFlow;false;ReturnUntypedArray;(System.Array);;Argument[0];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
// heuristic-summary=Models;CollectionFlow;false;ReturnUntypedList;(System.Collections.IList);;Argument[0];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 class IEnumerableFlow
tainted = s;
}
// SPURIOUS-heuristic-summary=Models;IEnumerableFlow;false;ReturnIEnumerable;(System.Collections.Generic.IEnumerable<System.String>);;Argument[0].Element;ReturnValue;taint;df-generated
// heuristic-summary=Models;IEnumerableFlow;false;ReturnIEnumerable;(System.Collections.Generic.IEnumerable<System.String>);;Argument[0];ReturnValue;value;df-generated
// contentbased-summary=Models;IEnumerableFlow;false;ReturnIEnumerable;(System.Collections.Generic.IEnumerable<System.String>);;Argument[0];ReturnValue;value;dfc-generated
public IEnumerable<string> ReturnIEnumerable(IEnumerable<string> input)
{
@@ -256,7 +256,7 @@ public class GenericFlow<T>
return new List<T> { tainted };
}
// heuristic-summary=Models;GenericFlow<T>;false;ReturnGenericParam<S>;(S);;Argument[0];ReturnValue;taint;df-generated
// heuristic-summary=Models;GenericFlow<T>;false;ReturnGenericParam<S>;(S);;Argument[0];ReturnValue;value;df-generated
// contentbased-summary=Models;GenericFlow<T>;false;ReturnGenericParam<S>;(S);;Argument[0];ReturnValue;value;dfc-generated
public S ReturnGenericParam<S>(S input)
{
@@ -280,7 +280,7 @@ public class GenericFlow<T>
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 abstract class BaseClassFlow
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 class DerivedClass1Flow : BaseClassFlow
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 class OperatorFlow
}
// 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 class EqualsGetHashCodeNoFlow
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 class Inheritance
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 @@ public class Inheritance
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 class Inheritance
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 class AvoidDuplicateLifted
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 class ParameterModifiers
}
// 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;

View File

@@ -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

View File

@@ -16,7 +16,7 @@ import PartialFlow::PartialPathGraph
int explorationLimit() { result = 3 }
module PartialFlow = Heuristic::PropagateFlow::FlowExplorationFwd<explorationLimit/0>;
module PartialFlow = Heuristic::PropagateTaintFlow::FlowExplorationFwd<explorationLimit/0>;
from
PartialFlow::PartialPathNode source, PartialFlow::PartialPathNode sink,

View File

@@ -12,16 +12,15 @@ import java
import semmle.code.java.dataflow.DataFlow
import utils.modelgenerator.internal.CaptureModels
import SummaryModels
import Heuristic
import PropagateFlow::PathGraph
import Heuristic::PropagateTaintFlow::PathGraph
from
PropagateFlow::PathNode source, PropagateFlow::PathNode sink, DataFlowSummaryTargetApi api,
DataFlow::Node p, DataFlow::Node returnNodeExt
Heuristic::PropagateTaintFlow::PathNode source, Heuristic::PropagateTaintFlow::PathNode sink,
DataFlowSummaryTargetApi api, DataFlow::Node p, DataFlow::Node returnNodeExt
where
PropagateFlow::flowPath(source, sink) and
Heuristic::PropagateTaintFlow::flowPath(source, sink) and
p = source.getNode() and
returnNodeExt = sink.getNode() and
exists(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"

View File

@@ -92,7 +92,7 @@ module ModelGeneratorCommonInput implements ModelGeneratorCommonInputSig<Locatio
string qualifierString() { result = "Argument[this]" }
string parameterAccess(J::Parameter p) {
string parameterApproximateAccess(J::Parameter p) {
if
p.getType() instanceof J::Array and
not isPrimitiveTypeUsedForBulkData(p.getType().(J::Array).getElementType())
@@ -103,20 +103,20 @@ module ModelGeneratorCommonInput implements ModelGeneratorCommonInputSig<Locatio
else result = "Argument[" + p.getPosition() + "]"
}
string parameterContentAccess(J::Parameter p) { result = "Argument[" + p.getPosition() + "]" }
string parameterExactAccess(J::Parameter p) { result = "Argument[" + p.getPosition() + "]" }
class InstanceParameterNode = DataFlow::InstanceParameterNode;
bindingset[c]
string paramReturnNodeAsOutput(Callable c, ParameterPosition pos) {
result = parameterAccess(c.getParameter(pos))
string paramReturnNodeAsApproximateOutput(Callable c, ParameterPosition pos) {
result = parameterApproximateAccess(c.getParameter(pos))
or
result = qualifierString() and pos = -1
}
bindingset[c]
string paramReturnNodeAsContentOutput(Callable c, ParameterPosition pos) {
result = parameterContentAccess(c.getParameter(pos))
string paramReturnNodeAsExactOutput(Callable c, ParameterPosition pos) {
result = parameterExactAccess(c.getParameter(pos))
or
result = qualifierString() and pos = -1
}

View File

@@ -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" }
}

View File

@@ -4,7 +4,7 @@ import SummaryModels
import utils.test.InlineMadTest
module InlineMadTestConfig implements InlineMadTestConfigSig {
string getCapturedModel(Callable c) { result = Heuristic::captureFlow(c) }
string getCapturedModel(Callable c) { result = Heuristic::captureFlow(c, _) }
string getKind() { result = "heuristic-summary" }
}

View File

@@ -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;

View File

@@ -24,7 +24,7 @@ public final class ImmutablePojo {
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

View File

@@ -10,7 +10,7 @@ public class Inheritance {
}
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 class Inheritance {
}
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 @@ public class Inheritance {
}
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 class Inheritance {
}
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 class Inheritance {
}
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 class Inheritance {
}
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) {

View File

@@ -9,14 +9,14 @@ public class InnerClasses {
}
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;

View File

@@ -2,7 +2,7 @@ package p;
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) {

View File

@@ -16,7 +16,7 @@ class MultipleImpl2 {
}
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;

View File

@@ -9,7 +9,7 @@ public class MultipleImpls {
}
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;

View File

@@ -7,7 +7,7 @@ import java.util.List;
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 class ParamFlow {
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) {

View File

@@ -40,8 +40,8 @@ public class Sources {
return socketStream();
}
// source=p;Sources;true;sourceToParameter;(InputStream[],List);;Argument[0].ArrayElement;remote;df-generated
// source=p;Sources;true;sourceToParameter;(InputStream[],List);;Argument[1].Element;remote;df-generated
// source=p;Sources;true;sourceToParameter;(InputStream[],List);;Argument[0];remote;df-generated
// source=p;Sources;true;sourceToParameter;(InputStream[],List);;Argument[1];remote;df-generated
// neutral=p;Sources;sourceToParameter;(InputStream[],List);summary;df-generated
public void sourceToParameter(InputStream[] streams, List<InputStream> otherStreams)
throws IOException {

View File

@@ -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

View File

@@ -15,7 +15,7 @@ import PartialFlow::PartialPathGraph
int explorationLimit() { result = 3 }
module PartialFlow = Heuristic::PropagateFlow::FlowExplorationFwd<explorationLimit/0>;
module PartialFlow = Heuristic::PropagateTaintFlow::FlowExplorationFwd<explorationLimit/0>;
from
PartialFlow::PartialPathNode source, PartialFlow::PartialPathNode sink,

View File

@@ -11,16 +11,15 @@
private import codeql.rust.dataflow.DataFlow
import utils.modelgenerator.internal.CaptureModels
import SummaryModels
import Heuristic
import PropagateFlow::PathGraph
import Heuristic::PropagateTaintFlow::PathGraph
from
PropagateFlow::PathNode source, PropagateFlow::PathNode sink, DataFlowSummaryTargetApi api,
DataFlow::Node p, DataFlow::Node returnNodeExt
Heuristic::PropagateTaintFlow::PathNode source, Heuristic::PropagateTaintFlow::PathNode sink,
DataFlowSummaryTargetApi api, DataFlow::Node p, DataFlow::Node returnNodeExt
where
PropagateFlow::flowPath(source, sink) and
Heuristic::PropagateTaintFlow::flowPath(source, sink) and
p = source.getNode() and
returnNodeExt = sink.getNode() and
exists(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"

View File

@@ -54,26 +54,26 @@ module ModelGeneratorCommonInput implements
string qualifierString() { result = "Argument[self]" }
string parameterAccess(R::ParamBase p) {
string parameterExactAccess(R::ParamBase p) {
result =
"Argument[" + any(DataFlowImpl::ParameterPosition pos | p = pos.getParameterIn(_)).toString() +
"]"
}
string parameterContentAccess(R::ParamBase p) { result = parameterAccess(p) }
string parameterApproximateAccess(R::ParamBase p) { result = parameterExactAccess(p) }
class InstanceParameterNode extends DataFlow::ParameterNode {
InstanceParameterNode() { this.asParameter() instanceof SelfParam }
}
bindingset[c]
string paramReturnNodeAsOutput(Callable c, DataFlowImpl::ParameterPosition pos) {
result = paramReturnNodeAsContentOutput(c, pos)
string paramReturnNodeAsApproximateOutput(Callable c, DataFlowImpl::ParameterPosition pos) {
result = paramReturnNodeAsExactOutput(c, pos)
}
bindingset[c]
string paramReturnNodeAsContentOutput(Callable c, DataFlowImpl::ParameterPosition pos) {
result = parameterContentAccess(c.getParamList().getParam(pos.getPosition()))
string paramReturnNodeAsExactOutput(Callable c, DataFlowImpl::ParameterPosition pos) {
result = parameterExactAccess(c.getParamList().getParam(pos.getPosition()))
or
pos.isSelf() and result = qualifierString()
}

View File

@@ -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" }
}

View File

@@ -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.
@@ -72,14 +73,14 @@ signature module ModelGeneratorCommonInputSig<LocationSig Location, InputSig<Loc
* `pos` of callable `c`.
*/
bindingset[c]
string paramReturnNodeAsOutput(Callable c, Lang::ParameterPosition p);
string paramReturnNodeAsApproximateOutput(Callable c, Lang::ParameterPosition p);
/**
* Gets the MaD string representation of return through parameter at position
* `pos` of callable `c` when used in content flow.
*/
bindingset[c]
string paramReturnNodeAsContentOutput(Callable c, Lang::ParameterPosition pos);
string paramReturnNodeAsExactOutput(Callable c, Lang::ParameterPosition pos);
/**
* Gets the enclosing callable of `ret`.
@@ -94,13 +95,13 @@ signature module ModelGeneratorCommonInputSig<LocationSig Location, InputSig<Loc
/**
* Gets the MaD string representation of the parameter `p`.
*/
string parameterAccess(Parameter p);
string parameterApproximateAccess(Parameter p);
/**
* Gets the MaD string representation of the parameter `p`
* when used in content flow.
*/
string parameterContentAccess(Parameter p);
string parameterExactAccess(Parameter p);
/**
* Gets the MaD string representation of the qualifier.
@@ -225,8 +226,12 @@ module MakeModelGeneratorFactory<
containerContent(c)
}
private string getOutput(ReturnNodeExt node) {
result = PrintReturnNodeExt<paramReturnNodeAsOutput/2>::getOutput(node)
private string getApproximateOutput(ReturnNodeExt node) {
result = PrintReturnNodeExt<paramReturnNodeAsApproximateOutput/2>::getOutput(node)
}
private string getExactOutput(ReturnNodeExt node) {
result = PrintReturnNodeExt<paramReturnNodeAsExactOutput/2>::getOutput(node)
}
/**
@@ -319,6 +324,16 @@ module MakeModelGeneratorFactory<
DataFlowSummaryTargetApi() { not isUninterestingForDataFlowModels(this) }
}
/**
* Gets the MaD string representation of the parameter `p`
* when used in exact flow.
*/
private string parameterNodeAsExactInput(DataFlow::ParameterNode p) {
result = parameterExactAccess(asParameter(p))
or
result = qualifierString() and p instanceof InstanceParameterNode
}
/**
* Provides classes and predicates related to capturing summary models
* based on heuristic data flow.
@@ -335,21 +350,25 @@ module MakeModelGeneratorFactory<
/**
* Gets the MaD string representation of the parameter node `p`.
*/
string parameterNodeAsInput(DataFlow::ParameterNode p) {
result = parameterAccess(asParameter(p))
private string parameterNodeAsApproximateInput(DataFlow::ParameterNode p) {
result = parameterApproximateAccess(asParameter(p))
or
result = qualifierString() and p instanceof InstanceParameterNode
}
/**
* 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) {
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 }
@@ -394,14 +413,22 @@ module MakeModelGeneratorFactory<
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<PropagateFlowConfigInputSig PropagateFlowConfigInput>
implements DataFlow::StateConfigSig
{
import PropagateFlowConfigInput
predicate isSource(DataFlow::Node source, FlowState state) {
source instanceof DataFlow::ParameterNode and
@@ -410,7 +437,7 @@ module MakeModelGeneratorFactory<
c instanceof DataFlowSummaryTargetApi and
not isUninterestingForHeuristicDataFlowModels(c)
) and
state.(TaintRead).getStep() = 0
state = initialState()
}
predicate isSink(DataFlow::Node sink, FlowState state) {
@@ -421,9 +448,34 @@ 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;
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
) {
@@ -445,51 +497,117 @@ module MakeModelGeneratorFactory<
state1.(TaintRead).getStep() + 1 = state2.(TaintRead).getStep()
)
}
predicate isBarrier(DataFlow::Node n) {
exists(Type t | t = n.(NodeExtended).getType() and not isRelevantType(t))
}
DataFlow::FlowFeature getAFeature() {
result instanceof DataFlow::FeatureEqualSourceSinkCallContext
}
}
module PropagateFlow = TaintTracking::GlobalWithState<PropagateFlowConfig>;
/**
* 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<PropagateFlowConfigInputTaintInput>;
module PropagateTaintFlow = TaintTracking::GlobalWithState<PropagateTaintFlowConfig>;
/**
* Gets the summary model(s) of `api`, if there is flow from parameters to return value or parameter.
* 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.
*/
string captureThroughFlow0(
module PropagateFlowConfigInputDataFlowInput implements PropagateFlowConfigInputSig {
class FlowState = Unit;
FlowState initialState() { any() }
}
/**
* 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<PropagateFlowConfigInputDataFlowInput>;
module PropagateDataFlow = DataFlow::GlobalWithState<PropagateDataFlowConfig>;
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 = ModelPrintingSummary::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
input = parameterNodeAsExactInput(p) and
output = getExactOutput(returnNodeExt) and
preservesValue = true
or
not PropagateDataFlow::flow(p, returnNodeExt) and
PropagateTaintFlow::flow(p, returnNodeExt) and
input = parameterNodeAsApproximateInput(p) and
output = getApproximateOutput(returnNodeExt) and
preservesValue = false
) and
getEnclosingCallable(p) = api and
getEnclosingCallable(returnNodeExt) = api 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, 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)
}
/**
* 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 captureFlow(DataFlowSummaryTargetApi api, boolean preservesValue) {
result = captureFlow(api, _, _, preservesValue)
}
/**
@@ -499,7 +617,7 @@ module MakeModelGeneratorFactory<
*/
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 = ModelPrintingSummary::asNeutralSummaryModel(api)
@@ -550,20 +668,6 @@ module MakeModelGeneratorFactory<
private module ContentModelPrinting =
Printing::ModelPrintingSummary<ContentModelPrintingInput>;
private string getContentOutput(ReturnNodeExt node) {
result = PrintReturnNodeExt<paramReturnNodeAsContentOutput/2>::getOutput(node)
}
/**
* Gets the MaD string representation of the parameter `p`
* when used in content flow.
*/
private string parameterNodeAsContentInput(DataFlow::ParameterNode p) {
result = parameterContentAccess(asParameter(p))
or
result = qualifierString() and p instanceof InstanceParameterNode
}
private string getContent(PropagateContentFlow::AccessPath ap, int i) {
result = "." + printContent(ap.getAtIndex(i))
}
@@ -639,8 +743,8 @@ module MakeModelGeneratorFactory<
PropagateContentFlow::AccessPath stores
|
apiFlow(this, parameter, reads, returnNodeExt, stores, _) and
input = parameterNodeAsContentInput(parameter) + printReadAccessPath(reads) and
output = getContentOutput(returnNodeExt) + printStoreAccessPath(stores)
input = parameterNodeAsExactInput(parameter) + printReadAccessPath(reads) and
output = getExactOutput(returnNodeExt) + printStoreAccessPath(stores)
)
) <= 3
}
@@ -847,8 +951,8 @@ module MakeModelGeneratorFactory<
PropagateContentFlow::AccessPath reads, PropagateContentFlow::AccessPath stores
|
apiRelevantContentFlow(api, p, reads, returnNodeExt, stores, preservesValue) and
input = parameterNodeAsContentInput(p) + printReadAccessPath(reads) and
output = getContentOutput(returnNodeExt) + printStoreAccessPath(stores) and
input = parameterNodeAsExactInput(p) + printReadAccessPath(reads) and
output = getExactOutput(returnNodeExt) + printStoreAccessPath(stores) and
input != output and
validateAccessPath(reads) and
validateAccessPath(stores) and
@@ -861,18 +965,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) {
exists(string input, string output, 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)
)
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)
}
}
@@ -885,17 +991,32 @@ module MakeModelGeneratorFactory<
* generate flow summaries using the heuristic based summary generator.
*/
string captureFlow(DataFlowSummaryTargetApi api, boolean lift) {
result = ContentSensitive::captureFlow(api, lift)
result = ContentSensitive::captureFlow(api, _, _, lift, _)
or
not exists(DataFlowSummaryTargetApi api0 |
(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::captureFlow(api) and
lift = true
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 then we omit generating the heuristic summary.
preservesValue = false
or
// If they're both value-preserving then we only generate a heuristic summary if
// we didn't generate a content-sensitive summary on the same input/output pair.
preservesValue = true and
preservesValue0 = true and
input0 = input and
output0 = output
|
(api0 = api or api.lift() = api0) and
exists(ContentSensitive::captureFlow(api0, input0, output0, false, preservesValue0))
or
api0.lift() = api.lift() and
exists(ContentSensitive::captureFlow(api0, input0, output0, true, preservesValue0))
) and
result = Heuristic::captureFlow(api, input, output, preservesValue) and
lift = true
)
}
/**
@@ -1056,7 +1177,7 @@ module MakeModelGeneratorFactory<
sourceNode(source, kind) and
api = getEnclosingCallable(sink) and
not irrelevantSourceSinkApi(getEnclosingCallable(source), api) and
result = ModelPrintingSourceOrSink::asSourceModel(api, getOutput(sink), kind)
result = ModelPrintingSourceOrSink::asSourceModel(api, getExactOutput(sink), kind)
)
}
}

View File

@@ -96,9 +96,11 @@ module ModelPrintingImpl<ModelPrintingLangSig Lang> {
/**
* 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 asLiftedModel(
Printing::SummaryApi api, string input, string output, boolean preservesValue
) {
result = asModel(api, input, output, preservesValue, true)
}
/**