Project

General

Profile

Actions

Bug #21511

open

Use-after-free of the execution context after the fiber object carrying it is freed in GC

Added by tuonigou (tianyang sun) about 15 hours ago. Updated about 10 hours ago.

Status:
Open
Assignee:
-
Target version:
-
ruby -v:
ruby 3.4.1 (2025-06-13 revision de8de51182) +PRISM [x86_64-linux]
[ruby-core:122734]

Description

In bootstraptest/test_thread.rb,

assert_equal 'ok', %{
  File.write("zzz_t1.rb", <<-END)
      begin
        Thread.new { fork { GC.start } }.join
        pid, status = Process.wait2
        $result = status.success? ? :ok : :ng
      rescue NotImplementedError
        $result = :ok
      end
    END
  require "./zzz_t1.rb"
  $result
}
# in build/
make btest BTESTS="file_containing_above.rb" 
# or
ruby --disable=gems  "../bootstraptest/runner.rb" --ruby="./miniruby -I../lib -I. -I.ext/common  -r./x86_64-linux-fake --disable-gems" file_containing_above.rb

Suppose thread 1 called the Thread.new and created thread 2

The forked process by thread 2 that initiates GC with GC.start would sweep the fiber object embedded in RTypedData in the gc_sweep_rest() stage of sweep in fiber_free(). That fiber object contains the execution context of thread 1, rb_execution_context_t saved_ec field of cont.

Since the fiber object is freed, the allocated area pointed by it should be invalid, including the embedded struct for ec, but after thread 2 joins, thread 1 still uses the ec in rb_current_thread(), causing a use after free.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0