Skip to content

Commit bb8fa2d

Browse files
Remi Delmasqinheping
Remi Delmas
authored andcommitted
CONTRACTS: dfcc_is_cprover_symbol now uses allow lists
The result of `dfcc_is_cprover_symbol` is used to skip frame conditon checks on symbols with special meaning. Before we were matching symbols based on their prefix, which would allow users to skip frame condition checks just by naming their symbols with these prefixes. We now use a closed allow list, and distinguish function symbolds form static var symbols. We add test that show that variables named with __CPROVER, __VERIFIER or nondet prefixes do not bypass frame condition checks.
1 parent 21e44f7 commit bb8fa2d

File tree

9 files changed

+258
-61
lines changed

9 files changed

+258
-61
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
void foo()
2+
{
3+
int nondet_var;
4+
int __VERIFIER_var;
5+
int __CPROVER_var;
6+
for(int i = 10; i > 0; i--)
7+
// clang-format off
8+
__CPROVER_assigns(i)
9+
__CPROVER_loop_invariant(0 <= i && i <= 10)
10+
__CPROVER_decreases(i)
11+
// clang-format on
12+
{
13+
nondet_var = 0;
14+
__VERIFIER_var = 0;
15+
__CPROVER_var = 0;
16+
}
17+
}
18+
19+
int main()
20+
{
21+
foo();
22+
return 0;
23+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CORE
2+
main.c
3+
--dfcc main --apply-loop-contracts
4+
^\[foo.assigns.\d+\] line \d+ Check that nondet_var is assignable: FAILURE$
5+
^\[foo.assigns.\d+\] line \d+ Check that __VERIFIER_var is assignable: FAILURE$
6+
^\[foo.assigns.\d+\] line \d+ Check that __CPROVER_var is assignable: FAILURE$
7+
^EXIT=10$
8+
^SIGNAL=0$
9+
^VERIFICATION FAILED$
10+
--
11+
--
12+
This test checks that program variables with special name prefixes
13+
__CPROVER_, __VERIFIER, or nondet do not escape assigns clause checking.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
void foo()
2+
{
3+
int nondet_var;
4+
int __VERIFIER_var;
5+
int __CPROVER_var;
6+
for(int i = 10; i > 0; i--)
7+
// clang-format off
8+
__CPROVER_assigns(i,nondet_var, __VERIFIER_var, __CPROVER_var)
9+
__CPROVER_loop_invariant(0 <= i && i <= 10)
10+
__CPROVER_decreases(i)
11+
// clang-format on
12+
{
13+
nondet_var = 0;
14+
__VERIFIER_var = 0;
15+
__CPROVER_var = 0;
16+
}
17+
}
18+
19+
int main()
20+
{
21+
foo();
22+
return 0;
23+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CORE
2+
main.c
3+
--dfcc main --apply-loop-contracts
4+
^\[foo.assigns.\d+\] line \d+ Check that nondet_var is assignable: SUCCESS$
5+
^\[foo.assigns.\d+\] line \d+ Check that __VERIFIER_var is assignable: SUCCESS$
6+
^\[foo.assigns.\d+\] line \d+ Check that __CPROVER_var is assignable: SUCCESS$
7+
^EXIT=0$
8+
^SIGNAL=0$
9+
^VERIFICATION SUCCESSFUL$
10+
--
11+
--
12+
This test checks that when program variables names have special prefixes
13+
__CPROVER_, __VERIFIER, or nondet, adding them to the write set makes them
14+
assignable.

src/goto-instrument/contracts/dynamic-frames/dfcc_cfg_info.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,7 @@ static bool must_check_lhs_from_local_and_tracked(
795795
return true;
796796
}
797797
const auto &id = to_symbol_expr(expr).get_identifier();
798-
if(dfcc_is_cprover_symbol(id))
798+
if(dfcc_is_cprover_static_symbol(id))
799799
{
800800
// Skip the check if we have a single cprover symbol as root object
801801
// cprover symbols are used for generic checks instrumentation and are

src/goto-instrument/contracts/dynamic-frames/dfcc_instrument.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ bool dfcc_instrumentt::is_internal_symbol(const irep_idt &id) const
235235
bool dfcc_instrumentt::do_not_instrument(const irep_idt &id) const
236236
{
237237
return !has_prefix(id2string(id), CPROVER_PREFIX "file_local") &&
238-
(dfcc_is_cprover_symbol(id) || is_internal_symbol(id));
238+
(dfcc_is_cprover_function_symbol(id) || is_internal_symbol(id));
239239
}
240240

241241
void dfcc_instrumentt::instrument_harness_function(

0 commit comments

Comments
 (0)