summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2021-09-21 00:25:12 +0300
committerIvan Maidanski <ivmai@mail.ru>2021-09-24 08:52:23 +0300
commit8e77a2642ed8b927feb1ab49f71bd57222397d85 (patch)
treebcc863c8f225410ce43db4581dd8c331354fd098
parent0e556e55eec00b57231c2587bef2b834ad31f42f (diff)
downloadbdwgc-8e77a2642ed8b927feb1ab49f71bd57222397d85.tar.gz
Fix overflow of scratch_free_ptr value
(a cherry-pick of commit 2c03a9c79 from 'release-7_4') Issue #270 (bdwgc). * headers.c (GC_scratch_alloc): Add bytes to scratch_free_ptr only if no overflow (and not beyond GC_scratch_end_ptr); add assertion that GC_scratch_end_ptr is not less than scratch_free_ptr.
-rw-r--r--headers.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/headers.c b/headers.c
index b5d7dd6a..f96c05b7 100644
--- a/headers.c
+++ b/headers.c
@@ -120,10 +120,12 @@ GC_INNER ptr_t GC_scratch_alloc(size_t bytes)
register ptr_t result = scratch_free_ptr;
bytes = ROUNDUP_GRANULE_SIZE(bytes);
- scratch_free_ptr += bytes;
- if (scratch_free_ptr <= GC_scratch_end_ptr) {
+ GC_ASSERT((word)GC_scratch_end_ptr >= (word)result);
+ if (bytes <= (word)GC_scratch_end_ptr - (word)result) {
+ scratch_free_ptr = result + bytes;
return(result);
}
+
{
word bytes_to_get = MINHINCR * HBLKSIZE;
@@ -132,7 +134,7 @@ GC_INNER ptr_t GC_scratch_alloc(size_t bytes)
bytes_to_get = ROUNDUP_PAGESIZE_IF_MMAP(bytes);
result = (ptr_t)GET_MEM(bytes_to_get);
GC_add_to_our_memory(result, bytes_to_get);
- scratch_free_ptr -= bytes;
+ /* No update of scratch free area pointer; get memory directly. */
if (result != NULL) {
GC_scratch_last_end_ptr = result + bytes;
}
@@ -145,7 +147,6 @@ GC_INNER ptr_t GC_scratch_alloc(size_t bytes)
if (result == 0) {
if (GC_print_stats)
GC_log_printf("Out of memory - trying to allocate less\n");
- scratch_free_ptr -= bytes;
bytes_to_get = ROUNDUP_PAGESIZE_IF_MMAP(bytes);
result = (ptr_t)GET_MEM(bytes_to_get);
GC_add_to_our_memory(result, bytes_to_get);