Skip to content

Commit cd2c65b

Browse files
authored
Merge pull request #5210 from xbauch/fix/malloc-size-too-large
Malloc should fail on too large allocations
2 parents 5568f64 + 195da86 commit cd2c65b

File tree

27 files changed

+179
-38
lines changed

27 files changed

+179
-38
lines changed

doc/cprover-manual/properties.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,3 +319,19 @@ example, replacing functions or setting global variables with the `__CPROVER`
319319
prefix might make analysis impossible. To avoid doing this by accident, negative
320320
lookahead can be used. For example, `(?!__).*` matches all names not starting
321321
with `__`.
322+
323+
### Malloc failure mode
324+
325+
|Flag | Check |
326+
|------------------------|-------------------------------------------------|
327+
| `--malloc-fail-null` | in case malloc fails return NULL |
328+
| `--malloc-fail-assert` | in case malloc fails report as failed property |
329+
330+
Calling `malloc` may fail for a number of reasons and the function may return a
331+
NULL pointer. The users can choose if and how they want the `malloc`-related
332+
failures to occur. The option `--malloc-fail-null` results in `malloc` returning
333+
the NULL pointer when failing. The option `--malloc-fail-assert` places
334+
additional properties inside `malloc` that are checked and if failing the
335+
verification is terminated (by `assume(false)`). One such property is that the
336+
allocated size is not too large, i.e. internally representable. When neither of
337+
those two options are used, CBMC will assume that `malloc` does not fail.

regression/cbmc/Pointer_byte_extract5/main.i

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ typedef union
1111
typedef struct
1212
{
1313
int Count;
14-
Union List[1];
14+
// flexible array member -- note that smt conversion does not yet support
15+
// 0-sized arrays
16+
Union List[0];
1517
} Struct3;
1618
#pragma pack(pop)
1719

1820
int main()
1921
{
20-
Struct3 *p = malloc(sizeof(Struct3) + sizeof(Union));
22+
Struct3 *p = malloc(sizeof(Struct3) + 2 * sizeof(Union));
2123
p->Count = 3;
2224
int po=0;
2325

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
CORE
1+
CORE broken-smt-backend
22
main.i
33
--bounds-check --32 --no-simplify
44
^EXIT=10$
55
^SIGNAL=0$
66
array\.List dynamic object upper bound in p->List\[2\]: FAILURE
7-
\*\* 1 of 14 failed
7+
\*\* 1 of 15 failed
88
--
99
^warning: ignoring
1010
--
1111
Test is built from SV-COMP's memsafety/20051113-1.c_false-valid-memtrack.c.
1212
C90 did not have flexible arrays, and using arrays of size 1 was common
13-
practice: http://c-faq.com/struct/structhack.html. We need to treat those as if
14-
it were a zero-sized array.
13+
practice: http://c-faq.com/struct/structhack.html. But past C90 using
14+
non-flexible members for struct-hack is undefined, hence we changed the test to
15+
use flexible member instead.

regression/cbmc/Pointer_byte_extract5/test.desc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ main.i
44
^EXIT=10$
55
^SIGNAL=0$
66
array\.List dynamic object upper bound in p->List\[2\]: FAILURE
7-
\*\* 1 of 11 failed
7+
\*\* 1 of 13 failed
88
--
99
^warning: ignoring
1010
--
1111
Test is built from SV-COMP's memsafety/20051113-1.c_false-valid-memtrack.c.
1212
C90 did not have flexible arrays, and using arrays of size 1 was common
13-
practice: http://c-faq.com/struct/structhack.html. We need to treat those as if
14-
it were a zero-sized array.
13+
practice: http://c-faq.com/struct/structhack.html. But past C90 using
14+
non-flexible members for struct-hack is undefined, hence we changed the test to
15+
use flexible member instead.

regression/cbmc/array_constraints1/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ main.c
44
^EXIT=10$
55
^SIGNAL=0$
66
^VERIFICATION FAILED$
7-
^\*\* 2 of 14
7+
^\*\* 2 of 15
88
--
99
^warning: ignoring
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include <assert.h>
2+
#include <stdint.h>
3+
#include <stdlib.h>
4+
5+
int main()
6+
{
7+
int *p = malloc(__CPROVER_max_malloc_size); // try to allocate exactly the max
8+
9+
return 0;
10+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
largest_representable.c
3+
--malloc-fail-assert
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^\[malloc.assertion.\d+\] line \d+ max allocation size exceeded: SUCCESS$
7+
^VERIFICATION SUCCESSFUL$
8+
--
9+
^warning: ignoring
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include <assert.h>
2+
#include <stdint.h>
3+
#include <stdlib.h>
4+
5+
int main()
6+
{
7+
int *p = malloc(SIZE_MAX);
8+
9+
return 0;
10+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
max_size.c
3+
--malloc-fail-assert
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^\[malloc.assertion.\d+\] line \d+ max allocation size exceeded: FAILURE$
7+
^VERIFICATION FAILED$
8+
--
9+
^warning: ignoring
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <assert.h>
2+
#include <stdint.h>
3+
#include <stdlib.h>
4+
5+
int main()
6+
{
7+
// try to allocate the smallest violating amount
8+
int *p = malloc(__CPROVER_max_malloc_size + 1);
9+
assert(p);
10+
11+
return 0;
12+
}

0 commit comments

Comments
 (0)