Skip to content

Commit bfd14f1

Browse files
author
Enrico Steffinlongo
authored
Merge pull request #7936 from esteffin/esteffin/pointer-check-for-sm-address
Add --pointer-check for shadow memory address
2 parents c864ba9 + 88250d7 commit bfd14f1

File tree

5 files changed

+78
-0
lines changed

5 files changed

+78
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <assert.h>
2+
3+
extern _Bool nondet();
4+
5+
int main()
6+
{
7+
__CPROVER_field_decl_local("field1", (_Bool)0);
8+
9+
char *buffer[10];
10+
11+
__CPROVER_set_field(&buffer[9], "field1", 1);
12+
assert(__CPROVER_get_field(&buffer[9], "field1") == 1);
13+
__CPROVER_set_field(&buffer[10], "field1", 1);
14+
if(nondet())
15+
{
16+
assert(__CPROVER_get_field(&buffer[10], "field1") == 1);
17+
}
18+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
CORE
2+
main.c
3+
--verbosity 10 --pointer-check
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
line 13 dereference failure: pointer outside object bounds.*: FAILURE
8+
line 16 dereference failure: pointer outside object bounds.*: FAILURE
9+
--
10+
^warning: ignoring
11+
line 11 dereference failure: pointer outside object bounds.*: FAILURE
12+
line 12 dereference failure: pointer outside object bounds.*: FAILURE
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#include <assert.h>
2+
3+
int main()
4+
{
5+
__CPROVER_field_decl_local("uninitialized", (char)0);
6+
7+
char a;
8+
int *i = &a;
9+
10+
__CPROVER_set_field(i, "uninitialized", 1); // should this fail?
11+
12+
assert(__CPROVER_get_field(&a, "uninitialized") == 1);
13+
assert(__CPROVER_get_field(&a + 1, "uninitialized") == 1);
14+
assert(__CPROVER_get_field(i, "uninitialized") == 1);
15+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
main.c
3+
--verbosity 10 --pointer-check
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
line 10 dereference failure: pointer outside object bounds in \*i.*: FAILURE
8+
line 13 dereference failure: pointer outside object bounds in \(&a\).*: FAILURE
9+
line 14 dereference failure: pointer outside object bounds in \*i.*: FAILURE
10+
--

src/ansi-c/goto_check_c.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ class goto_check_ct
103103
using guardt = std::function<exprt(exprt)>;
104104
const guardt identity = [](exprt expr) { return expr; };
105105

106+
void check_shadow_memory_api_calls(const goto_programt::instructiont &);
107+
106108
/// Check an address-of expression:
107109
/// if it is a dereference then check the pointer
108110
/// if it is an index then address-check the array and then check the index
@@ -2142,6 +2144,8 @@ void goto_check_ct::goto_check(
21422144
for(const auto &arg : i.call_arguments())
21432145
check(arg);
21442146

2147+
check_shadow_memory_api_calls(i);
2148+
21452149
// the call might invalidate any assertion
21462150
assertions.clear();
21472151
}
@@ -2243,6 +2247,25 @@ void goto_check_ct::goto_check(
22432247
remove_skip(goto_program);
22442248
}
22452249

2250+
void goto_check_ct::check_shadow_memory_api_calls(
2251+
const goto_programt::instructiont &i)
2252+
{
2253+
if(i.call_function().id() != ID_symbol)
2254+
return;
2255+
2256+
const irep_idt &identifier =
2257+
to_symbol_expr(i.call_function()).get_identifier();
2258+
2259+
if(
2260+
identifier == CPROVER_PREFIX "get_field" || identifier == CPROVER_PREFIX
2261+
"set_field")
2262+
{
2263+
const exprt &expr = i.call_arguments()[0];
2264+
PRECONDITION(expr.type().id() == ID_pointer);
2265+
check(dereference_exprt(expr));
2266+
}
2267+
}
2268+
22462269
goto_check_ct::conditionst
22472270
goto_check_ct::get_pointer_points_to_valid_memory_conditions(
22482271
const exprt &address,

0 commit comments

Comments
 (0)