diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libc/stdlib/malloc.c | 35 |
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) | |||
| 449 | static void | 452 | static void |
| 450 | omalloc_poolinit(struct dir_info **dp) | 453 | omalloc_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: | |||
| 1643 | done: | 1653 | done: |
| 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++; |
