diff --git a/rust/ql/src/queries/security/CWE-020/RegexInjection.ql b/rust/ql/src/queries/security/CWE-020/RegexInjection.ql index 14d6d8e167ed..287c616a43ed 100644 --- a/rust/ql/src/queries/security/CWE-020/RegexInjection.ql +++ b/rust/ql/src/queries/security/CWE-020/RegexInjection.ql @@ -34,6 +34,8 @@ module RegexInjectionConfig implements DataFlow::ConfigSig { predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { any(AdditionalFlowStep s).step(nodeFrom, nodeTo) } + + predicate observeDiffInformedIncrementalMode() { any() } } /** diff --git a/rust/ql/src/queries/security/CWE-022/TaintedPath.ql b/rust/ql/src/queries/security/CWE-022/TaintedPath.ql index 8896cf608427..7acfc2055764 100644 --- a/rust/ql/src/queries/security/CWE-022/TaintedPath.ql +++ b/rust/ql/src/queries/security/CWE-022/TaintedPath.ql @@ -79,6 +79,8 @@ module TaintedPathConfig implements DataFlow::StateConfigSig { stateFrom instanceof NotNormalized and stateTo instanceof NormalizedUnchecked } + + predicate observeDiffInformedIncrementalMode() { any() } } module TaintedPathFlow = TaintTracking::GlobalWithState; diff --git a/rust/ql/src/queries/security/CWE-089/SqlInjection.ql b/rust/ql/src/queries/security/CWE-089/SqlInjection.ql index f61295263bfb..883fafd00d25 100644 --- a/rust/ql/src/queries/security/CWE-089/SqlInjection.ql +++ b/rust/ql/src/queries/security/CWE-089/SqlInjection.ql @@ -26,6 +26,8 @@ module SqlInjectionConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node node) { node instanceof Sink } predicate isBarrier(DataFlow::Node barrier) { barrier instanceof Barrier } + + predicate observeDiffInformedIncrementalMode() { any() } } module SqlInjectionFlow = TaintTracking::Global; diff --git a/rust/ql/src/queries/security/CWE-311/CleartextTransmission.ql b/rust/ql/src/queries/security/CWE-311/CleartextTransmission.ql index 739dca0f4185..508937533899 100644 --- a/rust/ql/src/queries/security/CWE-311/CleartextTransmission.ql +++ b/rust/ql/src/queries/security/CWE-311/CleartextTransmission.ql @@ -37,6 +37,8 @@ module CleartextTransmissionConfig implements DataFlow::ConfigSig { // make sources barriers so that we only report the closest instance isSource(node) } + + predicate observeDiffInformedIncrementalMode() { any() } } module CleartextTransmissionFlow = TaintTracking::Global; diff --git a/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql b/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql index c2a1dcc747f5..b1c56114c7bd 100644 --- a/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql +++ b/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql @@ -45,6 +45,8 @@ module CleartextLoggingConfig implements DataFlow::ConfigSig { isSink(node) and c.getAReadContent() instanceof DataFlow::TuplePositionContent } + + predicate observeDiffInformedIncrementalMode() { any() } } module CleartextLoggingFlow = TaintTracking::Global; diff --git a/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql b/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql index 3d25ede3187d..cb5fe07b4aa8 100644 --- a/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql +++ b/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql @@ -32,6 +32,8 @@ module UncontrolledAllocationConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof Sink } predicate isBarrier(DataFlow::Node barrier) { barrier instanceof Barrier } + + predicate observeDiffInformedIncrementalMode() { any() } } module UncontrolledAllocationFlow = TaintTracking::Global; diff --git a/rust/ql/src/queries/security/CWE-825/AccessAfterLifetime.ql b/rust/ql/src/queries/security/CWE-825/AccessAfterLifetime.ql index b4f652668b71..fce64dcf0ff1 100644 --- a/rust/ql/src/queries/security/CWE-825/AccessAfterLifetime.ql +++ b/rust/ql/src/queries/security/CWE-825/AccessAfterLifetime.ql @@ -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; +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() diff --git a/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql b/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql index d0a13b9ddb14..5177e1fb0e03 100644 --- a/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql +++ b/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql @@ -32,6 +32,8 @@ module AccessInvalidPointerConfig implements DataFlow::ConfigSig { // make sinks barriers so that we only report the closest instance isSink(node) } + + predicate observeDiffInformedIncrementalMode() { any() } } module AccessInvalidPointerFlow = TaintTracking::Global;