Actions
Bug #21438
closeduse-after-free when resizing exivars
Description
Here's a semi-reliable reproduction:
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.
Actions
Like1
Like0Like0Like0