diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2022-06-14 07:38:44 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2022-06-17 06:48:45 +0300 |
commit | 745f7f83062c3b26b7e23db8b69f8399f7baf6ca (patch) | |
tree | bc98cff4e29784ee0d76617da445fb8a51c2a7e5 | |
parent | 84a018dc1adcb6341d419404abd633dfb75af6a0 (diff) | |
download | bdwgc-745f7f83062c3b26b7e23db8b69f8399f7baf6ca.tar.gz |
Ensure typed objects descriptor is never located in the first word
(a cherry-pick of commit 63814cbb0 from 'release-7_6')
Free objects are linked in the collector through the first word in the
object. This commit prevents placing type descriptor to the first
word of the allocated object by ensuring that the size of typed objects
(requested by a client) is non-zero.
Also, guarantee no nelements*size overflow in GC_make_array_descriptor.
* typd_mlc.c (GC_make_array_descriptor): Add comment that no overflow
guaranteed by caller.
* typd_mlc.c (GC_malloc_explicitly_typed,
GC_malloc_explicitly_typed_ignore_off_page): If lb is zero, then assume
lb is 1 (byte).
* typd_mlc.c (GC_calloc_explicitly_typed): If lb or n is zero, then
assume that lb*n is 1; check that lb*n does not overflow before
GC_make_array_descriptor() call.
-rw-r--r-- | typd_mlc.c | 12 |
1 files changed, 8 insertions, 4 deletions
@@ -223,7 +223,7 @@ STATIC int GC_make_array_descriptor(size_t nelements, size_t size, /* of space needed on the mark stack. */ if ((descriptor & GC_DS_TAGS) == GC_DS_LENGTH) { if (descriptor == (GC_descr)size) { - *simple_d = nelements * descriptor; + *simple_d = nelements * descriptor; /* no overflow */ return(SIMPLE); } else if ((word)descriptor == 0) { *simple_d = (GC_descr)0; @@ -626,6 +626,7 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_malloc_explicitly_typed(size_t lb, DCL_LOCK_STATE; GC_ASSERT(GC_explicit_typing_initialized); + if (EXPECT(0 == lb, FALSE)) lb = 1; /* ensure nwords > 1 */ lb = SIZET_SAT_ADD(lb, TYPD_EXTRA_BYTES); if (SMALL_OBJ(lb)) { GC_DBG_COLLECT_AT_MALLOC(lb); @@ -667,6 +668,7 @@ GC_API GC_ATTR_MALLOC void * GC_CALL DCL_LOCK_STATE; GC_ASSERT(GC_explicit_typing_initialized); + if (EXPECT(0 == lb, FALSE)) lb = 1; lb = SIZET_SAT_ADD(lb, TYPD_EXTRA_BYTES); if (SMALL_OBJ(lb)) { GC_DBG_COLLECT_AT_MALLOC(lb); @@ -710,11 +712,13 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_calloc_explicitly_typed(size_t n, DCL_LOCK_STATE; GC_ASSERT(GC_explicit_typing_initialized); - descr_type = GC_make_array_descriptor((word)n, (word)lb, d, &simple_descr, - &complex_descr, &leaf); + if (EXPECT(0 == lb || 0 == n, FALSE)) lb = n = 1; if ((lb | n) > GC_SQRT_SIZE_MAX /* fast initial check */ - && lb > 0 && n > GC_SIZE_MAX / lb) + && n > GC_SIZE_MAX / lb) return (*GC_get_oom_fn())(GC_SIZE_MAX); /* n*lb overflow */ + + descr_type = GC_make_array_descriptor((word)n, (word)lb, d, &simple_descr, + &complex_descr, &leaf); lb *= n; switch(descr_type) { case NO_MEM: return(0); |