Skip to content

Commit 19f8e94

Browse files
committed
Merge remote-tracking branch 'origin/michaelrfairhurst/update-dataflow-nodes-MISRA-C++-2023-Memory-Experimental' into jeongsoolee09/MISRA-C++-2023-Memory-Experimental
2 parents 53c0ef7 + 0b3a231 commit 19f8e94

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
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: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,3 +252,44 @@ int main(int argc, char *argv[]) {
252252

253253
return 0;
254254
}
255+
256+
void malloc_2d_test() {
257+
int **array = (int **)malloc(2 * sizeof(int *));
258+
array[0] = (int *)malloc(3 * sizeof(int));
259+
array[1] = (int *)malloc(3 * sizeof(int));
260+
261+
int valid11 = array[0][0]; // COMPLIANT: pointer is within boundary
262+
int valid12 = array[0][1]; // COMPLIANT: pointer is within boundary
263+
int valid13 = array[0][2]; // COMPLIANT: pointer points one beyond the last
264+
// element, but non-compliant to Rule 4.1.3
265+
int invalid1 = array[0][4]; // NON_COMPLIANT: pointer points more than one
266+
// beyond the last element
267+
268+
int valid21 = array[1][0]; // COMPLIANT: pointer is within boundary
269+
int valid22 = array[1][1]; // COMPLIANT: pointer is within boundary
270+
int valid23 = array[1][2]; // COMPLIANT: pointer points one beyond the last
271+
// element, but non-compliant to Rule 4.1.3
272+
int invalid2 = array[1][4]; // NON_COMPLIANT: pointer points more than one
273+
// beyond the last element
274+
275+
int valid31 = array[2][0]; // COMPLIANT: pointer points one beyond the last
276+
// element, but non-compliant to Rule 4.1.3
277+
int invalid3 = array[3][0]; // NON_COMPLIANT: pointer points more than one
278+
// beyond the last element
279+
280+
array + 1; // COMPLIANT
281+
array + 2; // COMPLIANT
282+
array + 3; // NON_COMPLIANT
283+
array[0] + 1; // COMPLIANT
284+
array[0] + 2; // COMPLIANT
285+
array[0] + 3; // COMPLIANT
286+
array[0] + 4; // NON_COMPLIANT
287+
288+
(array + 1)[0] +
289+
3; // COMPLIANT: pointer points to one beyond the last element
290+
(array + 1)[0] +
291+
4; // NON_COMPLIANT: pointer points more than one beyond the last element
292+
array[0][2] + 1; // COMPLIANT
293+
array[0][3] + 1; // COMPLIANT
294+
array[0][4] + 1; // NON_COMPLIANT
295+
}

0 commit comments

Comments
 (0)