Skip to content

Commit 7f7744a

Browse files
committed
Validity checking of void pointers in contracts
1 parent 6d77bf9 commit 7f7744a

File tree

4 files changed

+45
-4
lines changed

4 files changed

+45
-4
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <assert.h>
2+
#include <stdlib.h>
3+
4+
int x = 0;
5+
6+
void foo(void *y) __CPROVER_assigns(*y) __CPROVER_assigns(x)
7+
{
8+
x = 2;
9+
int *bar = (int *)y;
10+
*bar = 2;
11+
}
12+
13+
int main()
14+
{
15+
int *y = malloc(sizeof(*y));
16+
*y = 0;
17+
foo(y);
18+
assert(x == 2);
19+
assert(*y == 2);
20+
return 0;
21+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
main.c
3+
--enforce-contract foo _ --pointer-check
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
--
9+
Checks whether contract enforcement does not try to dereference void pointers.

src/goto-instrument/contracts/utils.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Date: September 2021
1111
#include "utils.h"
1212

1313
#include <util/pointer_expr.h>
14+
#include <util/pointer_offset_size.h>
1415
#include <util/pointer_predicates.h>
1516

1617
static void append_safe_havoc_code_for_expr(
@@ -58,9 +59,16 @@ exprt all_dereferences_are_valid(const exprt &expr, const namespacet &ns)
5859
{
5960
exprt::operandst validity_checks;
6061

61-
if(expr.id() == ID_dereference)
62-
validity_checks.push_back(
63-
good_pointer_def(to_dereference_expr(expr).pointer(), ns));
62+
if(expr.id() == ID_dereference) {
63+
const auto &pointer = to_dereference_expr(expr).pointer();
64+
const auto opt_size_of_deref =
65+
size_of_expr(to_pointer_type(pointer.type()).subtype(), ns);
66+
67+
if(opt_size_of_deref.has_value())
68+
validity_checks.push_back(good_pointer_def(pointer, ns));
69+
else
70+
validity_checks.push_back(false_exprt());
71+
}
6472

6573
for(const auto &op : expr.operands())
6674
validity_checks.push_back(all_dereferences_are_valid(op, ns));

src/util/pointer_predicates.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,10 @@ exprt good_pointer_def(
8989
const typet &dereference_type=pointer_type.subtype();
9090

9191
const auto size_of_expr_opt = size_of_expr(dereference_type, ns);
92-
CHECK_RETURN(size_of_expr_opt.has_value());
92+
PRECONDITION_WITH_DIAGNOSTICS(
93+
size_of_expr_opt.has_value(),
94+
"Could not compute sizeof on pointer's dereference type. "
95+
"It may be a void pointer.");
9396

9497
const exprt good_dynamic = not_exprt{deallocated(pointer, ns)};
9598

0 commit comments

Comments
 (0)