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+
16private import cpp
27private import semmle.code.cpp.ir.dataflow.internal.ProductFlow
38private 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+ */
219248pragma [ nomagic]
220249predicate pointerAddInstructionHasBounds (
221250 DataFlow:: Node allocation , PointerAddInstruction pai , DataFlow:: Node sink1 , int delta
0 commit comments