From 2c2506c4f813a5e99bcc259f36b0825647cc40c0 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 7 Apr 2025 12:07:51 +0100 Subject: [PATCH 1/4] Rust: Add Rust SSA inconsistency infrastructure. --- rust/ql/consistency-queries/SsaConsistency.ql | 9 ++++++++- .../hello-project/summary.expected | 1 + .../hello-workspace/summary.cargo.expected | 1 + .../hello-workspace/summary.rust-project.expected | 1 + .../queries/diagnostics/SsaConsistencyCounts.ql | 14 ++++++++++++++ rust/ql/src/queries/summary/Stats.qll | 10 ++++++++++ .../diagnostics/SsaConsistencyCounts.expected | 0 .../diagnostics/SsaConsistencyCounts.qlref | 1 + .../diagnostics/SummaryStatsReduced.expected | 1 + shared/ssa/codeql/ssa/Ssa.qll | 7 +++++++ 10 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 rust/ql/src/queries/diagnostics/SsaConsistencyCounts.ql create mode 100644 rust/ql/test/query-tests/diagnostics/SsaConsistencyCounts.expected create mode 100644 rust/ql/test/query-tests/diagnostics/SsaConsistencyCounts.qlref diff --git a/rust/ql/consistency-queries/SsaConsistency.ql b/rust/ql/consistency-queries/SsaConsistency.ql index 51a5f97e9786..f28b71e2a7d6 100644 --- a/rust/ql/consistency-queries/SsaConsistency.ql +++ b/rust/ql/consistency-queries/SsaConsistency.ql @@ -1,3 +1,10 @@ -import codeql.rust.dataflow.Ssa +/** + * @name Static single assignment inconsistencies + * @description Lists the static single assignment inconsistencies in the database. This query is intended for internal use. + * @kind table + * @id rust/diagnostics/ssa-consistency + */ + + import codeql.rust.dataflow.Ssa import codeql.rust.dataflow.internal.SsaImpl import Consistency diff --git a/rust/ql/integration-tests/hello-project/summary.expected b/rust/ql/integration-tests/hello-project/summary.expected index 1ce4e784cbf2..1f343b197c0f 100644 --- a/rust/ql/integration-tests/hello-project/summary.expected +++ b/rust/ql/integration-tests/hello-project/summary.expected @@ -7,6 +7,7 @@ | Inconsistencies - AST | 0 | | Inconsistencies - CFG | 0 | | Inconsistencies - Path resolution | 0 | +| Inconsistencies - SSA | 0 | | Inconsistencies - data flow | 0 | | Lines of code extracted | 6 | | Lines of user code extracted | 6 | diff --git a/rust/ql/integration-tests/hello-workspace/summary.cargo.expected b/rust/ql/integration-tests/hello-workspace/summary.cargo.expected index 67da3bcf3090..5912f7d69baf 100644 --- a/rust/ql/integration-tests/hello-workspace/summary.cargo.expected +++ b/rust/ql/integration-tests/hello-workspace/summary.cargo.expected @@ -7,6 +7,7 @@ | Inconsistencies - AST | 0 | | Inconsistencies - CFG | 0 | | Inconsistencies - Path resolution | 0 | +| Inconsistencies - SSA | 0 | | Inconsistencies - data flow | 0 | | Lines of code extracted | 9 | | Lines of user code extracted | 9 | diff --git a/rust/ql/integration-tests/hello-workspace/summary.rust-project.expected b/rust/ql/integration-tests/hello-workspace/summary.rust-project.expected index 67da3bcf3090..5912f7d69baf 100644 --- a/rust/ql/integration-tests/hello-workspace/summary.rust-project.expected +++ b/rust/ql/integration-tests/hello-workspace/summary.rust-project.expected @@ -7,6 +7,7 @@ | Inconsistencies - AST | 0 | | Inconsistencies - CFG | 0 | | Inconsistencies - Path resolution | 0 | +| Inconsistencies - SSA | 0 | | Inconsistencies - data flow | 0 | | Lines of code extracted | 9 | | Lines of user code extracted | 9 | diff --git a/rust/ql/src/queries/diagnostics/SsaConsistencyCounts.ql b/rust/ql/src/queries/diagnostics/SsaConsistencyCounts.ql new file mode 100644 index 000000000000..8293b6883f9f --- /dev/null +++ b/rust/ql/src/queries/diagnostics/SsaConsistencyCounts.ql @@ -0,0 +1,14 @@ +/** + * @name Static single assignment inconsistency counts + * @description Counts the number of static single assignment inconsistencies of each type. This query is intended for internal use. + * @kind diagnostic + * @id rust/diagnostics/ssa-consistency-counts + */ + + private import codeql.rust.dataflow.internal.SsaImpl as SsaImpl + +// see also `rust/diagnostics/ssa-consistency`, which lists the +// individual inconsistency results. +from string type, int num +where num = SsaImpl::Consistency::getInconsistencyCounts(type) +select type, num diff --git a/rust/ql/src/queries/summary/Stats.qll b/rust/ql/src/queries/summary/Stats.qll index ec252c36d701..a2e9c93af7cc 100644 --- a/rust/ql/src/queries/summary/Stats.qll +++ b/rust/ql/src/queries/summary/Stats.qll @@ -10,6 +10,7 @@ private import codeql.rust.internal.AstConsistency as AstConsistency private import codeql.rust.internal.PathResolutionConsistency as PathResolutionConsistency private import codeql.rust.controlflow.internal.CfgConsistency as CfgConsistency private import codeql.rust.dataflow.internal.DataFlowConsistency as DataFlowConsistency +private import codeql.rust.dataflow.internal.SsaImpl as SsaImpl private import codeql.rust.Concepts private import codeql.rust.Diagnostics private import codeql.rust.security.SensitiveData @@ -57,6 +58,13 @@ int getTotalCfgInconsistencies() { result = sum(string type | | CfgConsistency::getCfgInconsistencyCounts(type)) } +/** + * Gets a count of the total number of SSA inconsistencies in the database. + */ +int getTotalSsaInconsistencies() { + result = sum(string type | | SsaImpl::Consistency::getInconsistencyCounts(type)) +} + /** * Gets a count of the total number of data flow inconsistencies in the database. */ @@ -142,6 +150,8 @@ predicate inconsistencyStats(string key, int value) { or key = "Inconsistencies - CFG" and value = getTotalCfgInconsistencies() or + key = "Inconsistencies - SSA" and value = getTotalSsaInconsistencies() + or key = "Inconsistencies - data flow" and value = getTotalDataFlowInconsistencies() } diff --git a/rust/ql/test/query-tests/diagnostics/SsaConsistencyCounts.expected b/rust/ql/test/query-tests/diagnostics/SsaConsistencyCounts.expected new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/rust/ql/test/query-tests/diagnostics/SsaConsistencyCounts.qlref b/rust/ql/test/query-tests/diagnostics/SsaConsistencyCounts.qlref new file mode 100644 index 000000000000..40242e81c245 --- /dev/null +++ b/rust/ql/test/query-tests/diagnostics/SsaConsistencyCounts.qlref @@ -0,0 +1 @@ +queries/diagnostics/SsaConsistencyCounts.ql diff --git a/rust/ql/test/query-tests/diagnostics/SummaryStatsReduced.expected b/rust/ql/test/query-tests/diagnostics/SummaryStatsReduced.expected index 640bd179abd3..ed21d9772fce 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStatsReduced.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStatsReduced.expected @@ -7,6 +7,7 @@ | Inconsistencies - AST | 0 | | Inconsistencies - CFG | 0 | | Inconsistencies - Path resolution | 0 | +| Inconsistencies - SSA | 0 | | Inconsistencies - data flow | 0 | | Lines of code extracted | 60 | | Lines of user code extracted | 60 | diff --git a/shared/ssa/codeql/ssa/Ssa.qll b/shared/ssa/codeql/ssa/Ssa.qll index 5a18d128ab62..d9bfdf62d901 100644 --- a/shared/ssa/codeql/ssa/Ssa.qll +++ b/shared/ssa/codeql/ssa/Ssa.qll @@ -1468,6 +1468,13 @@ module Make Input> { inputRefs = count(BasicBlock bb, int i | AdjacentSsaRefs::adjacentRefPhi(bb, i, _, bbPhi, v)) and inputRefs < 2 } + + /** + * Gets counts of inconsistencies of each type. + */ + int getInconsistencyCounts(string type) { + type = "" and result = 0 + } } /** Provides the input to `DataFlowIntegration`. */ From 9c1567375defeceb6b864460d766ff7c43493952 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 7 Apr 2025 16:17:42 +0100 Subject: [PATCH 2/4] Shared: Implement getInconsistencyCounts for SSA. --- .../diagnostics/SsaConsistencyCounts.expected | 10 ++++ shared/ssa/codeql/ssa/Ssa.qll | 47 ++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/rust/ql/test/query-tests/diagnostics/SsaConsistencyCounts.expected b/rust/ql/test/query-tests/diagnostics/SsaConsistencyCounts.expected index e69de29bb2d1..7e264176d32d 100644 --- a/rust/ql/test/query-tests/diagnostics/SsaConsistencyCounts.expected +++ b/rust/ql/test/query-tests/diagnostics/SsaConsistencyCounts.expected @@ -0,0 +1,10 @@ +| Definition cannot reach a read | 0 | +| End of a basic block can be reached by multiple definitions | 0 | +| Phi has less than 2 immediately prior references | 0 | +| Phi node has less than two inputs | 0 | +| Phi read has less than 2 immediately prior references | 0 | +| Read can be reached from multiple definitions | 0 | +| Read cannot be reached from a definition | 0 | +| Read does not have a prior reference | 0 | +| Read has multiple prior references | 0 | +| Read is not dominated by a definition | 0 | diff --git a/shared/ssa/codeql/ssa/Ssa.qll b/shared/ssa/codeql/ssa/Ssa.qll index d9bfdf62d901..a0a8a1c864de 100644 --- a/shared/ssa/codeql/ssa/Ssa.qll +++ b/shared/ssa/codeql/ssa/Ssa.qll @@ -1473,7 +1473,52 @@ module Make Input> { * Gets counts of inconsistencies of each type. */ int getInconsistencyCounts(string type) { - type = "" and result = 0 + // total results from all the SSA consistency query predicates. + type = "Read can be reached from multiple definitions" and + result = + count(Definition def, SourceVariable v, BasicBlock bb, int i | nonUniqueDef(def, v, bb, i)) + or + type = "Read cannot be reached from a definition" and + result = count(SourceVariable v, BasicBlock bb, int i | readWithoutDef(v, bb, i)) + or + type = "Definition cannot reach a read" and + result = count(Definition def, SourceVariable v | deadDef(def, v)) + or + type = "Read is not dominated by a definition" and + result = + count(Definition def, SourceVariable v, BasicBlock bb, int i | + notDominatedByDef(def, v, bb, i) + ) + or + type = "End of a basic block can be reached by multiple definitions" and + result = + count(Definition def, SourceVariable v, BasicBlock bb | + nonUniqueDefReachesEndOfBlock(def, v, bb) + ) + or + type = "Phi node has less than two inputs" and + result = count(PhiNode phi, int inputs | uselessPhiNode(phi, inputs)) + or + type = "Read does not have a prior reference" and + result = count(SourceVariable v, BasicBlock bb, int i | readWithoutPriorRef(v, bb, i)) + or + type = "Read has multiple prior references" and + result = + count(SourceVariable v, BasicBlock bb1, int i1, BasicBlock bb2, int i2 | + readWithMultiplePriorRefs(v, bb1, i1, bb2, i2) + ) + or + type = "Phi has less than 2 immediately prior references" and + result = + count(PhiNode phi, BasicBlock bbPhi, SourceVariable v, int inputRefs | + phiWithoutTwoPriorRefs(phi, bbPhi, v, inputRefs) + ) + or + type = "Phi read has less than 2 immediately prior references" and + result = + count(BasicBlock bbPhi, SourceVariable v, int inputRefs | + phiReadWithoutTwoPriorRefs(bbPhi, v, inputRefs) + ) } } From ee54ba4c489b33290d7ca3661bc439da28d49131 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 7 Apr 2025 17:01:19 +0100 Subject: [PATCH 3/4] Rust: Autoformat. --- rust/ql/consistency-queries/SsaConsistency.ql | 2 +- rust/ql/src/queries/diagnostics/SsaConsistencyCounts.ql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/ql/consistency-queries/SsaConsistency.ql b/rust/ql/consistency-queries/SsaConsistency.ql index f28b71e2a7d6..1774f269749c 100644 --- a/rust/ql/consistency-queries/SsaConsistency.ql +++ b/rust/ql/consistency-queries/SsaConsistency.ql @@ -5,6 +5,6 @@ * @id rust/diagnostics/ssa-consistency */ - import codeql.rust.dataflow.Ssa +import codeql.rust.dataflow.Ssa import codeql.rust.dataflow.internal.SsaImpl import Consistency diff --git a/rust/ql/src/queries/diagnostics/SsaConsistencyCounts.ql b/rust/ql/src/queries/diagnostics/SsaConsistencyCounts.ql index 8293b6883f9f..287f14f9707d 100644 --- a/rust/ql/src/queries/diagnostics/SsaConsistencyCounts.ql +++ b/rust/ql/src/queries/diagnostics/SsaConsistencyCounts.ql @@ -5,7 +5,7 @@ * @id rust/diagnostics/ssa-consistency-counts */ - private import codeql.rust.dataflow.internal.SsaImpl as SsaImpl +private import codeql.rust.dataflow.internal.SsaImpl as SsaImpl // see also `rust/diagnostics/ssa-consistency`, which lists the // individual inconsistency results. From fd3dcb2d00ab4b6eb345ba88b0ebd076fff08c16 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 8 Apr 2025 09:27:02 +0100 Subject: [PATCH 4/4] Rust: More precise imports. --- rust/ql/src/queries/diagnostics/SsaConsistencyCounts.ql | 4 ++-- rust/ql/src/queries/summary/Stats.qll | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rust/ql/src/queries/diagnostics/SsaConsistencyCounts.ql b/rust/ql/src/queries/diagnostics/SsaConsistencyCounts.ql index 287f14f9707d..7b79a275f0ad 100644 --- a/rust/ql/src/queries/diagnostics/SsaConsistencyCounts.ql +++ b/rust/ql/src/queries/diagnostics/SsaConsistencyCounts.ql @@ -5,10 +5,10 @@ * @id rust/diagnostics/ssa-consistency-counts */ -private import codeql.rust.dataflow.internal.SsaImpl as SsaImpl +private import codeql.rust.dataflow.internal.SsaImpl::Consistency as SsaConsistency // see also `rust/diagnostics/ssa-consistency`, which lists the // individual inconsistency results. from string type, int num -where num = SsaImpl::Consistency::getInconsistencyCounts(type) +where num = SsaConsistency::getInconsistencyCounts(type) select type, num diff --git a/rust/ql/src/queries/summary/Stats.qll b/rust/ql/src/queries/summary/Stats.qll index a2e9c93af7cc..17ce97871d0f 100644 --- a/rust/ql/src/queries/summary/Stats.qll +++ b/rust/ql/src/queries/summary/Stats.qll @@ -10,7 +10,7 @@ private import codeql.rust.internal.AstConsistency as AstConsistency private import codeql.rust.internal.PathResolutionConsistency as PathResolutionConsistency private import codeql.rust.controlflow.internal.CfgConsistency as CfgConsistency private import codeql.rust.dataflow.internal.DataFlowConsistency as DataFlowConsistency -private import codeql.rust.dataflow.internal.SsaImpl as SsaImpl +private import codeql.rust.dataflow.internal.SsaImpl::Consistency as SsaConsistency private import codeql.rust.Concepts private import codeql.rust.Diagnostics private import codeql.rust.security.SensitiveData @@ -62,7 +62,7 @@ int getTotalCfgInconsistencies() { * Gets a count of the total number of SSA inconsistencies in the database. */ int getTotalSsaInconsistencies() { - result = sum(string type | | SsaImpl::Consistency::getInconsistencyCounts(type)) + result = sum(string type | | SsaConsistency::getInconsistencyCounts(type)) } /**