
Issue #21438 has been updated by k0kubun (Takashi Kokubun). Backport changed from 3.2: WONTFIX, 3.3: REQUIRED, 3.4: REQUIRED to 3.2: WONTFIX, 3.3: REQUIRED, 3.4: DONE ruby_3_4 commit:45ddafb95bd732f7305925a779cd8403ac30e1bf. ---------------------------------------- Bug #21438: use-after-free when resizing exivars https://bugs.ruby-lang.org/issues/21438#change-114042 * Author: byroot (Jean Boussier) * Status: Closed * Backport: 3.2: WONTFIX, 3.3: REQUIRED, 3.4: DONE ---------------------------------------- Here's a semi-reliable reproduction: ```ruby objs = 10_000.times.map do a = [] a.instance_variable_set(:@a, 1) a end GC.stress = true GC.auto_compact = true steps = 1000.times.map do a = [] a.instance_variable_set(:@a, 1) a.instance_variable_set(:@b, 2) a.instance_variable_set(:@c, 3) a.instance_variable_set(:@d, 4) a.instance_variable_set(:@e, 5) a.instance_variable_set(:@f, 6) a.instance_variable_set(:@g, 7) a.instance_variable_set(:@h, 8) # resize a.instance_variable_set(:@i, 9) a.instance_variable_set(:@j, 10) a end objs.clear GC.stress = false GC.auto_compact = false ``` The Exivar codepath uses `st_update` and allocate within the codebase. If GC trigger, it may remove entires from the table, or delete+insert in case of compaction, and this can trigger a table rebuild of the generic fields st_table in the middle of calling the st_update callback. This can cause entries to be reallocated or rearranged and the update to be for the wrong entry. Auto compaction isn't strictly required to trigger the bug, but makes it more likely. -- https://bugs.ruby-lang.org/