Project

General

Profile

Actions

Bug #22298

open

IO::Buffer is left unfreed with an invalid pointer when fiber scheduler raises

Bug #22298: IO::Buffer is left unfreed with an invalid pointer when fiber scheduler raises

Added by hanazuki (Kasumi Hanazuki) about 19 hours ago. Updated about 19 hours ago.

Status:
Open
Assignee:
-
Target version:
-
ruby -v:
ruby 4.1.0dev (2026-09-06T12:40:34Z master e536482403) +PRISM [x86_64-linux]
[ruby-core:126590]

Description

When an installed Fiber scheduler raises from its I/O hook, the temporary IO::Buffer passed to the hook is left unfreed. The buffer may then outlive the memory it wraps, so accessing it afterward can cause undefined behavior.

This only happens when the buffer escapes from the I/O callback, which is supposed to be a bug in the scheduler, but I think it is worth fixing silent memory corruption.

class Scheduler
  def block(*) = Fiber.yield
  def unblock(*) = nil
  def kernel_sleep(*) = nil
  def io_wait(*) = 0
  def fiber_interrupt(*) = nil

  def fiber(&block)
    Fiber.new(blocking: false, &block).tap(&:transfer)
  end

  def io_write(io, buffer, offset, length)
    $escape = buffer  # This buffer wraps a borrowed temporary memory
    fail
  end
end

r, w = IO.pipe

Fiber.set_scheduler(Scheduler.new)
Fiber.schedule { w.write('hello') } rescue nil

GC.start

p $escape  # .inspect will read freed memory
Actions

Also available in: PDF Atom