@@ -28,25 +28,40 @@ module AccessAfterLifetimeConfig implements DataFlow::ConfigSig {
28
28
predicate isSink ( DataFlow:: Node node ) { node instanceof AccessAfterLifetime:: Sink }
29
29
30
30
predicate isBarrier ( DataFlow:: Node barrier ) { barrier instanceof AccessAfterLifetime:: Barrier }
31
+
32
+ predicate observeDiffInformedIncrementalMode ( ) { any ( ) }
33
+
34
+ Location getASelectedSourceLocation ( DataFlow:: Node source ) {
35
+ exists ( Variable target , DataFlow:: Node sink | result = target .getLocation ( ) |
36
+ isSink ( sink ) and
37
+ narrowDereferenceAfterLifetime ( source , sink , target )
38
+ )
39
+ }
31
40
}
32
41
33
42
module AccessAfterLifetimeFlow = TaintTracking:: Global< AccessAfterLifetimeConfig > ;
34
43
44
+ pragma [ inline]
45
+ predicate narrowDereferenceAfterLifetime ( DataFlow:: Node source , DataFlow:: Node sink , Variable target ) {
46
+ // check that the dereference is outside the lifetime of the target
47
+ AccessAfterLifetime:: dereferenceAfterLifetime ( source , sink , target ) and
48
+ // include only results inside `unsafe` blocks, as other results tend to be false positives
49
+ (
50
+ sink .asExpr ( ) .getExpr ( ) .getEnclosingBlock * ( ) .isUnsafe ( ) or
51
+ sink .asExpr ( ) .getExpr ( ) .getEnclosingCallable ( ) .( Function ) .isUnsafe ( )
52
+ ) and
53
+ // exclude cases with sources / sinks in macros, since these results are difficult to interpret
54
+ not source .asExpr ( ) .getExpr ( ) .isFromMacroExpansion ( ) and
55
+ not sink .asExpr ( ) .getExpr ( ) .isFromMacroExpansion ( )
56
+ }
57
+
35
58
from
36
59
AccessAfterLifetimeFlow:: PathNode sourceNode , AccessAfterLifetimeFlow:: PathNode sinkNode ,
37
60
Variable target
38
61
where
39
62
// flow from a pointer or reference to the dereference
40
63
AccessAfterLifetimeFlow:: flowPath ( sourceNode , sinkNode ) and
41
64
// check that the dereference is outside the lifetime of the target
42
- AccessAfterLifetime:: dereferenceAfterLifetime ( sourceNode .getNode ( ) , sinkNode .getNode ( ) , target ) and
43
- // include only results inside `unsafe` blocks, as other results tend to be false positives
44
- (
45
- sinkNode .getNode ( ) .asExpr ( ) .getExpr ( ) .getEnclosingBlock * ( ) .isUnsafe ( ) or
46
- sinkNode .getNode ( ) .asExpr ( ) .getExpr ( ) .getEnclosingCallable ( ) .( Function ) .isUnsafe ( )
47
- ) and
48
- // exclude cases with sources / sinks in macros, since these results are difficult to interpret
49
- not sourceNode .getNode ( ) .asExpr ( ) .getExpr ( ) .isFromMacroExpansion ( ) and
50
- not sinkNode .getNode ( ) .asExpr ( ) .getExpr ( ) .isFromMacroExpansion ( )
65
+ narrowDereferenceAfterLifetime ( sourceNode .getNode ( ) , sinkNode .getNode ( ) , target )
51
66
select sinkNode .getNode ( ) , sourceNode , sinkNode ,
52
67
"Access of a pointer to $@ after its lifetime has ended." , target , target .toString ( )
0 commit comments