From b178914b111dda79a8f36ec4eb3e9d37b76f982e Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 19 Jan 2019 22:22:44 +0900 Subject: [PATCH] Fix invalid pointer free inside other heap's block 1. `e = mrb_obj_alloc(...)` 2. `e->stack = mrb->c->stack` (`mrb->c->stack` is anywhere in the range `stbase...stend`) 3. And raised exception by `mrb_malloc()`! 4. `mrb_free(e->stack)` by GC part (wrong free) --- src/proc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/proc.c b/src/proc.c index acc21fc3c..87855be6d 100644 --- a/src/proc.c +++ b/src/proc.c @@ -120,7 +120,14 @@ mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const p->flags |= MRB_PROC_ENVSET; mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)e); MRB_ENV_UNSHARE_STACK(e); + + /* NOTE: Prevents keeping invalid addresses when NoMemoryError is raised from `mrb_malloc()`. */ + e->stack = NULL; + MRB_ENV_SET_STACK_LEN(e, 0); + e->stack = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * argc); + MRB_ENV_SET_STACK_LEN(e, argc); + if (argv) { for (i = 0; i < argc; ++i) { e->stack[i] = argv[i];