summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2022-06-14 07:38:44 +0300
committerIvan Maidanski <ivmai@mail.ru>2022-06-17 06:48:45 +0300
commit745f7f83062c3b26b7e23db8b69f8399f7baf6ca (patch)
treebc98cff4e29784ee0d76617da445fb8a51c2a7e5
parent84a018dc1adcb6341d419404abd633dfb75af6a0 (diff)
downloadbdwgc-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.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/typd_mlc.c b/typd_mlc.c
index f19655a0..8a49a6a2 100644
--- a/typd_mlc.c
+++ b/typd_mlc.c
@@ -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);