Skip to content

Commit 0b3a231

Browse files
Updates to dataflow nodes & tests
1 parent 332a98d commit 0b3a231

File tree

2 files changed

+75
-10
lines changed

2 files changed

+75
-10
lines changed

cpp/misra/src/rules/RULE-8-7-1/Experimental.ql

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import cpp
1616
import codingstandards.cpp.misra
17+
import semmle.code.cpp.ir.IR
1718
import semmle.code.cpp.dataflow.new.DataFlow
1819
import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
1920
import semmle.code.cpp.security.BufferAccess
@@ -216,7 +217,9 @@ class PointerFormation extends TPointerFormation {
216217
/**
217218
* Gets the data-flow node associated with this pointer formation.
218219
*/
219-
DataFlow::Node getNode() { result.asExpr() = this.asExpr() }
220+
DataFlow::Node getNode() {
221+
result.asInstruction().(PointerAddInstruction).getAst() = this.asExpr()
222+
}
220223

221224
Location getLocation() {
222225
result = this.asArrayExpr().getLocation() or
@@ -279,6 +282,16 @@ class FatPointer extends TFatPointer {
279282
result = this.asAllocated().asExpr() or
280283
result = this.asIndexAdjusted().getBase()
281284
}
285+
286+
DataFlow::Node getBasePointerNode() {
287+
exists(PointerAddInstruction ptrAdd |
288+
result.asInstruction() = ptrAdd.getAnOperand().getDef() and
289+
(
290+
result.asInstruction().getAst() = this.asIndexAdjusted().getBase() or
291+
result.asInstruction().getAst() = this.asAllocated().asExpr()
292+
)
293+
)
294+
}
282295
}
283296

284297
predicate srcSinkLengthMap(
@@ -288,7 +301,7 @@ predicate srcSinkLengthMap(
288301
TrackArray::flowPath(src, sink) and
289302
/* Reiterate the data flow configuration here. */
290303
src.getNode() = start.getNode() and
291-
sink.getNode().asExpr() = end.getBasePointer()
304+
sink.getNode() = end.getBasePointerNode()
292305
|
293306
srcOffset = start.getOffset() and
294307
sinkOffset = end.getOffset() and
@@ -312,7 +325,7 @@ module TrackArrayConfig implements DataFlow::ConfigSig {
312325
}
313326

314327
predicate isSink(DataFlow::Node node) {
315-
exists(FatPointer fatPointer | node.asExpr() = fatPointer.getBasePointer())
328+
exists(FatPointer fatPointer | node = fatPointer.getBasePointerNode())
316329
}
317330
}
318331

cpp/misra/test/rules/RULE-8-7-1/pointer_only.cpp

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,17 +129,19 @@ void realloc_single_dimensional_array_access(int *array) { // [3, 6]
129129
void stack_allocated_multi_dimensional_array_access(int array[2][3]) {
130130
int valid11 = array[0][0]; // COMPLIANT: pointer is within boundary
131131
int valid12 = array[0][1]; // COMPLIANT: pointer is within boundary
132-
int valid13 = array[0][2]; // COMPLIANT: pointer points one beyond the last
132+
int valid13 = array[0][2]; // COMPLIANT: pointer is within boundary
133+
int valid14 = array[0][3]; // COMPLIANT: pointer points one beyond the last
133134
// element, but non-compliant to Rule 4.1.3
134-
int invalid1 = array[0][3]; // NON_COMPLIANT: pointer points more than one
135+
int invalid1 = array[0][4]; // NON_COMPLIANT: pointer points more than one
135136
// beyond the last element
136137

137138
int valid21 = array[1][0]; // COMPLIANT: pointer is within boundary
138139
int valid22 = array[1][1]; // COMPLIANT: pointer is within boundary
139-
int valid23 = array[1][2]; // COMPLIANT: pointer points one beyond the last
140+
int valid23 = array[1][2]; // COMPLIANT: pointer is within boundary
141+
int valid24 = array[1][3]; // COMPLIANT: pointer points one beyond the last
140142
// element, but non-compliant to Rule 4.1.3
141143

142-
int invalid2 = array[1][3]; // NON_COMPLIANT: pointer points more than one
144+
int invalid2 = array[1][4]; // NON_COMPLIANT: pointer points more than one
143145
// beyond the last element
144146

145147
int valid31 = array[2][0]; // COMPLIANT: pointer points one beyond the last
@@ -166,10 +168,16 @@ void stack_allocated_multi_dimensional_pointer_arithmetic(int array[2][3]) {
166168
*array +
167169
2); // COMPLIANT: pointer points one beyond the last
168170
// element, but non-compliant to Rule 4.1.3 (equivalent to the above)
169-
int invalid11 = *(*(array + 0) + 3); // NON_COMPLIANT: pointer points more
171+
172+
int valid134 = *(*(array + 0) + 3); // COMPLIANT: pointer is within boundary
173+
int valid135 = *(
174+
*array +
175+
3); // COMPLIANT: pointer points one beyond the last
176+
// element, but non-compliant to Rule 4.1.3 (equivalent to the above)
177+
int invalid11 = *(*(array + 0) + 4); // NON_COMPLIANT: pointer points more
170178
// than one beyond the last element
171179
int invalid12 =
172-
*(*array + 3); // NON_COMPLIANT: pointer points more than
180+
*(*array + 4); // NON_COMPLIANT: pointer points more than
173181
// one beyond the last element (equivalent to the above)
174182

175183
int valid211 = *(*(array + 1) + 0); // COMPLIANT: pointer is within boundary
@@ -180,7 +188,10 @@ void stack_allocated_multi_dimensional_pointer_arithmetic(int array[2][3]) {
180188
int valid23 =
181189
*(*(array + 1) + 2); // COMPLIANT: pointer points one beyond the last
182190
// element, but non-compliant to Rule 4.1.3
183-
int invalid2 = *(*(array + 1) + 3); // NON_COMPLIANT: pointer points more than
191+
int valid24 =
192+
*(*(array + 1) + 3); // COMPLIANT: pointer points one beyond the last
193+
// element, but non-compliant to Rule 4.1.3
194+
int invalid2 = *(*(array + 1) + 4); // NON_COMPLIANT: pointer points more than
184195
// one beyond the last element
185196

186197
int valid311 =
@@ -252,3 +263,44 @@ int main(int argc, char *argv[]) {
252263

253264
return 0;
254265
}
266+
267+
void malloc_2d_test() {
268+
int **array = (int **)malloc(2 * sizeof(int *));
269+
array[0] = (int *)malloc(3 * sizeof(int));
270+
array[1] = (int *)malloc(3 * sizeof(int));
271+
272+
int valid11 = array[0][0]; // COMPLIANT: pointer is within boundary
273+
int valid12 = array[0][1]; // COMPLIANT: pointer is within boundary
274+
int valid13 = array[0][2]; // COMPLIANT: pointer points one beyond the last
275+
// element, but non-compliant to Rule 4.1.3
276+
int invalid1 = array[0][4]; // NON_COMPLIANT: pointer points more than one
277+
// beyond the last element
278+
279+
int valid21 = array[1][0]; // COMPLIANT: pointer is within boundary
280+
int valid22 = array[1][1]; // COMPLIANT: pointer is within boundary
281+
int valid23 = array[1][2]; // COMPLIANT: pointer points one beyond the last
282+
// element, but non-compliant to Rule 4.1.3
283+
int invalid2 = array[1][4]; // NON_COMPLIANT: pointer points more than one
284+
// beyond the last element
285+
286+
int valid31 = array[2][0]; // COMPLIANT: pointer points one beyond the last
287+
// element, but non-compliant to Rule 4.1.3
288+
int invalid3 = array[3][0]; // NON_COMPLIANT: pointer points more than one
289+
// beyond the last element
290+
291+
array + 1; // COMPLIANT
292+
array + 2; // COMPLIANT
293+
array + 3; // NON_COMPLIANT
294+
array[0] + 1; // COMPLIANT
295+
array[0] + 2; // COMPLIANT
296+
array[0] + 3; // COMPLIANT
297+
array[0] + 4; // NON_COMPLIANT
298+
299+
(array + 1)[0] +
300+
3; // COMPLIANT: pointer points to one beyond the last element
301+
(array + 1)[0] +
302+
4; // NON_COMPLIANT: pointer points more than one beyond the last element
303+
array[0][2] + 1; // COMPLIANT
304+
array[0][3] + 1; // COMPLIANT
305+
array[0][4] + 1; // NON_COMPLIANT
306+
}

0 commit comments

Comments
 (0)