From bccec7fb468ad977be75e7e4c2644b4ea845ab0c Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Thu, 6 Apr 2023 10:25:59 -0400 Subject: [PATCH] Fix crash in rb_gc_register_address [Bug #19584] Some C extensions pass a pointer to a global variable to rb_gc_register_address. However, if a GC is triggered inside of rb_gc_register_address, then the object could get swept since it does not exist on the stack. --- gc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gc.c b/gc.c index f84d27d810..2386ec422c 100644 --- a/gc.c +++ b/gc.c @@ -9202,10 +9202,17 @@ rb_gc_register_address(VALUE *addr) rb_objspace_t *objspace = &rb_objspace; struct gc_list *tmp; + VALUE obj = *addr; + tmp = ALLOC(struct gc_list); tmp->next = global_list; tmp->varptr = addr; global_list = tmp; + + /* obj has to be guarded here because the allocation above could trigger a + * GC. However, C extensions could pass a pointer to a global variable + * which does not exist on the stack and thus could get swept. */ + RB_GC_GUARD(obj); } void