Commit 928fea3
committed
Fix crash when $LOADED_FEATURES is modified during require
[Bug #21567]
When we require an object that is not a string, it will attempt to convert
it to a string by calling to_str on it. If we modify the $LOADED_FEATURES
array while it calls to_str, Ruby can crash because it can end up inserting
the string in the wrong index in the array.
For example, the following script crashes:
require "tempfile"
class MyString
def initialize(path)
@path = path
end
def to_str
$LOADED_FEATURES.clear
@path
end
def to_path = @path
end
def create_ruby_file = Tempfile.create(["test", ".rb"]).path
require MyString.new(create_ruby_file)
$LOADED_FEATURES.unshift(create_ruby_file)
$LOADED_FEATURES << MyString.new(create_ruby_file)
require create_ruby_file
Crash log:
test.rb:21: [BUG] Segmentation fault at 0x0000000000000004
ruby 3.5.0dev (2025-09-09T09:29:35Z master ce94add) +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:0011 e:000010 CFUNC :require
c:0002 p:0076 s:0006 e:000005 EVAL test.rb:21 [FINISH]
c:0001 p:0000 s:0003 E:0001b0 DUMMY [FINISH]
-- Ruby level backtrace information ----------------------------------------
test.rb:21:in '<main>'
test.rb:21:in 'require'
-- Threading information ---------------------------------------------------
Total ractor count: 1
Ruby thread count for this ractor: 1
-- Machine register context ------------------------------------------------
x0: 0x0000000000000004 x1: 0x000000000000c800 x2: 0x0000000000000000
x3: 0x0000000000000000 x4: 0x0000000000000205 x5: 0x0000000000000000
x6: 0x0000000000000000 x7: 0x0000000000000001 x18: 0x0000000000000000
x19: 0x0000000209dfc0b0 x20: 0x0000000209dfc018 x21: 0x000000016ee8ab58
x22: 0x0fffffff0009d71d x23: 0x0000000209dfc018 x24: 0x0000000209dfc150
x25: 0x000000016ee8acc0 x26: 0x0000000000000000 x27: 0x0000000000000000
x28: 0x0000000000000000 lr: 0x0000000101244140 fp: 0x000000016ee887f0
sp: 0x000000016ee887d0
-- C level backtrace information -------------------------------------------
miniruby(rb_print_backtrace+0x24) [0x101317b08] vm_dump.c:843
miniruby(rb_print_backtrace) (null):0
miniruby(rb_vm_bugreport+0x26c) [0x101317d94] vm_dump.c:1175
miniruby(rb_bug_for_fatal_signal+0xa4) [0x10105ddac] error.c:1130
miniruby(sig_do_nothing+0x0) [0x1012278c0] signal.c:948
miniruby(sigsegv) (null):0
/usr/lib/system/libsystem_platform.dylib(_sigtramp+0x38) [0x19c1216a4]
miniruby(rb_str_new_frozen+0x1c) [0x101244140] string.c:1495
miniruby(rb_check_realpath_internal+0x68) [0x101077804] file.c:4679
miniruby(rb_check_realpath+0x2c) [0x101077aa4] file.c:4765
miniruby(get_loaded_features_index+0x37c) [0x1010f9c94] load.c:467
miniruby(rb_feature_p+0xd0) [0x1010f8174] load.c:582
miniruby(search_required+0xac) [0x1010f6ad4] load.c:1193
miniruby(require_internal+0x274) [0x1010f7518] load.c:1424
miniruby(rb_require_string_internal+0x94) [0x1010f6830] load.c:1571
miniruby(rb_require_string+0x58) [0x1010f66e8] load.c:1557
miniruby(rb_f_require+0x1c) [0x1010f6684] load.c:1150
miniruby(ractor_safe_call_cfunc_1+0x38) [0x101306c28] vm_insnhelper.c:3696
miniruby(vm_call_cfunc_with_frame_+0x250) [0x1012f857c] vm_insnhelper.c:3873
miniruby(vm_call_cfunc_with_frame+0x6c) [0x1012f8834] vm_insnhelper.c:3919
miniruby(vm_sendish+0x1a8) [0x1012c990c] vm_insnhelper.c:6087
miniruby(vm_exec_core+0x4050) [0x1012cfb48] insns.def:900
miniruby(vm_exec_loop+0x80) [0x1012e5448] vm.c:2666
miniruby(rb_vm_exec+0x134) [0x1012c9b40] vm.c:2645
miniruby(rb_iseq_eval_main+0x34) [0x1012e5628] vm.c:2919
miniruby(rb_ec_exec_node+0xe4) [0x10106d094] eval.c:282
miniruby(ruby_run_node+0x94) [0x10106cf64] eval.c:320
miniruby(rb_main+0x40) [0x100f7499c] main.c:42
miniruby(main+0x60) [0x100f74928] main.c:621 parent 624538b commit 928fea3
2 files changed
+33
-0
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
447 | 447 | | |
448 | 448 | | |
449 | 449 | | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
450 | 455 | | |
451 | 456 | | |
452 | 457 | | |
| |||
456 | 461 | | |
457 | 462 | | |
458 | 463 | | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
459 | 468 | | |
460 | 469 | | |
461 | 470 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
840 | 840 | | |
841 | 841 | | |
842 | 842 | | |
| 843 | + | |
| 844 | + | |
| 845 | + | |
| 846 | + | |
| 847 | + | |
| 848 | + | |
| 849 | + | |
| 850 | + | |
| 851 | + | |
| 852 | + | |
| 853 | + | |
| 854 | + | |
| 855 | + | |
| 856 | + | |
| 857 | + | |
| 858 | + | |
| 859 | + | |
| 860 | + | |
| 861 | + | |
| 862 | + | |
| 863 | + | |
| 864 | + | |
| 865 | + | |
| 866 | + | |
843 | 867 | | |
844 | 868 | | |
845 | 869 | | |
| |||
0 commit comments