summaryrefslogtreecommitdiff
path: root/lib/libc/stdlib
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/stdlib')
-rw-r--r--lib/libc/stdlib/malloc.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c
index 8778bf14101..663d0877ae6 100644
--- a/lib/libc/stdlib/malloc.c
+++ b/lib/libc/stdlib/malloc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: malloc.c,v 1.242 2018/01/26 19:14:51 otto Exp $ */
+/* $OpenBSD: malloc.c,v 1.243 2018/01/28 13:41:48 otto Exp $ */
/*
* Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net>
* Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org>
@@ -62,7 +62,7 @@
#define MALLOC_MAXCHUNK (1 << MALLOC_MAXSHIFT)
#define MALLOC_MAXCACHE 256
#define MALLOC_DELAYED_CHUNK_MASK 15
-#define MALLOC_INITIAL_REGIONS 512
+#define MALLOC_INITIAL_REGIONS (MALLOC_PAGESIZE / sizeof(struct region_info))
#define MALLOC_DEFAULT_CACHE 64
#define MALLOC_CHUNK_LISTS 4
#define CHUNK_CHECK_LENGTH 32
@@ -93,6 +93,9 @@
#define MMAP(sz) mmap(NULL, (sz), PROT_READ | PROT_WRITE, \
MAP_ANON | MAP_PRIVATE, -1, 0)
+#define MMAPNONE(sz) mmap(NULL, (sz), PROT_NONE, \
+ MAP_ANON | MAP_PRIVATE, -1, 0)
+
#define MMAPA(a,sz) mmap((a), (sz), PROT_READ | PROT_WRITE, \
MAP_ANON | MAP_PRIVATE, -1, 0)
@@ -449,7 +452,7 @@ omalloc_init(void)
static void
omalloc_poolinit(struct dir_info **dp)
{
- void *p;
+ char *p;
size_t d_avail, regioninfo_size;
struct dir_info *d;
int i, j;
@@ -459,13 +462,11 @@ omalloc_poolinit(struct dir_info **dp)
* randomise offset inside the page at which the dir_info
* lies (subject to alignment by 1 << MALLOC_MINSHIFT)
*/
- if ((p = MMAP(DIR_INFO_RSZ + (MALLOC_PAGESIZE * 2))) == MAP_FAILED)
+ if ((p = MMAPNONE(DIR_INFO_RSZ + (MALLOC_PAGESIZE * 2))) == MAP_FAILED)
wrterror(NULL, "malloc init mmap failed");
- mprotect(p, MALLOC_PAGESIZE, PROT_NONE);
- mprotect((char *)p + MALLOC_PAGESIZE + DIR_INFO_RSZ,
- MALLOC_PAGESIZE, PROT_NONE);
+ mprotect(p + MALLOC_PAGESIZE, DIR_INFO_RSZ, PROT_READ | PROT_WRITE);
d_avail = (DIR_INFO_RSZ - sizeof(*d)) >> MALLOC_MINSHIFT;
- d = (struct dir_info *)((char *)p + MALLOC_PAGESIZE +
+ d = (struct dir_info *)(p + MALLOC_PAGESIZE +
(arc4random_uniform(d_avail) << MALLOC_MINSHIFT));
rbytes_init(d);
@@ -1275,6 +1276,7 @@ ofree(struct dir_info *argpool, void *p, int clear, int check, size_t argsz)
{
struct dir_info *pool;
struct region_info *r;
+ char *saved_function;
size_t sz;
int i;
@@ -1291,12 +1293,15 @@ ofree(struct dir_info *argpool, void *p, int clear, int check, size_t argsz)
_MALLOC_LOCK(pool->mutex);
pool->active++;
r = find(pool, p);
- if (r != NULL)
+ if (r != NULL) {
+ saved_function = pool->func;
+ pool->func = argpool->func;
break;
+ }
}
}
if (r == NULL)
- wrterror(pool, "bogus pointer (double free?) %p", p);
+ wrterror(argpool, "bogus pointer (double free?) %p", p);
}
REALSIZE(sz, r);
@@ -1388,6 +1393,7 @@ ofree(struct dir_info *argpool, void *p, int clear, int check, size_t argsz)
if (argpool != pool) {
pool->active--;
+ pool->func = saved_function;
_MALLOC_UNLOCK(pool->mutex);
_MALLOC_LOCK(argpool->mutex);
argpool->active++;
@@ -1466,6 +1472,7 @@ orealloc(struct dir_info *argpool, void *p, size_t newsz, void *f)
struct chunk_info *info;
size_t oldsz, goldsz, gnewsz;
void *q, *ret;
+ char *saved_function;
int i;
uint32_t chunknum;
@@ -1486,12 +1493,15 @@ orealloc(struct dir_info *argpool, void *p, size_t newsz, void *f)
_MALLOC_LOCK(pool->mutex);
pool->active++;
r = find(pool, p);
- if (r != NULL)
+ if (r != NULL) {
+ saved_function = pool->func;
+ pool->func = argpool->func;
break;
+ }
}
}
if (r == NULL)
- wrterror(pool, "bogus pointer (double free?) %p", p);
+ wrterror(argpool, "bogus pointer (double free?) %p", p);
}
if (newsz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE) {
errno = ENOMEM;
@@ -1643,6 +1653,7 @@ gotit:
done:
if (argpool != pool) {
pool->active--;
+ pool->func = saved_function;
_MALLOC_UNLOCK(pool->mutex);
_MALLOC_LOCK(argpool->mutex);
argpool->active++;