Skip to content

Commit 2129b2f

Browse files
committed
Change goto_checkt::address_check() dynamic memory bounds checking
This changes the dynamic memory bounds checking predicate in address_check(). It now uses OBJECT_SIZE() instead of the variables __CPROVER_malloc_size and __CPROVER_malloc_object that are set in the malloc() model. This also means that the predicates __CPROVER_r_ok()/__CPROVER_w_ok() will be more precise. In the previous approach, the following assertion could not be proven for example: void main() { char *c = malloc(1); assert(!__CPROVER_r_ok(c, 2)); }
1 parent 7a87770 commit 2129b2f

File tree

9 files changed

+110
-4
lines changed

9 files changed

+110
-4
lines changed

regression/cbmc/r_w_ok5/main.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <assert.h>
2+
#include <stdlib.h>
3+
4+
void main()
5+
{
6+
char c[2];
7+
assert(__CPROVER_r_ok(c, 3));
8+
assert(!__CPROVER_r_ok(c, 3));
9+
10+
char *p = malloc(2);
11+
assert(__CPROVER_r_ok(p, 3));
12+
assert(!__CPROVER_r_ok(p, 3));
13+
}

regression/cbmc/r_w_ok5/test.desc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
CORE
2+
main.c
3+
4+
\[main.assertion.1\] .*: FAILURE
5+
\[main.assertion.2\] .*: SUCCESS
6+
\[main.assertion.3\] .*: FAILURE
7+
\[main.assertion.4\] .*: SUCCESS
8+
\*\* 2 of 4 failed
9+
^EXIT=10$
10+
^SIGNAL=0$
11+
--
12+
^warning: ignoring

regression/cbmc/r_w_ok6/main.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include <assert.h>
2+
#include <stdlib.h>
3+
4+
void main()
5+
{
6+
char *p;
7+
int choice;
8+
9+
if (choice) {
10+
p = malloc(2);
11+
}
12+
else
13+
{
14+
p = malloc(3);
15+
}
16+
17+
assert(__CPROVER_r_ok(p, 2));
18+
assert(!__CPROVER_r_ok(p, 2));
19+
20+
assert(__CPROVER_r_ok(p, 3));
21+
assert(!__CPROVER_r_ok(p, 3));
22+
23+
assert(__CPROVER_r_ok(p, 4));
24+
assert(!__CPROVER_r_ok(p, 4));
25+
}

regression/cbmc/r_w_ok6/test.desc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CORE
2+
main.c
3+
4+
\[main.assertion.1\] .*: SUCCESS
5+
\[main.assertion.2\] .*: FAILURE
6+
\[main.assertion.3\] .*: FAILURE
7+
\[main.assertion.4\] .*: FAILURE
8+
\[main.assertion.5\] .*: FAILURE
9+
\[main.assertion.6\] .*: SUCCESS
10+
\*\* 4 of 6 failed
11+
^EXIT=10$
12+
^SIGNAL=0$
13+
--
14+
^warning: ignoring

regression/cbmc/r_w_ok7/main.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <assert.h>
2+
#include <stdint.h>
3+
#include <stdlib.h>
4+
5+
int main()
6+
{
7+
size_t x;
8+
size_t y;
9+
uint8_t *a;
10+
11+
__CPROVER_assume(x > 0);
12+
__CPROVER_assume(y > x);
13+
14+
a = malloc(sizeof(*(a)) * (x));
15+
16+
assert(!__CPROVER_w_ok(a, y));
17+
}

regression/cbmc/r_w_ok7/test.desc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
4+
VERIFICATION SUCCESSFUL
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
--
8+
^warning: ignoring

regression/cbmc/r_w_ok8/main.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include <assert.h>
2+
#include <stdlib.h>
3+
4+
int main()
5+
{
6+
int *x = malloc(2);
7+
int *y = malloc(2);
8+
assert(__CPROVER_r_ok(x, 3) == __CPROVER_r_ok(y, 3));
9+
}

regression/cbmc/r_w_ok8/test.desc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
4+
VERIFICATION SUCCESSFUL
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
--
8+
^warning: ignoring

src/analyses/goto_check.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,15 +1249,15 @@ goto_checkt::address_check(const exprt &address, const exprt &size)
12491249

12501250
if(flags.is_unknown() || flags.is_dynamic_heap())
12511251
{
1252-
const or_exprt dynamic_bounds_violation(
1253-
dynamic_object_lower_bound(address, nil_exprt()),
1254-
dynamic_object_upper_bound(address, ns, size));
1252+
const or_exprt object_bounds_violation(
1253+
object_lower_bound(address, nil_exprt()),
1254+
object_upper_bound(address, size));
12551255

12561256
conditions.push_back(conditiont(
12571257
or_exprt(
12581258
in_bounds_of_some_explicit_allocation,
12591259
implies_exprt(
1260-
malloc_object(address, ns), not_exprt(dynamic_bounds_violation))),
1260+
dynamic_object(address), not_exprt(object_bounds_violation))),
12611261
"pointer outside dynamic object bounds"));
12621262
}
12631263

0 commit comments

Comments
 (0)