Skip to content

Commit 851cb04

Browse files
authored
Merge pull request #20193 from MathiasVP/fix-fp-in-overflow-buffer
C++: Fix FP in `cpp/overflow-buffer`
2 parents a1bc865 + b00107f commit 851cb04

File tree

4 files changed

+45
-19
lines changed

4 files changed

+45
-19
lines changed

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

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,19 +57,27 @@ private Class getRootType(FieldAccess fa) {
5757
)
5858
}
5959

60+
/**
61+
* Gets the size of `v`. This predicate does not have a result when the
62+
* unspecified type of `v` is a `ReferenceType`.
63+
*/
64+
private int getVariableSize(Variable v) {
65+
exists(Type t |
66+
t = v.getUnspecifiedType() and
67+
not t instanceof ReferenceType and
68+
result = t.getSize()
69+
)
70+
}
71+
6072
/**
6173
* Gets the size of the buffer access at `va`.
6274
*/
6375
private int getSize(VariableAccess va) {
6476
exists(Variable v | va.getTarget() = v |
6577
// If `v` is not a field then the size of the buffer is just
6678
// the size of the type of `v`.
67-
exists(Type t |
68-
t = v.getUnspecifiedType() and
69-
not v instanceof Field and
70-
not t instanceof ReferenceType and
71-
result = t.getSize()
72-
)
79+
not v instanceof Field and
80+
result = getVariableSize(v)
7381
or
7482
exists(Class c, int trueSize |
7583
// Otherwise, we find the "outermost" object and compute the size
@@ -92,7 +100,7 @@ private int getSize(VariableAccess va) {
92100
// buffer is `12 - 4 = 8`.
93101
c = getRootType(va) and
94102
// we calculate the size based on the last field, to avoid including any padding after it
95-
trueSize = max(Field f | | f.getOffsetInClass(c) + f.getUnspecifiedType().getSize()) and
103+
trueSize = max(Field f | | f.getOffsetInClass(c) + getVariableSize(f)) and
96104
result = trueSize - v.(Field).getOffsetInClass(c)
97105
)
98106
)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Fixed a false positive in `cpp/overflow-buffer` when the type of the destination buffer is a reference to a class/struct type.

cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/UnboundedWrite.expected

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ edges
2727
| main.cpp:9:29:9:32 | *argv | tests_restrict.c:15:41:15:44 | *argv | provenance | |
2828
| main.cpp:9:29:9:32 | tests_restrict_main output argument | main.cpp:10:20:10:23 | **argv | provenance | |
2929
| main.cpp:9:29:9:32 | tests_restrict_main output argument | main.cpp:10:20:10:23 | *argv | provenance | |
30-
| main.cpp:10:20:10:23 | **argv | tests.cpp:1060:32:1060:35 | **argv | provenance | |
31-
| main.cpp:10:20:10:23 | *argv | tests.cpp:1060:32:1060:35 | *argv | provenance | |
30+
| main.cpp:10:20:10:23 | **argv | tests.cpp:1074:32:1074:35 | **argv | provenance | |
31+
| main.cpp:10:20:10:23 | *argv | tests.cpp:1074:32:1074:35 | *argv | provenance | |
3232
| overflowdestination.cpp:23:45:23:48 | **argv | overflowdestination.cpp:23:45:23:48 | **argv | provenance | |
3333
| overflowdestination.cpp:23:45:23:48 | **argv | overflowdestination.cpp:23:45:23:48 | *argv | provenance | |
3434
| test_buffer_overrun.cpp:32:46:32:49 | **argv | test_buffer_overrun.cpp:32:46:32:49 | **argv | provenance | |
@@ -41,12 +41,12 @@ edges
4141
| tests.cpp:649:14:649:14 | *s [*home] | tests.cpp:649:14:649:19 | *home | provenance | |
4242
| tests.cpp:649:14:649:14 | *s [*home] | tests.cpp:649:16:649:19 | *home | provenance | |
4343
| tests.cpp:649:16:649:19 | *home | tests.cpp:649:14:649:19 | *home | provenance | |
44-
| tests.cpp:1060:32:1060:35 | **argv | tests.cpp:1085:9:1085:15 | *access to array | provenance | |
45-
| tests.cpp:1060:32:1060:35 | **argv | tests.cpp:1086:9:1086:15 | *access to array | provenance | |
46-
| tests.cpp:1060:32:1060:35 | *argv | tests.cpp:1085:9:1085:15 | *access to array | provenance | |
47-
| tests.cpp:1060:32:1060:35 | *argv | tests.cpp:1086:9:1086:15 | *access to array | provenance | |
48-
| tests.cpp:1085:9:1085:15 | *access to array | tests.cpp:634:19:634:24 | *source | provenance | |
49-
| tests.cpp:1086:9:1086:15 | *access to array | tests.cpp:643:19:643:24 | *source | provenance | |
44+
| tests.cpp:1074:32:1074:35 | **argv | tests.cpp:1099:9:1099:15 | *access to array | provenance | |
45+
| tests.cpp:1074:32:1074:35 | **argv | tests.cpp:1100:9:1100:15 | *access to array | provenance | |
46+
| tests.cpp:1074:32:1074:35 | *argv | tests.cpp:1099:9:1099:15 | *access to array | provenance | |
47+
| tests.cpp:1074:32:1074:35 | *argv | tests.cpp:1100:9:1100:15 | *access to array | provenance | |
48+
| tests.cpp:1099:9:1099:15 | *access to array | tests.cpp:634:19:634:24 | *source | provenance | |
49+
| tests.cpp:1100:9:1100:15 | *access to array | tests.cpp:643:19:643:24 | *source | provenance | |
5050
| tests_restrict.c:15:41:15:44 | **argv | tests_restrict.c:15:41:15:44 | **argv | provenance | |
5151
| tests_restrict.c:15:41:15:44 | *argv | tests_restrict.c:15:41:15:44 | *argv | provenance | |
5252
nodes
@@ -80,10 +80,10 @@ nodes
8080
| tests.cpp:649:14:649:14 | *s [*home] | semmle.label | *s [*home] |
8181
| tests.cpp:649:14:649:19 | *home | semmle.label | *home |
8282
| tests.cpp:649:16:649:19 | *home | semmle.label | *home |
83-
| tests.cpp:1060:32:1060:35 | **argv | semmle.label | **argv |
84-
| tests.cpp:1060:32:1060:35 | *argv | semmle.label | *argv |
85-
| tests.cpp:1085:9:1085:15 | *access to array | semmle.label | *access to array |
86-
| tests.cpp:1086:9:1086:15 | *access to array | semmle.label | *access to array |
83+
| tests.cpp:1074:32:1074:35 | **argv | semmle.label | **argv |
84+
| tests.cpp:1074:32:1074:35 | *argv | semmle.label | *argv |
85+
| tests.cpp:1099:9:1099:15 | *access to array | semmle.label | *access to array |
86+
| tests.cpp:1100:9:1100:15 | *access to array | semmle.label | *access to array |
8787
| tests_restrict.c:15:41:15:44 | **argv | semmle.label | **argv |
8888
| tests_restrict.c:15:41:15:44 | **argv | semmle.label | **argv |
8989
| tests_restrict.c:15:41:15:44 | *argv | semmle.label | *argv |

cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/tests.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,6 +1057,20 @@ void test30() {
10571057
strncpy(us.buffer2, "", sizeof(us) - 1); // BAD
10581058
}
10591059

1060+
struct S_Size16 {
1061+
unsigned short uint16;
1062+
unsigned char uint8;
1063+
unsigned char raw[13];
1064+
};
1065+
1066+
void test31() {
1067+
S_Size16 e;
1068+
1069+
[&e](void* data){
1070+
memcpy(&e, data, sizeof(e)); // GOOD
1071+
};
1072+
}
1073+
10601074
int tests_main(int argc, char *argv[])
10611075
{
10621076
long long arr17[19];

0 commit comments

Comments
 (0)