Fix a xallocx(..., MALLOCX_ZERO) bug.

Fix xallocx(..., MALLOCX_ZERO to zero the last full trailing page of
large allocations that have been randomly assigned an offset of 0 when
--enable-cache-oblivious configure option is enabled.  This addresses a
special case missed in d260f442ce (Fix
xallocx(..., MALLOCX_ZERO) bugs.).
This commit is contained in:
Jason Evans 2015-09-24 22:21:55 -07:00
parent e9192eacf8
commit a784e411f2
3 changed files with 20 additions and 3 deletions

View File

@ -4,6 +4,13 @@ brevity. Much more detail can be found in the git revision history:
https://github.com/jemalloc/jemalloc https://github.com/jemalloc/jemalloc
* 4.0.4 (XXX)
Bug fixes:
- Fix xallocx(..., MALLOCX_ZERO to zero the last full trailing page of large
allocations that have been randomly assigned an offset of 0 when
--enable-cache-oblivious configure option is enabled.
* 4.0.3 (September 24, 2015) * 4.0.3 (September 24, 2015)
This bugfix release continues the trend of xallocx() and heap profiling fixes. This bugfix release continues the trend of xallocx() and heap profiling fixes.

View File

@ -317,6 +317,10 @@ typedef unsigned szind_t;
#define PAGE ((size_t)(1U << LG_PAGE)) #define PAGE ((size_t)(1U << LG_PAGE))
#define PAGE_MASK ((size_t)(PAGE - 1)) #define PAGE_MASK ((size_t)(PAGE - 1))
/* Return the page base address for the page containing address a. */
#define PAGE_ADDR2BASE(a) \
((void *)((uintptr_t)(a) & ~PAGE_MASK))
/* Return the smallest pagesize multiple that is >= s. */ /* Return the smallest pagesize multiple that is >= s. */
#define PAGE_CEILING(s) \ #define PAGE_CEILING(s) \
(((s) + PAGE_MASK) & ~PAGE_MASK) (((s) + PAGE_MASK) & ~PAGE_MASK)

View File

@ -2683,10 +2683,16 @@ arena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk, void *ptr,
/* /*
* Zero the trailing bytes of the original allocation's * Zero the trailing bytes of the original allocation's
* last page, since they are in an indeterminate state. * last page, since they are in an indeterminate state.
* There will always be trailing bytes, because ptr's
* offset from the beginning of the run is a multiple of
* CACHELINE in [0 .. PAGE).
*/ */
assert(PAGE_CEILING(oldsize) == oldsize); void *zbase = (void *)((uintptr_t)ptr + oldsize);
memset((void *)((uintptr_t)ptr + oldsize), 0, void *zpast = PAGE_ADDR2BASE((void *)((uintptr_t)zbase +
PAGE_CEILING((uintptr_t)ptr) - (uintptr_t)ptr); PAGE));
size_t nzero = (uintptr_t)zpast - (uintptr_t)zbase;
assert(nzero > 0);
memset(zbase, 0, nzero);
} }
size = oldsize + splitsize; size = oldsize + splitsize;