Skip to content

Commit 89b91ec

Browse files
committed
C++: Disable field flow from the 'cpp/invalid-pointer-deref' query.
1 parent c3cf48b commit 89b91ec

File tree

3 files changed

+37
-0
lines changed

3 files changed

+37
-0
lines changed

cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/AllocationToInvalidPointer.qll

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,15 @@ predicate hasSize(HeuristicAllocationExpr alloc, DataFlow::Node n, int state) {
7777
)
7878
}
7979

80+
/**
81+
* Gets the virtual dispatch branching limit when calculating field flow while searching
82+
* for flow from an allocation to the construction of an out-of-bounds pointer.
83+
*
84+
* This can be overridden to a smaller value to improve performance (a
85+
* value of 0 disables field flow), or a larger value to get more results.
86+
*/
87+
int allocationToInvalidPointerFieldFlowBranchLimit() { result = 0 }
88+
8089
/**
8190
* A module that encapsulates a barrier guard to remove false positives from flow like:
8291
* ```cpp
@@ -105,6 +114,8 @@ private module SizeBarrier {
105114
InterestingPointerAddInstruction::isInterestingSize(source)
106115
}
107116

117+
int fieldFlowBranchLimit() { result = allocationToInvalidPointerFieldFlowBranchLimit() }
118+
108119
/**
109120
* Holds if `small <= large + k` holds if `g` evaluates to `testIsTrue`.
110121
*/
@@ -202,6 +213,8 @@ private module InterestingPointerAddInstruction {
202213
hasSize(source.asConvertedExpr(), _, _)
203214
}
204215

216+
int fieldFlowBranchLimit() { result = allocationToInvalidPointerFieldFlowBranchLimit() }
217+
205218
predicate isSink(DataFlow::Node sink) {
206219
sink.asInstruction() = any(PointerAddInstruction pai).getLeft()
207220
}
@@ -258,6 +271,10 @@ private module Config implements ProductFlow::StateConfigSig {
258271
hasSize(allocSource.asConvertedExpr(), sizeSource, sizeAddend)
259272
}
260273

274+
int fieldFlowBranchLimit1() { result = allocationToInvalidPointerFieldFlowBranchLimit() }
275+
276+
int fieldFlowBranchLimit2() { result = allocationToInvalidPointerFieldFlowBranchLimit() }
277+
261278
predicate isSinkPair(
262279
DataFlow::Node allocSink, FlowState1 unit, DataFlow::Node sizeSink, FlowState2 sizeAddend
263280
) {

cpp/ql/lib/semmle/code/cpp/security/InvalidPointerDereference/InvalidPointerToDereference.qll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,16 @@ private import semmle.code.cpp.controlflow.IRGuards
8383
private import AllocationToInvalidPointer as AllocToInvalidPointer
8484
private import semmle.code.cpp.rangeanalysis.new.RangeAnalysisUtil
8585

86+
/**
87+
* Gets the virtual dispatch branching limit when calculating field flow while
88+
* searching for flow from an out-of-bounds pointer to a dereference of the
89+
* pointer.
90+
*
91+
* This can be overridden to a smaller value to improve performance (a
92+
* value of 0 disables field flow), or a larger value to get more results.
93+
*/
94+
int invalidPointerToDereferenceFieldFlowBranchLimit() { result = 0 }
95+
8696
private module InvalidPointerToDerefBarrier {
8797
private module BarrierConfig implements DataFlow::ConfigSig {
8898
additional predicate isSource(DataFlow::Node source, PointerArithmeticInstruction pai) {
@@ -101,6 +111,8 @@ private module InvalidPointerToDerefBarrier {
101111
}
102112

103113
predicate isSink(DataFlow::Node sink) { isSink(_, sink, _, _, _) }
114+
115+
int fieldFlowBranchLimit() { result = invalidPointerToDereferenceFieldFlowBranchLimit() }
104116
}
105117

106118
private module BarrierFlow = DataFlow::Global<BarrierConfig>;
@@ -178,6 +190,8 @@ private module InvalidPointerToDerefConfig implements DataFlow::StateConfigSig {
178190
// Note that this is the only place where the `FlowState` is used in this configuration.
179191
node = InvalidPointerToDerefBarrier::getABarrierNode(pai)
180192
}
193+
194+
int fieldFlowBranchLimit() { result = invalidPointerToDereferenceFieldFlowBranchLimit() }
181195
}
182196

183197
private import DataFlow::GlobalWithState<InvalidPointerToDerefConfig>

cpp/ql/src/Security/CWE/CWE-193/InvalidPointerDeref.ql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ module FinalConfig implements DataFlow::StateConfigSig {
9494
)
9595
}
9696

97+
int fieldFlowBranchLimit() {
98+
result =
99+
allocationToInvalidPointerFieldFlowBranchLimit()
100+
.maximum(invalidPointerToDereferenceFieldFlowBranchLimit())
101+
}
102+
97103
predicate isAdditionalFlowStep(
98104
DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2
99105
) {

0 commit comments

Comments
 (0)