Actions
Bug #21198
openFiber::Scheduler#blocking_operation_wait crash due to stack-use-after-return
Description
The Fiber::Scheduler#blocking_operation_wait method is passed a proc through the rb_fiber_scheduler_blocking_operation_wait
function. This function stack allocates the arguments used for the proc (source). If this proc is captured anywhere, then calling it again will illegally read from and write to stack space.
The following script demonstrates this issue using the test/fiber/scheduler.rb scheduler:
require_relative "test/fiber/scheduler"
class MyScheduler < Scheduler
def blocking_operation_wait(work)
super
$work = work
end
end
scheduler = MyScheduler.new
Fiber.set_scheduler(scheduler)
require "tempfile"
Fiber.schedule do
file = Tempfile.new
file.write("hello world!")
$work.call
end
scheduler.run
Crashes with:
test.rb:19: [BUG] Bus Error at 0xce0f57696add0045
ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [arm64-darwin24]
-- Crash Report log information --------------------------------------------
See Crash Report log file in one of the following locations:
* ~/Library/Logs/DiagnosticReports
* /Library/Logs/DiagnosticReports
for more details.
Don't forget to include the above Crash Report log file in bug reports.
-- Control frame information -----------------------------------------------
c:0003 p:---- s:0010 e:000009 IFUNC
c:0002 p:0017 s:0007 e:000006 BLOCK test.rb:19 [FINISH]
c:0001 p:---- s:0003 e:000002 DUMMY [FINISH]
-- Ruby level backtrace information ----------------------------------------
test.rb:19:in 'block in <main>'
-- Threading information ---------------------------------------------------
Total ractor count: 1
Ruby thread count for this ractor: 1
Note that the Fiber scheduler is enabled
-- Machine register context ------------------------------------------------
x0: 0x000000010063a5f0 x1: 0x000000014b80ce00 x2: 0x0000000000000000
x3: 0x000000014b60f060 x4: 0x0000000000000000 x5: 0x0000000000000000
x6: 0x0000000000000004 x7: 0x0000000000000000 x18: 0x0000000000000000
x19: 0x000000014b6a4840 x20: 0xce0f57696add0045 x21: 0x000000010063a5f0
x22: 0x000000014b60f060 x23: 0x0000000000000000 x24: 0x000000014b60f998
x25: 0x0000000000014273 x26: 0x000000014b60f060 x27: 0x000000014b60f060
x28: 0x000000014b80ce00 lr: 0x0000000100d881d8 fp: 0x000000011bb039f0
sp: 0x000000011bb03980
-- C level backtrace information -------------------------------------------
SEGV received in BUS handler
[1] 52599 abort ruby test.rb
Updated by ioquatix (Samuel Williams) 4 days ago
A solution to this would be to invalidate the proc afterwards. I don't know if this is possible but I can take a look.
Actions
Like0
Like0