Merge pull request #17908 from geoffw0/dfcons

Rust: Expose counts of data flow inconsistencies
This commit is contained in:
Geoffrey White
2024-11-06 19:11:04 +00:00
committed by GitHub
8 changed files with 181 additions and 1 deletions

View File

@@ -1,3 +1,10 @@
/**
* @name Data flow inconsistencies
* @description Lists the data flow inconsistencies in the database. This query is intended for internal use.
* @kind table
* @id rust/diagnostics/data-flow-consistency
*/
import codeql.rust.dataflow.DataFlow::DataFlow as DataFlow
private import rust
private import codeql.rust.dataflow.internal.DataFlowImpl

View File

@@ -0,0 +1,21 @@
/**
* @name Data flow inconsistency counts
* @description Counts the number of data flow inconsistencies of each type. This query is intended for internal use.
* @kind diagnostic
* @id rust/diagnostics/data-flow-consistency-counts
*/
private import rust
private import codeql.rust.dataflow.internal.DataFlowImpl
private import codeql.rust.dataflow.internal.TaintTrackingImpl
private import codeql.dataflow.internal.DataFlowImplConsistency
private module Input implements InputSig<Location, RustDataFlow> { }
// see also `rust/diagnostics/data-flow-consistency`, which lists the
// individual inconsistency results.
from string type, int num
where
num =
MakeConsistency<Location, RustDataFlow, RustTaintTracking, Input>::getInconsistencyCounts(type)
select type, num

View File

@@ -3,8 +3,11 @@
*/
import rust
import codeql.rust.AstConsistency as AstConsistency
private import codeql.rust.dataflow.internal.DataFlowImpl
private import codeql.rust.dataflow.internal.TaintTrackingImpl
private import codeql.rust.AstConsistency as AstConsistency
private import codeql.rust.controlflow.internal.CfgConsistency as CfgConsistency
private import codeql.dataflow.internal.DataFlowImplConsistency as DataFlowImplConsistency
/**
* Gets a count of the total number of lines of code in the database.
@@ -31,3 +34,16 @@ int getTotalAstInconsistencies() {
int getTotalCfgInconsistencies() {
result = sum(string type | | CfgConsistency::getCfgInconsistencyCounts(type))
}
private module Input implements DataFlowImplConsistency::InputSig<Location, RustDataFlow> { }
/**
* Gets a count of the total number of data flow inconsistencies in the database.
*/
int getTotalDataFlowInconsistencies() {
result =
sum(string type |
|
DataFlowImplConsistency::MakeConsistency<Location, RustDataFlow, RustTaintTracking, Input>::getInconsistencyCounts(type)
)
}

View File

@@ -35,4 +35,6 @@ where
key = "Inconsistencies - AST" and value = getTotalAstInconsistencies()
or
key = "Inconsistencies - CFG" and value = getTotalCfgInconsistencies()
or
key = "Inconsistencies - data flow" and value = getTotalDataFlowInconsistencies()
select key, value

View File

@@ -0,0 +1,29 @@
| ArgumentNode is missing PostUpdateNode | 0 |
| Call context for isUnreachableInCall is inconsistent with call graph | 0 |
| Call context too large | 0 |
| Call should have one enclosing callable | 7 |
| Callable mismatch for parameter | 0 |
| Lambda call enclosing callable mismatch | 0 |
| Local flow step does not preserve enclosing callable | 0 |
| Missing call for argument node | 0 |
| Multiple calls for argument node | 0 |
| Node and call does not share enclosing callable | 0 |
| Node has multiple PostUpdateNodes | 0 |
| Node should have one enclosing callable | 0 |
| Node should have one location | 0 |
| Node should have one toString | 0 |
| Node should have one type | 0 |
| Node steps to itself | 0 |
| Nodes without location | 0 |
| Non-unique content approximation | 0 |
| Origin of readStep is missing a PostUpdateNode | 0 |
| Parameter node with multiple positions | 0 |
| Parameters with overlapping positions | 0 |
| PostUpdateNode does not share callable with its pre-update node | 0 |
| PostUpdateNode should have one pre-update node | 0 |
| PostUpdateNode should not be the target of local flow | 0 |
| PostUpdateNode should not equal its pre-update node | 0 |
| Read step does not preserve enclosing callable | 0 |
| Speculative step already hasM Model | 0 |
| Store step does not preserve enclosing callable | 0 |
| Type compatibility predicate is not reflexive | 0 |

View File

@@ -0,0 +1 @@
queries/diagnostics/DataFlowConsistencyCounts.ql

View File

@@ -7,5 +7,6 @@
| Files extracted - without errors | 5 |
| Inconsistencies - AST | 0 |
| Inconsistencies - CFG | 0 |
| Inconsistencies - data flow | 7 |
| Lines of code extracted | 59 |
| Lines of user code extracted | 59 |

View File

@@ -337,4 +337,107 @@ module MakeConsistency<
)
)
}
/**
* Gets counts of inconsistencies of each type.
*/
int getInconsistencyCounts(string type) {
// total results from all the AST consistency query predicates.
type = "Node should have one enclosing callable" and
result = count(Node n | uniqueEnclosingCallable(n, _))
or
type = "Call should have one enclosing callable" and
result = count(DataFlowCall c | uniqueCallEnclosingCallable(c, _))
or
type = "Node should have one type" and
result = count(Node n | uniqueType(n, _))
or
type = "Node should have one location" and
result = count(Node n | uniqueNodeLocation(n, _))
or
type = "Nodes without location" and
result = count( | missingLocation(_) | 1)
or
type = "Node should have one toString" and
result = count(Node n | uniqueNodeToString(n, _))
or
type = "Callable mismatch for parameter" and
result = count(ParameterNode p | parameterCallable(p, _))
or
type = "Local flow step does not preserve enclosing callable" and
result = count(Node n1, Node n2 | localFlowIsLocal(n1, n2, _))
or
type = "Read step does not preserve enclosing callable" and
result = count(Node n1, Node n2 | readStepIsLocal(n1, n2, _))
or
type = "Store step does not preserve enclosing callable" and
result = count(Node n1, Node n2 | storeStepIsLocal(n1, n2, _))
or
type = "Type compatibility predicate is not reflexive" and
result = count(DataFlowType t | compatibleTypesReflexive(t, _))
or
type = "Call context for isUnreachableInCall is inconsistent with call graph" and
result = count(Node n, DataFlowCall call | unreachableNodeCCtx(n, call, _))
or
type = "Node and call does not share enclosing callable" and
result = count(DataFlowCall call, Node n | localCallNodes(call, n, _))
or
type = "PostUpdateNode should not equal its pre-update node" and
result = count(PostUpdateNode n | postIsNotPre(n, _))
or
type = "PostUpdateNode should have one pre-update node" and
result = count(PostUpdateNode n | postHasUniquePre(n, _))
or
type = "Node has multiple PostUpdateNodes" and
result = count(Node n | uniquePostUpdate(n, _))
or
type = "PostUpdateNode does not share callable with its pre-update node" and
result = count(PostUpdateNode n | postIsInSameCallable(n, _))
or
type = "Origin of readStep is missing a PostUpdateNode" and
result = count(Node n | reverseRead(n, _))
or
type = "ArgumentNode is missing PostUpdateNode" and
result = count(ArgumentNode n | argHasPostUpdate(n, _))
or
type = "PostUpdateNode should not be the target of local flow" and
result = count(PostUpdateNode n | postWithInFlow(n, _))
or
type = "Call context too large" and
result =
count(DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable |
viableImplInCallContextTooLarge(call, ctx, callable)
)
or
type = "Parameters with overlapping positions" and
result =
count(DataFlowCallable c, ParameterPosition pos, Node p |
uniqueParameterNodeAtPosition(c, pos, p, _)
)
or
type = "Parameter node with multiple positions" and
result =
count(DataFlowCallable c, ParameterPosition pos, Node p |
uniqueParameterNodePosition(c, pos, p, _)
)
or
type = "Non-unique content approximation" and
result = count(Content c | uniqueContentApprox(c, _))
or
type = "Node steps to itself" and
result = count(Node n | identityLocalStep(n, _))
or
type = "Missing call for argument node" and
result = count(ArgumentNode n | missingArgumentCall(n, _))
or
type = "Multiple calls for argument node" and
result = count(ArgumentNode arg, DataFlowCall call | multipleArgumentCall(arg, call, _))
or
type = "Lambda call enclosing callable mismatch" and
result =
count(DataFlowCall call, Node receiver | lambdaCallEnclosingCallableMismatch(call, receiver))
or
type = "Speculative step already hasM Model" and
result = count(Node n1, Node n2 | speculativeStepAlreadyHasModel(n1, n2, _))
}
}