Project

General

Profile

Actions

Bug #22214

closed

SEGV when struct ractor_port.r is referenced after Ractor::Port.allocate

Bug #22214: SEGV when struct ractor_port.r is referenced after Ractor::Port.allocate

Added by himura467 (Akito Shitara) 7 days ago. Updated 7 days ago.

Status:
Closed
Target version:
-
[ruby-core:126183]

Description

Ractor::Port has a public allocator, so Ractor::Port.allocate returns a port whose owner Ractor (struct ractor_port.r) is still NULL; only ractor_port_init() fills it in. Methods dereference it without a check.

Ractor::Port.allocate.closed?
<internal:ractor>:829: [BUG] Segmentation fault at 0x0000000000000060
ruby 4.1.0dev (2026-07-26T18:55:18Z master eb9d72aea1) +PRISM [arm64-darwin25]

-- Ruby level backtrace information ----------------------------------------
-e:1:in '<main>'
<internal:ractor>:829:in 'closed?'

-- C level backtrace information -------------------------------------------
ruby(rb_native_mutex_lock+0xc) [0x104f922fc] ../thread_pthread.c:127
ruby(ractor_port_closed_p+0x30) [0x104efc2f8] ../ractor.c:74
ruby(builtin_inline_class_829) ../ractor.rb:830
ruby(builtin_invoker0+0x8) [0x104fd76ac] ../vm_insnhelper.c:7392

#send and Ractor#monitor / #unmonitor fault at the same address, #inspect at 0x8 in rb_ractor_id().

#receive and #close happen to raise Ractor::Error, but only because their rp->r != current ractor check catches NULL by accident, so they report the port as belonging to another Ractor.

Ractor.select does not crash, because ractor_try_receive() keys only on rp->id_. That field is 0 for an uninitialized port, which is also the id of the current Ractor's default port, so the port takes messages from it:

port = Ractor::Port.allocate
Ractor.current.default_port.send(:hello)
p Ractor.select(port)[1]  #=> :hello
Actions

Also available in: PDF Atom