Skip to content

Shared: Generalize the number of columns in a generated MaD row #18612

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,29 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CsharpDat
c.isDelegateCallReturn() and result = "ReturnValue"
}

predicate partialModel = ExternalFlow::partialModel/6;
string partialModelRow(Callable api, int i) {
i = 0 and ExternalFlow::partialModel(api, result, _, _, _, _) // package
or
i = 1 and ExternalFlow::partialModel(api, _, result, _, _, _) // type
or
i = 2 and ExternalFlow::partialModel(api, _, _, result, _, _) // extensible
or
i = 3 and ExternalFlow::partialModel(api, _, _, _, result, _) // name
or
i = 4 and ExternalFlow::partialModel(api, _, _, _, _, result) // parameters
or
i = 5 and result = "" and exists(api) // ext
Copy link
Contributor

@michaelnebel michaelnebel Jan 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So replacing the conjunction with disjuncts (and index) and a subsequent concat works because the values in each column is a function of the api (just an observation and not anything that requires action).

}

string partialNeutralModelRow(Callable api, int i) {
i = 0 and result = partialModelRow(api, 0) // package
or
i = 1 and result = partialModelRow(api, 1) // type
or
i = 2 and result = partialModelRow(api, 3) // name
or
i = 3 and result = partialModelRow(api, 4) // parameters
}

predicate sourceNode = ExternalFlow::sourceNode/2;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
private import csharp as CS
private import codeql.mad.modelgenerator.internal.ModelPrinting
private import semmle.code.csharp.dataflow.internal.ExternalFlow as ExternalFlow
private import CaptureModels::ModelGeneratorInput as ModelGeneratorInput

private module ModelPrintingLang implements ModelPrintingLangSig {
class Callable = CS::Callable;

predicate partialModel = ExternalFlow::partialModel/6;
predicate partialModelRow = ModelGeneratorInput::partialModelRow/2;

predicate partialNeutralModelRow = ModelGeneratorInput::partialNeutralModelRow/2;
}

import ModelPrintingImpl<ModelPrintingLang>
29 changes: 22 additions & 7 deletions java/ql/src/utils/modelgenerator/internal/CaptureModels.qll
Original file line number Diff line number Diff line change
Expand Up @@ -282,13 +282,28 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, JavaDataF
c instanceof DataFlowUtil::MapKeyContent and result = "MapKey"
}

predicate partialModel(
Callable api, string package, string type, string extensible, string name, string parameters
) {
qualifiedName(api, package, type) and
extensible = isExtensible(api) and
name = api.getName() and
parameters = ExternalFlow::paramsString(api)
string partialModelRow(Callable api, int i) {
i = 0 and qualifiedName(api, result, _) // package
or
i = 1 and qualifiedName(api, _, result) // type
or
i = 2 and result = isExtensible(api) // extensible
or
i = 3 and result = api.getName() // name
or
i = 4 and result = ExternalFlow::paramsString(api) // parameters
or
i = 5 and result = "" and exists(api) // ext
}

string partialNeutralModelRow(Callable api, int i) {
i = 0 and qualifiedName(api, result, _) // package
or
i = 1 and qualifiedName(api, _, result) // type
or
i = 2 and result = api.getName() // name
or
i = 3 and result = ExternalFlow::paramsString(api) // parameters
}

predicate sourceNode = ExternalFlow::sourceNode/2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ private import CaptureModels::ModelGeneratorInput as ModelGeneratorInput
private module ModelPrintingLang implements ModelPrintingLangSig {
class Callable = J::Callable;

predicate partialModel = ModelGeneratorInput::partialModel/6;
predicate partialModelRow = ModelGeneratorInput::partialModelRow/2;

predicate partialNeutralModelRow = ModelGeneratorInput::partialNeutralModelRow/2;
}

import ModelPrintingImpl<ModelPrintingLang>
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,14 @@ signature module ModelGeneratorInputSig<LocationSig Location, InputSig<Location>
predicate isUninterestingForHeuristicDataFlowModels(Callable api);

/**
* Holds if `namespace`, `type`, `extensible`, `name` and `parameters` are string representations
* for the corresponding MaD columns for `api`.
* Gets the string representation for the `i`th column in the MaD row for `api`.
*/
predicate partialModel(
Callable api, string namespace, string type, string extensible, string name, string parameters
);
string partialModelRow(Callable api, int i);

/**
* Gets the string representation for the `i`th column in the neutral MaD row for `api`.
*/
string partialNeutralModelRow(Callable api, int i);

/**
* Holds if `node` is specified as a source with the given kind in a MaD flow
Expand Down Expand Up @@ -274,7 +276,9 @@ module MakeModelGenerator<
private module ModelPrintingLang implements ModelPrintingLangSig {
class Callable = ModelGeneratorInput::Callable;

predicate partialModel = ModelGeneratorInput::partialModel/6;
predicate partialModelRow = ModelGeneratorInput::partialModelRow/2;

predicate partialNeutralModelRow = ModelGeneratorInput::partialNeutralModelRow/2;
}

private import ModelPrintingImpl<ModelPrintingLang> as Printing
Expand Down Expand Up @@ -436,7 +440,7 @@ module MakeModelGenerator<
}

/**
* A data-flow configuration for tracking flow through APIs.
* 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.
Expand Down Expand Up @@ -952,7 +956,7 @@ module MakeModelGenerator<
}

/**
* A dataflow configuration used for finding new sources.
* A data flow configuration used for finding new sources.
* The sources are the already known existing sources and the sinks are the API return nodes.
*
* This can be used to generate Source summaries for an API, if the API expose an already known source
Expand Down Expand Up @@ -997,7 +1001,7 @@ module MakeModelGenerator<
}

/**
* A dataflow configuration used for finding new sinks.
* A data flow configuration used for finding new sinks.
* The sources are the parameters of the API and the fields of the enclosing type.
*
* This can be used to generate Sink summaries for APIs, if the API propagates a parameter (or enclosing type field)
Expand Down
37 changes: 11 additions & 26 deletions shared/mad/codeql/mad/modelgenerator/internal/ModelPrinting.qll
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ signature module ModelPrintingLangSig {
class Callable;

/**
* Holds if `container`, `type`, `name`, and `parameters` contain the type signature of `api`
* and `extensible` is the string representation of a boolean that is true, if
* `api` can be overridden (otherwise false).
* Gets the string representation for the `i`th column in the MaD row for `api`.
*/
predicate partialModel(
Callable api, string container, string type, string extensible, string name, string parameters
);
string partialModelRow(Callable api, int i);

/**
* Gets the string representation for the `i`th column in the neutral MaD row for `api`.
*/
string partialNeutralModelRow(Callable api, int i);
}

module ModelPrintingImpl<ModelPrintingLangSig Lang> {
Expand All @@ -33,33 +34,17 @@ module ModelPrintingImpl<ModelPrintingLangSig Lang> {

module ModelPrinting<ModelPrintingSig Printing> {
/**
* Computes the first 6 columns for MaD rows used for summaries, sources and sinks.
* Computes the first columns for MaD rows used for summaries, sources and sinks.
*/
private string asPartialModel(Lang::Callable api) {
exists(string container, string type, string extensible, string name, string parameters |
Lang::partialModel(api, container, type, extensible, name, parameters) and
result =
container + ";" //
+ type + ";" //
+ extensible + ";" //
+ name + ";" //
+ parameters + ";" //
+ /* ext + */ ";" //
)
result = strictconcat(int i | | Lang::partialModelRow(api, i), ";" order by i) + ";"
}

/**
* Computes the first 4 columns for neutral MaD rows.
* Computes the first columns for neutral MaD rows.
*/
private string asPartialNeutralModel(Printing::SummaryApi api) {
exists(string container, string type, string name, string parameters |
Lang::partialModel(api, container, type, _, name, parameters) and
result =
container + ";" //
+ type + ";" //
+ name + ";" //
+ parameters + ";" //
)
result = strictconcat(int i | | Lang::partialNeutralModelRow(api, i), ";" order by i) + ";"
}

/**
Expand Down