summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Evans <je@fb.com>2014-11-17 17:54:49 (GMT)
committerJason Evans <je@fb.com>2014-11-17 17:54:49 (GMT)
commit2012d5a5601c787ce464fac0cbd2b16e3754cfa2 (patch)
tree6bfabd82827a7785c89d5e450d0855281a1b3491
parent9cf2be0a81b77d4586591c19fb469a51fe6684fa (diff)
downloadjemalloc-2012d5a5601c787ce464fac0cbd2b16e3754cfa2.zip
jemalloc-2012d5a5601c787ce464fac0cbd2b16e3754cfa2.tar.gz
jemalloc-2012d5a5601c787ce464fac0cbd2b16e3754cfa2.tar.bz2
Fix pointer arithmetic undefined behavior.
Reported by Denis Denisov.
-rw-r--r--src/arena.c11
-rw-r--r--src/huge.c37
2 files changed, 31 insertions, 17 deletions
diff --git a/src/arena.c b/src/arena.c
index ef42771..1ecc5d0 100644
--- a/src/arena.c
+++ b/src/arena.c
@@ -690,8 +690,10 @@ arena_chunk_ralloc_huge_shrink(arena_t *arena, void *chunk, size_t oldsize,
}
arena->nactive -= udiff >> LG_PAGE;
malloc_mutex_unlock(&arena->lock);
- if (cdiff != 0)
- chunk_dalloc(chunk + CHUNK_CEILING(usize), cdiff, arena->ind);
+ if (cdiff != 0) {
+ chunk_dalloc((void *)((uintptr_t)chunk + CHUNK_CEILING(usize)),
+ cdiff, arena->ind);
+ }
}
bool
@@ -714,8 +716,9 @@ arena_chunk_ralloc_huge_expand(arena_t *arena, void *chunk, size_t oldsize,
arena->nactive += (udiff >> LG_PAGE);
malloc_mutex_unlock(&arena->lock);
- if (chunk_alloc_arena(chunk_alloc, chunk_dalloc, arena->ind, chunk +
- CHUNK_CEILING(oldsize), cdiff, chunksize, zero) == NULL) {
+ if (chunk_alloc_arena(chunk_alloc, chunk_dalloc, arena->ind,
+ (void *)((uintptr_t)chunk + CHUNK_CEILING(oldsize)), cdiff,
+ chunksize, zero) == NULL) {
/* Revert optimistic stats updates. */
malloc_mutex_lock(&arena->lock);
if (config_stats) {
diff --git a/src/huge.c b/src/huge.c
index 826464c..7ad9b66 100644
--- a/src/huge.c
+++ b/src/huge.c
@@ -119,9 +119,11 @@ huge_ralloc_no_move_similar(void *ptr, size_t oldsize, size_t usize,
/* Fill if necessary (shrinking). */
if (oldsize > 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)) {
- memset(ptr + usize, 0x5a, oldsize - usize);
+ memset((void *)((uintptr_t)ptr + usize), 0x5a, oldsize -
+ usize);
zeroed = false;
}
} else
@@ -145,10 +147,14 @@ huge_ralloc_no_move_similar(void *ptr, size_t oldsize, size_t usize,
/* Fill if necessary (growing). */
if (oldsize < usize) {
if (zero || (config_fill && unlikely(opt_zero))) {
- if (!zeroed)
- memset(ptr + oldsize, 0, usize - oldsize);
- } else if (config_fill && unlikely(opt_junk))
- memset(ptr + oldsize, 0xa5, usize - oldsize);
+ if (!zeroed) {
+ memset((void *)((uintptr_t)ptr + oldsize), 0,
+ 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;
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)) {
- huge_dalloc_junk(ptr + usize, oldsize - usize);
+ huge_dalloc_junk((void *)((uintptr_t)ptr + usize), oldsize -
+ usize);
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 (!is_zeroed_subchunk) {
- memset(ptr + oldsize, 0, CHUNK_CEILING(oldsize) -
- oldsize);
+ memset((void *)((uintptr_t)ptr + oldsize), 0,
+ CHUNK_CEILING(oldsize) - oldsize);
}
if (!is_zeroed_chunk) {
- memset(ptr + CHUNK_CEILING(oldsize), 0, usize -
+ memset((void *)((uintptr_t)ptr +
+ CHUNK_CEILING(oldsize)), 0, usize -
CHUNK_CEILING(oldsize));
}
- } else if (config_fill && unlikely(opt_junk))
- memset(ptr + oldsize, 0xa5, usize - oldsize);
+ } else if (config_fill && unlikely(opt_junk)) {
+ memset((void *)((uintptr_t)ptr + oldsize), 0xa5, usize -
+ oldsize);
+ }
return (false);
}