Do not pass a raw pointer as the recursion key to rb_exec_recursive()#1381
Open
koic wants to merge 1 commit into
Open
Do not pass a raw pointer as the recursion key to rb_exec_recursive()#1381koic wants to merge 1 commit into
koic wants to merge 1 commit into
Conversation
54679aa to
370361f
Compare
The spec added in 20ae94d passed a pointer to a 4-byte C stack struct as both the `obj` and `arg` arguments of rb_exec_recursive(). While `arg` is passed through to the callback as-is, `obj` is used as a key of the recursion guard hash in CRuby. Storing it there fires the GC write barrier, which reads the (8-byte) object flags from the non-object address, and AddressSanitizer reports a stack-buffer-overflow: ``` ==29649==ERROR: AddressSanitizer: stack-buffer-overflow ... READ of size 8 at 0x7f0d9b7c7b20 thread T0 #0 RB_BUILTIN_TYPE include/ruby/internal/value_type.h:191:30 ruby#1 rb_gc_impl_writebarrier gc/default/default.c:6621:5 ... ruby#6 exec_recursive thread.c:5602:13 ruby#7 kernel_spec_rb_exec_recursive_with_pointer spec/ruby/optional/capi/ext/kernel_spec.c:370:10 ``` This crash has been blocking the daily `ruby-head` releases of ruby/ruby-dev-builder (`build (ubuntu-24.04, asan)`) since 2026-07-08: https://github.com/ruby/ruby-dev-builder/actions/runs/29044853326 As a result, downstream CIs that use `ruby-head` via ruby/setup-ruby are stuck with the 2026-07-06 snapshot, which predates ruby/ruby@291d0d95ea ("onig_reg_copy_body: fix copying of exact_end"). This is how the problem was found: the "Spec - ubuntu head" job on the default branch of rubocop/rubocop keeps failing because `Regexp.new(regexp)` copies made for the `AllowedPatterns` config silently fail to match on that snapshot: https://github.com/rubocop/rubocop/actions/runs/29061954887/job/86265559997 The intent of the spec is that the callback argument is passed as-is, so keep the raw pointer for `arg` and use a real Ruby object as the recursion key.
370361f to
80e37cb
Compare
8 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The spec added in 20ae94d (for truffleruby/truffleruby#4334) passes a pointer to a 4-byte C stack struct as both the
objandargarguments ofrb_exec_recursive().While
argis passed through to the callback as-is,objis used as a key of the recursion guard hash in CRuby. Storing it there fires the GC write barrier, which reads the (8-byte) object flags from the non-object address, and AddressSanitizer reports a stack-buffer-overflow:User impact
Since this spec was synced into ruby/ruby (ruby/ruby@0d68ef6b77), the
build (ubuntu-24.04, asan)job of the https://github.com/ruby/ruby-dev-builder daily builds has been crashing inoptional/capi/kernel_spec.rb, blocking theruby-headreleases used byruby/setup-rubysince 2026-07-08 (e.g. https://github.com/ruby/ruby-dev-builder/actions/runs/29044853326).As a result, downstream CIs that use
ruby-headviaruby/setup-rubyare stuck with the 2026-07-06 snapshot, which predates ruby/ruby@291d0d95ea ("onig_reg_copy_body: fix copying of exact_end"). This is how the problem was found: the "Spec - ubuntu head" job on the default branch of rubocop/rubocop keeps failing becauseRegexp.new(regexp)copies made for theAllowedPatternsconfig silently fail to match on that snapshot:https://github.com/rubocop/rubocop/actions/runs/29061954887/job/86265559997
Fix
The intent of the spec is that the callback argument is passed as-is, so this change keeps the raw pointer for
argand uses a real Ruby object (self) as the recursion key. The example still passes on CRuby: