From 06b2d09eb635e28fd16af4e3bdf3a167ed4476a3 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 26 Jul 2024 00:45:21 +0900 Subject: [PATCH 1/5] comment --- lib/platform.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/platform.h b/lib/platform.h index cf4deebe..1f7df54d 100644 --- a/lib/platform.h +++ b/lib/platform.h @@ -153,7 +153,10 @@ #if __has_builtin(__builtin_mul_overflow) #define MUL_SIZE_OVERFLOW(a, b, c) __builtin_mul_overflow(a, b, c) #else -/* Note: (floor(x) < b) == (x < b) */ +/* + * Note: (floor(x) < b) == (x < b) where + * x is a real number and b is an integer. + */ #define MUL_SIZE_OVERFLOW(a, b, c) \ (a != 0 && (SIZE_MAX / a < b) ? 1 : (*c = a * b, 0)) #endif From 5f83ba6efbafdd74b9340a817cc66eeb7825a82b Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 26 Jul 2024 00:46:02 +0900 Subject: [PATCH 2/5] memory_getptr2: use overflow checking macro --- lib/exec_insn_subr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/exec_insn_subr.c b/lib/exec_insn_subr.c index f3b35595..107adab5 100644 --- a/lib/exec_insn_subr.c +++ b/lib/exec_insn_subr.c @@ -49,14 +49,14 @@ memory_getptr2(struct exec_context *ctx, uint32_t memidx, uint32_t ptr, assert(meminst->allocated <= (uint64_t)meminst->size_in_pages << memtype_page_shift(meminst->type)); - if (__predict_false(offset > UINT32_MAX - ptr)) { + uint32_t ea; + if (ADD_U32_OVERFLOW(ptr, offset, &ea)) { /* * i failed to find this in the spec. * but some of spec tests seem to test this. */ goto do_trap; } - uint32_t ea = ptr + offset; if (__predict_false(size == 0)) { /* * a zero-length access still needs address check. @@ -70,10 +70,10 @@ memory_getptr2(struct exec_context *ctx, uint32_t memidx, uint32_t ptr, } goto success; } - if (size - 1 > UINT32_MAX - ea) { + uint32_t last_byte = ea + (size - 1); + if (ADD_U32_OVERFLOW(ea, size - 1, &last_byte)) { goto do_trap; } - uint32_t last_byte = ea + (size - 1); if (__predict_false(last_byte >= meminst->allocated)) { const uint32_t page_shift = memtype_page_shift(meminst->type); uint32_t need_in_pages = (last_byte >> page_shift) + 1; From 5e2a90e6ebe69b1dcc4eb84f2d315ede33fa157a Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 26 Jul 2024 00:46:45 +0900 Subject: [PATCH 3/5] table_instance_create: use overflow checking macro --- lib/instance.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/instance.c b/lib/instance.c index 1427926f..1d800cd9 100644 --- a/lib/instance.c +++ b/lib/instance.c @@ -305,8 +305,8 @@ table_instance_create(struct mem_context *mctx, struct tableinst **tip, tinst->mctx = mctx; tinst->size = tinst->type->lim.min; uint32_t csz = valtype_cellsize(tt->et); - size_t ncells = (size_t)tinst->size * csz; - if (ncells / csz != tinst->size) { + size_t ncells; + if (MUL_SIZE_OVERFLOW((size_t)tinst->size, (size_t)csz, &ncells)) { ret = EOVERFLOW; goto fail; } From 832be0119cbae48ef3da65b2804fda6ae4aed879 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 26 Jul 2024 00:48:07 +0900 Subject: [PATCH 4/5] table_grow: use overflow checking macro --- lib/exec_insn_subr.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/exec_insn_subr.c b/lib/exec_insn_subr.c index 107adab5..98f2d992 100644 --- a/lib/exec_insn_subr.c +++ b/lib/exec_insn_subr.c @@ -338,16 +338,17 @@ table_grow(struct tableinst *t, const struct val *val, uint32_t n) if (n == 0) { return t->size; } - if (UINT32_MAX - t->size < n || t->size + n > t->type->lim.max) { + uint32_t newsize; + if (ADD_U32_OVERFLOW(t->size, n, &newsize) || + newsize > t->type->lim.max) { return (uint32_t)-1; } - - uint32_t newsize = t->size + n; uint32_t csz = valtype_cellsize(t->type->et); - size_t newncells = (size_t)newsize * csz; - size_t newbytes = newncells * sizeof(*t->cells); + size_t newncells; + size_t newbytes; int ret; - if (newbytes / sizeof(*t->cells) / csz != newsize) { + if (MUL_SIZE_OVERFLOW((size_t)newsize, (size_t)csz, &newncells) || + MUL_SIZE_OVERFLOW(newncells, sizeof(*t->cells), &newbytes)) { ret = EOVERFLOW; } else { size_t oldncells = (size_t)t->size * csz; From a0858eedd5f8684f74beeb4c68081ef47dffa4a7 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 26 Jul 2024 00:52:35 +0900 Subject: [PATCH 5/5] memory_grow_impl: use overflow checking macro --- lib/exec_insn_subr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/exec_insn_subr.c b/lib/exec_insn_subr.c index 98f2d992..5cd2f92b 100644 --- a/lib/exec_insn_subr.c +++ b/lib/exec_insn_subr.c @@ -433,11 +433,11 @@ memory_grow_impl(struct exec_context *ctx, struct meminst *mi, uint32_t sz) retry: #endif orig_size = mi->size_in_pages; - if (sz > UINT32_MAX - orig_size) { + uint32_t new_size; + if (ADD_U32_OVERFLOW(orig_size, sz, &new_size)) { memory_unlock(mi); return (uint32_t)-1; /* fail */ } - uint32_t new_size = orig_size + sz; assert(lim->max <= WASM_MAX_MEMORY_SIZE >> page_shift); if (new_size > lim->max) { memory_unlock(mi);