mirror of
https://github.com/github/codeql.git
synced 2026-04-24 00:05:14 +02:00
[DIFF-INFORMED] Rust: AccessAfterLifetime
This commit is contained in:
@@ -28,10 +28,33 @@ module AccessAfterLifetimeConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node node) { node instanceof AccessAfterLifetime::Sink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node barrier) { barrier instanceof AccessAfterLifetime::Barrier }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
|
||||
Location getASelectedSourceLocation(DataFlow::Node source) {
|
||||
exists(Variable target, DataFlow::Node sink | result = target.getLocation() |
|
||||
isSink(sink) and
|
||||
narrowDereferenceAfterLifetime(source, sink, target)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module AccessAfterLifetimeFlow = TaintTracking::Global<AccessAfterLifetimeConfig>;
|
||||
|
||||
pragma[inline]
|
||||
predicate narrowDereferenceAfterLifetime(DataFlow::Node source, DataFlow::Node sink, Variable target) {
|
||||
// check that the dereference is outside the lifetime of the target
|
||||
AccessAfterLifetime::dereferenceAfterLifetime(source, sink, target) and
|
||||
// include only results inside `unsafe` blocks, as other results tend to be false positives
|
||||
(
|
||||
sink.asExpr().getExpr().getEnclosingBlock*().isUnsafe() or
|
||||
sink.asExpr().getExpr().getEnclosingCallable().(Function).isUnsafe()
|
||||
) and
|
||||
// exclude cases with sources / sinks in macros, since these results are difficult to interpret
|
||||
not source.asExpr().getExpr().isFromMacroExpansion() and
|
||||
not sink.asExpr().getExpr().isFromMacroExpansion()
|
||||
}
|
||||
|
||||
from
|
||||
AccessAfterLifetimeFlow::PathNode sourceNode, AccessAfterLifetimeFlow::PathNode sinkNode,
|
||||
Variable target
|
||||
@@ -39,14 +62,6 @@ where
|
||||
// flow from a pointer or reference to the dereference
|
||||
AccessAfterLifetimeFlow::flowPath(sourceNode, sinkNode) and
|
||||
// check that the dereference is outside the lifetime of the target
|
||||
AccessAfterLifetime::dereferenceAfterLifetime(sourceNode.getNode(), sinkNode.getNode(), target) and
|
||||
// include only results inside `unsafe` blocks, as other results tend to be false positives
|
||||
(
|
||||
sinkNode.getNode().asExpr().getExpr().getEnclosingBlock*().isUnsafe() or
|
||||
sinkNode.getNode().asExpr().getExpr().getEnclosingCallable().(Function).isUnsafe()
|
||||
) and
|
||||
// exclude cases with sources / sinks in macros, since these results are difficult to interpret
|
||||
not sourceNode.getNode().asExpr().getExpr().isFromMacroExpansion() and
|
||||
not sinkNode.getNode().asExpr().getExpr().isFromMacroExpansion()
|
||||
narrowDereferenceAfterLifetime(sourceNode.getNode(), sinkNode.getNode(), target)
|
||||
select sinkNode.getNode(), sourceNode, sinkNode,
|
||||
"Access of a pointer to $@ after its lifetime has ended.", target, target.toString()
|
||||
|
||||
Reference in New Issue
Block a user