summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorotto <>2018-01-28 13:41:48 +0000
committerotto <>2018-01-28 13:41:48 +0000
commit0fdd68e79323c32811255f4f326d3a2a1e136165 (patch)
tree78153bc2cbe6c97664fab850227401171eced9d8
parent61b1ba1dd4145a63b5348c8754eca8b7aead54d1 (diff)
downloadopenbsd-0fdd68e79323c32811255f4f326d3a2a1e136165.tar.gz
openbsd-0fdd68e79323c32811255f4f326d3a2a1e136165.tar.bz2
openbsd-0fdd68e79323c32811255f4f326d3a2a1e136165.zip
- 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
-rw-r--r--src/lib/libc/stdlib/malloc.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
index 8778bf1410..663d0877ae 100644
--- a/src/lib/libc/stdlib/malloc.c
+++ b/src/lib/libc/stdlib/malloc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: malloc.c,v 1.242 2018/01/26 19:14:51 otto Exp $ */ 1/* $OpenBSD: malloc.c,v 1.243 2018/01/28 13:41:48 otto Exp $ */
2/* 2/*
3 * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net> 3 * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net>
4 * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> 4 * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org>
@@ -62,7 +62,7 @@
62#define MALLOC_MAXCHUNK (1 << MALLOC_MAXSHIFT) 62#define MALLOC_MAXCHUNK (1 << MALLOC_MAXSHIFT)
63#define MALLOC_MAXCACHE 256 63#define MALLOC_MAXCACHE 256
64#define MALLOC_DELAYED_CHUNK_MASK 15 64#define MALLOC_DELAYED_CHUNK_MASK 15
65#define MALLOC_INITIAL_REGIONS 512 65#define MALLOC_INITIAL_REGIONS (MALLOC_PAGESIZE / sizeof(struct region_info))
66#define MALLOC_DEFAULT_CACHE 64 66#define MALLOC_DEFAULT_CACHE 64
67#define MALLOC_CHUNK_LISTS 4 67#define MALLOC_CHUNK_LISTS 4
68#define CHUNK_CHECK_LENGTH 32 68#define CHUNK_CHECK_LENGTH 32
@@ -93,6 +93,9 @@
93#define MMAP(sz) mmap(NULL, (sz), PROT_READ | PROT_WRITE, \ 93#define MMAP(sz) mmap(NULL, (sz), PROT_READ | PROT_WRITE, \
94 MAP_ANON | MAP_PRIVATE, -1, 0) 94 MAP_ANON | MAP_PRIVATE, -1, 0)
95 95
96#define MMAPNONE(sz) mmap(NULL, (sz), PROT_NONE, \
97 MAP_ANON | MAP_PRIVATE, -1, 0)
98
96#define MMAPA(a,sz) mmap((a), (sz), PROT_READ | PROT_WRITE, \ 99#define MMAPA(a,sz) mmap((a), (sz), PROT_READ | PROT_WRITE, \
97 MAP_ANON | MAP_PRIVATE, -1, 0) 100 MAP_ANON | MAP_PRIVATE, -1, 0)
98 101
@@ -449,7 +452,7 @@ omalloc_init(void)
449static void 452static void
450omalloc_poolinit(struct dir_info **dp) 453omalloc_poolinit(struct dir_info **dp)
451{ 454{
452 void *p; 455 char *p;
453 size_t d_avail, regioninfo_size; 456 size_t d_avail, regioninfo_size;
454 struct dir_info *d; 457 struct dir_info *d;
455 int i, j; 458 int i, j;
@@ -459,13 +462,11 @@ omalloc_poolinit(struct dir_info **dp)
459 * randomise offset inside the page at which the dir_info 462 * randomise offset inside the page at which the dir_info
460 * lies (subject to alignment by 1 << MALLOC_MINSHIFT) 463 * lies (subject to alignment by 1 << MALLOC_MINSHIFT)
461 */ 464 */
462 if ((p = MMAP(DIR_INFO_RSZ + (MALLOC_PAGESIZE * 2))) == MAP_FAILED) 465 if ((p = MMAPNONE(DIR_INFO_RSZ + (MALLOC_PAGESIZE * 2))) == MAP_FAILED)
463 wrterror(NULL, "malloc init mmap failed"); 466 wrterror(NULL, "malloc init mmap failed");
464 mprotect(p, MALLOC_PAGESIZE, PROT_NONE); 467 mprotect(p + MALLOC_PAGESIZE, DIR_INFO_RSZ, PROT_READ | PROT_WRITE);
465 mprotect((char *)p + MALLOC_PAGESIZE + DIR_INFO_RSZ,
466 MALLOC_PAGESIZE, PROT_NONE);
467 d_avail = (DIR_INFO_RSZ - sizeof(*d)) >> MALLOC_MINSHIFT; 468 d_avail = (DIR_INFO_RSZ - sizeof(*d)) >> MALLOC_MINSHIFT;
468 d = (struct dir_info *)((char *)p + MALLOC_PAGESIZE + 469 d = (struct dir_info *)(p + MALLOC_PAGESIZE +
469 (arc4random_uniform(d_avail) << MALLOC_MINSHIFT)); 470 (arc4random_uniform(d_avail) << MALLOC_MINSHIFT));
470 471
471 rbytes_init(d); 472 rbytes_init(d);
@@ -1275,6 +1276,7 @@ ofree(struct dir_info *argpool, void *p, int clear, int check, size_t argsz)
1275{ 1276{
1276 struct dir_info *pool; 1277 struct dir_info *pool;
1277 struct region_info *r; 1278 struct region_info *r;
1279 char *saved_function;
1278 size_t sz; 1280 size_t sz;
1279 int i; 1281 int i;
1280 1282
@@ -1291,12 +1293,15 @@ ofree(struct dir_info *argpool, void *p, int clear, int check, size_t argsz)
1291 _MALLOC_LOCK(pool->mutex); 1293 _MALLOC_LOCK(pool->mutex);
1292 pool->active++; 1294 pool->active++;
1293 r = find(pool, p); 1295 r = find(pool, p);
1294 if (r != NULL) 1296 if (r != NULL) {
1297 saved_function = pool->func;
1298 pool->func = argpool->func;
1295 break; 1299 break;
1300 }
1296 } 1301 }
1297 } 1302 }
1298 if (r == NULL) 1303 if (r == NULL)
1299 wrterror(pool, "bogus pointer (double free?) %p", p); 1304 wrterror(argpool, "bogus pointer (double free?) %p", p);
1300 } 1305 }
1301 1306
1302 REALSIZE(sz, r); 1307 REALSIZE(sz, r);
@@ -1388,6 +1393,7 @@ ofree(struct dir_info *argpool, void *p, int clear, int check, size_t argsz)
1388 1393
1389 if (argpool != pool) { 1394 if (argpool != pool) {
1390 pool->active--; 1395 pool->active--;
1396 pool->func = saved_function;
1391 _MALLOC_UNLOCK(pool->mutex); 1397 _MALLOC_UNLOCK(pool->mutex);
1392 _MALLOC_LOCK(argpool->mutex); 1398 _MALLOC_LOCK(argpool->mutex);
1393 argpool->active++; 1399 argpool->active++;
@@ -1466,6 +1472,7 @@ orealloc(struct dir_info *argpool, void *p, size_t newsz, void *f)
1466 struct chunk_info *info; 1472 struct chunk_info *info;
1467 size_t oldsz, goldsz, gnewsz; 1473 size_t oldsz, goldsz, gnewsz;
1468 void *q, *ret; 1474 void *q, *ret;
1475 char *saved_function;
1469 int i; 1476 int i;
1470 uint32_t chunknum; 1477 uint32_t chunknum;
1471 1478
@@ -1486,12 +1493,15 @@ orealloc(struct dir_info *argpool, void *p, size_t newsz, void *f)
1486 _MALLOC_LOCK(pool->mutex); 1493 _MALLOC_LOCK(pool->mutex);
1487 pool->active++; 1494 pool->active++;
1488 r = find(pool, p); 1495 r = find(pool, p);
1489 if (r != NULL) 1496 if (r != NULL) {
1497 saved_function = pool->func;
1498 pool->func = argpool->func;
1490 break; 1499 break;
1500 }
1491 } 1501 }
1492 } 1502 }
1493 if (r == NULL) 1503 if (r == NULL)
1494 wrterror(pool, "bogus pointer (double free?) %p", p); 1504 wrterror(argpool, "bogus pointer (double free?) %p", p);
1495 } 1505 }
1496 if (newsz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE) { 1506 if (newsz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE) {
1497 errno = ENOMEM; 1507 errno = ENOMEM;
@@ -1643,6 +1653,7 @@ gotit:
1643done: 1653done:
1644 if (argpool != pool) { 1654 if (argpool != pool) {
1645 pool->active--; 1655 pool->active--;
1656 pool->func = saved_function;
1646 _MALLOC_UNLOCK(pool->mutex); 1657 _MALLOC_UNLOCK(pool->mutex);
1647 _MALLOC_LOCK(argpool->mutex); 1658 _MALLOC_LOCK(argpool->mutex);
1648 argpool->active++; 1659 argpool->active++;