Bug #20493
closedSegfault on rb_io_getline_fast
Description
We've spotted a consistent segfault when running bundle install with --jobs 4
When running: bundle install -j 4
we'd get a Segfault at:
/usr/lib64/ruby/3.3.0/rubygems/ext/builder.rb:93: [BUG] Segmentation fault at 0x0000000000000014
ruby 3.3.1 (2024-04-23 revision c56cd86388) [x86_64-linux-gnu]
Full log is available here.
I could not find a shorter reproducer besides using bundler with --jobs 4
or
--jobs 8
.
Here's a sample command to trigger the behavior (it creates the Gemfile and
calls bundler) 1.
We installed all debug symbols and narrowed down the location of the segfault to
rb_io_getline_fast
in io.c
At line 4001 str
is T_NONE
, which makes further usage down the line in
io_enc_str
raise a null pointer dereference.
With the notes from extension.rdoc - Appendix E. RB_GC_GUARD to protect from premature GC I've prepared a patched ruby 3.3.1 package that does not
segfault. It's on OBS Project home:josegomezr:branches:ruby/ruby3.3.
Adding a RB_GC_GUARD
on rb_io_getline_fast
@ io.c:4004
just before the return
--- ruby3.3.orig/ruby-3.3.1/io.c
+++ ruby3.3/ruby-3.3.1/io.c
@@ -4004,6 +4004,7 @@ rb_io_getline_fast(rb_io_t *fptr, rb_enc
ENC_CODERANGE_SET(str, cr);
fptr->lineno++;
+ RB_GC_GUARD(str);
return str;
}
Fixes the segfault in our tests. bundle
finish the installation and the image is built.
I've set up a project in OBS to provide reproduceables.
- ruby3.3.1 package.
- ruby3.3.1 base image with enough dependencies to reproduce with the reproducer script.
And the corresponding container is exported in the containers-patched
repository.
Here I leave the docker images generated by OBS:
- 3.3.1 [without patches, segfaults.]
registry.opensuse.org/home/josegomezr/branches/ruby/containers/containers/base-ruby33:latest
- 3.3.1 [with patch, does not fail]
registry.opensuse.org/home/josegomezr/branches/ruby/containers/containers-patched/base-ruby33:latest