Skip to content

Commit

Permalink
JIT: Fix unsafe in-place update during disabled GC
Browse files Browse the repository at this point in the history
When GC was temporarily disabled (for example during the execution of
some BIFs), an unsafe in-place update of a record could occur.
  • Loading branch information
bjorng committed May 31, 2024
1 parent 5dccb45 commit a180597
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 0 deletions.
5 changes: 5 additions & 0 deletions erts/emulator/beam/erl_gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,11 @@ delay_garbage_collection(Process *p, int need, int fcalls)
}
p->abandoned_heap = orig_heap;
erts_adjust_memory_break(p, orig_htop - p->high_water);

/* Point at the end of the address range to ensure that
* test for the safe range in the new heap in the
* update_record_in_place instruction fails. */
p->high_water = (Eterm *) (Uint) -1;
}

#ifdef CHECK_FOR_HOLES
Expand Down
23 changes: 23 additions & 0 deletions erts/emulator/beam/jit/arm/instr_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,29 @@ void BeamModuleAssembler::emit_update_record_in_place(

a.add(destination.reg, untagged_src, TAG_PRIMARY_BOXED);
flush_var(destination);

#ifdef DEBUG
if (!all_safe && maybe_immediate.isNil()) {
Label pointer_ok = a.newLabel();

/* If p->high_water contained a garbage value, a tuple not in
* the safe part of the new heap could have been destructively
* updated. */
comment("sanity-checking tuple pointer");
mov_arg(ARG2, Dst);
a.ldr(ARG4, arm::Mem(c_p, offsetof(Process, heap)));
a.cmp(ARG2, HTOP);
a.ccmp(ARG2, ARG4, imm(NZCV::kNone), imm(arm::CondCode::kLO));
a.b_hs(pointer_ok);

emit_enter_runtime();
a.mov(ARG1, c_p);
runtime_call<2>(beam_jit_invalid_heap_ptr);
emit_leave_runtime();

a.bind(pointer_ok);
}
#endif
}

void BeamModuleAssembler::emit_set_tuple_element(const ArgSource &Element,
Expand Down
26 changes: 26 additions & 0 deletions erts/emulator/beam/jit/beam_jit_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1365,3 +1365,29 @@ bool beam_jit_is_shallow_boxed(Eterm term) {
return false;
}
}

#ifdef DEBUG
void beam_jit_invalid_heap_ptr(Process *p, Eterm term) {
ASSERT((void *)term <= (void *)p->heap || (void *)term >= (void *)p->hend);

erts_fprintf(stderr,
"term: %p\n"
"c_p: %p\n"
"heap: %p\n"
"high_water: %p\n"
"hend: %p\n"
"abandoned: %p\n",
(void *)term,
p,
p->heap,
p->high_water,
p->hend,
p->abandoned_heap);
if (p->old_heap != NULL && p->old_hend != NULL &&
(void *)term < (void *)p->old_hend &&
(void *)term >= (void *)p->old_heap) {
erts_fprintf(stderr, "the term is on the old heap\n");
}
abort();
}
#endif
4 changes: 4 additions & 0 deletions erts/emulator/beam/jit/beam_jit_common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -659,4 +659,8 @@ Export *beam_jit_handle_unloaded_fun(Process *c_p,
bool beam_jit_is_list_of_immediates(Eterm term);
bool beam_jit_is_shallow_boxed(Eterm term);

#ifdef DEBUG
void beam_jit_invalid_heap_ptr(Process *p, Eterm term);
#endif

#endif
28 changes: 28 additions & 0 deletions erts/emulator/beam/jit/x86/instr_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,34 @@ void BeamModuleAssembler::emit_update_record_in_place(
}

mov_arg(Dst, RET);

#ifdef DEBUG
if (!all_safe && maybe_immediate.isNil()) {
Label bad_pointer = a.newLabel(), pointer_ok = a.newLabel();

/* If p->high_water contained a garbage value, a tuple not in
* the safe part of the new heap could have been destructively
* updated. */
comment("sanity-checking tuple pointer");
a.mov(ARG1, x86::Mem(c_p, offsetof(Process, heap)));
a.cmp(RET, HTOP);
a.short_().jae(bad_pointer);

a.cmp(RET, ARG1);
a.short_().jae(pointer_ok);

a.bind(bad_pointer);
{
emit_enter_runtime();
a.mov(ARG1, c_p);
a.mov(ARG2, RET);
runtime_call<2>(beam_jit_invalid_heap_ptr);
emit_leave_runtime();
}

a.bind(pointer_ok);
}
#endif
}

void BeamModuleAssembler::emit_set_tuple_element(const ArgSource &Element,
Expand Down

0 comments on commit a180597

Please sign in to comment.