ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:122518] [Ruby Bug#21438] use-after-free when resizing exivars
@ 2025-06-11 19:23 byroot (Jean Boussier) via ruby-core
  2025-06-16  7:16 ` [ruby-core:122540] " byroot (Jean Boussier) via ruby-core
  2025-06-17  7:53 ` [ruby-core:122545] " byroot (Jean Boussier) via ruby-core
  0 siblings, 2 replies; 3+ messages in thread
From: byroot (Jean Boussier) via ruby-core @ 2025-06-11 19:23 UTC (permalink / raw)
  To: ruby-core; +Cc: byroot (Jean Boussier)

Issue #21438 has been reported by byroot (Jean Boussier).

----------------------------------------
Bug #21438: use-after-free when resizing exivars
https://bugs.ruby-lang.org/issues/21438

* Author: byroot (Jean Boussier)
* Status: Open
* Backport: 3.2: WONTFIX, 3.3: REQUIRED, 3.4: REQUIRED
----------------------------------------
Here's a semi-reliable reproduction: 

```ruby
objs = 10_000.times.map do
  a = []
  a.instance_variable_set(:@a, 1)
  a
end

GC.stress = true
GC.auto_compact = true

steps = 1000.times.map do
  a = []
  a.instance_variable_set(:@a, 1)
  a.instance_variable_set(:@b, 2)
  a.instance_variable_set(:@c, 3)
  a.instance_variable_set(:@d, 4)
  a.instance_variable_set(:@e, 5)
  a.instance_variable_set(:@f, 6)
  a.instance_variable_set(:@g, 7)
  a.instance_variable_set(:@h, 8)
  # resize
  a.instance_variable_set(:@i, 9)
  a.instance_variable_set(:@j, 10)
  a
end
objs.clear

GC.stress = false
GC.auto_compact = false
```

The Exivar codepath uses `st_update` and allocate within the codebase.

If GC trigger, it may remove entires from the table, or delete+insert in case of compaction, and this can trigger a table rebuild of the generic fields st_table in the middle of calling the st_update callback.
This can cause entries to be reallocated or rearranged and the update to be for the wrong entry.

Auto compaction isn't strictly required to trigger the bug, but makes it more likely.





-- 
https://bugs.ruby-lang.org/
______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [ruby-core:122540] [Ruby Bug#21438] use-after-free when resizing exivars
  2025-06-11 19:23 [ruby-core:122518] [Ruby Bug#21438] use-after-free when resizing exivars byroot (Jean Boussier) via ruby-core
@ 2025-06-16  7:16 ` byroot (Jean Boussier) via ruby-core
  2025-06-17  7:53 ` [ruby-core:122545] " byroot (Jean Boussier) via ruby-core
  1 sibling, 0 replies; 3+ messages in thread
From: byroot (Jean Boussier) via ruby-core @ 2025-06-16  7:16 UTC (permalink / raw)
  To: ruby-core; +Cc: byroot (Jean Boussier)

Issue #21438 has been updated by byroot (Jean Boussier).

Status changed from Closed to Open

Reopening because the fix we merged need some more work:

```
ruby(rb_vm_bugreport) ../src/vm_dump.c:1175
ruby(rb_bug_for_fatal_signal+0xf5) [0x55800a5c2d45] ../src/error.c:1130
ruby(sigsegv+0x46) [0x55800a31d176] ../src/signal.c:934
ruby(RVALUE_WB_UNPROTECTED+0x14) [0x55800a20e3cd] ../src/gc/default/default.c:1195
ruby(rgengc_check_relation) ../src/gc/default/default.c:4300
ruby(RVALUE_MARKED+0x0) [0x55800a217f31] ../src/gc/default/default.c:4369
ruby(gc_mark_set) ../src/gc/default/default.c:4311
ruby(gc_mark) ../src/gc/default/default.c:4370
ruby(rb_mark_generic_ivar+0xa8) [0x55800a397828] ../src/variable.c:1249
ruby(rb_gc_mark_children+0x108) [0x55800a218618] ../src/gc.c:3145
ruby(gc_mark_stacked_objects+0x76) [0x55800a21c58e] ../src/gc/default/default.c:4563
ruby(gc_mark_stacked_objects_all) ../src/gc/default/default.c:4622
ruby(gc_marks_rest) ../src/gc/default/default.c:5639
ruby(gc_marks+0x55a) [0x55800a220ff2] ../src/gc/default/default.c:5753
ruby(gc_start) ../src/gc/default/default.c:6425
ruby(rb_multi_ractor_p+0x0) [0x55800a222569] ../src/gc/default/default.c:6307
ruby(rb_vm_lock_leave) ../src/vm_sync.h:101
ruby(rb_gc_vm_unlock) ../src/gc.c:144
ruby(garbage_collect) ../src/gc/default/default.c:6309
ruby(objspace_malloc_gc_stress+0x2a) [0x55800a223dce] ../src/gc/default/default.c:7930
ruby(rb_gc_impl_malloc) ../src/gc/default/default.c:7921
ruby(handle_malloc_failure+0x0) [0x55800a224313] ../src/gc.c:5231
ruby(ruby_xmalloc) ../src/gc.c:5221
ruby(get_allocated_entries+0x0) [0x55800a328af2] ../src/st.c:551
ruby(rb_st_init_existing_table_with_size) ../src/st.c:559
ruby(rebuild_table+0xb6) [0x55800a328c46] ../src/st.c:585
ruby(rebuild_table_if_necessary+0x8) [0x55800a3298b0] ../src/st.c:1125
ruby(rb_st_insert) ../src/st.c:1143
ruby(generic_ivar_set_shape_fields+0x228) [0x55800a39ac38] ../src/variable.c:1846
ruby(general_ivar_set+0x17f) [0x55800a39306f] ../src/variable.c:1760
ruby(generic_ivar_set+0x0) [0x55800a39f02d] ../src/variable.c:1909
ruby(ivar_set) ../src/variable.c:2094
ruby(rb_ivar_set) ../src/variable.c:2103
```

https://github.com/ruby/ruby/actions/runs/15663763782/job/44125172775#step:12:385

----------------------------------------
Bug #21438: use-after-free when resizing exivars
https://bugs.ruby-lang.org/issues/21438#change-113768

* Author: byroot (Jean Boussier)
* Status: Open
* Backport: 3.2: WONTFIX, 3.3: REQUIRED, 3.4: REQUIRED
----------------------------------------
Here's a semi-reliable reproduction: 

```ruby
objs = 10_000.times.map do
  a = []
  a.instance_variable_set(:@a, 1)
  a
end

GC.stress = true
GC.auto_compact = true

steps = 1000.times.map do
  a = []
  a.instance_variable_set(:@a, 1)
  a.instance_variable_set(:@b, 2)
  a.instance_variable_set(:@c, 3)
  a.instance_variable_set(:@d, 4)
  a.instance_variable_set(:@e, 5)
  a.instance_variable_set(:@f, 6)
  a.instance_variable_set(:@g, 7)
  a.instance_variable_set(:@h, 8)
  # resize
  a.instance_variable_set(:@i, 9)
  a.instance_variable_set(:@j, 10)
  a
end
objs.clear

GC.stress = false
GC.auto_compact = false
```

The Exivar codepath uses `st_update` and allocate within the codebase.

If GC trigger, it may remove entires from the table, or delete+insert in case of compaction, and this can trigger a table rebuild of the generic fields st_table in the middle of calling the st_update callback.
This can cause entries to be reallocated or rearranged and the update to be for the wrong entry.

Auto compaction isn't strictly required to trigger the bug, but makes it more likely.





-- 
https://bugs.ruby-lang.org/
______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [ruby-core:122545] [Ruby Bug#21438] use-after-free when resizing exivars
  2025-06-11 19:23 [ruby-core:122518] [Ruby Bug#21438] use-after-free when resizing exivars byroot (Jean Boussier) via ruby-core
  2025-06-16  7:16 ` [ruby-core:122540] " byroot (Jean Boussier) via ruby-core
@ 2025-06-17  7:53 ` byroot (Jean Boussier) via ruby-core
  1 sibling, 0 replies; 3+ messages in thread
From: byroot (Jean Boussier) via ruby-core @ 2025-06-17  7:53 UTC (permalink / raw)
  To: ruby-core; +Cc: byroot (Jean Boussier)

Issue #21438 has been updated by byroot (Jean Boussier).

Status changed from Open to Closed

The remaining issue was fixed in 055fef00a1c27fdc8293114dc134ca7910b1dc79.

Backport PRs:

  - 3.4: https://github.com/ruby/ruby/pull/13637
  - 3.3: https://github.com/ruby/ruby/pull/13638

Note that the bug while possible is quite unlikely on older branches as it requires 9 ivars instead of 4, so maintainers should feel free to not backport.

----------------------------------------
Bug #21438: use-after-free when resizing exivars
https://bugs.ruby-lang.org/issues/21438#change-113776

* Author: byroot (Jean Boussier)
* Status: Closed
* Backport: 3.2: WONTFIX, 3.3: REQUIRED, 3.4: REQUIRED
----------------------------------------
Here's a semi-reliable reproduction: 

```ruby
objs = 10_000.times.map do
  a = []
  a.instance_variable_set(:@a, 1)
  a
end

GC.stress = true
GC.auto_compact = true

steps = 1000.times.map do
  a = []
  a.instance_variable_set(:@a, 1)
  a.instance_variable_set(:@b, 2)
  a.instance_variable_set(:@c, 3)
  a.instance_variable_set(:@d, 4)
  a.instance_variable_set(:@e, 5)
  a.instance_variable_set(:@f, 6)
  a.instance_variable_set(:@g, 7)
  a.instance_variable_set(:@h, 8)
  # resize
  a.instance_variable_set(:@i, 9)
  a.instance_variable_set(:@j, 10)
  a
end
objs.clear

GC.stress = false
GC.auto_compact = false
```

The Exivar codepath uses `st_update` and allocate within the codebase.

If GC trigger, it may remove entires from the table, or delete+insert in case of compaction, and this can trigger a table rebuild of the generic fields st_table in the middle of calling the st_update callback.
This can cause entries to be reallocated or rearranged and the update to be for the wrong entry.

Auto compaction isn't strictly required to trigger the bug, but makes it more likely.





-- 
https://bugs.ruby-lang.org/
______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-06-17  7:54 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-06-11 19:23 [ruby-core:122518] [Ruby Bug#21438] use-after-free when resizing exivars byroot (Jean Boussier) via ruby-core
2025-06-16  7:16 ` [ruby-core:122540] " byroot (Jean Boussier) via ruby-core
2025-06-17  7:53 ` [ruby-core:122545] " byroot (Jean Boussier) via ruby-core

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).