summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libc/stdlib/malloc.c83
1 files changed, 22 insertions, 61 deletions
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
index b4c0010f35..9aedc772db 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.192 2016/07/06 20:32:02 otto Exp $ */ 1/* $OpenBSD: malloc.c,v 1.193 2016/08/17 05:33:54 otto Exp $ */
2/* 2/*
3 * Copyright (c) 2008, 2010, 2011 Otto Moerbeek <otto@drijf.net> 3 * Copyright (c) 2008, 2010, 2011 Otto Moerbeek <otto@drijf.net>
4 * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> 4 * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org>
@@ -249,7 +249,7 @@ hash(void *p)
249 return sum; 249 return sum;
250} 250}
251 251
252static void 252__dead static void
253wrterror(struct dir_info *d, char *msg, void *p) 253wrterror(struct dir_info *d, char *msg, void *p)
254{ 254{
255 char *q = " error: "; 255 char *q = " error: ";
@@ -329,10 +329,8 @@ unmap(struct dir_info *d, void *p, size_t sz)
329 struct region_info *r; 329 struct region_info *r;
330 u_int i, offset; 330 u_int i, offset;
331 331
332 if (sz != PAGEROUND(sz)) { 332 if (sz != PAGEROUND(sz))
333 wrterror(d, "munmap round", NULL); 333 wrterror(d, "munmap round", NULL);
334 return;
335 }
336 334
337 if (psz > mopts.malloc_cache) { 335 if (psz > mopts.malloc_cache) {
338 i = munmap(p, sz); 336 i = munmap(p, sz);
@@ -415,10 +413,8 @@ map(struct dir_info *d, void *hint, size_t sz, int zero_fill)
415 if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) || 413 if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) ||
416 d->canary1 != ~d->canary2) 414 d->canary1 != ~d->canary2)
417 wrterror(d, "internal struct corrupt", NULL); 415 wrterror(d, "internal struct corrupt", NULL);
418 if (sz != PAGEROUND(sz)) { 416 if (sz != PAGEROUND(sz))
419 wrterror(d, "map round", NULL); 417 wrterror(d, "map round", NULL);
420 return MAP_FAILED;
421 }
422 if (!hint && psz > d->free_regions_size) { 418 if (!hint && psz > d->free_regions_size) {
423 _MALLOC_LEAVE(d); 419 _MALLOC_LEAVE(d);
424 p = MMAP(sz); 420 p = MMAP(sz);
@@ -667,11 +663,9 @@ omalloc_init(struct dir_info **dp)
667 d->regions_free = d->regions_total = MALLOC_INITIAL_REGIONS; 663 d->regions_free = d->regions_total = MALLOC_INITIAL_REGIONS;
668 regioninfo_size = d->regions_total * sizeof(struct region_info); 664 regioninfo_size = d->regions_total * sizeof(struct region_info);
669 d->r = MMAP(regioninfo_size); 665 d->r = MMAP(regioninfo_size);
670 if (d->r == MAP_FAILED) { 666 if (d->r == MAP_FAILED)
671 wrterror(NULL, "malloc init mmap failed", NULL); 667 wrterror(NULL, "malloc init mmap failed", NULL);
672 d->regions_total = 0; 668
673 return 1;
674 }
675 for (i = 0; i <= MALLOC_MAXSHIFT; i++) { 669 for (i = 0; i <= MALLOC_MAXSHIFT; i++) {
676 LIST_INIT(&d->chunk_info_list[i]); 670 LIST_INIT(&d->chunk_info_list[i]);
677 for (j = 0; j < MALLOC_CHUNK_LISTS; j++) 671 for (j = 0; j < MALLOC_CHUNK_LISTS; j++)
@@ -1045,15 +1039,11 @@ find_chunknum(struct dir_info *d, struct region_info *r, void *ptr)
1045 /* Find the chunk number on the page */ 1039 /* Find the chunk number on the page */
1046 chunknum = ((uintptr_t)ptr & MALLOC_PAGEMASK) >> info->shift; 1040 chunknum = ((uintptr_t)ptr & MALLOC_PAGEMASK) >> info->shift;
1047 1041
1048 if ((uintptr_t)ptr & ((1U << (info->shift)) - 1)) { 1042 if ((uintptr_t)ptr & ((1U << (info->shift)) - 1))
1049 wrterror(d, "modified chunk-pointer", ptr); 1043 wrterror(d, "modified chunk-pointer", ptr);
1050 return -1;
1051 }
1052 if (info->bits[chunknum / MALLOC_BITS] & 1044 if (info->bits[chunknum / MALLOC_BITS] &
1053 (1U << (chunknum % MALLOC_BITS))) { 1045 (1U << (chunknum % MALLOC_BITS)))
1054 wrterror(d, "chunk is already free", ptr); 1046 wrterror(d, "chunk is already free", ptr);
1055 return -1;
1056 }
1057 return chunknum; 1047 return chunknum;
1058} 1048}
1059 1049
@@ -1226,10 +1216,8 @@ malloc(size_t size)
1226 r = omalloc(d, size, 0, CALLER); 1216 r = omalloc(d, size, 0, CALLER);
1227 d->active--; 1217 d->active--;
1228 _MALLOC_UNLOCK(); 1218 _MALLOC_UNLOCK();
1229 if (r == NULL && mopts.malloc_xmalloc) { 1219 if (r == NULL && mopts.malloc_xmalloc)
1230 wrterror(d, "out of memory", NULL); 1220 wrterror(d, "out of memory", NULL);
1231 errno = ENOMEM;
1232 }
1233 if (r != NULL) 1221 if (r != NULL)
1234 errno = saved_errno; 1222 errno = saved_errno;
1235 return r; 1223 return r;
@@ -1244,20 +1232,16 @@ validate_junk(struct dir_info *pool, void *p) {
1244 if (p == NULL) 1232 if (p == NULL)
1245 return; 1233 return;
1246 r = find(pool, p); 1234 r = find(pool, p);
1247 if (r == NULL) { 1235 if (r == NULL)
1248 wrterror(pool, "bogus pointer in validate_junk", p); 1236 wrterror(pool, "bogus pointer in validate_junk", p);
1249 return;
1250 }
1251 REALSIZE(sz, r); 1237 REALSIZE(sz, r);
1252 if (sz > 0 && sz <= MALLOC_MAXCHUNK) 1238 if (sz > 0 && sz <= MALLOC_MAXCHUNK)
1253 sz -= mopts.malloc_canaries; 1239 sz -= mopts.malloc_canaries;
1254 if (sz > 32) 1240 if (sz > 32)
1255 sz = 32; 1241 sz = 32;
1256 for (byte = 0; byte < sz; byte++) { 1242 for (byte = 0; byte < sz; byte++) {
1257 if (((unsigned char *)p)[byte] != SOME_FREEJUNK) { 1243 if (((unsigned char *)p)[byte] != SOME_FREEJUNK)
1258 wrterror(pool, "use after free", p); 1244 wrterror(pool, "use after free", p);
1259 return;
1260 }
1261 } 1245 }
1262} 1246}
1263 1247
@@ -1268,18 +1252,14 @@ ofree(struct dir_info *pool, void *p)
1268 size_t sz; 1252 size_t sz;
1269 1253
1270 r = find(pool, p); 1254 r = find(pool, p);
1271 if (r == NULL) { 1255 if (r == NULL)
1272 wrterror(pool, "bogus pointer (double free?)", p); 1256 wrterror(pool, "bogus pointer (double free?)", p);
1273 return;
1274 }
1275 REALSIZE(sz, r); 1257 REALSIZE(sz, r);
1276 if (sz > MALLOC_MAXCHUNK) { 1258 if (sz > MALLOC_MAXCHUNK) {
1277 if (sz - mopts.malloc_guard >= MALLOC_PAGESIZE - 1259 if (sz - mopts.malloc_guard >= MALLOC_PAGESIZE -
1278 MALLOC_LEEWAY) { 1260 MALLOC_LEEWAY) {
1279 if (r->p != p) { 1261 if (r->p != p)
1280 wrterror(pool, "bogus pointer", p); 1262 wrterror(pool, "bogus pointer", p);
1281 return;
1282 }
1283 } else { 1263 } else {
1284#if notyetbecause_of_realloc 1264#if notyetbecause_of_realloc
1285 /* shifted towards the end */ 1265 /* shifted towards the end */
@@ -1320,20 +1300,16 @@ ofree(struct dir_info *pool, void *p)
1320 i = getrbyte(pool) & MALLOC_DELAYED_CHUNK_MASK; 1300 i = getrbyte(pool) & MALLOC_DELAYED_CHUNK_MASK;
1321 tmp = p; 1301 tmp = p;
1322 p = pool->delayed_chunks[i]; 1302 p = pool->delayed_chunks[i];
1323 if (tmp == p) { 1303 if (tmp == p)
1324 wrterror(pool, "double free", p); 1304 wrterror(pool, "double free", p);
1325 return;
1326 }
1327 if (mopts.malloc_junk) 1305 if (mopts.malloc_junk)
1328 validate_junk(pool, p); 1306 validate_junk(pool, p);
1329 pool->delayed_chunks[i] = tmp; 1307 pool->delayed_chunks[i] = tmp;
1330 } 1308 }
1331 if (p != NULL) { 1309 if (p != NULL) {
1332 r = find(pool, p); 1310 r = find(pool, p);
1333 if (r == NULL) { 1311 if (r == NULL)
1334 wrterror(pool, "bogus pointer (double free?)", p); 1312 wrterror(pool, "bogus pointer (double free?)", p);
1335 return;
1336 }
1337 free_bytes(pool, r, p); 1313 free_bytes(pool, r, p);
1338 } 1314 }
1339 } 1315 }
@@ -1354,7 +1330,6 @@ free(void *ptr)
1354 if (d == NULL) { 1330 if (d == NULL) {
1355 _MALLOC_UNLOCK(); 1331 _MALLOC_UNLOCK();
1356 wrterror(d, "free() called before allocation", NULL); 1332 wrterror(d, "free() called before allocation", NULL);
1357 return;
1358 } 1333 }
1359 d->func = "free():"; 1334 d->func = "free():";
1360 if (d->active++) { 1335 if (d->active++) {
@@ -1380,10 +1355,8 @@ orealloc(struct dir_info *pool, void *p, size_t newsz, void *f)
1380 return omalloc(pool, newsz, 0, f); 1355 return omalloc(pool, newsz, 0, f);
1381 1356
1382 r = find(pool, p); 1357 r = find(pool, p);
1383 if (r == NULL) { 1358 if (r == NULL)
1384 wrterror(pool, "bogus pointer (double free?)", p); 1359 wrterror(pool, "bogus pointer (double free?)", p);
1385 return NULL;
1386 }
1387 if (newsz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE) { 1360 if (newsz >= SIZE_MAX - mopts.malloc_guard - MALLOC_PAGESIZE) {
1388 errno = ENOMEM; 1361 errno = ENOMEM;
1389 return NULL; 1362 return NULL;
@@ -1512,10 +1485,8 @@ realloc(void *ptr, size_t size)
1512 1485
1513 d->active--; 1486 d->active--;
1514 _MALLOC_UNLOCK(); 1487 _MALLOC_UNLOCK();
1515 if (r == NULL && mopts.malloc_xmalloc) { 1488 if (r == NULL && mopts.malloc_xmalloc)
1516 wrterror(d, "out of memory", NULL); 1489 wrterror(d, "out of memory", NULL);
1517 errno = ENOMEM;
1518 }
1519 if (r != NULL) 1490 if (r != NULL)
1520 errno = saved_errno; 1491 errno = saved_errno;
1521 return r; 1492 return r;
@@ -1565,10 +1536,8 @@ calloc(size_t nmemb, size_t size)
1565 1536
1566 d->active--; 1537 d->active--;
1567 _MALLOC_UNLOCK(); 1538 _MALLOC_UNLOCK();
1568 if (r == NULL && mopts.malloc_xmalloc) { 1539 if (r == NULL && mopts.malloc_xmalloc)
1569 wrterror(d, "out of memory", NULL); 1540 wrterror(d, "out of memory", NULL);
1570 errno = ENOMEM;
1571 }
1572 if (r != NULL) 1541 if (r != NULL)
1573 errno = saved_errno; 1542 errno = saved_errno;
1574 return r; 1543 return r;
@@ -1580,14 +1549,10 @@ mapalign(struct dir_info *d, size_t alignment, size_t sz, int zero_fill)
1580{ 1549{
1581 char *p, *q; 1550 char *p, *q;
1582 1551
1583 if (alignment < MALLOC_PAGESIZE || ((alignment - 1) & alignment) != 0) { 1552 if (alignment < MALLOC_PAGESIZE || ((alignment - 1) & alignment) != 0)
1584 wrterror(d, "mapalign bad alignment", NULL); 1553 wrterror(d, "mapalign bad alignment", NULL);
1585 return MAP_FAILED; 1554 if (sz != PAGEROUND(sz))
1586 }
1587 if (sz != PAGEROUND(sz)) {
1588 wrterror(d, "mapalign round", NULL); 1555 wrterror(d, "mapalign round", NULL);
1589 return MAP_FAILED;
1590 }
1591 1556
1592 /* Allocate sz + alignment bytes of memory, which must include a 1557 /* Allocate sz + alignment bytes of memory, which must include a
1593 * subrange of size bytes that is properly aligned. Unmap the 1558 * subrange of size bytes that is properly aligned. Unmap the
@@ -1696,10 +1661,8 @@ posix_memalign(void **memptr, size_t alignment, size_t size)
1696 d->active--; 1661 d->active--;
1697 _MALLOC_UNLOCK(); 1662 _MALLOC_UNLOCK();
1698 if (r == NULL) { 1663 if (r == NULL) {
1699 if (mopts.malloc_xmalloc) { 1664 if (mopts.malloc_xmalloc)
1700 wrterror(d, "out of memory", NULL); 1665 wrterror(d, "out of memory", NULL);
1701 errno = ENOMEM;
1702 }
1703 goto err; 1666 goto err;
1704 } 1667 }
1705 errno = saved_errno; 1668 errno = saved_errno;
@@ -1948,10 +1911,8 @@ malloc_dump(int fd)
1948 if (p == NULL) 1911 if (p == NULL)
1949 continue; 1912 continue;
1950 r = find(pool, p); 1913 r = find(pool, p);
1951 if (r == NULL) { 1914 if (r == NULL)
1952 wrterror(pool, "bogus pointer in malloc_dump", p); 1915 wrterror(pool, "bogus pointer in malloc_dump", p);
1953 continue;
1954 }
1955 free_bytes(pool, r, p); 1916 free_bytes(pool, r, p);
1956 pool->delayed_chunks[i] = NULL; 1917 pool->delayed_chunks[i] = NULL;
1957 } 1918 }