Java/C++: Thread additional models through the shared lib.

This commit is contained in:
Anders Schack-Mulligen
2025-12-11 09:59:13 +01:00
parent 47dcf05a32
commit 07252519c8
7 changed files with 226 additions and 170 deletions

View File

@@ -106,10 +106,6 @@ private import codeql.mad.ModelValidation as SharedModelVal
private import codeql.util.Unit
private import codeql.mad.static.MaD as SharedMaD
private module MaD = SharedMaD::ModelsAsData<Extensions>;
import MaD
/**
* A unit class for adding additional source model rows.
*
@@ -149,11 +145,12 @@ predicate sinkModel(string row) { any(SinkModelCsv s).row(row) }
/** Holds if `row` is a summary model. */
predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) }
/** Holds if a source model exists for the given parameters. */
predicate sourceModel(
private module MadInput implements SharedMaD::InputSig {
/** Holds if a source model exists for the given parameters. */
predicate additionalSourceModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string output, string kind, string provenance, string model
) {
) {
exists(string row |
sourceModel(row) and
row.splitAt(";", 0) = namespace and
@@ -168,19 +165,13 @@ predicate sourceModel(
) and
provenance = "manual" and
model = ""
or
exists(QlBuiltins::ExtensionId madId |
Extensions::sourceModel(namespace, type, subtypes, name, signature, ext, output, kind,
provenance, madId) and
model = "MaD:" + madId.toString()
)
}
}
/** Holds if a sink model exists for the given parameters. */
predicate sinkModel(
/** Holds if a sink model exists for the given parameters. */
predicate additionalSinkModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string input, string kind, string provenance, string model
) {
) {
exists(string row |
sinkModel(row) and
row.splitAt(";", 0) = namespace and
@@ -195,23 +186,17 @@ predicate sinkModel(
) and
provenance = "manual" and
model = ""
or
exists(QlBuiltins::ExtensionId madId |
Extensions::sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance,
madId) and
model = "MaD:" + madId.toString()
)
}
}
/**
/**
* Holds if a summary model exists for the given parameters.
*
* This predicate does not expand `@` to `*`s.
*/
private predicate summaryModel0(
predicate additionalSummaryModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string input, string output, string kind, string provenance, string model
) {
) {
exists(string row |
summaryModel(row) and
row.splitAt(";", 0) = namespace and
@@ -227,14 +212,13 @@ private predicate summaryModel0(
) and
provenance = "manual" and
model = ""
or
exists(QlBuiltins::ExtensionId madId |
Extensions::summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind,
provenance, madId) and
model = "MaD:" + madId.toString()
)
}
}
private module MaD = SharedMaD::ModelsAsData<Extensions, MadInput>;
import MaD
/**
* Holds if `input` is `input0`, but with all occurrences of `@` replaced
* by `n` repetitions of `*` (and similarly for `output` and `output0`).
@@ -256,7 +240,7 @@ predicate summaryModel(
string input, string output, string kind, string provenance, string model
) {
exists(string input0, string output0 |
summaryModel0(namespace, type, subtypes, name, signature, ext, input0, output0, kind,
MaD::summaryModel(namespace, type, subtypes, name, signature, ext, input0, output0, kind,
provenance, model) and
expandInputAndOutput(input0, input, output0, output,
[0 .. Private::getMaxElementContentIndirectionIndex() - 1])

View File

@@ -88,7 +88,7 @@
*/
import csharp
import ExternalFlowExtensions
private import ExternalFlowExtensions::Extensions as Extensions
private import DataFlowDispatch
private import DataFlowPrivate
private import DataFlowPublic
@@ -103,7 +103,9 @@ private import codeql.dataflow.internal.AccessPathSyntax as AccessPathSyntax
private import codeql.mad.ModelValidation as SharedModelVal
private import codeql.mad.static.MaD as SharedMaD
private module MaD = SharedMaD::ModelsAsData<Extensions>;
private module MadInput implements SharedMaD::InputSig { }
private module MaD = SharedMaD::ModelsAsData<Extensions, MadInput>;
import MaD
@@ -169,7 +171,7 @@ module ModelValidation {
predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _, _) }
predicate neutralKind(string kind) { neutralModel(_, _, _, _, kind, _) }
predicate neutralKind(string kind) { Extensions::neutralModel(_, _, _, _, kind, _) }
}
private module KindVal = SharedModelVal::KindValidation<KindValConfig>;
@@ -186,7 +188,7 @@ module ModelValidation {
summaryModel(namespace, type, _, name, signature, ext, _, _, _, provenance, _) and
pred = "summary"
or
neutralModel(namespace, type, name, signature, _, provenance) and
Extensions::neutralModel(namespace, type, name, signature, _, provenance) and
ext = "" and
pred = "neutral"
|
@@ -229,7 +231,7 @@ private predicate elementSpec(
or
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _)
or
neutralModel(namespace, type, name, signature, _, _) and ext = "" and subtypes = true
Extensions::neutralModel(namespace, type, name, signature, _, _) and ext = "" and subtypes = true
}
private predicate elementSpec(
@@ -501,19 +503,17 @@ private predicate interpretSummary(
UnboundCallable c, string input, string output, string kind, string provenance, string model
) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
QlBuiltins::ExtensionId madId
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance,
madId) and
model = "MaD:" + madId.toString() and
model) and
c = interpretElement(namespace, type, subtypes, name, signature, ext)
)
}
predicate interpretNeutral(UnboundCallable c, string kind, string provenance) {
exists(string namespace, string type, string name, string signature |
neutralModel(namespace, type, name, signature, kind, provenance) and
Extensions::neutralModel(namespace, type, name, signature, kind, provenance) and
c = interpretElement(namespace, type, true, name, signature, "")
)
}

View File

@@ -213,11 +213,9 @@ module SourceSinkInterpretationInput implements
Element e, string output, string kind, Public::Provenance provenance, string model
) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
QlBuiltins::ExtensionId madId
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance, madId) and
model = "MaD:" + madId.toString() and
sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance, model) and
e = interpretElement(namespace, type, subtypes, name, signature, ext)
)
}
@@ -226,11 +224,9 @@ module SourceSinkInterpretationInput implements
Element e, string input, string kind, Public::Provenance provenance, string model
) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
QlBuiltins::ExtensionId madId
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance, madId) and
model = "MaD:" + madId.toString() and
sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance, model) and
e = interpretElement(namespace, type, subtypes, name, signature, ext)
)
}

View File

@@ -96,7 +96,9 @@ private import internal.FlowSummaryImpl::Private::External
private import codeql.mad.ModelValidation as SharedModelVal
private import codeql.mad.static.MaD as SharedMaD
private module MaD = SharedMaD::ModelsAsData<Extensions>;
private module MadInput implements SharedMaD::InputSig { }
private module MaD = SharedMaD::ModelsAsData<Extensions, MadInput>;
import MaD

View File

@@ -102,7 +102,47 @@ private import internal.ExternalFlowExtensions::Extensions as Extensions
private import codeql.mad.ModelValidation as SharedModelVal
private import codeql.mad.static.MaD as SharedMaD
private module MaD = SharedMaD::ModelsAsData<Extensions>;
private module MadInput implements SharedMaD::InputSig {
/** Holds if a source model exists for the given parameters. */
predicate additionalSourceModel(
string package, string type, boolean subtypes, string name, string signature, string ext,
string output, string kind, string provenance, string model
) {
exists(QlBuiltins::ExtensionId madId |
any(ActiveExperimentalModelsInternal q)
.sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance,
madId) and
model = "MaD:" + madId.toString()
)
}
/** Holds if a sink model exists for the given parameters. */
predicate additionalSinkModel(
string package, string type, boolean subtypes, string name, string signature, string ext,
string input, string kind, string provenance, string model
) {
exists(QlBuiltins::ExtensionId madId |
any(ActiveExperimentalModelsInternal q)
.sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance, madId) and
model = "MaD:" + madId.toString()
)
}
/** Holds if a summary model exists for the given parameters. */
predicate additionalSummaryModel(
string package, string type, boolean subtypes, string name, string signature, string ext,
string input, string output, string kind, string provenance, string model
) {
exists(QlBuiltins::ExtensionId madId |
any(ActiveExperimentalModelsInternal q)
.summaryModel(package, type, subtypes, name, signature, ext, input, output, kind,
provenance, madId) and
model = "MaD:" + madId.toString()
)
}
}
private module MaD = SharedMaD::ModelsAsData<Extensions, MadInput>;
import MaD
@@ -152,34 +192,6 @@ abstract private class ActiveExperimentalModelsInternal extends string {
deprecated class ActiveExperimentalModels = ActiveExperimentalModelsInternal;
/** Holds if a source model exists for the given parameters. */
predicate sourceModel(
string package, string type, boolean subtypes, string name, string signature, string ext,
string output, string kind, string provenance, QlBuiltins::ExtensionId madId
) {
(
Extensions::sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance,
madId)
or
any(ActiveExperimentalModelsInternal q)
.sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance, madId)
)
}
/** Holds if a sink model exists for the given parameters. */
predicate sinkModel(
string package, string type, boolean subtypes, string name, string signature, string ext,
string input, string kind, string provenance, QlBuiltins::ExtensionId madId
) {
(
Extensions::sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance,
madId)
or
any(ActiveExperimentalModelsInternal q)
.sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance, madId)
)
}
/** Holds if a barrier model exists for the given parameters. */
predicate barrierModel(
string package, string type, boolean subtypes, string name, string signature, string ext,
@@ -198,21 +210,6 @@ predicate barrierGuardModel(
acceptingvalue, kind, provenance, madId)
}
/** Holds if a summary model exists for the given parameters. */
predicate summaryModel(
string package, string type, boolean subtypes, string name, string signature, string ext,
string input, string output, string kind, string provenance, QlBuiltins::ExtensionId madId
) {
(
Extensions::summaryModel(package, type, subtypes, name, signature, ext, input, output, kind,
provenance, madId)
or
any(ActiveExperimentalModelsInternal q)
.summaryModel(package, type, subtypes, name, signature, ext, input, output, kind,
provenance, madId)
)
}
/**
* Holds if the given extension tuple `madId` should pretty-print as `model`.
*

View File

@@ -228,11 +228,10 @@ module SourceSinkInterpretationInput implements
) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
SourceOrSinkElement baseSource, string originalOutput, QlBuiltins::ExtensionId madId
SourceOrSinkElement baseSource, string originalOutput
|
sourceModel(namespace, type, subtypes, name, signature, ext, originalOutput, kind, provenance,
madId) and
model = "MaD:" + madId.toString() and
model) and
baseSource = interpretElement(namespace, type, subtypes, name, signature, ext, _) and
(
e = baseSource and output = originalOutput
@@ -247,11 +246,10 @@ module SourceSinkInterpretationInput implements
) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
SourceOrSinkElement baseSink, string originalInput, QlBuiltins::ExtensionId madId
SourceOrSinkElement baseSink, string originalInput
|
sinkModel(namespace, type, subtypes, name, signature, ext, originalInput, kind, provenance,
madId) and
model = "MaD:" + madId.toString() and
model) and
baseSink = interpretElement(namespace, type, subtypes, name, signature, ext, _) and
(
e = baseSink and originalInput = input
@@ -384,12 +382,10 @@ module Private {
) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string originalInput, string originalOutput, Callable baseCallable,
QlBuiltins::ExtensionId madId
string originalInput, string originalOutput, Callable baseCallable
|
summaryModel(namespace, type, subtypes, name, signature, ext, originalInput, originalOutput,
kind, provenance, madId) and
model = "MaD:" + madId.toString() and
kind, provenance, model) and
baseCallable = interpretElement(namespace, type, subtypes, name, signature, ext, isExact) and
(
c.asCallable() = baseCallable and input = originalInput and output = originalOutput

View File

@@ -51,7 +51,39 @@ signature module ExtensionsSig {
);
}
module ModelsAsData<ExtensionsSig Extensions> {
signature module InputSig {
/**
* Holds if a source model exists for the given parameters.
*/
default predicate additionalSourceModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string output, string kind, string provenance, string model
) {
none()
}
/**
* Holds if a sink model exists for the given parameters.
*/
default predicate additionalSinkModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string input, string kind, string provenance, string model
) {
none()
}
/**
* Holds if a summary model exists for the given parameters.
*/
default predicate additionalSummaryModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string input, string output, string kind, string provenance, string model
) {
none()
}
}
module ModelsAsData<ExtensionsSig Extensions, InputSig Input> {
/**
* Holds if the given extension tuple `madId` should pretty-print as `model`.
*
@@ -122,10 +154,61 @@ module ModelsAsData<ExtensionsSig Extensions> {
)
}
/**
* Holds if a source model exists for the given parameters.
*/
predicate sourceModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string output, string kind, string provenance, string model
) {
exists(QlBuiltins::ExtensionId madId |
Extensions::sourceModel(namespace, type, subtypes, name, signature, ext, output, kind,
provenance, madId) and
model = "MaD:" + madId.toString()
)
or
Input::additionalSourceModel(namespace, type, subtypes, name, signature, ext, output, kind,
provenance, model)
}
/**
* Holds if a sink model exists for the given parameters.
*/
predicate sinkModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string input, string kind, string provenance, string model
) {
exists(QlBuiltins::ExtensionId madId |
Extensions::sinkModel(namespace, type, subtypes, name, signature, ext, input, kind,
provenance, madId) and
model = "MaD:" + madId.toString()
)
or
Input::additionalSinkModel(namespace, type, subtypes, name, signature, ext, input, kind,
provenance, model)
}
/**
* Holds if a summary model exists for the given parameters.
*/
predicate summaryModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string input, string output, string kind, string provenance, string model
) {
exists(QlBuiltins::ExtensionId madId |
Extensions::summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind,
provenance, madId) and
model = "MaD:" + madId.toString()
)
or
Input::additionalSummaryModel(namespace, type, subtypes, name, signature, ext, input, output,
kind, provenance, model)
}
private predicate relevantNamespace(string namespace) {
Extensions::sourceModel(namespace, _, _, _, _, _, _, _, _, _) or
Extensions::sinkModel(namespace, _, _, _, _, _, _, _, _, _) or
Extensions::summaryModel(namespace, _, _, _, _, _, _, _, _, _, _)
sourceModel(namespace, _, _, _, _, _, _, _, _, _) or
sinkModel(namespace, _, _, _, _, _, _, _, _, _) or
summaryModel(namespace, _, _, _, _, _, _, _, _, _, _)
}
private predicate namespaceLink(string shortns, string longns) {
@@ -157,8 +240,7 @@ module ModelsAsData<ExtensionsSig Extensions> {
strictcount(string subns, string type, boolean subtypes, string name, string signature,
string ext, string output, string provenance |
canonicalNamespaceLink(namespace, subns) and
Extensions::sourceModel(subns, type, subtypes, name, signature, ext, output, kind,
provenance, _)
sourceModel(subns, type, subtypes, name, signature, ext, output, kind, provenance, _)
)
or
part = "sink" and
@@ -166,8 +248,7 @@ module ModelsAsData<ExtensionsSig Extensions> {
strictcount(string subns, string type, boolean subtypes, string name, string signature,
string ext, string input, string provenance |
canonicalNamespaceLink(namespace, subns) and
Extensions::sinkModel(subns, type, subtypes, name, signature, ext, input, kind,
provenance, _)
sinkModel(subns, type, subtypes, name, signature, ext, input, kind, provenance, _)
)
or
part = "summary" and
@@ -175,8 +256,8 @@ module ModelsAsData<ExtensionsSig Extensions> {
strictcount(string subns, string type, boolean subtypes, string name, string signature,
string ext, string input, string output, string provenance |
canonicalNamespaceLink(namespace, subns) and
Extensions::summaryModel(subns, type, subtypes, name, signature, ext, input, output, kind,
provenance, _)
summaryModel(subns, type, subtypes, name, signature, ext, input, output, kind, provenance,
_)
)
)
}