Skip to content

Commit a735d18

Browse files
committed
C++: Add inline expectations tests for the allocation-to-invalid-pointer stage of the query.
1 parent 5099de5 commit a735d18

File tree

3 files changed

+70
-39
lines changed

3 files changed

+70
-39
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
failures
2+
testFailures
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import cpp
2+
import semmle.code.cpp.security.InvalidPointerDereference.AllocationToInvalidPointer
3+
import TestUtilities.InlineExpectationsTest
4+
import semmle.code.cpp.ir.IR
5+
import semmle.code.cpp.dataflow.new.DataFlow
6+
7+
module AllocationToInvalidPointerTest implements TestSig {
8+
string getARelevantTag() { result = "alloc" }
9+
10+
predicate hasActualResult(Location location, string element, string tag, string value) {
11+
exists(DataFlow::Node allocation, PointerAddInstruction pai, DataFlow::Node sink1, int delta |
12+
pointerAddInstructionHasBounds(allocation, pai, sink1, delta) and
13+
location = pai.getLocation() and
14+
element = pai.toString() and
15+
tag = "alloc"
16+
|
17+
delta > 0 and
18+
value = "L" + allocation.getLocation().getStartLine().toString() + "+" + delta.toString()
19+
or
20+
delta = 0 and
21+
value = "L" + allocation.getLocation().getStartLine().toString()
22+
or
23+
delta < 0 and
24+
value = "L" + allocation.getLocation().getStartLine().toString() + "-" + (-delta).toString()
25+
)
26+
}
27+
}
28+
29+
import MakeTest<AllocationToInvalidPointerTest>

cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ char *malloc(int size);
22

33
void test1(int size) {
44
char* p = malloc(size);
5-
char* q = p + size;
5+
char* q = p + size; // $ alloc=L4
66
char a = *q; // BAD
77
char b = *(q - 1); // GOOD
88
char c = *(q + 1); // BAD
@@ -14,7 +14,7 @@ void test1(int size) {
1414

1515
void test2(int size) {
1616
char* p = malloc(size);
17-
char* q = p + size - 1;
17+
char* q = p + size - 1; // $ alloc=L16
1818
char a = *q; // GOOD
1919
char b = *(q - 1); // GOOD
2020
char c = *(q + 1); // BAD
@@ -26,7 +26,7 @@ void test2(int size) {
2626

2727
void test3(int size) {
2828
char* p = malloc(size + 1);
29-
char* q = p + (size + 1);
29+
char* q = p + (size + 1); // $ alloc=L28+1
3030
char a = *q; // BAD
3131
char b = *(q - 1); // GOOD
3232
char c = *(q + 1); // BAD
@@ -38,7 +38,7 @@ void test3(int size) {
3838

3939
void test4(int size) {
4040
char* p = malloc(size - 1);
41-
char* q = p + (size - 1);
41+
char* q = p + (size - 1); // $ alloc=L40-1
4242
char a = *q; // BAD
4343
char b = *(q - 1); // GOOD
4444
char c = *(q + 1); // BAD
@@ -50,7 +50,7 @@ void test4(int size) {
5050

5151
char* mk_array(int size, char** end) {
5252
char* begin = malloc(size);
53-
*end = begin + size;
53+
*end = begin + size; // $ alloc=L52
5454

5555
return begin;
5656
}
@@ -80,7 +80,7 @@ struct array_t {
8080
array_t mk_array(int size) {
8181
array_t arr;
8282
arr.begin = malloc(size);
83-
arr.end = arr.begin + size;
83+
arr.end = arr.begin + size; // $ alloc=L82
8484

8585
return arr;
8686
}
@@ -123,7 +123,7 @@ void test8(int size) {
123123
array_t arr;
124124
char* p = malloc(size);
125125
arr.begin = p;
126-
arr.end = p + size;
126+
arr.end = p + size; // $ alloc=L124
127127

128128
for (int i = 0; i < arr.end - arr.begin; i++) {
129129
*(arr.begin + i) = 0; // GOOD
@@ -141,7 +141,7 @@ void test8(int size) {
141141
array_t *mk_array_p(int size) {
142142
array_t *arr = (array_t*) malloc(sizeof(array_t));
143143
arr->begin = malloc(size);
144-
arr->end = arr->begin + size;
144+
arr->end = arr->begin + size; // $ alloc=L143
145145

146146
return arr;
147147
}
@@ -186,13 +186,13 @@ void deref_plus_one(char* q) {
186186

187187
void test11(unsigned size) {
188188
char *p = malloc(size);
189-
char *q = p + size - 1;
189+
char *q = p + size - 1; // $ alloc=L188
190190
deref_plus_one(q);
191191
}
192192

193193
void test12(unsigned len, unsigned index) {
194194
char* p = (char *)malloc(len);
195-
char* end = p + len;
195+
char* end = p + len; // $ alloc=L194
196196

197197
if(p + index > end) {
198198
return;
@@ -203,7 +203,7 @@ void test12(unsigned len, unsigned index) {
203203

204204
void test13(unsigned len, unsigned index) {
205205
char* p = (char *)malloc(len);
206-
char* end = p + len;
206+
char* end = p + len; // $ alloc=L205
207207

208208
char* q = p + index;
209209
if(q > end) {
@@ -229,14 +229,14 @@ void test15(unsigned index) {
229229
return;
230230
}
231231
int* newname = new int[size];
232-
newname[index] = 0; // GOOD [FALSE POSITIVE]
232+
newname[index] = 0; // $ alloc=L231 // GOOD [FALSE POSITIVE]
233233
}
234234

235235
void test16(unsigned index) {
236236
unsigned size = index + 13;
237237
if(size >= index) {
238238
int* newname = new int[size];
239-
newname[index] = 0; // GOOD [FALSE POSITIVE]
239+
newname[index] = 0; // $ alloc=L238 // GOOD [FALSE POSITIVE]
240240
}
241241
}
242242

@@ -251,14 +251,14 @@ void test17(unsigned *p, unsigned x, unsigned k) {
251251
// The following access is okay because:
252252
// n = 3*p[0] + k >= p[0] + k >= p[1] + k > p[1] = i
253253
// (where p[0] denotes the original value for p[0])
254-
p[i] = x; // GOOD [FALSE POSITIVE]
254+
p[i] = x; // $ alloc=L248 // GOOD [FALSE POSITIVE]
255255
}
256256
}
257257

258258
void test17(unsigned len)
259259
{
260260
int *xs = new int[len];
261-
int *end = xs + len;
261+
int *end = xs + len; // $ alloc=L260
262262
for (int *x = xs; x <= end; x++)
263263
{
264264
int i = *x; // BAD
@@ -268,7 +268,7 @@ void test17(unsigned len)
268268
void test18(unsigned len)
269269
{
270270
int *xs = new int[len];
271-
int *end = xs + len;
271+
int *end = xs + len; // $ alloc=L270
272272
for (int *x = xs; x <= end; x++)
273273
{
274274
*x = 0; // BAD
@@ -278,7 +278,7 @@ void test18(unsigned len)
278278
void test19(unsigned len)
279279
{
280280
int *xs = new int[len];
281-
int *end = xs + len;
281+
int *end = xs + len; // $ alloc=L280
282282
for (int *x = xs; x < end; x++)
283283
{
284284
int i = *x; // GOOD
@@ -288,7 +288,7 @@ void test19(unsigned len)
288288
void test20(unsigned len)
289289
{
290290
int *xs = new int[len];
291-
int *end = xs + len;
291+
int *end = xs + len; // $ alloc=L290
292292
for (int *x = xs; x < end; x++)
293293
{
294294
*x = 0; // GOOD
@@ -305,13 +305,13 @@ void test21() {
305305

306306
for (int i = 0; i < n; i += 2) {
307307
xs[i] = test21_get(i); // GOOD
308-
xs[i+1] = test21_get(i+1); // GOOD [FALSE POSITIVE]
308+
xs[i+1] = test21_get(i+1); // $ alloc=L304 alloc=L304-1 // GOOD [FALSE POSITIVE]
309309
}
310310
}
311311

312312
void test22(unsigned size, int val) {
313313
char *xs = new char[size];
314-
char *end = xs + size; // GOOD
314+
char *end = xs + size; // $ alloc=L313 // GOOD
315315
char **current = &end;
316316
do {
317317
if (*current - xs < 1) // GOOD
@@ -323,7 +323,7 @@ void test22(unsigned size, int val) {
323323

324324
void test23(unsigned size, int val) {
325325
char *xs = new char[size];
326-
char *end = xs + size;
326+
char *end = xs + size; // $ alloc=L325
327327
char **current = &end;
328328

329329
if (val < 1) {
@@ -345,15 +345,15 @@ void test23(unsigned size, int val) {
345345

346346
void test24(unsigned size) {
347347
char *xs = new char[size];
348-
char *end = xs + size;
348+
char *end = xs + size; // $ alloc=L347
349349
if (xs < end) {
350350
int val = *xs++; // GOOD
351351
}
352352
}
353353

354354
void test25(unsigned size) {
355355
char *xs = new char[size];
356-
char *end = xs + size;
356+
char *end = xs + size; // $ alloc=L355
357357
char *end_plus_one = end + 1;
358358
int val1 = *end_plus_one; // BAD
359359
int val2 = *(end_plus_one + 1); // BAD
@@ -362,7 +362,7 @@ void test25(unsigned size) {
362362
void test26(unsigned size) {
363363
char *xs = new char[size];
364364
char *p = xs;
365-
char *end = p + size;
365+
char *end = p + size; // $ alloc=L363
366366

367367
if (p + 4 <= end) {
368368
p += 4;
@@ -375,7 +375,7 @@ void test26(unsigned size) {
375375

376376
void test27(unsigned size, bool b) {
377377
char *xs = new char[size];
378-
char *end = xs + size;
378+
char *end = xs + size; // $ alloc=L377
379379

380380
if (b) {
381381
end++;
@@ -386,7 +386,7 @@ void test27(unsigned size, bool b) {
386386

387387
void test28(unsigned size) {
388388
char *xs = new char[size];
389-
char *end = &xs[size];
389+
char *end = &xs[size]; // $ alloc=L388
390390
if (xs >= end)
391391
return;
392392
xs++;
@@ -397,7 +397,7 @@ void test28(unsigned size) {
397397

398398
void test28_simple(unsigned size) {
399399
char *xs = new char[size];
400-
char *end = &xs[size];
400+
char *end = &xs[size]; // $ alloc=L399
401401
if (xs < end) {
402402
xs++;
403403
if (xs < end) {
@@ -408,7 +408,7 @@ void test28_simple(unsigned size) {
408408

409409
void test28_simple2(unsigned size) {
410410
char *xs = new char[size];
411-
char *end = &xs[size];
411+
char *end = &xs[size]; // $ alloc=L410
412412
if (xs < end) {
413413
xs++;
414414
if (xs < end + 1) {
@@ -419,7 +419,7 @@ void test28_simple2(unsigned size) {
419419

420420
void test28_simple3(unsigned size) {
421421
char *xs = new char[size];
422-
char *end = &xs[size];
422+
char *end = &xs[size]; // $ alloc=L421
423423
if (xs < end) {
424424
xs++;
425425
if (xs - 1 < end) {
@@ -430,7 +430,7 @@ void test28_simple3(unsigned size) {
430430

431431
void test28_simple4(unsigned size) {
432432
char *xs = new char[size];
433-
char *end = &xs[size];
433+
char *end = &xs[size]; // $ alloc=L432
434434
if (xs < end) {
435435
end++;
436436
xs++;
@@ -442,7 +442,7 @@ void test28_simple4(unsigned size) {
442442

443443
void test28_simple5(unsigned size) {
444444
char *xs = new char[size];
445-
char *end = &xs[size];
445+
char *end = &xs[size]; // $ alloc=L444
446446
end++;
447447
if (xs < end) {
448448
xs++;
@@ -466,7 +466,7 @@ void test28_simple6(unsigned size) {
466466

467467
void test28_simple7(unsigned size) {
468468
char *xs = new char[size];
469-
char *end = &xs[size];
469+
char *end = &xs[size]; // $ alloc=L468
470470
end++;
471471
if (xs < end) {
472472
xs++;
@@ -478,7 +478,7 @@ void test28_simple7(unsigned size) {
478478

479479
void test28_simple8(unsigned size) {
480480
char *xs = new char[size];
481-
char *end = &xs[size];
481+
char *end = &xs[size]; // $ alloc=L480
482482
end += 500;
483483
if (xs < end) {
484484
xs++;
@@ -545,7 +545,7 @@ void test31_simple2(unsigned size, unsigned src_pos)
545545
src_pos = size;
546546
}
547547
if (src_pos < size + 1) {
548-
xs[src_pos] = 0; // BAD
548+
xs[src_pos] = 0; // $ alloc=L543 // BAD
549549
}
550550
}
551551

@@ -556,7 +556,7 @@ void test31_simple3(unsigned size, unsigned src_pos)
556556
src_pos = size;
557557
}
558558
if (src_pos - 1 < size) {
559-
xs[src_pos] = 0; // BAD
559+
xs[src_pos] = 0; // $ alloc=L554 // BAD
560560
}
561561
}
562562

@@ -644,13 +644,13 @@ void test31_simple1_sub1(unsigned size, unsigned src_pos)
644644
src_pos = size;
645645
}
646646
if (src_pos < size) {
647-
xs[src_pos] = 0; // BAD
647+
xs[src_pos] = 0; // $ alloc=L642-1 // BAD
648648
}
649649
}
650650

651651
void test32(unsigned size) {
652652
char *xs = new char[size];
653-
char *end = &xs[size];
653+
char *end = &xs[size]; // $ alloc=L652
654654
if (xs >= end)
655655
return;
656656
xs++;
@@ -672,12 +672,12 @@ void test33(unsigned size, unsigned src_pos)
672672
while (dst_pos < size - 1) {
673673
dst_pos++;
674674
if (true)
675-
xs[dst_pos++] = 0; // GOOD [FALSE POSITIVE]
675+
xs[dst_pos++] = 0; // $ alloc=L667+1 // GOOD [FALSE POSITIVE]
676676
}
677677
}
678678

679679
int* pointer_arithmetic(int *p, int offset) {
680-
return p + offset;
680+
return p + offset; // $ alloc=L684
681681
}
682682

683683
void test_missing_call_context_1(unsigned size) {

0 commit comments

Comments
 (0)