Skip to content

Commit 1354beb

Browse files
committed
C++: Fix an issue with padding.
1 parent dbab845 commit 1354beb

File tree

3 files changed

+11
-8
lines changed

3 files changed

+11
-8
lines changed

cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ private int getSize(VariableAccess va) {
7171
result = t.getSize()
7272
)
7373
or
74-
exists(Class c |
74+
exists(Class c, int trueSize |
7575
// Otherwise, we find the "outermost" object and compute the size
7676
// as the difference between the size of the type of the "outermost
7777
// object" and the offset of the field relative to that type.
@@ -91,7 +91,9 @@ private int getSize(VariableAccess va) {
9191
// of `y` relative to the type `S2` (i.e., `4`). So the size of the
9292
// buffer is `12 - 4 = 8`.
9393
c = getRootType(va) and
94-
result = c.getSize() - v.(Field).getOffsetInClass(c)
94+
// we calculate the size based on the last field, to avoid including any padding after it
95+
trueSize = max(Field f | f = c.getAField() | f.getOffsetInClass(c) + f.getUnspecifiedType().getSize()) and
96+
result = trueSize - v.(Field).getOffsetInClass(c)
9597
)
9698
)
9799
}

cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/VeryLikelyOverrunWrite.expected

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,17 @@
1616
| tests.c:136:2:136:8 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 10 bytes. |
1717
| tests.c:186:3:186:9 | call to sprintf | This 'call to sprintf' operation requires 9 bytes but the destination is only 2 bytes. |
1818
| tests.c:189:3:189:9 | call to sprintf | This 'call to sprintf' operation requires 3 bytes but the destination is only 2 bytes. |
19-
| unions.c:26:2:26:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 16 bytes. |
20-
| unions.c:27:2:27:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 16 bytes. |
19+
| unions.c:26:2:26:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 15 bytes. |
20+
| unions.c:27:2:27:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 15 bytes. |
2121
| var_size_struct.cpp:22:3:22:8 | call to strcpy | This 'call to strcpy' operation requires 10 bytes but the destination is only 9 bytes. |
2222
| varbuffer.c:15:5:15:10 | call to strcpy | This 'call to strcpy' operation requires 2 bytes but the destination is only 1 bytes. |
2323
| varbuffer.c:16:5:16:10 | call to strcpy | This 'call to strcpy' operation requires 10 bytes but the destination is only 1 bytes. |
2424
| varbuffer.c:23:5:23:10 | call to strcpy | This 'call to strcpy' operation requires 12 bytes but the destination is only 11 bytes. |
2525
| varbuffer.c:24:5:24:10 | call to strcpy | This 'call to strcpy' operation requires 17 bytes but the destination is only 11 bytes. |
26-
| varbuffer.c:40:5:40:10 | call to strcpy | This 'call to strcpy' operation requires 10 bytes but the destination is only 4 bytes. |
27-
| varbuffer.c:45:5:45:10 | call to strcpy | This 'call to strcpy' operation requires 10 bytes but the destination is only 4 bytes. |
28-
| varbuffer.c:46:5:46:10 | call to strcpy | This 'call to strcpy' operation requires 17 bytes but the destination is only 4 bytes. |
26+
| varbuffer.c:39:5:39:10 | call to strcpy | This 'call to strcpy' operation requires 3 bytes but the destination is only 2 bytes. |
27+
| varbuffer.c:40:5:40:10 | call to strcpy | This 'call to strcpy' operation requires 10 bytes but the destination is only 2 bytes. |
28+
| varbuffer.c:45:5:45:10 | call to strcpy | This 'call to strcpy' operation requires 10 bytes but the destination is only 2 bytes. |
29+
| varbuffer.c:46:5:46:10 | call to strcpy | This 'call to strcpy' operation requires 17 bytes but the destination is only 2 bytes. |
2930
| varbuffer.c:60:5:60:10 | call to strcpy | This 'call to strcpy' operation requires 2 bytes but the destination is only 1 bytes. |
3031
| varbuffer.c:61:5:61:10 | call to strcpy | This 'call to strcpy' operation requires 10 bytes but the destination is only 1 bytes. |
3132
| varbuffer.c:67:5:67:10 | call to strcpy | This 'call to strcpy' operation requires 17 bytes but the destination is only 11 bytes. |

cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/varbuffer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ void testMyFixedStruct()
3636
ptr1->len = 1;
3737
strcpy(ptr1->buffer, ""); // GOOD
3838
strcpy(ptr1->buffer, "1"); // GOOD
39-
strcpy(ptr1->buffer, "12"); // BAD: length 3, but destination only has length 2 [NOT DETECTED]
39+
strcpy(ptr1->buffer, "12"); // BAD: length 3, but destination only has length 2
4040
strcpy(ptr1->buffer, "123456789"); // BAD: length 10, but destination only has length 2
4141
// ...
4242

0 commit comments

Comments
 (0)