Skip to content

Commit 9d3bab0

Browse files
committed
Split out source and sinks into their cases
1 parent c0b1e55 commit 9d3bab0

File tree

1 file changed

+63
-17
lines changed

1 file changed

+63
-17
lines changed

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

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,21 @@ class ArrayDeclaration extends VariableDeclarationEntry {
2626
* Gets the declared length of this array.
2727
*/
2828
int getLength() { result = length }
29+
30+
/**
31+
* Gets the expression that the variable declared is initialized to, given there is such one.
32+
*/
33+
Expr getInitExpr() { result = this.getVariable().getInitializer().getExpr() }
2934
}
3035

3136
newtype TArrayAllocation =
3237
TStackAllocation(ArrayDeclaration arrayDecl) or
3338
TDynamicAllocation(AllocationFunction alloc)
3439

40+
newtype TPointerFormation =
41+
TArrayExpr(ArrayExprBA arrayExpr) or
42+
TPointerArithmetic(PointerArithmeticOperation pointerArithmetic)
43+
3544
class ArrayAllocation extends TArrayAllocation {
3645
ArrayDeclaration asStackAllocation() { this = TStackAllocation(result) }
3746

@@ -48,44 +57,81 @@ class ArrayAllocation extends TArrayAllocation {
4857
}
4958
}
5059

60+
class PointerFormation extends TPointerFormation {
61+
ArrayExprBA asArrayExpr() { this = TArrayExpr(result) }
62+
63+
PointerArithmeticOperation asPointerArithmetic() { this = TPointerArithmetic(result) }
64+
65+
string toString() {
66+
result = this.asArrayExpr().toString() or
67+
result = this.asPointerArithmetic().toString()
68+
}
69+
70+
int getOffset() {
71+
result = this.asArrayExpr().getArrayOffset().getValue().toInt()
72+
or
73+
exists(PointerAddExpr pointerAddition | pointerAddition = this.asPointerArithmetic() |
74+
result = pointerAddition.getAnOperand().getValue().toInt() // TODO: only get the number being added
75+
)
76+
or
77+
exists(PointerSubExpr pointerSubtraction | pointerSubtraction = this.asPointerArithmetic() |
78+
result = -pointerSubtraction.getAnOperand().getValue().toInt()
79+
)
80+
}
81+
82+
Expr asExpr() {
83+
result = this.asArrayExpr() or
84+
result = this.asPointerArithmetic()
85+
}
86+
87+
DataFlow::Node getNode() {
88+
result.asExpr() = this.asExpr() or
89+
result.asIndirectExpr() = this.asExpr()
90+
}
91+
}
92+
5193
module TrackArrayConfig implements DataFlow::ConfigSig {
5294
predicate isSource(DataFlow::Node node) {
5395
/* 1. Declaring / Initializing an array-type variable */
54-
exists(ArrayDeclaration arrayDecl |
55-
node.asExpr() = arrayDecl.getVariable().getInitializer().getExpr()
96+
exists(ArrayAllocation arrayAllocation |
97+
node.asExpr() = arrayAllocation.asStackAllocation().getInitExpr()
5698
)
5799
or
58100
/* 2. Allocating dynamic memory as an array */
59101
none() // TODO
60102
}
61103

62104
predicate isSink(DataFlow::Node node) {
63-
/* 1. Pointer arithmetic */
64-
exists(PointerArithmeticOperation pointerArithmetic |
65-
node.asIndirectExpr() = pointerArithmetic.getAnOperand()
66-
)
67-
or
68-
/* 2. Array access */
69-
node.asExpr() instanceof ArrayExprBA
105+
exists(PointerFormation pointerFormation | node = pointerFormation.getNode())
70106
}
71107
}
72108

73109
module TrackArray = DataFlow::Global<TrackArrayConfig>;
74110

75111
private predicate arrayDeclarationAndAccess(
76-
DataFlow::Node arrayDeclaration, DataFlow::Node arrayAccess
112+
DataFlow::Node arrayDeclarationNode, DataFlow::Node arrayAccessNode
77113
) {
78-
TrackArray::flow(arrayDeclaration, arrayAccess)
114+
TrackArray::flow(arrayDeclarationNode, arrayAccessNode)
79115
}
80116

81117
private predicate arrayIndexExceedsOutOfBounds(
82-
DataFlow::Node arrayDeclaration, DataFlow::Node arrayAccess
118+
DataFlow::Node arrayDeclarationNode, DataFlow::Node arrayAccessNode
83119
) {
84-
arrayDeclarationAndAccess(arrayDeclaration, arrayAccess) and
85-
// exists(int declaredLength |
86-
// declaredLength = arrayDeclaration
87-
// )
88-
any() // TODO
120+
/* 1. Ensure the array access is reachable from the array declaration. */
121+
arrayDeclarationAndAccess(arrayDeclarationNode, arrayAccessNode) and
122+
exists(ArrayAllocation arrayAllocation, PointerFormation pointerFormation |
123+
arrayDeclarationNode.asExpr() = arrayAllocation.asStackAllocation().getInitExpr() and
124+
arrayAccessNode = pointerFormation.getNode()
125+
|
126+
/* 2. Cases where a pointer formation becomes illegal. */
127+
(
128+
/* 2-1. An offset cannot be negative. */
129+
pointerFormation.getOffset() < 0
130+
or
131+
/* 2-2. The offset should be at most (number of elements) + 1 = (the declared length). */
132+
arrayAllocation.getLength() < pointerFormation.getOffset()
133+
)
134+
)
89135
}
90136

91137
from Expr expr

0 commit comments

Comments
 (0)