From 14cdd88970a2f1ec07bf97a5de50a47f4f6e7e4f Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Thu, 2 Oct 2025 18:39:24 -0400 Subject: [PATCH] [Bug #21620] Fix strict aliasing in rb_managed_id_table_lookup We cannot pass &ccs into rb_managed_id_table_lookup because rb_managed_id_table_lookup takes in a VALUE*, so it violates strict aliasing in C. This causes segfaults when compiling with LTO enabled. --- vm_insnhelper.c | 15 +++++++++++---- vm_method.c | 5 +++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/vm_insnhelper.c b/vm_insnhelper.c index d50b11e377..f4f0314ed9 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -2120,8 +2120,9 @@ vm_evict_cc(VALUE klass, VALUE cc_tbl, ID mid) return; } - struct rb_class_cc_entries *ccs = NULL; - rb_managed_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs); + VALUE ccs_obj = 0; + rb_managed_id_table_lookup(cc_tbl, mid, &ccs_obj); + struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_obj; if (!ccs || !METHOD_ENTRY_INVALIDATED(ccs->cme)) { // Another ractor replaced that entry while we were waiting on the VM lock. @@ -2182,7 +2183,11 @@ vm_populate_cc(VALUE klass, const struct rb_callinfo * const ci, ID mid) if (ccs == NULL) { VM_ASSERT(cc_tbl); - if (!LIKELY(rb_managed_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs))) { + VALUE ccs_obj; + if (UNLIKELY(rb_managed_id_table_lookup(cc_tbl, mid, &ccs_obj))) { + ccs = (struct rb_class_cc_entries *)ccs_obj; + } + else { // TODO: required? ccs = vm_ccs_create(klass, cc_tbl, mid, cme); } @@ -2217,7 +2222,9 @@ retry: // CCS data is keyed on method id, so we don't need the method id // for doing comparisons in the `for` loop below. - if (rb_managed_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) { + VALUE ccs_obj; + if (rb_managed_id_table_lookup(cc_tbl, mid, &ccs_obj)) { + ccs = (struct rb_class_cc_entries *)ccs_obj; const int ccs_len = ccs->len; if (UNLIKELY(METHOD_ENTRY_INVALIDATED(ccs->cme))) { diff --git a/vm_method.c b/vm_method.c index 16f402e893..60c273ff2f 100644 --- a/vm_method.c +++ b/vm_method.c @@ -195,8 +195,9 @@ rb_vm_ccs_invalidate_and_free(struct rb_class_cc_entries *ccs) void rb_vm_cc_table_delete(VALUE table, ID mid) { - struct rb_class_cc_entries *ccs; - if (rb_managed_id_table_lookup(table, mid, (VALUE *)&ccs)) { + VALUE ccs_obj; + if (rb_managed_id_table_lookup(table, mid, &ccs_obj)) { + struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_obj; rb_managed_id_table_delete(table, mid); rb_vm_ccs_invalidate_and_free(ccs); }