Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixed allocation of CallFrame.scope in JITted code
Browse files Browse the repository at this point in the history
Consider the following:

  def method_yield(arg)
    yield(6, 7)
  end

  50_000.times do
    shadow = 2
    method_yield([]) { |shadow, k| }
  end

In the { |shadow, k| } block of the below piece of code,
machine_code->total_args (2) > machine_code_->number_of_locals (1).

the JIT would allocate space for number_of_locals elements in
the CallFrame.scope->locals_ array, but write total_args elements
into the array, past the boundary of allocated memory.

this showed up as an overwrite of the subsequent CallFrame object,
corrupting its previous pointer and causing a segfault when GC
attempted to walk back through callframes.
sshao committed Oct 29, 2014
1 parent 64f2394 commit 295842c
Showing 3 changed files with 12 additions and 3 deletions.
5 changes: 4 additions & 1 deletion vm/llvm/jit_builder.cpp
Original file line number Diff line number Diff line change
@@ -646,8 +646,11 @@ namespace jit {
cint((sizeof(CallFrame) / sizeof(Object*)) + machine_code_->stack_size),
"cfstk");

size_t num_vars = std::max(machine_code_->number_of_locals,
machine_code_->total_args);

Value* var_mem = b().CreateAlloca(obj_type,
cint((sizeof(StackVariables) / sizeof(Object*)) + machine_code_->number_of_locals),
cint((sizeof(StackVariables) / sizeof(Object*)) + num_vars),
"var_mem");

call_frame = b().CreateBitCast(
5 changes: 4 additions & 1 deletion vm/llvm/jit_inline_block.cpp
Original file line number Diff line number Diff line change
@@ -43,8 +43,11 @@ namespace jit {

info_.set_stack(stk);

size_t num_vars = std::max(machine_code_->number_of_locals,
machine_code_->total_args);

Value* var_mem = new AllocaInst(obj_type,
cint((sizeof(StackVariables) / sizeof(Object*)) + machine_code_->number_of_locals),
cint((sizeof(StackVariables) / sizeof(Object*)) + num_vars),
"var_mem", alloca_block->getTerminator());

vars = b().CreateBitCast(
5 changes: 4 additions & 1 deletion vm/llvm/jit_inline_method.cpp
Original file line number Diff line number Diff line change
@@ -41,9 +41,12 @@ namespace jit {
info_.set_call_frame(call_frame);
info_.set_stack(stk);

size_t num_vars = std::max(machine_code_->number_of_locals,
machine_code_->total_args);

Value* var_mem = new AllocaInst(obj_type,
ConstantInt::get(ctx_->Int32Ty,
(sizeof(StackVariables) / sizeof(Object*)) + machine_code_->number_of_locals),
(sizeof(StackVariables) / sizeof(Object*)) + num_vars),
"var_mem", alloca_block->getTerminator());

vars = b().CreateBitCast(

0 comments on commit 295842c

Please sign in to comment.