Skip to content

Commit c195e63

Browse files
committed
Remove 'erase' in replace_java_nondet.cpp
Erasing a range of instructions from a goto program can cause memory bugs when `goto_program::update` is called. Specifically, if any of the remaining nodes in the program have elements of `targets` which point into the erased range, then the program may attempt an invalid read during the `update` call. To avoid this, I thought of two options: - check through the goto-program for instructions with `target`s that point into the removed range, and remove those `target`s, or - just replace the existing instructions with no-ops. Although I think the first solution is better, I can't think of a good way of doing it with acceptable complexity, so this patch implements the second option.
1 parent 466f629 commit c195e63

File tree

1 file changed

+14
-9
lines changed

1 file changed

+14
-9
lines changed

src/goto-programs/replace_java_nondet.cpp

+14-9
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,9 @@ Function: check_and_replace_target
215215
216216
\*******************************************************************/
217217

218-
static goto_programt::const_targett check_and_replace_target(
218+
static goto_programt::targett check_and_replace_target(
219219
goto_programt &goto_program,
220-
const goto_programt::const_targett &target)
220+
const goto_programt::targett &target)
221221
{
222222
// Check whether this is a nondet library method, and return if not
223223
const auto instr_info=get_nondet_instruction_info(target);
@@ -241,7 +241,7 @@ static goto_programt::const_targett check_and_replace_target(
241241
to_symbol_expr(next_instr_assign_lhs).get_identifier();
242242

243243
auto &instructions=goto_program.instructions;
244-
const auto end=instructions.cend();
244+
const auto end=instructions.end();
245245

246246
// Look for an instruction where this name is on the RHS of an assignment
247247
const auto matching_assignment=std::find_if(
@@ -263,10 +263,15 @@ static goto_programt::const_targett check_and_replace_target(
263263
const auto after_matching_assignment=std::next(matching_assignment);
264264
assert(after_matching_assignment!=end);
265265

266-
const auto after_erased=goto_program.instructions.erase(
267-
target, after_matching_assignment);
266+
std::for_each(
267+
target,
268+
after_matching_assignment,
269+
[](goto_programt::instructiont &instr)
270+
{
271+
instr.make_skip();
272+
});
268273

269-
const auto inserted=goto_program.insert_before(after_erased);
274+
const auto inserted=goto_program.insert_before(after_matching_assignment);
270275
inserted->make_assignment();
271276
side_effect_expr_nondett inserted_expr(nondet_var.type());
272277
inserted_expr.set_nullable(
@@ -278,7 +283,7 @@ static goto_programt::const_targett check_and_replace_target(
278283

279284
goto_program.update();
280285

281-
return after_erased;
286+
return after_matching_assignment;
282287
}
283288

284289
/*******************************************************************\
@@ -297,8 +302,8 @@ Function: replace_java_nondet
297302

298303
static void replace_java_nondet(goto_programt &goto_program)
299304
{
300-
for(auto instruction_iterator=goto_program.instructions.cbegin(),
301-
end=goto_program.instructions.cend();
305+
for(auto instruction_iterator=goto_program.instructions.begin(),
306+
end=goto_program.instructions.end();
302307
instruction_iterator!=end;)
303308
{
304309
instruction_iterator=check_and_replace_target(

0 commit comments

Comments
 (0)