Skip to content

Commit f066694

Browse files
tautschnigmarek-trtik
authored andcommitted
Constrain the malloc/alloca size to fit our object:offset encoding
See diffblue#311 for an extended discussion.
1 parent 2548e7f commit f066694

File tree

2 files changed

+61
-20
lines changed

2 files changed

+61
-20
lines changed

src/ansi-c/library/new.c

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ inline void *__new(__typeof__(sizeof(int)) malloc_size)
88
// This just does memory allocation.
99
__CPROVER_HIDE:;
1010
void *res;
11+
// ensure that all bytes in the allocated memory can be addressed
12+
// using our object:offset encoding as specified in
13+
// flattening/pointer_logic.h; also avoid sign-extension issues
14+
// for 32-bit systems that yields a maximum allocation of 2^23-1,
15+
// i.e., just under 8MB
16+
__CPROVER_assume(malloc_size < (1ULL << ((sizeof(char*) - 1) * 8 - 1)));
1117
res = __CPROVER_allocate(malloc_size, 0);
1218

1319
// ensure it's not recorded as deallocated
@@ -34,22 +40,32 @@ inline void *__new_array(__CPROVER_size_t count, __CPROVER_size_t size)
3440
{
3541
// The constructor call is done by the front-end.
3642
// This just does memory allocation.
37-
__CPROVER_HIDE:;
43+
44+
__CPROVER_HIDE:;
45+
46+
// ensure that all bytes in the allocated memory can be addressed
47+
// using our object:offset encoding as specified in
48+
// flattening/pointer_logic.h; also avoid sign-extension issues
49+
// for 32-bit systems that yields a maximum allocation of 2^23-1,
50+
// i.e., just under 8MB
51+
__CPROVER_assume(size * count < (1ULL << ((sizeof(char*) - 1) * 8 - 1)));
3852
void *res;
39-
res = __CPROVER_allocate(size*count, 0);
53+
res = __CPROVER_allocate(size * count, 0);
4054

4155
// ensure it's not recorded as deallocated
42-
__CPROVER_deallocated=(res==__CPROVER_deallocated)?0:__CPROVER_deallocated;
56+
__CPROVER_deallocated =
57+
(res == __CPROVER_deallocated) ? 0 : __CPROVER_deallocated;
4358

4459
// non-deterministically record the object size for bounds checking
45-
__CPROVER_bool record_malloc=__VERIFIER_nondet___CPROVER_bool();
46-
__CPROVER_malloc_object=record_malloc?res:__CPROVER_malloc_object;
47-
__CPROVER_malloc_size=record_malloc?size*count:__CPROVER_malloc_size;
48-
__CPROVER_malloc_is_new_array=record_malloc?1:__CPROVER_malloc_is_new_array;
60+
__CPROVER_bool record_malloc = __VERIFIER_nondet___CPROVER_bool();
61+
__CPROVER_malloc_object = record_malloc ? res : __CPROVER_malloc_object;
62+
__CPROVER_malloc_size = record_malloc ? size * count : __CPROVER_malloc_size;
63+
__CPROVER_malloc_is_new_array =
64+
record_malloc ? 1 : __CPROVER_malloc_is_new_array;
4965

5066
// detect memory leaks
51-
__CPROVER_bool record_may_leak=__VERIFIER_nondet___CPROVER_bool();
52-
__CPROVER_memory_leak=record_may_leak?res:__CPROVER_memory_leak;
67+
__CPROVER_bool record_may_leak = __VERIFIER_nondet___CPROVER_bool();
68+
__CPROVER_memory_leak = record_may_leak ? res : __CPROVER_memory_leak;
5369

5470
return res;
5571
}

src/ansi-c/library/stdlib.c

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,17 @@ __CPROVER_bool __VERIFIER_nondet___CPROVER_bool();
6565

6666
inline void *calloc(__CPROVER_size_t nmemb, __CPROVER_size_t size)
6767
{
68-
// realistically, calloc may return NULL,
69-
// and __CPROVER_allocate doesn't, but no one cares
70-
__CPROVER_HIDE:;
68+
// realistically, calloc may return NULL,
69+
// and __CPROVER_allocate doesn't, but no one cares
70+
71+
__CPROVER_HIDE:;
72+
73+
// ensure that all bytes in the allocated memory can be addressed
74+
// using our object:offset encoding as specified in
75+
// flattening/pointer_logic.h; also avoid sign-extension issues
76+
// for 32-bit systems that yields a maximum allocation of 2^23-1,
77+
// i.e., just under 8MB
78+
__CPROVER_assume(nmemb * size < (1ULL << ((sizeof(char*) - 1) * 8 - 1)));
7179
void *malloc_res;
7280
malloc_res = __CPROVER_allocate(nmemb * size, 1);
7381

@@ -104,8 +112,16 @@ __CPROVER_bool __VERIFIER_nondet___CPROVER_bool();
104112
inline void *malloc(__CPROVER_size_t malloc_size)
105113
{
106114
// realistically, malloc may return NULL,
107-
// and __CPROVER_allocate doesn't, but no one cares
108-
__CPROVER_HIDE:;
115+
// and __CPROVER_allocate doesn't, but no one cares
116+
117+
__CPROVER_HIDE:;
118+
119+
// ensure that all bytes in the allocated memory can be addressed
120+
// using our object:offset encoding as specified in
121+
// flattening/pointer_logic.h; also avoid sign-extension issues
122+
// for 32-bit systems that yields a maximum allocation of 2^23-1,
123+
// i.e., just under 8MB
124+
__CPROVER_assume(malloc_size < (1ULL << ((sizeof(char*) - 1) * 8 - 1)));
109125
void *malloc_res;
110126
malloc_res = __CPROVER_allocate(malloc_size, 0);
111127

@@ -131,18 +147,27 @@ __CPROVER_bool __VERIFIER_nondet___CPROVER_bool();
131147

132148
inline void *__builtin_alloca(__CPROVER_size_t alloca_size)
133149
{
134-
__CPROVER_HIDE:;
150+
__CPROVER_HIDE:;
151+
152+
// ensure that all bytes in the allocated memory can be addressed
153+
// using our object:offset encoding as specified in
154+
// flattening/pointer_logic.h; also avoid sign-extension issues
155+
// for 32-bit systems that yields a maximum allocation of 2^23-1,
156+
// i.e., just under 8MB
157+
__CPROVER_assume(alloca_size < (1ULL << ((sizeof(char*) - 1) * 8 - 1)));
135158
void *res;
136159
res = __CPROVER_allocate(alloca_size, 0);
137160

138161
// make sure it's not recorded as deallocated
139-
__CPROVER_deallocated=(res==__CPROVER_deallocated)?0:__CPROVER_deallocated;
162+
__CPROVER_deallocated =
163+
(res == __CPROVER_deallocated) ? 0 : __CPROVER_deallocated;
140164

141165
// record the object size for non-determistic bounds checking
142-
__CPROVER_bool record_malloc=__VERIFIER_nondet___CPROVER_bool();
143-
__CPROVER_malloc_object=record_malloc?res:__CPROVER_malloc_object;
144-
__CPROVER_malloc_size=record_malloc?alloca_size:__CPROVER_malloc_size;
145-
__CPROVER_malloc_is_new_array=record_malloc?0:__CPROVER_malloc_is_new_array;
166+
__CPROVER_bool record_malloc = __VERIFIER_nondet___CPROVER_bool();
167+
__CPROVER_malloc_object = record_malloc ? res : __CPROVER_malloc_object;
168+
__CPROVER_malloc_size = record_malloc ? alloca_size : __CPROVER_malloc_size;
169+
__CPROVER_malloc_is_new_array =
170+
record_malloc ? 0 : __CPROVER_malloc_is_new_array;
146171

147172
return res;
148173
}

0 commit comments

Comments
 (0)