Skip to content

Commit d18fb64

Browse files
committed
C++: handle cast arrays properly in off-by-one query
1 parent 6e230e1 commit d18fb64

File tree

3 files changed

+7
-4
lines changed

3 files changed

+7
-4
lines changed

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,7 @@ predicate isInvalidPointerDerefSink2(DataFlow::Node sink, Instruction i, string
8181
predicate pointerArithOverflow0(
8282
PointerArithmeticInstruction pai, Variable v, int size, int bound, int delta
8383
) {
84-
pai.getElementSize() = v.getUnspecifiedType().(ArrayType).getBaseType().getSize() and
85-
v.getUnspecifiedType().(ArrayType).getArraySize() = size and
84+
v.getUnspecifiedType().(ArrayType).getByteSize() / pai.getElementSize() = size and
8685
semBounded(getSemanticExpr(pai.getRight()), any(SemZeroBound b), bound, true, _) and
8786
delta = bound - size and
8887
delta >= 0 and
@@ -162,7 +161,7 @@ from
162161
Variable v, ArrayAddressToDerefFlow::PathNode source, PointerArithmeticInstruction pai,
163162
ArrayAddressToDerefFlow::PathNode sink, Instruction deref, string operation, int delta
164163
where
165-
ArrayAddressToDerefFlow::flowPath(source, sink) and
164+
ArrayAddressToDerefFlow::flowPath(source, sink) and
166165
isInvalidPointerDerefSink2(sink.getNode(), deref, operation) and
167166
source.getState() = ArrayAddressToDerefConfig::TArray(v) and
168167
sink.getState() = ArrayAddressToDerefConfig::TOverflowArithmetic(pai) and

cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/constant-size/ConstantSizeArrayOffByOne.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ edges
1111
| test.cpp:77:32:77:34 | buf | test.cpp:77:26:77:44 | & ... |
1212
| test.cpp:79:27:79:34 | buf | test.cpp:70:33:70:33 | p |
1313
| test.cpp:79:32:79:34 | buf | test.cpp:79:27:79:34 | buf |
14+
| test.cpp:85:34:85:36 | buf | test.cpp:88:5:88:27 | access to array |
1415
| test.cpp:128:9:128:11 | arr | test.cpp:128:9:128:14 | access to array |
1516
nodes
1617
| test.cpp:35:5:35:22 | access to array | semmle.label | access to array |
@@ -34,6 +35,8 @@ nodes
3435
| test.cpp:77:32:77:34 | buf | semmle.label | buf |
3536
| test.cpp:79:27:79:34 | buf | semmle.label | buf |
3637
| test.cpp:79:32:79:34 | buf | semmle.label | buf |
38+
| test.cpp:85:34:85:36 | buf | semmle.label | buf |
39+
| test.cpp:88:5:88:27 | access to array | semmle.label | access to array |
3740
| test.cpp:128:9:128:11 | arr | semmle.label | arr |
3841
| test.cpp:128:9:128:14 | access to array | semmle.label | access to array |
3942
subpaths
@@ -47,4 +50,5 @@ subpaths
4750
| test.cpp:61:9:61:19 | PointerAdd: access to array | test.cpp:61:14:61:16 | buf | test.cpp:61:9:61:19 | access to array | This pointer arithmetic may have an off-by-2 error allowing it to overrun $@ at this $@. | test.cpp:19:9:19:11 | buf | buf | test.cpp:61:9:61:23 | Store: ... = ... | write |
4851
| test.cpp:72:5:72:15 | PointerAdd: access to array | test.cpp:79:32:79:34 | buf | test.cpp:72:5:72:15 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:72:5:72:19 | Store: ... = ... | write |
4952
| test.cpp:77:27:77:44 | PointerAdd: access to array | test.cpp:77:32:77:34 | buf | test.cpp:66:32:66:32 | p | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:67:5:67:10 | Store: ... = ... | write |
53+
| test.cpp:88:5:88:27 | PointerAdd: access to array | test.cpp:85:34:85:36 | buf | test.cpp:88:5:88:27 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:88:5:88:31 | Store: ... = ... | write |
5054
| test.cpp:128:9:128:14 | PointerAdd: access to array | test.cpp:128:9:128:11 | arr | test.cpp:128:9:128:14 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:125:11:125:13 | arr | arr | test.cpp:128:9:128:18 | Store: ... = ... | write |

cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/constant-size/test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ void testCharIndex(BigArray *arr) {
8585
char *charBuf = (char*) arr->buf;
8686

8787
charBuf[MAX_SIZE_BYTES - 1] = 0; // GOOD
88-
charBuf[MAX_SIZE_BYTES] = 0; // BAD [FALSE NEGATIVE]
88+
charBuf[MAX_SIZE_BYTES] = 0; // BAD
8989
}
9090

9191
void testEqRefinement() {

0 commit comments

Comments
 (0)