Skip to content

Commit 14cdd88

Browse files
committed
[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.
1 parent 52287c6 commit 14cdd88

File tree

2 files changed

+14
-6
lines changed

2 files changed

+14
-6
lines changed

vm_insnhelper.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2120,8 +2120,9 @@ vm_evict_cc(VALUE klass, VALUE cc_tbl, ID mid)
21202120
return;
21212121
}
21222122

2123-
struct rb_class_cc_entries *ccs = NULL;
2124-
rb_managed_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs);
2123+
VALUE ccs_obj = 0;
2124+
rb_managed_id_table_lookup(cc_tbl, mid, &ccs_obj);
2125+
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_obj;
21252126

21262127
if (!ccs || !METHOD_ENTRY_INVALIDATED(ccs->cme)) {
21272128
// 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)
21822183
if (ccs == NULL) {
21832184
VM_ASSERT(cc_tbl);
21842185

2185-
if (!LIKELY(rb_managed_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs))) {
2186+
VALUE ccs_obj;
2187+
if (UNLIKELY(rb_managed_id_table_lookup(cc_tbl, mid, &ccs_obj))) {
2188+
ccs = (struct rb_class_cc_entries *)ccs_obj;
2189+
}
2190+
else {
21862191
// TODO: required?
21872192
ccs = vm_ccs_create(klass, cc_tbl, mid, cme);
21882193
}
@@ -2217,7 +2222,9 @@ vm_lookup_cc(const VALUE klass, const struct rb_callinfo * const ci, ID mid)
22172222
// CCS data is keyed on method id, so we don't need the method id
22182223
// for doing comparisons in the `for` loop below.
22192224

2220-
if (rb_managed_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) {
2225+
VALUE ccs_obj;
2226+
if (rb_managed_id_table_lookup(cc_tbl, mid, &ccs_obj)) {
2227+
ccs = (struct rb_class_cc_entries *)ccs_obj;
22212228
const int ccs_len = ccs->len;
22222229

22232230
if (UNLIKELY(METHOD_ENTRY_INVALIDATED(ccs->cme))) {

vm_method.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,9 @@ rb_vm_ccs_invalidate_and_free(struct rb_class_cc_entries *ccs)
195195
void
196196
rb_vm_cc_table_delete(VALUE table, ID mid)
197197
{
198-
struct rb_class_cc_entries *ccs;
199-
if (rb_managed_id_table_lookup(table, mid, (VALUE *)&ccs)) {
198+
VALUE ccs_obj;
199+
if (rb_managed_id_table_lookup(table, mid, &ccs_obj)) {
200+
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_obj;
200201
rb_managed_id_table_delete(table, mid);
201202
rb_vm_ccs_invalidate_and_free(ccs);
202203
}

0 commit comments

Comments
 (0)