Skip to content

Commit ca2694a

Browse files
committed
C++: exclude end pointers in iterator-style loops
1 parent 3570137 commit ca2694a

File tree

3 files changed

+49
-10
lines changed

3 files changed

+49
-10
lines changed

cpp/ql/src/experimental/Likely Bugs/ArrayAccessProductFlow.ql

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ class RangeAnalysisIRConfig extends IRConfiguration {
2121
}
2222
}
2323

24-
2524
predicate bounded(Instruction i, Bound b, int delta, boolean upper) {
2625
// TODO: reason
2726
semBounded(getSemanticExpr(i), b, delta, upper, _)
@@ -31,9 +30,9 @@ class ArraySizeConfiguration extends ProductFlow::Configuration {
3130
ArraySizeConfiguration() { this = "ArraySizeConfiguration" }
3231

3332
override predicate isSourcePair(DataFlow::Node source1, DataFlow::Node source2) {
34-
exists(GVN sizeGVN |
35-
source1.asConvertedExpr().(AllocationExpr).getSizeExpr() = sizeGVN.getAnExpr() and
36-
source2.asConvertedExpr() = sizeGVN.getAnExpr()
33+
exists(GVN sizeGvn |
34+
source1.asConvertedExpr().(AllocationExpr).getSizeExpr() = sizeGvn.getAnExpr() and
35+
source2.asConvertedExpr() = sizeGvn.getAnExpr()
3736
)
3837
}
3938

@@ -43,7 +42,16 @@ class ArraySizeConfiguration extends ProductFlow::Configuration {
4342
pai.getLeft() = sink1.asInstruction() and
4443
bounded(index, b, delta, true) and
4544
sink2.asInstruction() = b.getInstruction() and
46-
delta >= 0
45+
(
46+
delta = 0 and
47+
exists(DataFlow::Node paiNode, DataFlow::Node derefNode |
48+
DataFlow::localFlow(paiNode, derefNode) and
49+
paiNode.asInstruction() = pai and
50+
derefNode.asOperand() instanceof AddressOperand
51+
)
52+
or
53+
delta >= 1
54+
)
4755
)
4856
}
4957
}

cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/array-access/ArrayAccessProductFlow.expected

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,23 @@
2121
| test.cpp:70:14:70:19 | call to malloc | test.cpp:69:17:69:20 | size | test.cpp:83:14:83:14 | p | test.cpp:82:31:82:34 | size |
2222
| test.cpp:70:14:70:19 | call to malloc | test.cpp:69:17:69:20 | size | test.cpp:93:14:93:14 | p | test.cpp:88:30:88:33 | size |
2323
| test.cpp:70:14:70:19 | call to malloc | test.cpp:69:17:69:20 | size | test.cpp:93:14:93:14 | p | test.cpp:92:31:92:34 | size |
24+
| test.cpp:103:17:103:22 | call to malloc | test.cpp:103:24:103:27 | size | test.cpp:104:29:104:31 | arr | test.cpp:103:24:103:27 | size |
25+
| test.cpp:103:17:103:22 | call to malloc | test.cpp:103:24:103:27 | size | test.cpp:104:29:104:31 | arr | test.cpp:103:24:103:27 | size |
26+
| test.cpp:103:17:103:22 | call to malloc | test.cpp:103:24:103:27 | size | test.cpp:104:29:104:31 | arr | test.cpp:104:35:104:38 | size |
27+
| test.cpp:103:17:103:22 | call to malloc | test.cpp:103:24:103:27 | size | test.cpp:104:29:104:31 | arr | test.cpp:104:35:104:38 | size |
28+
| test.cpp:103:17:103:22 | call to malloc | test.cpp:103:24:103:27 | size | test.cpp:104:29:104:31 | arr | test.cpp:108:36:108:39 | size |
29+
| test.cpp:103:17:103:22 | call to malloc | test.cpp:103:24:103:27 | size | test.cpp:108:30:108:32 | arr | test.cpp:103:24:103:27 | size |
30+
| test.cpp:103:17:103:22 | call to malloc | test.cpp:103:24:103:27 | size | test.cpp:108:30:108:32 | arr | test.cpp:103:24:103:27 | size |
31+
| test.cpp:103:17:103:22 | call to malloc | test.cpp:103:24:103:27 | size | test.cpp:108:30:108:32 | arr | test.cpp:104:35:104:38 | size |
32+
| test.cpp:103:17:103:22 | call to malloc | test.cpp:103:24:103:27 | size | test.cpp:108:30:108:32 | arr | test.cpp:104:35:104:38 | size |
33+
| test.cpp:103:17:103:22 | call to malloc | test.cpp:103:24:103:27 | size | test.cpp:108:30:108:32 | arr | test.cpp:108:36:108:39 | size |
34+
| test.cpp:103:17:103:22 | call to malloc | test.cpp:104:35:104:38 | size | test.cpp:104:29:104:31 | arr | test.cpp:104:35:104:38 | size |
35+
| test.cpp:103:17:103:22 | call to malloc | test.cpp:104:35:104:38 | size | test.cpp:104:29:104:31 | arr | test.cpp:104:35:104:38 | size |
36+
| test.cpp:103:17:103:22 | call to malloc | test.cpp:104:35:104:38 | size | test.cpp:104:29:104:31 | arr | test.cpp:108:36:108:39 | size |
37+
| test.cpp:103:17:103:22 | call to malloc | test.cpp:104:35:104:38 | size | test.cpp:108:30:108:32 | arr | test.cpp:104:35:104:38 | size |
38+
| test.cpp:103:17:103:22 | call to malloc | test.cpp:104:35:104:38 | size | test.cpp:108:30:108:32 | arr | test.cpp:104:35:104:38 | size |
39+
| test.cpp:103:17:103:22 | call to malloc | test.cpp:104:35:104:38 | size | test.cpp:108:30:108:32 | arr | test.cpp:108:36:108:39 | size |
40+
| test.cpp:103:17:103:22 | call to malloc | test.cpp:108:36:108:39 | size | test.cpp:104:29:104:31 | arr | test.cpp:108:36:108:39 | size |
41+
| test.cpp:103:17:103:22 | call to malloc | test.cpp:108:36:108:39 | size | test.cpp:104:29:104:31 | arr | test.cpp:108:36:108:39 | size |
42+
| test.cpp:103:17:103:22 | call to malloc | test.cpp:108:36:108:39 | size | test.cpp:108:30:108:32 | arr | test.cpp:108:36:108:39 | size |
43+
| test.cpp:103:17:103:22 | call to malloc | test.cpp:108:36:108:39 | size | test.cpp:108:30:108:32 | arr | test.cpp:108:36:108:39 | size |

cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/array-access/test.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ char *malloc(int size);
33
void test1(int size) {
44
char *arr = malloc(size);
55
for (int i = 0; i < size; i++) {
6-
arr[i] = 0;
6+
arr[i] = 0; // GOOD
77
}
88

99
for (int i = 0; i <= size; i++) {
10-
arr[i] = i;
10+
arr[i] = i; // BAD
1111
}
1212
}
1313

@@ -32,7 +32,7 @@ void test2(int size) {
3232
}
3333

3434
for (int i = 0; i <= arr.size; i++) {
35-
arr.p[i] = i; // BAD
35+
arr.p[i] = i; // BAD [NOT DETECTED]
3636
}
3737
}
3838

@@ -42,7 +42,7 @@ void test3_callee(array_t arr) {
4242
}
4343

4444
for (int i = 0; i <= arr.size; i++) {
45-
arr.p[i] = i; // BAD
45+
arr.p[i] = i; // BAD [NOT DETECTED]
4646
}
4747
}
4848

@@ -96,4 +96,15 @@ void test6_callee(array_t *arr) {
9696

9797
void test6(int size) {
9898
test6_callee(mk_array_p(size));
99-
}
99+
}
100+
101+
void test7(int size) {
102+
char *arr = malloc(size);
103+
for (char *p = arr; p < arr + size; p++) {
104+
*p = 0; // GOOD
105+
}
106+
107+
for (char *p = arr; p <= arr + size; p++) {
108+
*p = 0; // BAD [NOT DETECTED]
109+
}
110+
}

0 commit comments

Comments
 (0)