Fix pointer arithmetic undefined behavior.
Reported by Denis Denisov.
This commit is contained in:
parent
9cf2be0a81
commit
2012d5a560
11
src/arena.c
11
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;
|
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) {
|
||||||
|
37
src/huge.c
37
src/huge.c
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user