Fix pointer arithmetic undefined behavior.

Reported by Denis Denisov.
This commit is contained in:
Jason Evans 2014-11-17 09:54:49 -08:00
parent 9cf2be0a81
commit 2012d5a560
2 changed files with 31 additions and 17 deletions

View File

@ -690,8 +690,10 @@ arena_chunk_ralloc_huge_shrink(arena_t *arena, void *chunk, size_t oldsize,
} }
arena->nactive -= udiff >> LG_PAGE; arena->nactive -= udiff >> LG_PAGE;
malloc_mutex_unlock(&arena->lock); malloc_mutex_unlock(&arena->lock);
if (cdiff != 0) if (cdiff != 0) {
chunk_dalloc(chunk + CHUNK_CEILING(usize), cdiff, arena->ind); chunk_dalloc((void *)((uintptr_t)chunk + CHUNK_CEILING(usize)),
cdiff, arena->ind);
}
} }
bool bool
@ -714,8 +716,9 @@ arena_chunk_ralloc_huge_expand(arena_t *arena, void *chunk, size_t oldsize,
arena->nactive += (udiff >> LG_PAGE); arena->nactive += (udiff >> LG_PAGE);
malloc_mutex_unlock(&arena->lock); malloc_mutex_unlock(&arena->lock);
if (chunk_alloc_arena(chunk_alloc, chunk_dalloc, arena->ind, chunk + if (chunk_alloc_arena(chunk_alloc, chunk_dalloc, arena->ind,
CHUNK_CEILING(oldsize), cdiff, chunksize, zero) == NULL) { (void *)((uintptr_t)chunk + CHUNK_CEILING(oldsize)), cdiff,
chunksize, zero) == NULL) {
/* Revert optimistic stats updates. */ /* Revert optimistic stats updates. */
malloc_mutex_lock(&arena->lock); malloc_mutex_lock(&arena->lock);
if (config_stats) { if (config_stats) {

View File

@ -119,9 +119,11 @@ huge_ralloc_no_move_similar(void *ptr, size_t oldsize, size_t usize,
/* Fill if necessary (shrinking). */ /* Fill if necessary (shrinking). */
if (oldsize > usize) { if (oldsize > usize) {
size_t sdiff = CHUNK_CEILING(usize) - usize; size_t sdiff = CHUNK_CEILING(usize) - usize;
zeroed = (sdiff != 0) ? !pages_purge(ptr + usize, sdiff) : true; zeroed = (sdiff != 0) ? !pages_purge((void *)((uintptr_t)ptr +
usize), sdiff) : true;
if (config_fill && unlikely(opt_junk)) { if (config_fill && unlikely(opt_junk)) {
memset(ptr + usize, 0x5a, oldsize - usize); memset((void *)((uintptr_t)ptr + usize), 0x5a, oldsize -
usize);
zeroed = false; zeroed = false;
} }
} else } else
@ -145,10 +147,14 @@ huge_ralloc_no_move_similar(void *ptr, size_t oldsize, size_t usize,
/* Fill if necessary (growing). */ /* Fill if necessary (growing). */
if (oldsize < usize) { if (oldsize < usize) {
if (zero || (config_fill && unlikely(opt_zero))) { if (zero || (config_fill && unlikely(opt_zero))) {
if (!zeroed) if (!zeroed) {
memset(ptr + oldsize, 0, usize - oldsize); memset((void *)((uintptr_t)ptr + oldsize), 0,
} else if (config_fill && unlikely(opt_junk)) usize - oldsize);
memset(ptr + oldsize, 0xa5, usize - oldsize); }
} else if (config_fill && unlikely(opt_junk)) {
memset((void *)((uintptr_t)ptr + oldsize), 0xa5, usize -
oldsize);
}
} }
} }
@ -161,9 +167,11 @@ huge_ralloc_no_move_shrink(void *ptr, size_t oldsize, size_t usize)
arena_t *arena; arena_t *arena;
sdiff = CHUNK_CEILING(usize) - usize; sdiff = CHUNK_CEILING(usize) - usize;
zeroed = (sdiff != 0) ? !pages_purge(ptr + usize, sdiff) : true; zeroed = (sdiff != 0) ? !pages_purge((void *)((uintptr_t)ptr + usize),
sdiff) : true;
if (config_fill && unlikely(opt_junk)) { if (config_fill && unlikely(opt_junk)) {
huge_dalloc_junk(ptr + usize, oldsize - usize); huge_dalloc_junk((void *)((uintptr_t)ptr + usize), oldsize -
usize);
zeroed = false; zeroed = false;
} }
@ -222,15 +230,18 @@ huge_ralloc_no_move_expand(void *ptr, size_t oldsize, size_t size, bool zero) {
if (zero || (config_fill && unlikely(opt_zero))) { if (zero || (config_fill && unlikely(opt_zero))) {
if (!is_zeroed_subchunk) { if (!is_zeroed_subchunk) {
memset(ptr + oldsize, 0, CHUNK_CEILING(oldsize) - memset((void *)((uintptr_t)ptr + oldsize), 0,
oldsize); CHUNK_CEILING(oldsize) - oldsize);
} }
if (!is_zeroed_chunk) { if (!is_zeroed_chunk) {
memset(ptr + CHUNK_CEILING(oldsize), 0, usize - memset((void *)((uintptr_t)ptr +
CHUNK_CEILING(oldsize)), 0, usize -
CHUNK_CEILING(oldsize)); CHUNK_CEILING(oldsize));
} }
} else if (config_fill && unlikely(opt_junk)) } else if (config_fill && unlikely(opt_junk)) {
memset(ptr + oldsize, 0xa5, usize - oldsize); memset((void *)((uintptr_t)ptr + oldsize), 0xa5, usize -
oldsize);
}
return (false); return (false);
} }