From a784e411f21f4dc827c8c411b7afa7df949c2233 Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Thu, 24 Sep 2015 22:21:55 -0700 Subject: [PATCH] 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 d260f442ce693de4351229027b37b3293fcbfd7d (Fix xallocx(..., MALLOCX_ZERO) bugs.). --- ChangeLog | 7 +++++++ include/jemalloc/internal/jemalloc_internal.h.in | 4 ++++ src/arena.c | 12 +++++++++--- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index e3b0a519..cd8f695b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,13 @@ brevity. Much more detail can be found in the git revision history: 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) This bugfix release continues the trend of xallocx() and heap profiling fixes. diff --git a/include/jemalloc/internal/jemalloc_internal.h.in b/include/jemalloc/internal/jemalloc_internal.h.in index 8536a3ed..654cd088 100644 --- a/include/jemalloc/internal/jemalloc_internal.h.in +++ b/include/jemalloc/internal/jemalloc_internal.h.in @@ -317,6 +317,10 @@ typedef unsigned szind_t; #define PAGE ((size_t)(1U << LG_PAGE)) #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. */ #define PAGE_CEILING(s) \ (((s) + PAGE_MASK) & ~PAGE_MASK) diff --git a/src/arena.c b/src/arena.c index 3081519c..43733cc1 100644 --- a/src/arena.c +++ b/src/arena.c @@ -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 * 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); - memset((void *)((uintptr_t)ptr + oldsize), 0, - PAGE_CEILING((uintptr_t)ptr) - (uintptr_t)ptr); + void *zbase = (void *)((uintptr_t)ptr + oldsize); + void *zpast = PAGE_ADDR2BASE((void *)((uintptr_t)zbase + + PAGE)); + size_t nzero = (uintptr_t)zpast - (uintptr_t)zbase; + assert(nzero > 0); + memset(zbase, 0, nzero); } size = oldsize + splitsize;