From: Ivan Maidanski Date: Tue, 15 Nov 2016 12:25:54 +0000 (+0300) Subject: Fix potential integer overflow in GC_find_limit_* functions X-Git-Tag: v8.0.0~1040 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e22aaf50d0111ad5481081050d58a39e84e7ed87;p=platform%2Fupstream%2Flibgc.git Fix potential integer overflow in GC_find_limit_* functions * os_dep.c [OPENBSD] (GC_find_limit_openbsd, GC_skip_hole_openbsd): Add assertion for the minimum value of bound; increment result by pgsz only if no overflow is guaranteed. * os_dep.c [USE_PROC_FOR_LIBRARIES && THREADS || NEED_FIND_LIMIT] (GC_find_limit_with_bound): Add assertion for the minimum/maximum value of bound; increment/decrement result by MIN_PAGE_SIZE only if no overflow/underflow is guaranteed. --- diff --git a/os_dep.c b/os_dep.c index 5a962c1..e8601b2 100644 --- a/os_dep.c +++ b/os_dep.c @@ -536,6 +536,8 @@ GC_INNER char * GC_get_maps(void) struct sigaction act; size_t pgsz = (size_t)sysconf(_SC_PAGESIZE); + + GC_ASSERT((word)bound >= pgsz); GC_ASSERT(I_HOLD_LOCK()); act.sa_handler = GC_fault_handler_openbsd; @@ -547,11 +549,11 @@ GC_INNER char * GC_get_maps(void) if (sigsetjmp(GC_jmp_buf_openbsd, 1) == 0) { result = (ptr_t)((word)p & ~(pgsz-1)); for (;;) { - result += pgsz; - if ((word)result >= (word)bound) { + if ((word)result >= (word)bound - pgsz) { result = bound; break; } + result += pgsz; /* no overflow expected */ GC_noop1((word)(*result)); } } @@ -574,6 +576,8 @@ GC_INNER char * GC_get_maps(void) struct sigaction act; size_t pgsz = (size_t)sysconf(_SC_PAGESIZE); + + GC_ASSERT((word)bound >= pgsz); GC_ASSERT(I_HOLD_LOCK()); act.sa_handler = GC_fault_handler_openbsd; @@ -586,10 +590,10 @@ GC_INNER char * GC_get_maps(void) result = (ptr_t)((word)p & ~(pgsz-1)); if (sigsetjmp(GC_jmp_buf_openbsd, 1) != 0 || firstpass) { firstpass = 0; - result += pgsz; - if ((word)result >= (word)bound) { + if ((word)result >= (word)bound - pgsz) { result = bound; } else { + result += pgsz; /* no overflow expected */ GC_noop1((word)(*result)); } } @@ -942,6 +946,8 @@ GC_INNER size_t GC_page_size = 0; /* static since it's only called with the */ /* allocation lock held. */ + GC_ASSERT(up ? (word)bound >= MIN_PAGE_SIZE + : (word)bound <= ~(word)MIN_PAGE_SIZE); GC_ASSERT(I_HOLD_LOCK()); GC_setup_temporary_fault_handler(); if (SETJMP(GC_jmp_buf) == 0) { @@ -949,14 +955,13 @@ GC_INNER size_t GC_page_size = 0; & ~(MIN_PAGE_SIZE-1)); for (;;) { if (up) { - result += MIN_PAGE_SIZE; - if ((word)result >= (word)bound) { + if ((word)result >= (word)bound - MIN_PAGE_SIZE) { result = bound; break; } + result += MIN_PAGE_SIZE; /* no overflow expected */ } else { - result -= MIN_PAGE_SIZE; - if ((word)result <= (word)bound) { + if ((word)result <= (word)bound + MIN_PAGE_SIZE) { result = bound - MIN_PAGE_SIZE; /* This is to compensate */ /* further result increment (we */ @@ -965,6 +970,7 @@ GC_INNER size_t GC_page_size = 0; /* by setjmp otherwise). */ break; } + result -= MIN_PAGE_SIZE; /* no underflow expected */ } GC_noop1((word)(*result)); }