Skip to content

Commit 3e1b4d9

Browse files
committed
C++: Add QLDoc.
1 parent 576f021 commit 3e1b4d9

File tree

3 files changed

+52
-5
lines changed

3 files changed

+52
-5
lines changed

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

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/**
2+
* This file provides the first phase of the `cpp/invalid-pointer-deref` query that identifies flow
3+
* an allocation to a pointer-arithmetic instruction that constructs a pointer that's out of bounds.
4+
*/
5+
16
private import cpp
27
private import semmle.code.cpp.ir.dataflow.internal.ProductFlow
38
private import semmle.code.cpp.ir.ValueNumbering
@@ -85,6 +90,10 @@ module Barrier2 {
8590
)
8691
}
8792

93+
/**
94+
* Gets an instruction that is guarded by a guard condition which ensures that
95+
* the value of the instruction is upper-bounded by size of some allocation.
96+
*/
8897
Instruction getABarrierInstruction(FlowState2 state) {
8998
exists(IRGuardCondition g, ValueNumber value, Operand use, boolean edge |
9099
use = value.getAUse() and
@@ -95,16 +104,24 @@ module Barrier2 {
95104
)
96105
}
97106

107+
/**
108+
* Gets a `DataFlow::Node` that is guarded by a guard condition which ensures that
109+
* the value of the node is upper-bounded by size of some allocation.
110+
*/
98111
DataFlow::Node getABarrierNode(FlowState2 state) {
99112
result.asOperand() = getABarrierInstruction(state).getAUse()
100113
}
101114

115+
/**
116+
* Gets the block of a node that is guarded (see `getABarrierInstruction` or
117+
* `getABarrierNode` for the definition of what it means to be guarded).
118+
*/
102119
IRBlock getABarrierBlock(FlowState2 state) {
103120
result.getAnInstruction() = getABarrierInstruction(state)
104121
}
105122
}
106123

107-
module InterestingPointerAddInstruction {
124+
private module InterestingPointerAddInstruction {
108125
private module PointerAddInstructionConfig implements DataFlow::ConfigSig {
109126
predicate isSource(DataFlow::Node source) {
110127
// The sources is the same as in the sources for the second
@@ -119,6 +136,12 @@ module InterestingPointerAddInstruction {
119136

120137
private import DataFlow::Global<PointerAddInstructionConfig>
121138

139+
/**
140+
* Holds if `pai` is a pointer-arithmetic instruction such that the
141+
* result of an allocation flows to the left-hand side of `pai`.
142+
*
143+
* This predicate is used to reduce the set of tuples in `isSinkPair`.
144+
*/
122145
predicate isInteresting(PointerAddInstruction pai) {
123146
exists(DataFlow::Node n |
124147
n.asInstruction() = pai.getLeft() and
@@ -210,12 +233,18 @@ private predicate pointerAddInstructionHasBounds0(
210233
pai.getRight() = right and
211234
pai.getLeft() = sink1.asInstruction() and
212235
instr2 = sink2.asInstruction() and
236+
// pai.getRight() <= sink2 + delta
213237
bounded1(right, instr2, delta) and
214238
not right = Barrier2::getABarrierInstruction(delta) and
215239
not instr2 = Barrier2::getABarrierInstruction(delta)
216240
)
217241
}
218242

243+
/**
244+
* Holds if `allocation` flows to `sink1` and `sink1` represents the left-hand
245+
* side of the pointer-arithmetic instruction `pai`, and the right-hand side of `pai`
246+
* is non-strictly upper bounded by the size of `alllocation` + `delta`.
247+
*/
219248
pragma[nomagic]
220249
predicate pointerAddInstructionHasBounds(
221250
DataFlow::Node allocation, PointerAddInstruction pai, DataFlow::Node sink1, int delta

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/**
2+
* This file provides the second phase of the `cpp/invalid-pointer-deref` query that identifies flow
3+
* from the out-of-bounds pointer identified by the `AllocationToInvalidPointer.qll` library to
4+
* a dereference of the out-of-bounds pointer.
5+
*/
6+
17
private import cpp
28
private import semmle.code.cpp.dataflow.new.DataFlow
39
private import semmle.code.cpp.ir.ValueNumbering

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

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
/**
2+
* This file contains the range-analysis specific parts of the `cpp/invalid-pointer-deref` query
3+
* that is used by both `AllocationToInvalidPointer.qll` and `InvalidPointerToDereference.qll`.
4+
*/
5+
16
private import cpp
2-
private import semmle.code.cpp.ir.dataflow.internal.ProductFlow
37
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysis
48
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific
5-
private import semmle.code.cpp.ir.ValueNumbering
6-
private import semmle.code.cpp.controlflow.IRGuards
79
private import semmle.code.cpp.ir.IR
8-
private import codeql.util.Unit
910

1011
pragma[nomagic]
1112
private Instruction getABoundIn(SemBound b, IRFunction func) {
@@ -25,12 +26,23 @@ private predicate boundedImpl(Instruction i, Instruction b, int delta) {
2526
)
2627
}
2728

29+
/**
30+
* Holds if `i <= b + delta`.
31+
*
32+
* This predicate enforces a join-order that ensures that `i` has already been bound.
33+
*/
2834
bindingset[i]
2935
pragma[inline_late]
3036
predicate bounded1(Instruction i, Instruction b, int delta) { boundedImpl(i, b, delta) }
3137

38+
/**
39+
* Holds if `i <= b + delta`.
40+
*
41+
* This predicate enforces a join-order that ensures that `b` has already been bound.
42+
*/
3243
bindingset[b]
3344
pragma[inline_late]
3445
predicate bounded2(Instruction i, Instruction b, int delta) { boundedImpl(i, b, delta) }
3546

47+
/** Holds if `i <= b + delta`. */
3648
predicate bounded = boundedImpl/3;

0 commit comments

Comments
 (0)