[ruby-core:125174] [Ruby Bug#21977] Ruby::Box crash with `RUBY_BOX=1` via `Binding` refinement, `UnboundMethod#bind_call`, and `Symbol#to_proc`
Issue #21977 has been reported by singetu0096 (Rintaro Kawasugi). ---------------------------------------- Bug #21977: Ruby::Box crash with `RUBY_BOX=1` via `Binding` refinement, `UnboundMethod#bind_call`, and `Symbol#to_proc` https://bugs.ruby-lang.org/issues/21977 * Author: singetu0096 (Rintaro Kawasugi) * Status: Open * ruby -v: ruby 4.1.0dev (2026-03-24T21:47:14Z master 30dcc2a082) +PRISM [x86_64-linux] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- ## Summary I found a reproducible interpreter crash when Ruby is run with `RUBY_BOX=1`. A refinement on `Binding`, combined with `UnboundMethod#bind_call` and `Symbol#to_proc`, causes Ruby to abort with: ```text [BUG] BUG: Local ep without cme/box, flags: 66660087 ``` I reproduced this on: ```text ruby 4.1.0dev (2026-03-24T21:47:14Z master 30dcc2a082) +PRISM [x86_64-linux] ``` Follow-up validation confirmed an important discriminator: replacing `map(&:to_s)` with an explicit block such as `map { _1.to_s }` avoids the crash. The currently available evidence therefore points to a box/frame bookkeeping bug in the `Symbol#to_proc` path that reaches an explicit internal `rb_bug(...)` assertion, not to confirmed memory corruption. ## PoC ```ruby using Module.new { refine ::Binding do def eval_methods ::Kernel.instance_method(:methods).bind_call(receiver) end end } p binding.eval_methods.map(&:to_s) ``` Run: ```bash RUBY_BOX=1 ./miniruby -e ' using Module.new { refine ::Binding do def eval_methods ::Kernel.instance_method(:methods).bind_call(receiver) end end } p binding.eval_methods.map(&:to_s) ' ``` Observed result: ```text [BUG] BUG: Local ep without cme/box, flags: 66660087 ruby 4.1.0dev (2026-03-24T21:47:14Z master 30dcc2a082) +PRISM [x86_64-linux] Crashed while printing bug report ``` Important discriminator: ```ruby p binding.eval_methods.map { _1.to_s } ``` Replacing `map(&:to_s)` with an explicit block avoids the crash, which strongly suggests that the failure depends specifically on the `Symbol#to_proc` path rather than `map` in general. ## Impact The currently confirmed impact is denial of service in processes using Ruby::Box with `RUBY_BOX=1`. Confirmed claim: - reliable interpreter abort - trigger requires `RUBY_BOX=1` - trigger depends specifically on the `Symbol#to_proc` path in this setup Current non-claims: - no confirmed memory corruption - no confirmed sandbox escape - no confirmed privilege escalation - no confirmed arbitrary code execution This report should remain separate from the Ruby::Box double-free issue, because the trigger path, failure mode, and currently demonstrated impact are different. -- https://bugs.ruby-lang.org/
participants (1)
-
singetu0096 (Rintaro Kawasugi)