Browse Source

Also place canaries in > page sized objects (if C is in effect); ok tb@

OPENBSD_6_1
otto 8 years ago
parent
commit
5656d7bf98
1 changed files with 110 additions and 103 deletions
  1. +110
    -103
      src/lib/libc/stdlib/malloc.c

+ 110
- 103
src/lib/libc/stdlib/malloc.c View File

@ -1,4 +1,4 @@
/* $OpenBSD: malloc.c,v 1.202 2016/10/15 18:24:40 guenther Exp $ */
/* $OpenBSD: malloc.c,v 1.203 2016/10/20 05:38:41 otto Exp $ */
/* /*
* Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net> * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net>
* Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org>
@ -31,6 +31,7 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <errno.h> #include <errno.h>
#include <stdarg.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -199,6 +200,8 @@ static union {
char *malloc_options; /* compile-time options */ char *malloc_options; /* compile-time options */
static u_char getrbyte(struct dir_info *d); static u_char getrbyte(struct dir_info *d);
static __dead void wrterror(struct dir_info *d, char *msg, ...)
__attribute__((__format__ (printf, 2, 3)));
#ifdef MALLOC_STATS #ifdef MALLOC_STATS
void malloc_dump(int, struct dir_info *); void malloc_dump(int, struct dir_info *);
@ -261,40 +264,26 @@ struct dir_info *getpool(void)
} }
static __dead void static __dead void
wrterror(struct dir_info *d, char *msg, void *p)
wrterror(struct dir_info *d, char *msg, ...)
{ {
char *q = " error: ";
struct iovec iov[7];
char pidbuf[20];
char buf[20];
int saved_errno = errno, i;
iov[0].iov_base = __progname;
iov[0].iov_len = strlen(__progname);
iov[1].iov_base = pidbuf;
snprintf(pidbuf, sizeof(pidbuf), "(%d) in ", getpid());
iov[1].iov_len = strlen(pidbuf);
if (d != NULL) {
iov[2].iov_base = d->func;
iov[2].iov_len = strlen(d->func);
} else {
iov[2].iov_base = "unknown";
iov[2].iov_len = 7;
}
iov[3].iov_base = q;
iov[3].iov_len = strlen(q);
iov[4].iov_base = msg;
iov[4].iov_len = strlen(msg);
iov[5].iov_base = buf;
if (p == NULL)
iov[5].iov_len = 0;
else {
snprintf(buf, sizeof(buf), " %010p", p);
iov[5].iov_len = strlen(buf);
}
iov[6].iov_base = "\n";
iov[6].iov_len = 1;
writev(STDERR_FILENO, iov, 7);
struct iovec iov[3];
char pidbuf[80];
char buf[80];
int saved_errno = errno, ret;
va_list ap;
iov[0].iov_base = pidbuf;
ret = snprintf(pidbuf, sizeof(pidbuf), "%.50s(%d) in %s(): ",
__progname, getpid(), d->func ? d->func : "unknown");
iov[0].iov_len = ret > 0 ? strlen(pidbuf) : 0;
iov[1].iov_base = buf;
va_start(ap, msg);
ret = vsnprintf(buf, sizeof(buf), msg, ap);
va_end(ap);
iov[1].iov_len = ret > 0 ? strlen(buf) : 0;
iov[2].iov_base = "\n";
iov[2].iov_len = 1;
writev(STDERR_FILENO, iov, 3);
#ifdef MALLOC_STATS #ifdef MALLOC_STATS
if (mopts.malloc_stats) if (mopts.malloc_stats)
@ -342,12 +331,12 @@ unmap(struct dir_info *d, void *p, size_t sz)
u_int i, offset; u_int i, offset;
if (sz != PAGEROUND(sz)) if (sz != PAGEROUND(sz))
wrterror(d, "munmap round", NULL);
wrterror(d, "munmap round");
if (psz > mopts.malloc_cache) { if (psz > mopts.malloc_cache) {
i = munmap(p, sz); i = munmap(p, sz);
if (i) if (i)
wrterror(d, "munmap", p);
wrterror(d, "munmap %p", p);
STATS_SUB(d->malloc_used, sz); STATS_SUB(d->malloc_used, sz);
return; return;
} }
@ -361,7 +350,7 @@ unmap(struct dir_info *d, void *p, size_t sz)
if (r->p != NULL) { if (r->p != NULL) {
rsz = r->size << MALLOC_PAGESHIFT; rsz = r->size << MALLOC_PAGESHIFT;
if (munmap(r->p, rsz)) if (munmap(r->p, rsz))
wrterror(d, "munmap", r->p);
wrterror(d, "munmap %p", r->p);
r->p = NULL; r->p = NULL;
if (tounmap > r->size) if (tounmap > r->size)
tounmap -= r->size; tounmap -= r->size;
@ -373,7 +362,7 @@ unmap(struct dir_info *d, void *p, size_t sz)
} }
} }
if (tounmap > 0) if (tounmap > 0)
wrterror(d, "malloc cache underflow", NULL);
wrterror(d, "malloc cache underflow");
for (i = 0; i < mopts.malloc_cache; i++) { for (i = 0; i < mopts.malloc_cache; i++) {
r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)]; r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)];
if (r->p == NULL) { if (r->p == NULL) {
@ -393,9 +382,9 @@ unmap(struct dir_info *d, void *p, size_t sz)
} }
} }
if (i == mopts.malloc_cache) if (i == mopts.malloc_cache)
wrterror(d, "malloc free slot lost", NULL);
wrterror(d, "malloc free slot lost");
if (d->free_regions_size > mopts.malloc_cache) if (d->free_regions_size > mopts.malloc_cache)
wrterror(d, "malloc cache overflow", NULL);
wrterror(d, "malloc cache overflow");
} }
static void static void
@ -410,7 +399,7 @@ zapcacheregion(struct dir_info *d, void *p, size_t len)
if (r->p >= p && r->p <= (void *)((char *)p + len)) { if (r->p >= p && r->p <= (void *)((char *)p + len)) {
rsz = r->size << MALLOC_PAGESHIFT; rsz = r->size << MALLOC_PAGESHIFT;
if (munmap(r->p, rsz)) if (munmap(r->p, rsz))
wrterror(d, "munmap", r->p);
wrterror(d, "munmap %p", r->p);
r->p = NULL; r->p = NULL;
d->free_regions_size -= r->size; d->free_regions_size -= r->size;
r->size = 0; r->size = 0;
@ -429,9 +418,9 @@ map(struct dir_info *d, void *hint, size_t sz, int zero_fill)
if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) || if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) ||
d->canary1 != ~d->canary2) d->canary1 != ~d->canary2)
wrterror(d, "internal struct corrupt", NULL);
wrterror(d, "internal struct corrupt");
if (sz != PAGEROUND(sz)) if (sz != PAGEROUND(sz))
wrterror(d, "map round", NULL);
wrterror(d, "map round");
if (!hint && psz > d->free_regions_size) { if (!hint && psz > d->free_regions_size) {
_MALLOC_LEAVE(d); _MALLOC_LEAVE(d);
@ -486,7 +475,7 @@ map(struct dir_info *d, void *hint, size_t sz, int zero_fill)
if (hint) if (hint)
return MAP_FAILED; return MAP_FAILED;
if (d->free_regions_size > mopts.malloc_cache) if (d->free_regions_size > mopts.malloc_cache)
wrterror(d, "malloc cache", NULL);
wrterror(d, "malloc cache");
_MALLOC_LEAVE(d); _MALLOC_LEAVE(d);
p = MMAP(sz); p = MMAP(sz);
_MALLOC_ENTER(d); _MALLOC_ENTER(d);
@ -673,7 +662,7 @@ omalloc_poolinit(struct dir_info **dp)
* lies (subject to alignment by 1 << MALLOC_MINSHIFT) * lies (subject to alignment by 1 << MALLOC_MINSHIFT)
*/ */
if ((p = MMAP(DIR_INFO_RSZ + (MALLOC_PAGESIZE * 2))) == MAP_FAILED) if ((p = MMAP(DIR_INFO_RSZ + (MALLOC_PAGESIZE * 2))) == MAP_FAILED)
wrterror(NULL, "malloc init mmap failed", NULL);
wrterror(NULL, "malloc init mmap failed");
mprotect(p, MALLOC_PAGESIZE, PROT_NONE); mprotect(p, MALLOC_PAGESIZE, PROT_NONE);
mprotect(p + MALLOC_PAGESIZE + DIR_INFO_RSZ, mprotect(p + MALLOC_PAGESIZE + DIR_INFO_RSZ,
MALLOC_PAGESIZE, PROT_NONE); MALLOC_PAGESIZE, PROT_NONE);
@ -687,7 +676,7 @@ omalloc_poolinit(struct dir_info **dp)
d->r = MMAP(regioninfo_size); d->r = MMAP(regioninfo_size);
if (d->r == MAP_FAILED) { if (d->r == MAP_FAILED) {
d->regions_total = 0; d->regions_total = 0;
wrterror(NULL, "malloc init mmap failed", NULL);
wrterror(NULL, "malloc init mmap failed");
} }
for (i = 0; i <= MALLOC_MAXSHIFT; i++) { for (i = 0; i <= MALLOC_MAXSHIFT; i++) {
LIST_INIT(&d->chunk_info_list[i]); LIST_INIT(&d->chunk_info_list[i]);
@ -738,7 +727,7 @@ omalloc_grow(struct dir_info *d)
} }
/* avoid pages containing meta info to end up in cache */ /* avoid pages containing meta info to end up in cache */
if (munmap(d->r, d->regions_total * sizeof(struct region_info))) if (munmap(d->r, d->regions_total * sizeof(struct region_info)))
wrterror(d, "munmap", d->r);
wrterror(d, "munmap %p", d->r);
else else
STATS_SUB(d->malloc_used, STATS_SUB(d->malloc_used,
d->regions_total * sizeof(struct region_info)); d->regions_total * sizeof(struct region_info));
@ -828,7 +817,7 @@ find(struct dir_info *d, void *p)
if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) || if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) ||
d->canary1 != ~d->canary2) d->canary1 != ~d->canary2)
wrterror(d, "internal struct corrupt", NULL);
wrterror(d, "internal struct corrupt");
p = MASK_POINTER(p); p = MASK_POINTER(p);
index = hash(p) & mask; index = hash(p) & mask;
r = d->r[index].p; r = d->r[index].p;
@ -851,7 +840,7 @@ delete(struct dir_info *d, struct region_info *ri)
size_t i, j, r; size_t i, j, r;
if (d->regions_total & (d->regions_total - 1)) if (d->regions_total & (d->regions_total - 1))
wrterror(d, "regions_total not 2^x", NULL);
wrterror(d, "regions_total not 2^x");
d->regions_free++; d->regions_free++;
STATS_INC(d->deletes); STATS_INC(d->deletes);
@ -936,7 +925,7 @@ omalloc_make_chunks(struct dir_info *d, int bits, int listnum)
bits++; bits++;
if ((uintptr_t)pp & bits) if ((uintptr_t)pp & bits)
wrterror(d, "pp & bits", pp);
wrterror(d, "pp & bits %p", pp);
insert(d, (void *)((uintptr_t)pp | bits), (uintptr_t)bp, NULL); insert(d, (void *)((uintptr_t)pp | bits), (uintptr_t)bp, NULL);
return bp; return bp;
@ -956,7 +945,7 @@ malloc_bytes(struct dir_info *d, size_t argsize, void *f)
if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) || if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) ||
d->canary1 != ~d->canary2) d->canary1 != ~d->canary2)
wrterror(d, "internal struct corrupt", NULL);
wrterror(d, "internal struct corrupt");
size = argsize; size = argsize;
@ -984,7 +973,7 @@ malloc_bytes(struct dir_info *d, size_t argsize, void *f)
} }
if (bp->canary != d->canary1) if (bp->canary != d->canary1)
wrterror(d, "chunk info corrupted", NULL);
wrterror(d, "chunk info corrupted");
i = d->chunk_start; i = d->chunk_start;
if (bp->free > 1) if (bp->free > 1)
@ -1045,6 +1034,25 @@ malloc_bytes(struct dir_info *d, size_t argsize, void *f)
return ((char *)bp->page + k); return ((char *)bp->page + k);
} }
static void
validate_canary(struct dir_info *d, u_char *ptr, size_t sz, size_t allocated)
{
size_t check_sz = allocated - sz;
u_char *p, *q;
if (check_sz > CHUNK_CHECK_LENGTH)
check_sz = CHUNK_CHECK_LENGTH;
p = (u_char *)ptr + sz;
q = p + check_sz;
while (p < q) {
if (*p++ != SOME_JUNK) {
wrterror(d, "chunk canary corrupted %p %#tx@%#zx",
ptr, p - ptr - 1, sz);
}
}
}
static uint32_t static uint32_t
find_chunknum(struct dir_info *d, struct region_info *r, void *ptr, int check) find_chunknum(struct dir_info *d, struct region_info *r, void *ptr, int check)
{ {
@ -1053,32 +1061,20 @@ find_chunknum(struct dir_info *d, struct region_info *r, void *ptr, int check)
info = (struct chunk_info *)r->size; info = (struct chunk_info *)r->size;
if (info->canary != d->canary1) if (info->canary != d->canary1)
wrterror(d, "chunk info corrupted", NULL);
wrterror(d, "chunk info corrupted");
/* Find the chunk number on the page */ /* Find the chunk number on the page */
chunknum = ((uintptr_t)ptr & MALLOC_PAGEMASK) >> info->shift; chunknum = ((uintptr_t)ptr & MALLOC_PAGEMASK) >> info->shift;
if (check && mopts.chunk_canaries && info->size > 0) { if (check && mopts.chunk_canaries && info->size > 0) {
size_t sz = info->bits[info->offset + chunknum];
size_t check_sz = info->size - sz;
u_char *p, *q;
if (check_sz > CHUNK_CHECK_LENGTH)
check_sz = CHUNK_CHECK_LENGTH;
p = (u_char *)ptr + sz;
q = p + check_sz;
while (p < q)
if (*p++ != SOME_JUNK) {
q = (void *)(sz << 16 | p - (u_char *)ptr - 1);
wrterror(d, "chunk canary corrupted: ", q);
}
validate_canary(d, ptr, info->bits[info->offset + chunknum],
info->size);
} }
if ((uintptr_t)ptr & ((1U << (info->shift)) - 1)) if ((uintptr_t)ptr & ((1U << (info->shift)) - 1))
wrterror(d, "modified chunk-pointer", ptr);
wrterror(d, "modified chunk-pointer %p", ptr);
if (info->bits[chunknum / MALLOC_BITS] & if (info->bits[chunknum / MALLOC_BITS] &
(1U << (chunknum % MALLOC_BITS))) (1U << (chunknum % MALLOC_BITS)))
wrterror(d, "chunk is already free", ptr);
wrterror(d, "chunk is already free %p", ptr);
return chunknum; return chunknum;
} }
@ -1156,7 +1152,7 @@ omalloc(struct dir_info *pool, size_t sz, int zero_fill, void *f)
if (mopts.malloc_guard) { if (mopts.malloc_guard) {
if (mprotect((char *)p + psz - mopts.malloc_guard, if (mprotect((char *)p + psz - mopts.malloc_guard,
mopts.malloc_guard, PROT_NONE)) mopts.malloc_guard, PROT_NONE))
wrterror(pool, "mprotect", NULL);
wrterror(pool, "mprotect");
STATS_ADD(pool->malloc_guarded, mopts.malloc_guard); STATS_ADD(pool->malloc_guarded, mopts.malloc_guard);
} }
@ -1180,6 +1176,12 @@ omalloc(struct dir_info *pool, size_t sz, int zero_fill, void *f)
else else
memset(p, SOME_JUNK, memset(p, SOME_JUNK,
psz - mopts.malloc_guard); psz - mopts.malloc_guard);
} else if (mopts.chunk_canaries) {
size_t csz = psz - mopts.malloc_guard - sz;
if (csz > CHUNK_CHECK_LENGTH)
csz = CHUNK_CHECK_LENGTH;
memset(p + sz, SOME_JUNK, csz);
} }
} }
@ -1205,7 +1207,7 @@ malloc_recurse(struct dir_info *d)
if (noprint == 0) { if (noprint == 0) {
noprint = 1; noprint = 1;
wrterror(d, "recursive call", NULL);
wrterror(d, "recursive call");
} }
d->active--; d->active--;
_MALLOC_UNLOCK(d->mutex); _MALLOC_UNLOCK(d->mutex);
@ -1264,7 +1266,7 @@ malloc(size_t size)
d = getpool(); d = getpool();
} }
_MALLOC_LOCK(d->mutex); _MALLOC_LOCK(d->mutex);
d->func = "malloc():";
d->func = "malloc";
if (d->active++) { if (d->active++) {
malloc_recurse(d); malloc_recurse(d);
@ -1274,7 +1276,7 @@ malloc(size_t size)
d->active--; d->active--;
_MALLOC_UNLOCK(d->mutex); _MALLOC_UNLOCK(d->mutex);
if (r == NULL && mopts.malloc_xmalloc) if (r == NULL && mopts.malloc_xmalloc)
wrterror(d, "out of memory", NULL);
wrterror(d, "out of memory");
if (r != NULL) if (r != NULL)
errno = saved_errno; errno = saved_errno;
return r; return r;
@ -1291,13 +1293,13 @@ validate_junk(struct dir_info *pool, void *p)
return; return;
r = find(pool, p); r = find(pool, p);
if (r == NULL) if (r == NULL)
wrterror(pool, "bogus pointer in validate_junk", p);
wrterror(pool, "bogus pointer in validate_junk %p", p);
REALSIZE(sz, r); REALSIZE(sz, r);
if (sz > CHUNK_CHECK_LENGTH) if (sz > CHUNK_CHECK_LENGTH)
sz = CHUNK_CHECK_LENGTH; sz = CHUNK_CHECK_LENGTH;
for (byte = 0; byte < sz; byte++) { for (byte = 0; byte < sz; byte++) {
if (((unsigned char *)p)[byte] != SOME_FREEJUNK) if (((unsigned char *)p)[byte] != SOME_FREEJUNK)
wrterror(pool, "use after free", p);
wrterror(pool, "use after free %p", p);
} }
} }
@ -1327,7 +1329,7 @@ ofree(struct dir_info *argpool, void *p)
} }
} }
if (r == NULL) if (r == NULL)
wrterror(pool, "bogus pointer (double free?)", p);
wrterror(pool, "bogus pointer (double free?) %p", p);
} }
REALSIZE(sz, r); REALSIZE(sz, r);
@ -1335,7 +1337,11 @@ ofree(struct dir_info *argpool, void *p)
if (sz - mopts.malloc_guard >= MALLOC_PAGESIZE - if (sz - mopts.malloc_guard >= MALLOC_PAGESIZE -
MALLOC_LEEWAY) { MALLOC_LEEWAY) {
if (r->p != p) if (r->p != p)
wrterror(pool, "bogus pointer", p);
wrterror(pool, "bogus pointer %p", p);
if (mopts.chunk_canaries)
validate_canary(pool, p,
sz - mopts.malloc_guard,
PAGEROUND(sz - mopts.malloc_guard));
} else { } else {
#if notyetbecause_of_realloc #if notyetbecause_of_realloc
/* shifted towards the end */ /* shifted towards the end */
@ -1348,12 +1354,12 @@ ofree(struct dir_info *argpool, void *p)
} }
if (mopts.malloc_guard) { if (mopts.malloc_guard) {
if (sz < mopts.malloc_guard) if (sz < mopts.malloc_guard)
wrterror(pool, "guard size", NULL);
wrterror(pool, "guard size");
if (!mopts.malloc_freeunmap) { if (!mopts.malloc_freeunmap) {
if (mprotect((char *)p + PAGEROUND(sz) - if (mprotect((char *)p + PAGEROUND(sz) -
mopts.malloc_guard, mopts.malloc_guard, mopts.malloc_guard, mopts.malloc_guard,
PROT_READ | PROT_WRITE)) PROT_READ | PROT_WRITE))
wrterror(pool, "mprotect", NULL);
wrterror(pool, "mprotect");
} }
STATS_SUB(pool->malloc_guarded, mopts.malloc_guard); STATS_SUB(pool->malloc_guarded, mopts.malloc_guard);
} }
@ -1371,7 +1377,7 @@ ofree(struct dir_info *argpool, void *p)
tmp = p; tmp = p;
p = pool->delayed_chunks[i]; p = pool->delayed_chunks[i];
if (tmp == p) if (tmp == p)
wrterror(pool, "double free", p);
wrterror(pool, "double free %p", tmp);
if (mopts.malloc_junk) if (mopts.malloc_junk)
validate_junk(pool, p); validate_junk(pool, p);
pool->delayed_chunks[i] = tmp; pool->delayed_chunks[i] = tmp;
@ -1382,11 +1388,12 @@ ofree(struct dir_info *argpool, void *p)
if (p != NULL) { if (p != NULL) {
r = find(pool, p); r = find(pool, p);
if (r == NULL) if (r == NULL)
wrterror(pool, "bogus pointer (double free?)", p);
wrterror(pool,
"bogus pointer (double free?) %p", p);
free_bytes(pool, r, p); free_bytes(pool, r, p);
} }
} }
done:
if (argpool != pool) { if (argpool != pool) {
pool->active--; pool->active--;
_MALLOC_UNLOCK(pool->mutex); _MALLOC_UNLOCK(pool->mutex);
@ -1407,9 +1414,9 @@ free(void *ptr)
d = getpool(); d = getpool();
if (d == NULL) if (d == NULL)
wrterror(d, "free() called before allocation", NULL);
wrterror(d, "free() called before allocation");
_MALLOC_LOCK(d->mutex); _MALLOC_LOCK(d->mutex);
d->func = "free():";
d->func = "free";
if (d->active++) { if (d->active++) {
malloc_recurse(d); malloc_recurse(d);
return; return;
@ -1453,7 +1460,7 @@ orealloc(struct dir_info *argpool, void *p, size_t newsz, void *f)
} }
} }
if (r == NULL) if (r == NULL)
wrterror(pool, "bogus pointer (double free?)", p);
wrterror(pool, "bogus pointer (double free?) %p", p);
} }
if (newsz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE) { if (newsz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE) {
errno = ENOMEM; errno = ENOMEM;
@ -1465,7 +1472,7 @@ orealloc(struct dir_info *argpool, void *p, size_t newsz, void *f)
goldsz = oldsz; goldsz = oldsz;
if (oldsz > MALLOC_MAXCHUNK) { if (oldsz > MALLOC_MAXCHUNK) {
if (oldsz < mopts.malloc_guard) if (oldsz < mopts.malloc_guard)
wrterror(pool, "guard size", NULL);
wrterror(pool, "guard size");
oldsz -= mopts.malloc_guard; oldsz -= mopts.malloc_guard;
} }
@ -1474,7 +1481,7 @@ orealloc(struct dir_info *argpool, void *p, size_t newsz, void *f)
gnewsz += mopts.malloc_guard; gnewsz += mopts.malloc_guard;
if (newsz > MALLOC_MAXCHUNK && oldsz > MALLOC_MAXCHUNK && p == r->p && if (newsz > MALLOC_MAXCHUNK && oldsz > MALLOC_MAXCHUNK && p == r->p &&
!mopts.malloc_realloc) {
!mopts.chunk_canaries && !mopts.malloc_realloc) {
size_t roldsz = PAGEROUND(goldsz); size_t roldsz = PAGEROUND(goldsz);
size_t rnewsz = PAGEROUND(gnewsz); size_t rnewsz = PAGEROUND(gnewsz);
@ -1505,7 +1512,7 @@ gotit:
goto done; goto done;
} else if (q != MAP_FAILED) { } else if (q != MAP_FAILED) {
if (munmap(q, needed)) if (munmap(q, needed))
wrterror(pool, "munmap", q);
wrterror(pool, "munmap %p", q);
} }
} }
} else if (rnewsz < roldsz) { } else if (rnewsz < roldsz) {
@ -1513,11 +1520,11 @@ gotit:
if (mprotect((char *)p + roldsz - if (mprotect((char *)p + roldsz -
mopts.malloc_guard, mopts.malloc_guard, mopts.malloc_guard, mopts.malloc_guard,
PROT_READ | PROT_WRITE)) PROT_READ | PROT_WRITE))
wrterror(pool, "mprotect", NULL);
wrterror(pool, "mprotect");
if (mprotect((char *)p + rnewsz - if (mprotect((char *)p + rnewsz -
mopts.malloc_guard, mopts.malloc_guard, mopts.malloc_guard, mopts.malloc_guard,
PROT_NONE)) PROT_NONE))
wrterror(pool, "mprotect", NULL);
wrterror(pool, "mprotect");
} }
unmap(pool, (char *)p + rnewsz, roldsz - rnewsz); unmap(pool, (char *)p + rnewsz, roldsz - rnewsz);
r->size = gnewsz; r->size = gnewsz;
@ -1578,7 +1585,7 @@ realloc(void *ptr, size_t size)
d = getpool(); d = getpool();
} }
_MALLOC_LOCK(d->mutex); _MALLOC_LOCK(d->mutex);
d->func = "realloc():";
d->func = "realloc";
if (d->active++) { if (d->active++) {
malloc_recurse(d); malloc_recurse(d);
return NULL; return NULL;
@ -1588,7 +1595,7 @@ realloc(void *ptr, size_t size)
d->active--; d->active--;
_MALLOC_UNLOCK(d->mutex); _MALLOC_UNLOCK(d->mutex);
if (r == NULL && mopts.malloc_xmalloc) if (r == NULL && mopts.malloc_xmalloc)
wrterror(d, "out of memory", NULL);
wrterror(d, "out of memory");
if (r != NULL) if (r != NULL)
errno = saved_errno; errno = saved_errno;
return r; return r;
@ -1615,12 +1622,12 @@ calloc(size_t nmemb, size_t size)
d = getpool(); d = getpool();
} }
_MALLOC_LOCK(d->mutex); _MALLOC_LOCK(d->mutex);
d->func = "calloc():";
d->func = "calloc";
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
nmemb > 0 && SIZE_MAX / nmemb < size) { nmemb > 0 && SIZE_MAX / nmemb < size) {
_MALLOC_UNLOCK(d->mutex); _MALLOC_UNLOCK(d->mutex);
if (mopts.malloc_xmalloc) if (mopts.malloc_xmalloc)
wrterror(d, "out of memory", NULL);
wrterror(d, "out of memory");
errno = ENOMEM; errno = ENOMEM;
return NULL; return NULL;
} }
@ -1636,7 +1643,7 @@ calloc(size_t nmemb, size_t size)
d->active--; d->active--;
_MALLOC_UNLOCK(d->mutex); _MALLOC_UNLOCK(d->mutex);
if (r == NULL && mopts.malloc_xmalloc) if (r == NULL && mopts.malloc_xmalloc)
wrterror(d, "out of memory", NULL);
wrterror(d, "out of memory");
if (r != NULL) if (r != NULL)
errno = saved_errno; errno = saved_errno;
return r; return r;
@ -1649,9 +1656,9 @@ mapalign(struct dir_info *d, size_t alignment, size_t sz, int zero_fill)
char *p, *q; char *p, *q;
if (alignment < MALLOC_PAGESIZE || ((alignment - 1) & alignment) != 0) if (alignment < MALLOC_PAGESIZE || ((alignment - 1) & alignment) != 0)
wrterror(d, "mapalign bad alignment", NULL);
wrterror(d, "mapalign bad alignment");
if (sz != PAGEROUND(sz)) if (sz != PAGEROUND(sz))
wrterror(d, "mapalign round", NULL);
wrterror(d, "mapalign round");
/* Allocate sz + alignment bytes of memory, which must include a /* Allocate sz + alignment bytes of memory, which must include a
* subrange of size bytes that is properly aligned. Unmap the * subrange of size bytes that is properly aligned. Unmap the
@ -1668,10 +1675,10 @@ mapalign(struct dir_info *d, size_t alignment, size_t sz, int zero_fill)
q = (char *)(((uintptr_t)p + alignment - 1) & ~(alignment - 1)); q = (char *)(((uintptr_t)p + alignment - 1) & ~(alignment - 1));
if (q != p) { if (q != p) {
if (munmap(p, q - p)) if (munmap(p, q - p))
wrterror(d, "munmap", p);
wrterror(d, "munmap %p", p);
} }
if (munmap(q + sz, alignment - (q - p))) if (munmap(q + sz, alignment - (q - p)))
wrterror(d, "munmap", q + sz);
wrterror(d, "munmap %p", q + sz);
STATS_SUB(d->malloc_used, alignment); STATS_SUB(d->malloc_used, alignment);
return q; return q;
@ -1716,7 +1723,7 @@ omemalign(struct dir_info *pool, size_t alignment, size_t sz, int zero_fill, voi
if (mopts.malloc_guard) { if (mopts.malloc_guard) {
if (mprotect((char *)p + psz - mopts.malloc_guard, if (mprotect((char *)p + psz - mopts.malloc_guard,
mopts.malloc_guard, PROT_NONE)) mopts.malloc_guard, PROT_NONE))
wrterror(pool, "mprotect", NULL);
wrterror(pool, "mprotect");
STATS_ADD(pool->malloc_guarded, mopts.malloc_guard); STATS_ADD(pool->malloc_guarded, mopts.malloc_guard);
} }
@ -1748,7 +1755,7 @@ posix_memalign(void **memptr, size_t alignment, size_t size)
d = getpool(); d = getpool();
} }
_MALLOC_LOCK(d->mutex); _MALLOC_LOCK(d->mutex);
d->func = "posix_memalign():";
d->func = "posix_memalign";
if (d->active++) { if (d->active++) {
malloc_recurse(d); malloc_recurse(d);
goto err; goto err;
@ -1758,7 +1765,7 @@ posix_memalign(void **memptr, size_t alignment, size_t size)
_MALLOC_UNLOCK(d->mutex); _MALLOC_UNLOCK(d->mutex);
if (r == NULL) { if (r == NULL) {
if (mopts.malloc_xmalloc) if (mopts.malloc_xmalloc)
wrterror(d, "out of memory", NULL);
wrterror(d, "out of memory");
goto err; goto err;
} }
errno = saved_errno; errno = saved_errno;
@ -2007,7 +2014,7 @@ malloc_dump(int fd, struct dir_info *pool)
continue; continue;
r = find(pool, p); r = find(pool, p);
if (r == NULL) if (r == NULL)
wrterror(pool, "bogus pointer in malloc_dump", p);
wrterror(pool, "bogus pointer in malloc_dump %p", p);
free_bytes(pool, r, p); free_bytes(pool, r, p);
pool->delayed_chunks[i] = NULL; pool->delayed_chunks[i] = NULL;
} }


Loading…
Cancel
Save