diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/ExternalFlowExtensions.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/ExternalFlowExtensions.qll index 16597020620..d128feffc20 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/ExternalFlowExtensions.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/ExternalFlowExtensions.qll @@ -53,4 +53,6 @@ extensible predicate neutralModel( module Extensions implements SharedMaD::ExtensionsSig { import ExternalFlowExtensions + + predicate packageGrouping(string group, string package) { none() } } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/ExternalFlowExtensions.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/ExternalFlowExtensions.qll index f845ddf7951..acbb651bcc4 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/ExternalFlowExtensions.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/ExternalFlowExtensions.qll @@ -53,4 +53,6 @@ extensible predicate neutralModel( module Extensions implements SharedMaD::ExtensionsSig { import ExternalFlowExtensions + + predicate packageGrouping(string group, string package) { none() } } diff --git a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll index dfa8f5bb3a2..544d73fef26 100644 --- a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll @@ -107,86 +107,6 @@ module FlowExtensions = Extensions; /** Gets the prefix for a group of packages. */ private string groupPrefix() { result = "group:" } -/** - * Gets a package represented by `packageOrGroup`. - * - * If `packageOrGroup` is of the form `group:` then `result` is a - * package in the group ``, as determined by `packageGrouping`. - * Otherwise, `result` is `packageOrGroup`. - */ -bindingset[packageOrGroup] -private string getPackage(string packageOrGroup) { - not exists(string group | packageOrGroup = groupPrefix() + group) and result = packageOrGroup - or - exists(string group | - FlowExtensions::packageGrouping(group, result) and - packageOrGroup = groupPrefix() + group - ) -} - -/** - * Holds if a source model exists for the given parameters. - * - * Note that `group:` references are expanded into one or more actual packages - * by this predicate. - */ -predicate sourceModel( - string package, string type, boolean subtypes, string name, string signature, string ext, - string output, string kind, string provenance, QlBuiltins::ExtensionId madId -) { - exists(string packageOrGroup | - package = getPackage(packageOrGroup) and - FlowExtensions::sourceModel(packageOrGroup, type, subtypes, name, signature, ext, output, kind, - provenance, madId) - ) -} - -/** - * Holds if a sink model exists for the given parameters. - * - * Note that `group:` references are expanded into one or more actual packages - * by this predicate. - */ -predicate sinkModel( - string package, string type, boolean subtypes, string name, string signature, string ext, - string input, string kind, string provenance, QlBuiltins::ExtensionId madId -) { - exists(string packageOrGroup | package = getPackage(packageOrGroup) | - FlowExtensions::sinkModel(packageOrGroup, type, subtypes, name, signature, ext, input, kind, - provenance, madId) - ) -} - -/** - * Holds if a summary model exists for the given parameters. - * - * Note that `group:` references are expanded into one or more actual packages - * by this predicate. - */ -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 -) { - exists(string packageOrGroup | package = getPackage(packageOrGroup) | - FlowExtensions::summaryModel(packageOrGroup, type, subtypes, name, signature, ext, input, - output, kind, provenance, madId) - ) -} - -/** - * Holds if a neutral model exists for the given parameters. - * - * Note that `group:` references are expanded into one or more actual packages - * by this predicate. - */ -predicate neutralModel( - string package, string type, string name, string signature, string kind, string provenance -) { - exists(string packageOrGroup | package = getPackage(packageOrGroup) | - FlowExtensions::neutralModel(packageOrGroup, type, name, signature, kind, provenance) - ) -} - bindingset[p] private string cleanPackage(string p) { exists(string noPrefix | diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index 41ded04634b..39af0cef1ad 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -137,11 +137,9 @@ module SourceSinkInterpretationInput implements SourceOrSinkElement e, string output, string kind, Public::Provenance provenance, string model ) { exists( - string package, string type, boolean subtypes, string name, string signature, string ext, - QlBuiltins::ExtensionId madId + string package, string type, boolean subtypes, string name, string signature, string ext | - sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance, madId) and - model = "MaD:" + madId.toString() and + sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance, model) and e = interpretElement(package, type, subtypes, name, signature, ext) ) } @@ -154,11 +152,9 @@ module SourceSinkInterpretationInput implements SourceOrSinkElement e, string input, string kind, Public::Provenance provenance, string model ) { exists( - string package, string type, boolean subtypes, string name, string signature, string ext, - QlBuiltins::ExtensionId madId + string package, string type, boolean subtypes, string name, string signature, string ext | - sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance, madId) and - model = "MaD:" + madId.toString() and + sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance, model) and e = interpretElement(package, type, subtypes, name, signature, ext) ) } @@ -504,12 +500,10 @@ module Private { 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 + provenance, model) and c.asFunction() = interpretElement(namespace, type, subtypes, name, signature, ext).asEntity() ) diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index 108799aee16..1f8ae76ed63 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -192,24 +192,6 @@ abstract private class ActiveExperimentalModelsInternal extends string { deprecated class ActiveExperimentalModels = ActiveExperimentalModelsInternal; -/** Holds if a barrier model exists for the given parameters. */ -predicate barrierModel( - string package, string type, boolean subtypes, string name, string signature, string ext, - string output, string kind, string provenance, QlBuiltins::ExtensionId madId -) { - Extensions::barrierModel(package, type, subtypes, name, signature, ext, output, kind, provenance, - madId) -} - -/** Holds if a barrier guard model exists for the given parameters. */ -predicate barrierGuardModel( - string package, string type, boolean subtypes, string name, string signature, string ext, - string input, string acceptingvalue, string kind, string provenance, QlBuiltins::ExtensionId madId -) { - Extensions::barrierGuardModel(package, type, subtypes, name, signature, ext, input, - acceptingvalue, kind, provenance, madId) -} - /** * Holds if the given extension tuple `madId` should pretty-print as `model`. * @@ -255,9 +237,6 @@ predicate interpretModelForTest(QlBuiltins::ExtensionId madId, string model) { ) } -/** Holds if a neutral model exists for the given parameters. */ -predicate neutralModel = Extensions::neutralModel/6; - /** Provides a query predicate to check the MaD models for validation errors. */ module ModelValidation { private import codeql.dataflow.internal.AccessPathSyntax as AccessPathSyntax diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/ExternalFlowExtensions.qll b/java/ql/lib/semmle/code/java/dataflow/internal/ExternalFlowExtensions.qll index c01766c317a..946872ab384 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/ExternalFlowExtensions.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/ExternalFlowExtensions.qll @@ -98,4 +98,6 @@ extensible predicate experimentalSummaryModel( module Extensions implements SharedMaD::ExtensionsSig { import ExternalFlowExtensions + + predicate packageGrouping(string group, string package) { none() } } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll index 4f5de01e3e3..b9d8f58cecb 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll @@ -264,11 +264,10 @@ module SourceSinkInterpretationInput implements ) { exists( string namespace, string type, boolean subtypes, string name, string signature, string ext, - SourceOrSinkElement baseBarrier, string originalOutput, QlBuiltins::ExtensionId madId + SourceOrSinkElement baseBarrier, string originalOutput | barrierModel(namespace, type, subtypes, name, signature, ext, originalOutput, kind, - provenance, madId) and - model = "MaD:" + madId.toString() and + provenance, model) and baseBarrier = interpretElement(namespace, type, subtypes, name, signature, ext, _) and ( e = baseBarrier and output = originalOutput @@ -284,11 +283,10 @@ module SourceSinkInterpretationInput implements ) { exists( string namespace, string type, boolean subtypes, string name, string signature, string ext, - SourceOrSinkElement baseBarrier, string originalInput, QlBuiltins::ExtensionId madId + SourceOrSinkElement baseBarrier, string originalInput | barrierGuardModel(namespace, type, subtypes, name, signature, ext, originalInput, - acceptingvalue, kind, provenance, madId) and - model = "MaD:" + madId.toString() and + acceptingvalue, kind, provenance, model) and baseBarrier = interpretElement(namespace, type, subtypes, name, signature, ext, _) and ( e = baseBarrier and input = originalInput diff --git a/shared/mad/codeql/mad/static/MaD.qll b/shared/mad/codeql/mad/static/MaD.qll index 76d4fa484a6..fbd12d909ab 100644 --- a/shared/mad/codeql/mad/static/MaD.qll +++ b/shared/mad/codeql/mad/static/MaD.qll @@ -49,6 +49,11 @@ signature module ExtensionsSig { predicate neutralModel( string namespace, string type, string name, string signature, string kind, string provenance ); + + /** + * Holds if the package `package` is part of the group `group`. + */ + predicate packageGrouping(string group, string package); } signature module InputSig { @@ -157,6 +162,27 @@ module ModelsAsData { ) } + /** Gets the prefix for a group of packages/namespaces. */ + private string groupPrefix() { result = "group:" } + + /** + * Gets a package/namespace represented by `namespaceOrGroup`. + * + * If `namespaceOrGroup` is of the form `group:` then `result` is a + * package/namespace in the group ``, as determined by `packageGrouping`. + * Otherwise, `result` is `namespaceOrGroup`. + */ + bindingset[namespaceOrGroup] + private string getNamespace(string namespaceOrGroup) { + not exists(string group | namespaceOrGroup = groupPrefix() + group) and + result = namespaceOrGroup + or + exists(string group | + Extensions::packageGrouping(group, result) and + namespaceOrGroup = groupPrefix() + group + ) + } + /** * Holds if a source model exists for the given parameters. */ @@ -164,14 +190,16 @@ module ModelsAsData { 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() + exists(string namespaceOrGroup | namespace = getNamespace(namespaceOrGroup) | + exists(QlBuiltins::ExtensionId madId | + Extensions::sourceModel(namespaceOrGroup, type, subtypes, name, signature, ext, output, + kind, provenance, madId) and + model = "MaD:" + madId.toString() + ) + or + Input::additionalSourceModel(namespaceOrGroup, type, subtypes, name, signature, ext, output, + kind, provenance, model) ) - or - Input::additionalSourceModel(namespace, type, subtypes, name, signature, ext, output, kind, - provenance, model) } /** @@ -181,14 +209,42 @@ module ModelsAsData { 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, + exists(string namespaceOrGroup | namespace = getNamespace(namespaceOrGroup) | + exists(QlBuiltins::ExtensionId madId | + Extensions::sinkModel(namespaceOrGroup, type, subtypes, name, signature, ext, input, kind, + provenance, madId) and + model = "MaD:" + madId.toString() + ) + or + Input::additionalSinkModel(namespaceOrGroup, type, subtypes, name, signature, ext, input, + kind, provenance, model) + ) + } + + /** Holds if a barrier model exists for the given parameters. */ + predicate barrierModel( + string namespace, string type, boolean subtypes, string name, string signature, string ext, + string output, string kind, string provenance, string model + ) { + exists(string namespaceOrGroup, QlBuiltins::ExtensionId madId | + namespace = getNamespace(namespaceOrGroup) and + Extensions::barrierModel(namespaceOrGroup, type, subtypes, name, signature, ext, output, kind, provenance, madId) and model = "MaD:" + madId.toString() ) - or - Input::additionalSinkModel(namespace, type, subtypes, name, signature, ext, input, kind, - provenance, model) + } + + /** Holds if a barrier guard model exists for the given parameters. */ + predicate barrierGuardModel( + string namespace, string type, boolean subtypes, string name, string signature, string ext, + string input, string acceptingvalue, string kind, string provenance, string model + ) { + exists(string namespaceOrGroup, QlBuiltins::ExtensionId madId | + namespace = getNamespace(namespaceOrGroup) and + Extensions::barrierGuardModel(namespaceOrGroup, type, subtypes, name, signature, ext, input, + acceptingvalue, kind, provenance, madId) and + model = "MaD:" + madId.toString() + ) } /** @@ -198,14 +254,27 @@ module ModelsAsData { 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() + exists(string namespaceOrGroup | namespace = getNamespace(namespaceOrGroup) | + exists(QlBuiltins::ExtensionId madId | + Extensions::summaryModel(namespaceOrGroup, type, subtypes, name, signature, ext, input, + output, kind, provenance, madId) and + model = "MaD:" + madId.toString() + ) + or + Input::additionalSummaryModel(namespaceOrGroup, type, subtypes, name, signature, ext, input, + output, kind, provenance, model) + ) + } + + /** + * Holds if a neutral model exists for the given parameters. + */ + predicate neutralModel( + string namespace, string type, string name, string signature, string kind, string provenance + ) { + exists(string namespaceOrGroup | namespace = getNamespace(namespaceOrGroup) | + Extensions::neutralModel(namespaceOrGroup, type, name, signature, kind, provenance) ) - or - Input::additionalSummaryModel(namespace, type, subtypes, name, signature, ext, input, output, - kind, provenance, model) } private predicate relevantNamespace(string namespace) {