Skip to content

Commit 7cc0d71

Browse files
committed
WIP: optimize query
1 parent 7d24d96 commit 7cc0d71

File tree

1 file changed

+47
-13
lines changed

1 file changed

+47
-13
lines changed

cpp/ql/src/Critical/MissingCheckScanf.ql

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,23 +65,21 @@ class ScanfOutput extends Expr {
6565
* but before it gets reset or reused in another `scanf` call.
6666
*/
6767
Access getAnAccess() {
68-
exists(Instruction dst |
69-
this.bigStep() = dst and
70-
dst.getAst() = result and
71-
valueNumber(dst) = valNum
68+
exists(Instruction source, Instruction sink |
69+
this.hasFlow(source, sink) and
70+
sink.getAst() = result
7271
)
7372
}
7473

75-
private Instruction bigStep() {
76-
result = this.smallStep(instr)
77-
or
78-
exists(Instruction i | i = this.bigStep() | result = this.smallStep(i))
79-
}
74+
// --- definition of the flow graph ---
75+
pragma[inline]
76+
private predicate isEdge(Instruction i, Instruction j) { i.getASuccessor() = j }
77+
78+
private predicate isSource(Instruction i) { i = instr }
8079

81-
private Instruction smallStep(Instruction i) {
82-
instr.getASuccessor*() = i and
83-
i.getASuccessor() = result and
84-
not this.isBarrier(result)
80+
private predicate isSink(Instruction i) {
81+
valueNumber(i) = valNum and
82+
i.getAst() instanceof Access
8583
}
8684

8785
private predicate isBarrier(Instruction i) {
@@ -92,6 +90,42 @@ class ScanfOutput extends Expr {
9290
[e, e.getParent().(AddressOfExpr)] instanceof ScanfOutput
9391
)
9492
}
93+
94+
// --- flow graph search implementation ---
95+
private predicate hasFlow(Instruction source, Instruction sink) {
96+
this.isSource(source) and
97+
this.isSink(sink) and
98+
this.multiStep(source, sink)
99+
}
100+
101+
private predicate multiStep(Instruction i, Instruction j) {
102+
this.prunedStep(i, j)
103+
or
104+
exists(Instruction ij | this.multiStep(i, ij) | this.prunedStep(ij, j))
105+
}
106+
107+
private predicate prunedStep(Instruction i, Instruction j) {
108+
this.reachedFromSource(i) and
109+
this.reachesSink(j) and
110+
this.oneStep(i, j)
111+
}
112+
113+
pragma[inline]
114+
private predicate oneStep(Instruction i, Instruction j) {
115+
this.isEdge(i, j) and not this.isBarrier(j)
116+
}
117+
118+
private predicate reachedFromSource(Instruction i) {
119+
isSource(i)
120+
or
121+
exists(Instruction h | reachedFromSource(h) | oneStep(h, i))
122+
}
123+
124+
private predicate reachesSink(Instruction i) {
125+
isSink(i)
126+
or
127+
exists(Instruction j | reachesSink(j) | oneStep(i, j))
128+
}
95129
}
96130

97131
/** Returns a block guarded by the assertion of `value op call` */

0 commit comments

Comments
 (0)