Actions
Bug #21996
openCrash when modifying instance variables during inspect or Marshal dump
Bug #21996:
Crash when modifying instance variables during inspect or Marshal dump
Description
In #15968 describes an issue where instance variables being modified lead to incorrect Marshal output being generated, which was partially solved by checking for the number of IVs changing and raising an exception. However, if enough IVs removed this could cause the buffer to be moved/re-embedded, but we'd still attempt to read the now removed variables. I've found this reproduces back to Ruby 3.3, but suspect there are other ways to hit issues on older versions.
We've seen the test from #15968 start failing on CI recently (likely because the changes to size pools makes this crash reproducible) https://github.com/ruby/ruby/actions/runs/24247666394/job/70803324392
class Evil
def initialize(parent)
@parent = parent
end
def marshal_dump
@parent.instance_variables.each { |v| @parent.remove_instance_variable(v) }
{}
end
def marshal_load(data) = nil
end
obj = Object.new
obj.instance_variable_set(:@evil, Evil.new(obj))
10.times { |i| obj.instance_variable_set(:"@v#{i}", 0) }
Marshal.dump(obj) # SEGV
class Evil
def initialize(parent)
@parent = parent
end
def inspect
@parent.instance_variables.each { |v| @parent.remove_instance_variable(v) }
""
end
end
obj = Object.new
obj.instance_variable_set(:@evil, Evil.new(obj))
10.times { |i| obj.instance_variable_set(:"@v#{i}", 0) }
obj.inspect # SEGV
Updated by jhawthorn (John Hawthorn) about 9 hours ago
- Related to Bug #15968: Custom marshal_load methods allow object instance variables to "leak" into other objects added
Actions