Skip to content

Commit 93215ba

Browse files
authored
Merge pull request github#13355 from jketema/ptr-deref-forward
C++: Ensure that the sink instruction occurs last in `cpp/invalid-pointer-deref`
2 parents dc26dc8 + 7f7b048 commit 93215ba

File tree

3 files changed

+25
-11
lines changed

3 files changed

+25
-11
lines changed

cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,15 +179,34 @@ predicate isSinkImpl(
179179
pointerAddInstructionHasBounds(pai, sink1, sink2, delta)
180180
}
181181

182+
/**
183+
* Yields any instruction that is control-flow reachable from `instr`.
184+
*/
185+
bindingset[instr, result]
186+
pragma[inline_late]
187+
Instruction getASuccessor(Instruction instr) {
188+
exists(IRBlock b, int instrIndex, int resultIndex |
189+
result.getBlock() = b and
190+
instr.getBlock() = b and
191+
b.getInstruction(instrIndex) = instr and
192+
b.getInstruction(resultIndex) = result
193+
|
194+
resultIndex >= instrIndex
195+
)
196+
or
197+
instr.getBlock().getASuccessor+() = result.getBlock()
198+
}
199+
182200
/**
183201
* Holds if `sink` is a sink for `InvalidPointerToDerefConfig` and `i` is a `StoreInstruction` that
184202
* writes to an address that non-strictly upper-bounds `sink`, or `i` is a `LoadInstruction` that
185203
* reads from an address that non-strictly upper-bounds `sink`.
186204
*/
187205
pragma[inline]
188206
predicate isInvalidPointerDerefSink(DataFlow::Node sink, Instruction i, string operation, int delta) {
189-
exists(AddressOperand addr |
190-
bounded1(addr.getDef(), sink.asInstruction(), delta) and
207+
exists(AddressOperand addr, Instruction s |
208+
s = sink.asInstruction() and
209+
bounded1(addr.getDef(), s, delta) and
191210
delta >= 0 and
192211
i.getAnOperand() = addr
193212
|
@@ -247,7 +266,8 @@ newtype TMergedPathNode =
247266
TPathNodeSink(Instruction i) {
248267
exists(DataFlow::Node n |
249268
InvalidPointerToDerefFlow::flowTo(n) and
250-
isInvalidPointerDerefSink(n, i, _, _)
269+
isInvalidPointerDerefSink(n, i, _, _) and
270+
i = getASuccessor(n.asInstruction())
251271
)
252272
}
253273

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -663,8 +663,6 @@ edges
663663
| test.cpp:326:15:326:23 | ... + ... | test.cpp:342:8:342:17 | * ... |
664664
| test.cpp:338:8:338:15 | * ... | test.cpp:342:8:342:17 | * ... |
665665
| test.cpp:341:8:341:17 | * ... | test.cpp:342:8:342:17 | * ... |
666-
| test.cpp:342:8:342:17 | * ... | test.cpp:333:5:333:21 | Store: ... = ... |
667-
| test.cpp:342:8:342:17 | * ... | test.cpp:341:5:341:21 | Store: ... = ... |
668666
| test.cpp:347:14:347:27 | new[] | test.cpp:348:15:348:16 | xs |
669667
| test.cpp:348:15:348:16 | xs | test.cpp:350:16:350:19 | ... ++ |
670668
| test.cpp:348:15:348:16 | xs | test.cpp:350:16:350:19 | ... ++ |
@@ -1031,9 +1029,7 @@ nodes
10311029
| test.cpp:326:15:326:16 | xs | semmle.label | xs |
10321030
| test.cpp:326:15:326:23 | ... + ... | semmle.label | ... + ... |
10331031
| test.cpp:326:15:326:23 | ... + ... | semmle.label | ... + ... |
1034-
| test.cpp:333:5:333:21 | Store: ... = ... | semmle.label | Store: ... = ... |
10351032
| test.cpp:338:8:338:15 | * ... | semmle.label | * ... |
1036-
| test.cpp:341:5:341:21 | Store: ... = ... | semmle.label | Store: ... = ... |
10371033
| test.cpp:341:8:341:17 | * ... | semmle.label | * ... |
10381034
| test.cpp:342:8:342:17 | * ... | semmle.label | * ... |
10391035
| test.cpp:347:14:347:27 | new[] | semmle.label | new[] |
@@ -1088,8 +1084,6 @@ subpaths
10881084
| test.cpp:264:13:264:14 | Load: * ... | test.cpp:260:13:260:24 | new[] | test.cpp:264:13:264:14 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:260:13:260:24 | new[] | new[] | test.cpp:261:19:261:21 | len | len |
10891085
| test.cpp:274:5:274:10 | Store: ... = ... | test.cpp:270:13:270:24 | new[] | test.cpp:274:5:274:10 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:270:13:270:24 | new[] | new[] | test.cpp:271:19:271:21 | len | len |
10901086
| test.cpp:308:5:308:29 | Store: ... = ... | test.cpp:304:15:304:26 | new[] | test.cpp:308:5:308:29 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:304:15:304:26 | new[] | new[] | test.cpp:308:8:308:10 | ... + ... | ... + ... |
1091-
| test.cpp:333:5:333:21 | Store: ... = ... | test.cpp:325:14:325:27 | new[] | test.cpp:333:5:333:21 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:325:14:325:27 | new[] | new[] | test.cpp:326:20:326:23 | size | size |
1092-
| test.cpp:341:5:341:21 | Store: ... = ... | test.cpp:325:14:325:27 | new[] | test.cpp:341:5:341:21 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:325:14:325:27 | new[] | new[] | test.cpp:326:20:326:23 | size | size |
10931087
| test.cpp:350:15:350:19 | Load: * ... | test.cpp:347:14:347:27 | new[] | test.cpp:350:15:350:19 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:347:14:347:27 | new[] | new[] | test.cpp:348:20:348:23 | size | size |
10941088
| test.cpp:358:14:358:26 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:358:14:358:26 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size |
10951089
| test.cpp:359:14:359:32 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:359:14:359:32 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 2. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size |

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,15 +330,15 @@ void test23(unsigned size, int val) {
330330
if(*current - xs < 1)
331331
return;
332332

333-
*--(*current) = 0; // GOOD [FALSE POSITIVE]
333+
*--(*current) = 0; // GOOD
334334
return;
335335
}
336336

337337
if (val < 2) {
338338
if(*current - xs < 2)
339339
return;
340340

341-
*--(*current) = 0; // GOOD [FALSE POSITIVE]
341+
*--(*current) = 0; // GOOD
342342
*--(*current) = 0; // GOOD
343343
}
344344
}

0 commit comments

Comments
 (0)