Skip to content

Commit 2bccb81

Browse files
committed
C++: Speed up the 'cpp/unbounded-write' query.
1 parent 2204b08 commit 2bccb81

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

Diff for: cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll

+22
Original file line numberDiff line numberDiff line change
@@ -1375,3 +1375,25 @@ private module Cached {
13751375
}
13761376

13771377
private import Cached
1378+
1379+
/**
1380+
* Holds if `left < right + k` evaluates to `isLt` given that some guard
1381+
* evaluates to `value`.
1382+
*
1383+
* To find the specific guard that performs the comparison
1384+
* use `IRGuards.comparesLt`.
1385+
*/
1386+
predicate comparesLt(Operand left, Operand right, int k, boolean isLt, AbstractValue value) {
1387+
compares_lt(_, left, right, k, isLt, value)
1388+
}
1389+
1390+
/**
1391+
* Holds if `left = right + k` evaluates to `isLt` given that some guard
1392+
* evaluates to `value`.
1393+
*
1394+
* To find the specific guard that performs the comparison
1395+
* use `IRGuards.comparesEq`.
1396+
*/
1397+
predicate comparesEq(Operand left, Operand right, int k, boolean isLt, AbstractValue value) {
1398+
compares_eq(_, left, right, k, isLt, value)
1399+
}

Diff for: cpp/ql/src/Security/CWE/CWE-120/UnboundedWrite.ql

+31
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,42 @@ predicate isSink(DataFlow::Node sink, BufferWrite bw, boolean qualifier) {
7373
unboundedWriteSource(sink.asDefiningArgument(), bw, qualifier)
7474
}
7575

76+
/**
77+
* A configuration that specifies flow from a `FlowSource` to a relational
78+
* comparison.
79+
*
80+
* This configuration is used to speed up the barrier computations in Config.
81+
*/
82+
module BarrierConfig implements DataFlow::ConfigSig {
83+
predicate isSource(DataFlow::Node source) { isSource(source, _) }
84+
85+
predicate isSink(DataFlow::Node sink) {
86+
comparesEq(sink.asOperand(), _, _, true, _) or
87+
comparesLt(sink.asOperand(), _, _, true, _)
88+
}
89+
}
90+
91+
module BarrierFlow = TaintTracking::Global<BarrierConfig>;
92+
93+
import semmle.code.cpp.ir.dataflow.internal.DataFlowImplCommon as DataFlowImplCommon
94+
95+
/**
96+
* Holds if `left` is a left operand of some relational comparison that may
97+
* depend on user input.
98+
*/
99+
predicate interestingLessThanOrEqual(Operand left) {
100+
exists(DataFlowImplCommon::NodeEx node |
101+
node.asNode().asOperand() = left and
102+
BarrierFlow::Stages::Stage1::sinkNode(node, _)
103+
)
104+
}
105+
76106
predicate lessThanOrEqual(IRGuardCondition g, Expr e, boolean branch) {
77107
exists(Operand left |
78108
g.comparesLt(left, _, _, true, branch) or
79109
g.comparesEq(left, _, _, true, branch)
80110
|
111+
interestingLessThanOrEqual(left) and
81112
left.getDef().getUnconvertedResultExpression() = e
82113
)
83114
}

0 commit comments

Comments
 (0)