From 42d23084b72541b74e9f4cc279afc5f89f89d4e1 Mon Sep 17 00:00:00 2001 From: Go Saito Date: Mon, 23 Feb 2015 11:25:21 +0900 Subject: fix pointer dereference after realloc In src/vm.c: mrb_funcall_with_block stack_extend may realloc mrb->c->stbase, if argv points on mruby's stack, then it points invalid address after stack_extend. e.g. src/class.c: mrb_instance_new This code: ```ruby class A def initialize(a0,a1,a2,a3,a4) a0.is_a? Array end end def f(a0,a1,a2,a3,a4) A.new(a0,a1,a2,a3,a4) f(a0,a1,a2,a3,a4) end f(0,1,2,3,4) ``` is expected to get exception ``` stack level too deep. (limit=(0x40000 - 128)) (SystemStackError) ``` but get segfault. Signed-off-by: Go Saito --- src/vm.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/vm.c b/src/vm.c index a03bcc17e..3734ccaf8 100644 --- a/src/vm.c +++ b/src/vm.c @@ -340,6 +340,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc mrb_sym undef = 0; mrb_callinfo *ci; int n; + ptrdiff_t voff = -1; if (!mrb->c->stack) { stack_init(mrb); @@ -363,6 +364,9 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc ci->argc = argc; ci->target_class = c; mrb->c->stack = mrb->c->stack + n; + if (mrb->c->stbase <= argv && argv < mrb->c->stend) { + voff = argv - mrb->c->stbase; + } if (MRB_PROC_CFUNC_P(p)) { ci->nregs = argc + 2; stack_extend(mrb, ci->nregs, 0); @@ -371,6 +375,9 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc ci->nregs = p->body.irep->nregs + n; stack_extend(mrb, ci->nregs, argc+2); } + if (voff >= 0) { + argv = mrb->c->stbase + voff; + } mrb->c->stack[0] = self; if (undef) { mrb->c->stack[1] = mrb_symbol_value(undef); -- cgit v1.2.3