Skip to content

Commit 744c6f3

Browse files
authored
Merge pull request #4256 from tautschnig/allocated-bounds
Take __CPROVER_allocated_memory regions into account for --bounds-check
2 parents df79716 + 51f5796 commit 744c6f3

File tree

3 files changed

+73
-4
lines changed

3 files changed

+73
-4
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#define _cbmc_printf2(str, var) \
2+
{ \
3+
unsigned int ValueOf_##str = (unsigned int)var; \
4+
}
5+
6+
#define BUFFER_SIZE 100
7+
typedef struct
8+
{
9+
int buffer[BUFFER_SIZE];
10+
} buffert;
11+
12+
#define BUF_BASE 0x1000
13+
#define BUF0_BASE (BUF_BASE + 0x00000)
14+
#define BUF1_BASE (BUF_BASE + 0x10000)
15+
#define BUF2_BASE (BUF_BASE + 0x20000)
16+
#define BUF3_BASE (BUF_BASE + 0x30000)
17+
18+
#define BUF0 ((buffert *)BUF0_BASE)
19+
#define BUF1 ((buffert *)BUF1_BASE)
20+
#define BUF2 ((buffert *)BUF2_BASE)
21+
#define BUF3 ((buffert *)BUF3_BASE)
22+
23+
static buffert(*const buffers[4]) = {BUF0, BUF1, BUF2, BUF3};
24+
25+
main()
26+
{
27+
__CPROVER_allocated_memory(BUF0_BASE, sizeof(buffert));
28+
__CPROVER_allocated_memory(BUF1_BASE, sizeof(buffert));
29+
__CPROVER_allocated_memory(BUF2_BASE, sizeof(buffert));
30+
__CPROVER_allocated_memory(BUF3_BASE, sizeof(buffert));
31+
32+
_cbmc_printf2(sizeof_buffers, sizeof(buffers));
33+
_cbmc_printf2(sizeof_buffers_0, sizeof(buffers[0]));
34+
_cbmc_printf2(sizeof_buffer, sizeof(buffers[0]->buffer));
35+
36+
buffers[0]->buffer[0];
37+
buffers[0]->buffer[BUFFER_SIZE - 1];
38+
buffers[0]->buffer[BUFFER_SIZE]; // should be out-of-bounds
39+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE broken-smt-backend
2+
main.c
3+
--bounds-check
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^\[main\.array_bounds\.[1-5]\] .*: SUCCESS$
7+
^\[main\.array_bounds\.[67]\] line 38 array.buffer (dynamic object )?upper bound in buffers\[\(signed long (long )?int\)0\]->buffer\[\(signed long (long )?int\)100\]: FAILURE$
8+
^\*\* 2 of 7 failed
9+
^VERIFICATION FAILED$
10+
--
11+
^warning: ignoring

src/analyses/goto_check.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ class goto_checkt
169169
void goto_checkt::collect_allocations(
170170
const goto_functionst &goto_functions)
171171
{
172-
if(!enable_pointer_check)
172+
if(!enable_pointer_check && !enable_bounds_check)
173173
return;
174174

175175
forall_goto_functions(itf, goto_functions)
@@ -1296,10 +1296,29 @@ void goto_checkt::bounds_check(
12961296

12971297
binary_relation_exprt inequality(effective_offset, ID_lt, size_casted);
12981298

1299+
exprt::operandst alloc_disjuncts;
1300+
for(const auto &a : allocations)
1301+
{
1302+
typecast_exprt int_ptr{pointer, a.first.type()};
1303+
1304+
binary_relation_exprt lower_bound_check{a.first, ID_le, int_ptr};
1305+
1306+
plus_exprt upper_bound{
1307+
int_ptr,
1308+
typecast_exprt::conditional_cast(ode.offset(), int_ptr.type())};
1309+
1310+
binary_relation_exprt upper_bound_check{
1311+
std::move(upper_bound), ID_lt, plus_exprt{a.first, a.second}};
1312+
1313+
alloc_disjuncts.push_back(
1314+
and_exprt{std::move(lower_bound_check), std::move(upper_bound_check)});
1315+
}
1316+
1317+
exprt in_bounds_of_some_explicit_allocation = disjunction(alloc_disjuncts);
1318+
12991319
or_exprt precond(
1300-
and_exprt(
1301-
dynamic_object(pointer),
1302-
not_exprt(malloc_object(pointer, ns))),
1320+
std::move(in_bounds_of_some_explicit_allocation),
1321+
and_exprt(dynamic_object(pointer), not_exprt(malloc_object(pointer, ns))),
13031322
inequality);
13041323

13051324
add_guarded_claim(

0 commit comments

Comments
 (0)