Skip to content

Commit 2543754

Browse files
committed
Rust: Remove newtype construction
1 parent 5bc457f commit 2543754

File tree

1 file changed

+20
-48
lines changed

1 file changed

+20
-48
lines changed

rust/ql/src/queries/security/CWE-825/AccessAfterLifetime.ql

Lines changed: 20 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -54,68 +54,33 @@ module AccessAfterLifetimeConfig implements DataFlow::ConfigSig {
5454

5555
module AccessAfterLifetimeFlow = TaintTracking::Global<AccessAfterLifetimeConfig>;
5656

57-
private newtype TTcNode =
58-
TSource(Source s, Variable target) {
59-
AccessAfterLifetimeFlow::flow(s, _) and sourceValueScope(s, target, _)
60-
} or
61-
TBlockExpr(BlockExpr be) or
62-
TSink(Sink s) { AccessAfterLifetimeFlow::flow(_, s) }
63-
64-
private class TcNode extends TTcNode {
65-
Source asSource(Variable target) { this = TSource(result, target) }
66-
67-
BlockExpr asBlockExpr() { this = TBlockExpr(result) }
68-
69-
Sink asSink() { this = TSink(result) }
70-
71-
string toString() {
72-
result = this.asSource(_).toString()
73-
or
74-
result = this.asBlockExpr().toString()
75-
or
76-
result = this.asSink().toString()
77-
}
78-
79-
Location getLocation() {
80-
result = this.asSource(_).getLocation()
81-
or
82-
result = this.asBlockExpr().getLocation()
83-
or
84-
result = this.asSink().getLocation()
85-
}
57+
predicate sourceBlock(Source s, Variable target, BlockExpr be) {
58+
AccessAfterLifetimeFlow::flow(s, _) and
59+
sourceValueScope(s, target, be.getEnclosingBlock*())
8660
}
8761

88-
pragma[nomagic]
89-
private predicate tcStep(TcNode a, TcNode b) {
90-
// `b` is a child of `a`
91-
exists(Source source, Variable target, BlockExpr be |
92-
source = a.asSource(target) and
93-
be = b.asBlockExpr().getEnclosingBlock*() and
94-
sourceValueScope(source, target, be) and
95-
AccessAfterLifetimeFlow::flow(source, _)
96-
)
97-
or
62+
predicate sinkBlock(Sink s, BlockExpr be) { be = s.asExpr().getEnclosingBlock() }
63+
64+
private predicate tcStep(BlockExpr a, BlockExpr b) {
9865
// propagate through function calls
9966
exists(Call call |
100-
a.asBlockExpr() = call.getEnclosingBlock() and
101-
call.getARuntimeTarget() = b.asBlockExpr().getEnclosingCallable()
67+
a = call.getEnclosingBlock() and
68+
call.getARuntimeTarget() = b.getEnclosingCallable()
10269
)
103-
or
104-
a.asBlockExpr() = b.asSink().asExpr().getEnclosingBlock()
10570
}
10671

107-
private predicate isTcSource(TcNode n) { n instanceof TSource }
72+
private predicate isTcSource(BlockExpr be) { sourceBlock(_, _, be) }
10873

109-
private predicate isTcSink(TcNode n) { n instanceof TSink }
74+
private predicate isTcSink(BlockExpr be) { sinkBlock(_, be) }
11075

11176
/**
11277
* Holds if block `a` contains block `b`, in the sense that a stack allocated variable in
11378
* `a` may still be on the stack during execution of `b`. This is interprocedural,
11479
* but is an overapproximation that doesn't accurately track call contexts
115-
* (for example if `f` and `g` both call `b`, then then depending on the
80+
* (for example if `f` and `g` both call `b`, then depending on the
11681
* caller a variable in `f` or `g` may or may-not be on the stack during `b`).
11782
*/
118-
private predicate mayEncloseOnStack(TcNode a, TcNode b) =
83+
private predicate mayEncloseOnStack(BlockExpr a, BlockExpr b) =
11984
doublyBoundedFastTC(tcStep/2, isTcSource/1, isTcSink/1)(a, b)
12085

12186
/**
@@ -126,7 +91,14 @@ private predicate mayEncloseOnStack(TcNode a, TcNode b) =
12691
predicate dereferenceAfterLifetime(Source source, Sink sink, Variable target) {
12792
AccessAfterLifetimeFlow::flow(source, sink) and
12893
sourceValueScope(source, target, _) and
129-
not mayEncloseOnStack(TSource(source, target), TSink(sink))
94+
not exists(BlockExpr beSource, BlockExpr beSink |
95+
sourceBlock(source, target, beSource) and
96+
sinkBlock(sink, beSink)
97+
|
98+
beSource = beSink
99+
or
100+
mayEncloseOnStack(beSource, beSink)
101+
)
130102
}
131103

132104
from

0 commit comments

Comments
 (0)