aboutsummaryrefslogtreecommitdiffstats
path: root/transient_heap.c
diff options
context:
space:
mode:
author卜部昌平 <shyouhei@ruby-lang.org>2019-10-07 16:56:08 +0900
committer卜部昌平 <shyouhei@ruby-lang.org>2019-10-09 12:12:28 +0900
commit7e0ae1698d4db0baec858a46de8d1ae875360cf5 (patch)
tree646fbe720b13469679973060b8ab5299cf076236 /transient_heap.c
parenta220410be70264a0e4089c4d63a9c22dd688ca7c (diff)
downloadruby-7e0ae1698d4db0baec858a46de8d1ae875360cf5.tar.gz
avoid overflow in integer multiplication
This changeset basically replaces `ruby_xmalloc(x * y)` into `ruby_xmalloc2(x, y)`. Some convenient functions are also provided for instance `rb_xmalloc_mul_add(x, y, z)` which allocates x * y + z byes.
Diffstat (limited to 'transient_heap.c')
-rw-r--r--transient_heap.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/transient_heap.c b/transient_heap.c
index dcf65fc7ab..6cdd34284f 100644
--- a/transient_heap.c
+++ b/transient_heap.c
@@ -440,6 +440,9 @@ Init_TransientHeap(void)
theap->promoted_objects_index = 0;
/* should not use ALLOC_N to be free from GC */
theap->promoted_objects = malloc(sizeof(VALUE) * theap->promoted_objects_size);
+ STATIC_ASSERT(
+ integer_overflow,
+ sizeof(VALUE) <= SIZE_MAX / TRANSIENT_HEAP_PROMOTED_DEFAULT_SIZE);
if (theap->promoted_objects == NULL) rb_bug("Init_TransientHeap: malloc failed.");
}
@@ -618,7 +621,13 @@ transient_heap_promote_add(struct transient_heap* theap, VALUE obj)
if (theap->promoted_objects_size <= theap->promoted_objects_index) {
theap->promoted_objects_size *= 2;
if (TRANSIENT_HEAP_DEBUG >= 1) fprintf(stderr, "rb_transient_heap_promote: expand table to %d\n", theap->promoted_objects_size);
- theap->promoted_objects = realloc(theap->promoted_objects, theap->promoted_objects_size * sizeof(VALUE));
+ if (UNLIKELY((size_t)theap->promoted_objects_size > SIZE_MAX / sizeof(VALUE))) {
+ /* realloc failure due to integer overflow */
+ theap->promoted_objects = NULL;
+ }
+ else {
+ theap->promoted_objects = realloc(theap->promoted_objects, theap->promoted_objects_size * sizeof(VALUE));
+ }
if (theap->promoted_objects == NULL) rb_bug("rb_transient_heap_promote: realloc failed");
}
theap->promoted_objects[theap->promoted_objects_index++] = obj;