aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2022-12-19 11:21:16 -0500
committerPeter Zhu <peter@peterzhu.ca>2022-12-19 13:13:26 -0500
commit8275cad1e1646a2b301962313dc3e8ff1deb87b3 (patch)
treea4ceda3cf6b87f5078c01841c3eea9ac4829f8ec
parentb2f53dccbedd9f399bc4668eb02f26b2eafa6f5c (diff)
downloadruby-8275cad1e1646a2b301962313dc3e8ff1deb87b3.tar.gz
Fix buffer overrun when re-embedding objects
We eagerly set the new shape of an object when moving an object during compaction. This new shape may have a different capacity than the current original shape capacity. This means that we cannot copy from the original buffer using size of the new capacity. Instead, we should use the ivar count (which is less than or equal to both the new and original capacities). Co-Authored-By: Matt Valentine-House <matt@eightbitraptor.com>
-rw-r--r--gc.c6
1 files changed, 2 insertions, 4 deletions
diff --git a/gc.c b/gc.c
index 3f6a1bde51..785235046b 100644
--- a/gc.c
+++ b/gc.c
@@ -10118,13 +10118,11 @@ gc_ref_update_object(rb_objspace_t *objspace, VALUE v)
}
#if USE_RVARGC
- uint32_t numiv = ROBJECT_IV_CAPACITY(v);
-
size_t slot_size = rb_gc_obj_slot_size(v);
- size_t embed_size = rb_obj_embedded_size(numiv);
+ size_t embed_size = rb_obj_embedded_size(ROBJECT_IV_CAPACITY(v));
if (slot_size >= embed_size && !RB_FL_TEST_RAW(v, ROBJECT_EMBED)) {
// Object can be re-embedded
- memcpy(ROBJECT(v)->as.ary, ptr, sizeof(VALUE) * numiv);
+ memcpy(ROBJECT(v)->as.ary, ptr, sizeof(VALUE) * ROBJECT_IV_COUNT(v));
RB_FL_SET_RAW(v, ROBJECT_EMBED);
if (ROBJ_TRANSIENT_P(v)) {
ROBJ_TRANSIENT_UNSET(v);