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.util.Unit
private import codeql.mad.static.MaD as SharedMaD 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. * A unit class for adding additional source model rows.
* *
@@ -149,91 +145,79 @@ predicate sinkModel(string row) { any(SinkModelCsv s).row(row) }
/** Holds if `row` is a summary model. */ /** Holds if `row` is a summary model. */
predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) } predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) }
/** Holds if a source model exists for the given parameters. */ private module MadInput implements SharedMaD::InputSig {
predicate sourceModel( /** Holds if a source model exists for the given parameters. */
string namespace, string type, boolean subtypes, string name, string signature, string ext, predicate additionalSourceModel(
string output, string kind, string provenance, string model 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 exists(string row |
row.splitAt(";", 0) = namespace and sourceModel(row) and
row.splitAt(";", 1) = type and row.splitAt(";", 0) = namespace and
row.splitAt(";", 2) = subtypes.toString() and row.splitAt(";", 1) = type and
subtypes = [true, false] and row.splitAt(";", 2) = subtypes.toString() and
row.splitAt(";", 3) = name and subtypes = [true, false] and
row.splitAt(";", 4) = signature and row.splitAt(";", 3) = name and
row.splitAt(";", 5) = ext and row.splitAt(";", 4) = signature and
row.splitAt(";", 6) = output and row.splitAt(";", 5) = ext and
row.splitAt(";", 7) = kind row.splitAt(";", 6) = output and
) and row.splitAt(";", 7) = kind
provenance = "manual" and ) and
model = "" provenance = "manual" and
or model = ""
exists(QlBuiltins::ExtensionId madId | }
Extensions::sourceModel(namespace, type, subtypes, name, signature, ext, output, kind,
provenance, madId) and /** Holds if a sink model exists for the given parameters. */
model = "MaD:" + madId.toString() 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
row.splitAt(";", 1) = type and
row.splitAt(";", 2) = subtypes.toString() and
subtypes = [true, false] and
row.splitAt(";", 3) = name and
row.splitAt(";", 4) = signature and
row.splitAt(";", 5) = ext and
row.splitAt(";", 6) = input and
row.splitAt(";", 7) = kind
) and
provenance = "manual" and
model = ""
}
/**
* Holds if a summary model exists for the given parameters.
*
* This predicate does not expand `@` to `*`s.
*/
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
row.splitAt(";", 1) = type and
row.splitAt(";", 2) = subtypes.toString() and
subtypes = [true, false] and
row.splitAt(";", 3) = name and
row.splitAt(";", 4) = signature and
row.splitAt(";", 5) = ext and
row.splitAt(";", 6) = input and
row.splitAt(";", 7) = output and
row.splitAt(";", 8) = kind
) and
provenance = "manual" and
model = ""
}
} }
/** Holds if a sink model exists for the given parameters. */ private module MaD = SharedMaD::ModelsAsData<Extensions, MadInput>;
predicate sinkModel(
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
row.splitAt(";", 1) = type and
row.splitAt(";", 2) = subtypes.toString() and
subtypes = [true, false] and
row.splitAt(";", 3) = name and
row.splitAt(";", 4) = signature and
row.splitAt(";", 5) = ext and
row.splitAt(";", 6) = input and
row.splitAt(";", 7) = kind
) 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()
)
}
/** import MaD
* Holds if a summary model exists for the given parameters.
*
* This predicate does not expand `@` to `*`s.
*/
private predicate summaryModel0(
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
row.splitAt(";", 1) = type and
row.splitAt(";", 2) = subtypes.toString() and
subtypes = [true, false] and
row.splitAt(";", 3) = name and
row.splitAt(";", 4) = signature and
row.splitAt(";", 5) = ext and
row.splitAt(";", 6) = input and
row.splitAt(";", 7) = output and
row.splitAt(";", 8) = kind
) 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()
)
}
/** /**
* Holds if `input` is `input0`, but with all occurrences of `@` replaced * Holds if `input` is `input0`, but with all occurrences of `@` replaced
@@ -256,7 +240,7 @@ predicate summaryModel(
string input, string output, string kind, string provenance, string model string input, string output, string kind, string provenance, string model
) { ) {
exists(string input0, string output0 | 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 provenance, model) and
expandInputAndOutput(input0, input, output0, output, expandInputAndOutput(input0, input, output0, output,
[0 .. Private::getMaxElementContentIndirectionIndex() - 1]) [0 .. Private::getMaxElementContentIndirectionIndex() - 1])

View File

@@ -88,7 +88,7 @@
*/ */
import csharp import csharp
import ExternalFlowExtensions private import ExternalFlowExtensions::Extensions as Extensions
private import DataFlowDispatch private import DataFlowDispatch
private import DataFlowPrivate private import DataFlowPrivate
private import DataFlowPublic 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.ModelValidation as SharedModelVal
private import codeql.mad.static.MaD as SharedMaD 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 import MaD
@@ -169,7 +171,7 @@ module ModelValidation {
predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _, _) } 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>; private module KindVal = SharedModelVal::KindValidation<KindValConfig>;
@@ -186,7 +188,7 @@ module ModelValidation {
summaryModel(namespace, type, _, name, signature, ext, _, _, _, provenance, _) and summaryModel(namespace, type, _, name, signature, ext, _, _, _, provenance, _) and
pred = "summary" pred = "summary"
or or
neutralModel(namespace, type, name, signature, _, provenance) and Extensions::neutralModel(namespace, type, name, signature, _, provenance) and
ext = "" and ext = "" and
pred = "neutral" pred = "neutral"
| |
@@ -229,7 +231,7 @@ private predicate elementSpec(
or or
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _) summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _)
or 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( private predicate elementSpec(
@@ -501,19 +503,17 @@ private predicate interpretSummary(
UnboundCallable c, string input, string output, string kind, string provenance, string model UnboundCallable c, string input, string output, string kind, string provenance, string model
) { ) {
exists( exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext, string namespace, string type, boolean subtypes, string name, string signature, string ext
QlBuiltins::ExtensionId madId
| |
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance, summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance,
madId) and model) and
model = "MaD:" + madId.toString() and
c = interpretElement(namespace, type, subtypes, name, signature, ext) c = interpretElement(namespace, type, subtypes, name, signature, ext)
) )
} }
predicate interpretNeutral(UnboundCallable c, string kind, string provenance) { predicate interpretNeutral(UnboundCallable c, string kind, string provenance) {
exists(string namespace, string type, string name, string signature | 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, "") 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 Element e, string output, string kind, Public::Provenance provenance, string model
) { ) {
exists( exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext, string namespace, string type, boolean subtypes, string name, string signature, string ext
QlBuiltins::ExtensionId madId
| |
sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance, madId) and sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance, model) and
model = "MaD:" + madId.toString() and
e = interpretElement(namespace, type, subtypes, name, signature, ext) 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 Element e, string input, string kind, Public::Provenance provenance, string model
) { ) {
exists( exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext, string namespace, string type, boolean subtypes, string name, string signature, string ext
QlBuiltins::ExtensionId madId
| |
sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance, madId) and sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance, model) and
model = "MaD:" + madId.toString() and
e = interpretElement(namespace, type, subtypes, name, signature, ext) 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.ModelValidation as SharedModelVal
private import codeql.mad.static.MaD as SharedMaD 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 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.ModelValidation as SharedModelVal
private import codeql.mad.static.MaD as SharedMaD 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 import MaD
@@ -152,34 +192,6 @@ abstract private class ActiveExperimentalModelsInternal extends string {
deprecated class ActiveExperimentalModels = ActiveExperimentalModelsInternal; 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. */ /** Holds if a barrier model exists for the given parameters. */
predicate barrierModel( predicate barrierModel(
string package, string type, boolean subtypes, string name, string signature, string ext, string package, string type, boolean subtypes, string name, string signature, string ext,
@@ -198,21 +210,6 @@ predicate barrierGuardModel(
acceptingvalue, kind, provenance, madId) 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`. * Holds if the given extension tuple `madId` should pretty-print as `model`.
* *

View File

@@ -228,11 +228,10 @@ module SourceSinkInterpretationInput implements
) { ) {
exists( exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext, 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, sourceModel(namespace, type, subtypes, name, signature, ext, originalOutput, kind, provenance,
madId) and model) and
model = "MaD:" + madId.toString() and
baseSource = interpretElement(namespace, type, subtypes, name, signature, ext, _) and baseSource = interpretElement(namespace, type, subtypes, name, signature, ext, _) and
( (
e = baseSource and output = originalOutput e = baseSource and output = originalOutput
@@ -247,11 +246,10 @@ module SourceSinkInterpretationInput implements
) { ) {
exists( exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext, 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, sinkModel(namespace, type, subtypes, name, signature, ext, originalInput, kind, provenance,
madId) and model) and
model = "MaD:" + madId.toString() and
baseSink = interpretElement(namespace, type, subtypes, name, signature, ext, _) and baseSink = interpretElement(namespace, type, subtypes, name, signature, ext, _) and
( (
e = baseSink and originalInput = input e = baseSink and originalInput = input
@@ -384,12 +382,10 @@ module Private {
) { ) {
exists( exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext, string namespace, string type, boolean subtypes, string name, string signature, string ext,
string originalInput, string originalOutput, Callable baseCallable, string originalInput, string originalOutput, Callable baseCallable
QlBuiltins::ExtensionId madId
| |
summaryModel(namespace, type, subtypes, name, signature, ext, originalInput, originalOutput, summaryModel(namespace, type, subtypes, name, signature, ext, originalInput, originalOutput,
kind, provenance, madId) and kind, provenance, model) and
model = "MaD:" + madId.toString() and
baseCallable = interpretElement(namespace, type, subtypes, name, signature, ext, isExact) and baseCallable = interpretElement(namespace, type, subtypes, name, signature, ext, isExact) and
( (
c.asCallable() = baseCallable and input = originalInput and output = originalOutput 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`. * 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) { private predicate relevantNamespace(string namespace) {
Extensions::sourceModel(namespace, _, _, _, _, _, _, _, _, _) or sourceModel(namespace, _, _, _, _, _, _, _, _, _) or
Extensions::sinkModel(namespace, _, _, _, _, _, _, _, _, _) or sinkModel(namespace, _, _, _, _, _, _, _, _, _) or
Extensions::summaryModel(namespace, _, _, _, _, _, _, _, _, _, _) summaryModel(namespace, _, _, _, _, _, _, _, _, _, _)
} }
private predicate namespaceLink(string shortns, string longns) { 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, strictcount(string subns, string type, boolean subtypes, string name, string signature,
string ext, string output, string provenance | string ext, string output, string provenance |
canonicalNamespaceLink(namespace, subns) and canonicalNamespaceLink(namespace, subns) and
Extensions::sourceModel(subns, type, subtypes, name, signature, ext, output, kind, sourceModel(subns, type, subtypes, name, signature, ext, output, kind, provenance, _)
provenance, _)
) )
or or
part = "sink" and part = "sink" and
@@ -166,8 +248,7 @@ module ModelsAsData<ExtensionsSig Extensions> {
strictcount(string subns, string type, boolean subtypes, string name, string signature, strictcount(string subns, string type, boolean subtypes, string name, string signature,
string ext, string input, string provenance | string ext, string input, string provenance |
canonicalNamespaceLink(namespace, subns) and canonicalNamespaceLink(namespace, subns) and
Extensions::sinkModel(subns, type, subtypes, name, signature, ext, input, kind, sinkModel(subns, type, subtypes, name, signature, ext, input, kind, provenance, _)
provenance, _)
) )
or or
part = "summary" and part = "summary" and
@@ -175,8 +256,8 @@ module ModelsAsData<ExtensionsSig Extensions> {
strictcount(string subns, string type, boolean subtypes, string name, string signature, strictcount(string subns, string type, boolean subtypes, string name, string signature,
string ext, string input, string output, string provenance | string ext, string input, string output, string provenance |
canonicalNamespaceLink(namespace, subns) and canonicalNamespaceLink(namespace, subns) and
Extensions::summaryModel(subns, type, subtypes, name, signature, ext, input, output, kind, summaryModel(subns, type, subtypes, name, signature, ext, input, output, kind, provenance,
provenance, _) _)
) )
) )
} }