Browse Source

- An error in the multithreaded case could print the wrong function name

- Start with a full page of struct region_info's
- Save an mprotect in the init code: allocate 3 pages with none and
make the middle page r/w instead of a r/w allocation and two calls to make the
guard pages none
OPENBSD_6_3
otto 6 years ago
parent
commit
22e454653c
1 changed files with 23 additions and 12 deletions
  1. +23
    -12
      src/lib/libc/stdlib/malloc.c

+ 23
- 12
src/lib/libc/stdlib/malloc.c View File

@ -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++;


Loading…
Cancel
Save