Rust: Speedup AccessAfterLifetime.ql

This commit is contained in:
Tom Hvitved
2025-11-15 15:17:33 +01:00
parent 8668473916
commit 8455663255
2 changed files with 17 additions and 69 deletions

View File

@@ -23,9 +23,22 @@ import AccessAfterLifetimeFlow::PathGraph
* lifetime has ended.
*/
module AccessAfterLifetimeConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { node instanceof AccessAfterLifetime::Source }
predicate isSource(DataFlow::Node node) {
node instanceof AccessAfterLifetime::Source and
// exclude cases with sources in macros, since these results are difficult to interpret
not node.asExpr().getExpr().isFromMacroExpansion()
}
predicate isSink(DataFlow::Node node) { node instanceof AccessAfterLifetime::Sink }
predicate isSink(DataFlow::Node node) {
node instanceof AccessAfterLifetime::Sink and
// exclude cases with sinks in macros, since these results are difficult to interpret
not node.asExpr().getExpr().isFromMacroExpansion() and
// include only results inside `unsafe` blocks, as other results tend to be false positives
(
node.asExpr().getExpr().getEnclosingBlock*().isUnsafe() or
node.asExpr().getExpr().getEnclosingCallable().(Function).isUnsafe()
)
}
predicate isBarrier(DataFlow::Node barrier) { barrier instanceof AccessAfterLifetime::Barrier }
@@ -36,27 +49,13 @@ module AccessAfterLifetimeConfig implements DataFlow::ConfigSig {
result = [target.getLocation(), source.getLocation()]
|
isSink(sink) and
narrowDereferenceAfterLifetime(source, sink, target)
AccessAfterLifetime::dereferenceAfterLifetime(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
@@ -64,6 +63,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
narrowDereferenceAfterLifetime(sourceNode.getNode(), sinkNode.getNode(), target)
AccessAfterLifetime::dereferenceAfterLifetime(sourceNode.getNode(), sinkNode.getNode(), target)
select sinkNode.getNode(), sourceNode, sinkNode,
"Access of a pointer to $@ after its lifetime has ended.", target, target.toString()

View File

@@ -186,28 +186,6 @@ edges
| lifetime.rs:655:11:655:25 | &raw const str2 | lifetime.rs:655:4:655:7 | ref1 | provenance | |
| lifetime.rs:655:11:655:25 | &raw const str2 [&ref] | lifetime.rs:655:4:655:7 | ref1 [&ref] | provenance | |
| lifetime.rs:655:22:655:25 | str2 | lifetime.rs:655:11:655:25 | &raw const str2 [&ref] | provenance | |
| lifetime.rs:680:7:680:8 | r1 | lifetime.rs:692:13:692:14 | r1 | provenance | |
| lifetime.rs:682:4:682:12 | &... | lifetime.rs:680:7:680:8 | r1 | provenance | |
| lifetime.rs:684:7:684:14 | TuplePat [tuple.0] | lifetime.rs:684:8:684:9 | r2 | provenance | |
| lifetime.rs:684:7:684:14 | TuplePat [tuple.1] | lifetime.rs:684:12:684:13 | r3 | provenance | |
| lifetime.rs:684:8:684:9 | r2 | lifetime.rs:693:13:693:14 | r2 | provenance | |
| lifetime.rs:684:12:684:13 | r3 | lifetime.rs:694:13:694:14 | r3 | provenance | |
| lifetime.rs:686:4:687:16 | TupleExpr [tuple.0] | lifetime.rs:684:7:684:14 | TuplePat [tuple.0] | provenance | |
| lifetime.rs:686:4:687:16 | TupleExpr [tuple.1] | lifetime.rs:684:7:684:14 | TuplePat [tuple.1] | provenance | |
| lifetime.rs:686:5:686:13 | &... | lifetime.rs:686:4:687:16 | TupleExpr [tuple.0] | provenance | |
| lifetime.rs:687:5:687:15 | &... | lifetime.rs:686:4:687:16 | TupleExpr [tuple.1] | provenance | |
| lifetime.rs:717:35:723:2 | { ... } | lifetime.rs:730:11:730:25 | e1.test_match() | provenance | |
| lifetime.rs:718:7:718:8 | r1 | lifetime.rs:717:35:723:2 | { ... } | provenance | |
| lifetime.rs:719:26:719:34 | &... | lifetime.rs:718:7:718:8 | r1 | provenance | |
| lifetime.rs:730:6:730:7 | r1 | lifetime.rs:734:12:734:13 | r1 | provenance | |
| lifetime.rs:730:11:730:25 | e1.test_match() | lifetime.rs:730:6:730:7 | r1 | provenance | |
| lifetime.rs:766:2:766:11 | &val | lifetime.rs:766:2:766:11 | ptr | provenance | |
| lifetime.rs:766:2:766:11 | ptr | lifetime.rs:766:2:766:11 | ptr | provenance | |
| lifetime.rs:767:2:767:11 | &val | lifetime.rs:767:2:767:11 | ptr | provenance | |
| lifetime.rs:767:2:767:11 | ptr | lifetime.rs:767:2:767:11 | ptr | provenance | |
| lifetime.rs:769:6:769:8 | ptr | lifetime.rs:771:12:771:14 | ptr | provenance | |
| lifetime.rs:769:12:769:21 | &val | lifetime.rs:769:12:769:21 | ptr | provenance | |
| lifetime.rs:769:12:769:21 | ptr | lifetime.rs:769:6:769:8 | ptr | provenance | |
| lifetime.rs:781:2:781:19 | return ... | lifetime.rs:785:11:785:41 | get_local_for_unsafe_function(...) | provenance | |
| lifetime.rs:781:9:781:19 | &my_local10 | lifetime.rs:781:2:781:19 | return ... | provenance | |
| lifetime.rs:785:6:785:7 | p1 | lifetime.rs:789:12:789:13 | p1 | provenance | |
@@ -421,35 +399,6 @@ nodes
| lifetime.rs:655:22:655:25 | str2 | semmle.label | str2 |
| lifetime.rs:659:15:659:18 | ref1 | semmle.label | ref1 |
| lifetime.rs:667:14:667:17 | ref1 | semmle.label | ref1 |
| lifetime.rs:680:7:680:8 | r1 | semmle.label | r1 |
| lifetime.rs:682:4:682:12 | &... | semmle.label | &... |
| lifetime.rs:684:7:684:14 | TuplePat [tuple.0] | semmle.label | TuplePat [tuple.0] |
| lifetime.rs:684:7:684:14 | TuplePat [tuple.1] | semmle.label | TuplePat [tuple.1] |
| lifetime.rs:684:8:684:9 | r2 | semmle.label | r2 |
| lifetime.rs:684:12:684:13 | r3 | semmle.label | r3 |
| lifetime.rs:686:4:687:16 | TupleExpr [tuple.0] | semmle.label | TupleExpr [tuple.0] |
| lifetime.rs:686:4:687:16 | TupleExpr [tuple.1] | semmle.label | TupleExpr [tuple.1] |
| lifetime.rs:686:5:686:13 | &... | semmle.label | &... |
| lifetime.rs:687:5:687:15 | &... | semmle.label | &... |
| lifetime.rs:692:13:692:14 | r1 | semmle.label | r1 |
| lifetime.rs:693:13:693:14 | r2 | semmle.label | r2 |
| lifetime.rs:694:13:694:14 | r3 | semmle.label | r3 |
| lifetime.rs:717:35:723:2 | { ... } | semmle.label | { ... } |
| lifetime.rs:718:7:718:8 | r1 | semmle.label | r1 |
| lifetime.rs:719:26:719:34 | &... | semmle.label | &... |
| lifetime.rs:730:6:730:7 | r1 | semmle.label | r1 |
| lifetime.rs:730:11:730:25 | e1.test_match() | semmle.label | e1.test_match() |
| lifetime.rs:734:12:734:13 | r1 | semmle.label | r1 |
| lifetime.rs:766:2:766:11 | &val | semmle.label | &val |
| lifetime.rs:766:2:766:11 | ptr | semmle.label | ptr |
| lifetime.rs:766:2:766:11 | ptr | semmle.label | ptr |
| lifetime.rs:767:2:767:11 | &val | semmle.label | &val |
| lifetime.rs:767:2:767:11 | ptr | semmle.label | ptr |
| lifetime.rs:767:2:767:11 | ptr | semmle.label | ptr |
| lifetime.rs:769:6:769:8 | ptr | semmle.label | ptr |
| lifetime.rs:769:12:769:21 | &val | semmle.label | &val |
| lifetime.rs:769:12:769:21 | ptr | semmle.label | ptr |
| lifetime.rs:771:12:771:14 | ptr | semmle.label | ptr |
| lifetime.rs:781:2:781:19 | return ... | semmle.label | return ... |
| lifetime.rs:781:9:781:19 | &my_local10 | semmle.label | &my_local10 |
| lifetime.rs:785:6:785:7 | p1 | semmle.label | p1 |