Project

General

Profile

Actions

Bug #22240

open

Protect against SEGV caused by native extensions using rb_funcall between rb_protect and rb_jump_tag

Bug #22240: Protect against SEGV caused by native extensions using rb_funcall between rb_protect and rb_jump_tag

Added by rwstauner (Randy Stauner) 2 months ago. Updated 4 days ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:126364]

Description

It's possible for native extensions do something like

int state = 0;
rb_protect(some_func, Qnil, &state);
if (state) {
    rb_funcall(self, rb_intern("handler"), 0);
    rb_jump_tag(state);
}

If the ruby code in the rb_funcall has a rescue clause it will clear errinfo.

When rb_jump_tag flows to hook_before_rewind with errinfo as Qnil it currently will SEGV.

If I add a check to avoid the SEGV, the process then exits silently.

If a native extension puts us in this state, the original message is gone.

One thing we can do is detect this scenario and fabricate an exception.

I have a PR up with a possible solution for this but am looking for feedback on the exception type and message or alternative suggestions for handling.

I have reproduced this crash as far back as Ruby 3.3.

Updated by rwstauner (Randy Stauner) 2 months ago Actions #2 [ruby-core:126394]

So far I have discovered that this bug was possible to encounter with
bootsnap before https://github.com/rails/bootsnap/pull/564
and with
io-event before https://github.com/socketry/io-event/pull/209

Updated by rwstauner (Randy Stauner) 10 days ago Actions #3 [ruby-core:127030]

https://bugs.ruby-lang.org/issues/22415 is a similar issue but the tracking failure is inside Ruby, not a native extensions.

Updated by rwstauner (Randy Stauner) 4 days ago Actions #4 [ruby-core:127135]

I also found where magnus is explicitly setting errinfo to nil:
https://github.com/matsadler/magnus/pull/188

If a magnus-backed function was called from an exception handler
(prior to #22415) it could also lead to this SEGV.

Actions

Also available in: PDF Atom