From 4062069679fe6c07b0ab55119061be1ec38970e0 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 2 Sep 2024 22:34:40 +0900 Subject: [PATCH] gc.c (gc_arena_keep): revert 2 commits regarding arena allocation; #6329 We assumed there's no need for gc_arena_keep() when MRB_GC_FIXED_ARENA is set. But it turned out that gc_protect() still can cause use-after-free with fixed arena. Revert "gc.c (gc_protect): should not call gc_arena_keep twice from allocation" This reverts commit 28ece4ed8b7e95e80ffdbeb043880346aacfc92f. Revert "gc.c (gc_arena_keep): reorganized for MRB_GC_FIXED_ARENA; ref #6329" This reverts commit 33dd623a02165c33a6feda4a4be723a7428aea81. --- src/gc.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/gc.c b/src/gc.c index 883ca989d..a9549e730 100644 --- a/src/gc.c +++ b/src/gc.c @@ -371,23 +371,8 @@ mrb_gc_destroy(mrb_state *mrb, mrb_gc *gc) #endif } -#ifdef MRB_GC_FIXED_ARENA -#define gc_arena_keep(mrb, gc) /* empty */ -#else static void gc_arena_keep(mrb_state *mrb, mrb_gc *gc) -{ - if (gc->arena_idx >= gc->arena_capa) { - /* extend arena */ - int newcapa = gc->arena_capa * 3 / 2; - gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*newcapa); - gc->arena_capa = newcapa; - } -} -#endif - -static inline void -gc_protect(mrb_state *mrb, mrb_gc *gc, struct RBasic *p) { #ifdef MRB_GC_FIXED_ARENA if (gc->arena_idx >= MRB_GC_ARENA_SIZE) { @@ -395,6 +380,21 @@ gc_protect(mrb_state *mrb, mrb_gc *gc, struct RBasic *p) gc->arena_idx = MRB_GC_ARENA_SIZE - 4; /* force room in arena */ mrb_exc_raise(mrb, mrb_obj_value(mrb->arena_err)); } +#else + if (gc->arena_idx >= gc->arena_capa) { + /* extend arena */ + int newcapa = gc->arena_capa * 3 / 2; + gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*newcapa); + gc->arena_capa = newcapa; + } +#endif +} + +static inline void +gc_protect(mrb_state *mrb, mrb_gc *gc, struct RBasic *p) +{ +#ifdef MRB_GC_FIXED_ARENA + mrb_assert(gc->arena_idx < MRB_GC_ARENA_SIZE); #else mrb_assert(gc->arena_idx < gc->arena_capa); #endif