ruby-changes:72227
From: nagachika <ko1@a...>
Date: Sat, 18 Jun 2022 15:59:57 +0900 (JST)
Subject: [ruby-changes:72227] 607a20b000 (ruby_3_1): merge revision(s) 97426e15d721119738a548ecfa7232b1d027cd34: [Backport #18627]
https://git.ruby-lang.org/ruby.git/commit/?id=607a20b000 From 607a20b000f83003958e92b68319e860094f44fc Mon Sep 17 00:00:00 2001 From: nagachika <nagachika@r...> Date: Sat, 18 Jun 2022 15:58:15 +0900 Subject: merge revision(s) 97426e15d721119738a548ecfa7232b1d027cd34: [Backport #18627] [Bug #18627] Fix crash when including module During lazy sweeping, the iclass could be a dead object that has not yet been swept. However, the chain of superclasses of the iclass could already have been swept (and become a new object), which would cause a crash when trying to read the object. --- class.c | 48 ++++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 18 deletions(-) --- class.c | 48 ++++++++++++++++++++++++++++++------------------ version.h | 2 +- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/class.c b/class.c index 65a989f9d7..4179b038fa 100644 --- a/class.c +++ b/class.c @@ -1060,17 +1060,24 @@ rb_include_module(VALUE klass, VALUE module) https://github.com/ruby/ruby/blob/trunk/class.c#L1060 int do_include = 1; while (iclass) { VALUE check_class = iclass->klass; - while (check_class) { - if (RB_TYPE_P(check_class, T_ICLASS) && - (RBASIC(check_class)->klass == module)) { - do_include = 0; + /* During lazy sweeping, iclass->klass could be a dead object that + * has not yet been swept. */ + if (!rb_objspace_garbage_object_p(check_class)) { + while (check_class) { + RUBY_ASSERT(!rb_objspace_garbage_object_p(check_class)); + + if (RB_TYPE_P(check_class, T_ICLASS) && + (RBASIC(check_class)->klass == module)) { + do_include = 0; + } + check_class = RCLASS_SUPER(check_class); } - check_class = RCLASS_SUPER(check_class); - } - if (do_include) { - include_modules_at(iclass->klass, RCLASS_ORIGIN(iclass->klass), module, TRUE); + if (do_include) { + include_modules_at(iclass->klass, RCLASS_ORIGIN(iclass->klass), module, TRUE); + } } + iclass = iclass->next; } } @@ -1306,17 +1313,22 @@ rb_prepend_module(VALUE klass, VALUE module) https://github.com/ruby/ruby/blob/trunk/class.c#L1313 struct rb_id_table *klass_m_tbl = RCLASS_M_TBL(klass); struct rb_id_table *klass_origin_m_tbl = RCLASS_M_TBL(klass_origin); while (iclass) { - if (klass_had_no_origin && klass_origin_m_tbl == RCLASS_M_TBL(iclass->klass)) { - // backfill an origin iclass to handle refinements and future prepends - rb_id_table_foreach(RCLASS_M_TBL(iclass->klass), clear_module_cache_i, (void *)iclass->klass); - RCLASS_M_TBL(iclass->klass) = klass_m_tbl; - VALUE origin = rb_include_class_new(klass_origin, RCLASS_SUPER(iclass->klass)); - RCLASS_SET_SUPER(iclass->klass, origin); - RCLASS_SET_INCLUDER(origin, RCLASS_INCLUDER(iclass->klass)); - RCLASS_SET_ORIGIN(iclass->klass, origin); - RICLASS_SET_ORIGIN_SHARED_MTBL(origin); + /* During lazy sweeping, iclass->klass could be a dead object that + * has not yet been swept. */ + if (!rb_objspace_garbage_object_p(iclass->klass)) { + if (klass_had_no_origin && klass_origin_m_tbl == RCLASS_M_TBL(iclass->klass)) { + // backfill an origin iclass to handle refinements and future prepends + rb_id_table_foreach(RCLASS_M_TBL(iclass->klass), clear_module_cache_i, (void *)iclass->klass); + RCLASS_M_TBL(iclass->klass) = klass_m_tbl; + VALUE origin = rb_include_class_new(klass_origin, RCLASS_SUPER(iclass->klass)); + RCLASS_SET_SUPER(iclass->klass, origin); + RCLASS_SET_INCLUDER(origin, RCLASS_INCLUDER(iclass->klass)); + RCLASS_SET_ORIGIN(iclass->klass, origin); + RICLASS_SET_ORIGIN_SHARED_MTBL(origin); + } + include_modules_at(iclass->klass, iclass->klass, module, FALSE); } - include_modules_at(iclass->klass, iclass->klass, module, FALSE); + iclass = iclass->next; } } diff --git a/version.h b/version.h index 912d34219f..80636ea154 100644 --- a/version.h +++ b/version.h @@ -11,7 +11,7 @@ https://github.com/ruby/ruby/blob/trunk/version.h#L11 # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 3 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 32 +#define RUBY_PATCHLEVEL 33 #define RUBY_RELEASE_YEAR 2022 #define RUBY_RELEASE_MONTH 6 -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/