Repository navigation
Commit 54679aa
committed
Do not pass a raw pointer as the recursion key to rb_exec_recursive()
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
#1 rb_gc_impl_writebarrier gc/default/default.c:6621:5
...
#6 exec_recursive thread.c:5602:13
#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 releases of
https://github.com/ruby/ruby-dev-builder (`build (ubuntu-24.04, asan)`)
since 2026-07-08.
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.1 parent 072057e commit 54679aa
1 file changed
Lines changed: 2 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
352 | 352 | | |
353 | 353 | | |
354 | 354 | | |
355 | | - | |
356 | 355 | | |
357 | | - | |
| 356 | + | |
358 | 357 | | |
359 | 358 | | |
360 | 359 | | |
| |||
367 | 366 | | |
368 | 367 | | |
369 | 368 | | |
370 | | - | |
| 369 | + | |
371 | 370 | | |
372 | 371 | | |
373 | 372 | | |
| |||
0 commit comments