Skip to content

Commit 93d35cb

Browse files
committed
Constrain the malloc/alloca size to fit our object:offset encoding
See diffblue#311 for an extended discussion.
1 parent f177db5 commit 93d35cb

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

src/ansi-c/library/new.c

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

1117
// ensure it's not recorded as deallocated
@@ -31,6 +37,12 @@ inline void *__new_array(__CPROVER_size_t count, __CPROVER_size_t size)
3137
// The constructor call is done by the front-end.
3238
// This just does memory allocation.
3339
__CPROVER_HIDE:;
40+
// ensure that all bytes in the allocated memory can be addressed
41+
// using our object:offset encoding as specified in
42+
// flattening/pointer_logic.h; also avoid sign-extension issues
43+
// for 32-bit systems that yields a maximum allocation of 2^23-1,
44+
// i.e., just under 8MB
45+
__CPROVER_assume(size*count<(1UL<<((sizeof(char*)-1)*8-1)));
3446
void *res;
3547
res=__CPROVER_malloc(size*count);
3648

src/ansi-c/library/stdlib.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ inline void *malloc(__CPROVER_size_t malloc_size)
9292
// realistically, malloc may return NULL,
9393
// and __CPROVER_malloc doesn't, but no one cares
9494
__CPROVER_HIDE:;
95+
// ensure that all bytes in the allocated memory can be addressed
96+
// using our object:offset encoding as specified in
97+
// flattening/pointer_logic.h; also avoid sign-extension issues
98+
// for 32-bit systems that yields a maximum allocation of 2^23-1,
99+
// i.e., just under 8MB
100+
__CPROVER_assume(malloc_size<(1UL<<((sizeof(char*)-1)*8-1)));
95101
void *malloc_res;
96102
malloc_res=__CPROVER_malloc(malloc_size);
97103

@@ -116,6 +122,12 @@ inline void *malloc(__CPROVER_size_t malloc_size)
116122
inline void *__builtin_alloca(__CPROVER_size_t alloca_size)
117123
{
118124
__CPROVER_HIDE:;
125+
// ensure that all bytes in the allocated memory can be addressed
126+
// using our object:offset encoding as specified in
127+
// flattening/pointer_logic.h; also avoid sign-extension issues
128+
// for 32-bit systems that yields a maximum allocation of 2^23-1,
129+
// i.e., just under 8MB
130+
__CPROVER_assume(alloca_size<(1UL<<((sizeof(char*)-1)*8-1)));
119131
void *res;
120132
res=__CPROVER_malloc(alloca_size);
121133

@@ -301,6 +313,8 @@ inline long atol(const char *nptr)
301313
#define __CPROVER_LIMITS_H_INCLUDED
302314
#endif
303315

316+
inline void *__builtin_alloca(__CPROVER_size_t alloca_size);
317+
304318
inline char *getenv(const char *name)
305319
{
306320
__CPROVER_HIDE:;
@@ -330,7 +344,7 @@ inline char *getenv(const char *name)
330344
// the range.
331345

332346
__CPROVER_assume(1<=buf_size && buf_size<=SSIZE_MAX);
333-
buffer=(char *)__CPROVER_malloc(buf_size);
347+
buffer=(char *)__builtin_alloca(buf_size);
334348
buffer[buf_size-1]=0;
335349

336350
return buffer;

src/goto-symex/symex_builtin_functions.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ void goto_symext::symex_malloc(
6262
return; // ignore
6363

6464
dynamic_counter++;
65+
// we can only encode 254 fresh objects + invalid + null in 8 bits
66+
if(dynamic_counter>254)
67+
throw "at most 254 distinct dynamic objects are supported";
6568

6669
exprt size=code.op0();
6770
typet object_type=nil_typet();
@@ -373,6 +376,9 @@ void goto_symext::symex_cpp_new(
373376
do_array=(code.get(ID_statement)==ID_cpp_new_array);
374377

375378
dynamic_counter++;
379+
// we can only encode 254 fresh objects + invalid + null in 8 bits
380+
if(dynamic_counter>254)
381+
throw "at most 254 distinct dynamic objects are supported";
376382

377383
const std::string count_string(std::to_string(dynamic_counter));
378384

0 commit comments

Comments
 (0)