Skip to content

Commit 1b77f50

Browse files
committed
Shared: Address review comments.
1 parent ed1fe14 commit 1b77f50

File tree

1 file changed

+60
-34
lines changed

1 file changed

+60
-34
lines changed

shared/typetracking/codeql/typetracking/TypeTracking.qll

Lines changed: 60 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33
* for tracking types.
44
*/
55

6-
import codeql.util.Boolean
7-
import codeql.util.Option
6+
private import codeql.util.Boolean
7+
private import codeql.util.Option
88

9+
/**
10+
* The step relations for type tracking.
11+
*/
912
signature module TypeTrackingInput {
1013
/** A node that is used by the type-trackers. */
1114
class Node {
15+
/** Gets a textual representation of this node. */
1216
string toString();
1317
}
1418

@@ -21,6 +25,7 @@ signature module TypeTrackingInput {
2125

2226
/** A type of content to be used with the store and read steps. */
2327
class Content {
28+
/** Gets a textual representation of this content. */
2429
string toString();
2530
}
2631

@@ -70,21 +75,21 @@ signature module TypeTrackingInput {
7075
predicate returnStep(Node nodeFrom, LocalSourceNode nodeTo);
7176

7277
/**
73-
* Holds if `nodeFrom` is being written to the content `f` of the object in
78+
* Holds if `nodeFrom` is being written to the content `c` of the object in
7479
* `nodeTo`.
7580
*/
76-
predicate storeStep(Node nodeFrom, Node nodeTo, Content f);
81+
predicate storeStep(Node nodeFrom, Node nodeTo, Content c);
7782

7883
/**
79-
* Holds if `nodeTo` is the result of accessing the content `f` of `nodeFrom`.
84+
* Holds if `nodeTo` is the result of accessing the content `c` of `nodeFrom`.
8085
*/
81-
predicate loadStep(Node nodeFrom, LocalSourceNode nodeTo, Content f);
86+
predicate loadStep(Node nodeFrom, LocalSourceNode nodeTo, Content c);
8287

8388
/**
84-
* Holds if the content `f1` of `nodeFrom` is stored in the content `f2` of
89+
* Holds if the content `c1` of `nodeFrom` is stored in the content `c2` of
8590
* `nodeTo`.
8691
*/
87-
predicate loadStoreStep(Node nodeFrom, Node nodeTo, Content f1, Content f2);
92+
predicate loadStoreStep(Node nodeFrom, Node nodeTo, Content c1, Content c2);
8893

8994
/**
9095
* Holds if type-tracking should step from `nodeFrom` to `nodeTo` if inside a
@@ -113,9 +118,14 @@ signature module TypeTrackingInput {
113118
predicate hasFeatureBacktrackStoreTarget();
114119
}
115120

121+
/**
122+
* Given a set of step relations, this module provides classes and predicates
123+
* for simple data-flow reachability suitable for tracking types.
124+
*/
116125
module TypeTracking<TypeTrackingInput I> {
117126
private import I
118127

128+
/** Provides consistency checks for the type-tracker step relations. */
119129
module ConsistencyChecks {
120130
private predicate stepEntry(Node n, string kind) {
121131
simpleLocalSmallStep(n, _) and kind = "simpleLocalSmallStep"
@@ -329,12 +339,17 @@ module TypeTracking<TypeTrackingInput I> {
329339
)
330340
}
331341

342+
pragma[inline]
343+
private predicate isLocalSourceNode(LocalSourceNode n) { any() }
344+
332345
/**
333346
* Holds if there is flow from `localSource` to `dst` using zero or more
334347
* `simpleLocalSmallStep`s.
335348
*/
336349
pragma[nomagic]
337350
predicate flowsTo(LocalSourceNode localSource, Node dst) {
351+
// explicit type check in base case to avoid repeated type tests in recursive case
352+
isLocalSourceNode(localSource) and
338353
dst = localSource
339354
or
340355
exists(Node mid |
@@ -344,27 +359,27 @@ module TypeTracking<TypeTrackingInput I> {
344359
}
345360

346361
pragma[nomagic]
347-
private predicate storeStepIntoSource(Node nodeFrom, LocalSourceNode nodeTo, Content f) {
362+
private predicate storeStepIntoSource(Node nodeFrom, LocalSourceNode nodeTo, Content c) {
348363
if hasFeatureBacktrackStoreTarget()
349364
then
350365
exists(Node obj |
351366
flowsTo(nodeTo, obj) and
352-
storeStep(nodeFrom, obj, f)
367+
storeStep(nodeFrom, obj, c)
353368
)
354-
else storeStep(nodeFrom, nodeTo, f)
369+
else storeStep(nodeFrom, nodeTo, c)
355370
}
356371

357372
pragma[nomagic]
358373
private predicate loadStoreStepIntoSource(
359-
Node nodeFrom, LocalSourceNode nodeTo, Content f1, Content f2
374+
Node nodeFrom, LocalSourceNode nodeTo, Content c1, Content c2
360375
) {
361376
if hasFeatureBacktrackStoreTarget()
362377
then
363378
exists(Node obj |
364379
flowsTo(nodeTo, obj) and
365-
loadStoreStep(nodeFrom, obj, f1, f2)
380+
loadStoreStep(nodeFrom, obj, c1, c2)
366381
)
367-
else loadStoreStep(nodeFrom, nodeTo, f1, f2)
382+
else loadStoreStep(nodeFrom, nodeTo, c1, c2)
368383
}
369384

370385
pragma[nomagic]
@@ -465,8 +480,8 @@ module TypeTracking<TypeTrackingInput I> {
465480
* instead of `tt2.step`.
466481
*/
467482
class TypeTracker extends TTypeTracker {
468-
Boolean hasCall;
469-
ContentOption content;
483+
private Boolean hasCall;
484+
private ContentOption content;
470485

471486
TypeTracker() { this = MkTypeTracker(hasCall, content) }
472487

@@ -478,9 +493,10 @@ module TypeTracking<TypeTrackingInput I> {
478493
exists(string withCall, string withContent |
479494
(if hasCall = true then withCall = "with" else withCall = "without") and
480495
(
481-
if content instanceof ContentOption::Some
482-
then withContent = " with content " + content.asSome()
483-
else withContent = ""
496+
withContent = " with content " + content.asSome()
497+
or
498+
content instanceof ContentOption::None and
499+
withContent = ""
484500
) and
485501
result = "type tracker " + withCall + " call steps" + withContent
486502
)
@@ -613,8 +629,8 @@ module TypeTracking<TypeTrackingInput I> {
613629
* instead of `t2.step`.
614630
*/
615631
class TypeBackTracker extends TTypeBackTracker {
616-
Boolean hasReturn;
617-
ContentOption content;
632+
private Boolean hasReturn;
633+
private ContentOption content;
618634

619635
TypeBackTracker() { this = MkTypeBackTracker(hasReturn, content) }
620636

@@ -626,9 +642,10 @@ module TypeTracking<TypeTrackingInput I> {
626642
exists(string withReturn, string withContent |
627643
(if hasReturn = true then withReturn = "with" else withReturn = "without") and
628644
(
629-
if content instanceof ContentOption::Some
630-
then withContent = " with content " + content
631-
else withContent = ""
645+
withContent = " with content " + content.asSome()
646+
or
647+
content instanceof ContentOption::None and
648+
withContent = ""
632649
) and
633650
result = "type back-tracker " + withReturn + " return steps" + withContent
634651
)
@@ -753,7 +770,7 @@ module TypeTracking<TypeTrackingInput I> {
753770
* A node on a path that is reachable from a source. This is a pair of a
754771
* `Node` and a `TypeTracker`.
755772
*/
756-
class PathNode extends TPathNode {
773+
class PathNodeFwd extends TPathNode {
757774
/** Gets the node of this `PathNode`. */
758775
Node getNode() { this = MkPathNode(result, _) }
759776

@@ -762,14 +779,15 @@ module TypeTracking<TypeTrackingInput I> {
762779

763780
private string ppContent() {
764781
exists(ContentOption c | this.getTypeTracker() = MkTypeTracker(_, c) |
765-
if c instanceof ContentOption::Some
766-
then result = " with content " + c.asSome()
767-
else result = ""
782+
result = " with content " + c.asSome()
783+
or
784+
c instanceof ContentOption::None and
785+
result = ""
768786
)
769787
}
770788

771789
/** Gets a textual representation of this node. */
772-
string toString() { result = this.getNode().toString() + " " + this.ppContent() }
790+
string toString() { result = this.getNode().toString() + this.ppContent() }
773791

774792
/** Holds if this is a source. */
775793
predicate isSource() { source(this.getNode()) and this.getTypeTracker().start() }
@@ -783,26 +801,34 @@ module TypeTracking<TypeTrackingInput I> {
783801
tt2 = tt1.step(n1, n2)
784802
}
785803

786-
private predicate edgeCand(PathNode n1, PathNode n2) {
804+
private predicate edgeCand(PathNodeFwd n1, PathNodeFwd n2) {
787805
edgeCand(n1.getNode(), n1.getTypeTracker(), n2.getNode(), n2.getTypeTracker())
788806
}
789807

790-
private predicate reachRev(PathNode n) {
808+
private predicate reachRev(PathNodeFwd n) {
791809
n.isSink()
792810
or
793-
exists(PathNode mid |
811+
exists(PathNodeFwd mid |
794812
edgeCand(n, mid) and
795813
reachRev(mid)
796814
)
797815
}
798816

817+
/**
818+
* A node on a path that is reachable from a source and can reach a sink.
819+
* This is a pair of a `Node` and a `TypeTracker`.
820+
*/
821+
class PathNode extends PathNodeFwd {
822+
PathNode() { reachRev(this) }
823+
}
824+
799825
/** Holds if `(p1, p2)` is an edge in a path between a source and a sink. */
800-
query predicate edges(PathNode n1, PathNode n2) { edgeCand(n1, n2) and reachRev(n2) }
826+
query predicate edges(PathNode n1, PathNode n2) { edgeCand(n1, n2) }
801827

802828
private predicate stepPlus(PathNode n1, PathNode n2) = fastTC(edges/2)(n1, n2)
803829

804830
/** Holds if there is a path between `source` and `sink`. */
805-
predicate flowPair(PathNode source, PathNode sink) {
831+
predicate hasFlow(PathNode source, PathNode sink) {
806832
source.isSource() and
807833
sink.isSink() and
808834
(source = sink or stepPlus(source, sink))

0 commit comments

Comments
 (0)