diff options
author | otto <> | 2017-09-23 15:13:12 +0000 |
---|---|---|
committer | otto <> | 2017-09-23 15:13:12 +0000 |
commit | 258b17fa326a0d3afda80e2e13941090d75c2f9f (patch) | |
tree | 7053af173364fae2f857ddda82460b7abc3b5cc0 /src/lib | |
parent | 263609dd4f2b34a02f6d2e943f58b18b8eef887a (diff) | |
download | openbsd-258b17fa326a0d3afda80e2e13941090d75c2f9f.tar.gz openbsd-258b17fa326a0d3afda80e2e13941090d75c2f9f.tar.bz2 openbsd-258b17fa326a0d3afda80e2e13941090d75c2f9f.zip |
Make delayed free non-optional and make F do an extensive double free check.
ok tb@ tedu@
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libc/stdlib/malloc.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c index e522e0aee5..221a876f69 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.231 2017/09/12 18:36:30 otto Exp $ */ | 1 | /* $OpenBSD: malloc.c,v 1.232 2017/09/23 15:13:12 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> |
@@ -179,7 +179,7 @@ struct chunk_info { | |||
179 | struct malloc_readonly { | 179 | struct malloc_readonly { |
180 | struct dir_info *malloc_pool[_MALLOC_MUTEXES]; /* Main bookkeeping information */ | 180 | struct dir_info *malloc_pool[_MALLOC_MUTEXES]; /* Main bookkeeping information */ |
181 | int malloc_mt; /* multi-threaded mode? */ | 181 | int malloc_mt; /* multi-threaded mode? */ |
182 | int malloc_freenow; /* Free quickly - disable chunk rnd */ | 182 | int malloc_freecheck; /* Extensive double free check */ |
183 | int malloc_freeunmap; /* mprotect free pages PROT_NONE? */ | 183 | int malloc_freeunmap; /* mprotect free pages PROT_NONE? */ |
184 | int malloc_junk; /* junk fill? */ | 184 | int malloc_junk; /* junk fill? */ |
185 | int malloc_realloc; /* always realloc? */ | 185 | int malloc_realloc; /* always realloc? */ |
@@ -520,11 +520,11 @@ omalloc_parseopt(char opt) | |||
520 | break; | 520 | break; |
521 | #endif /* MALLOC_STATS */ | 521 | #endif /* MALLOC_STATS */ |
522 | case 'f': | 522 | case 'f': |
523 | mopts.malloc_freenow = 0; | 523 | mopts.malloc_freecheck = 0; |
524 | mopts.malloc_freeunmap = 0; | 524 | mopts.malloc_freeunmap = 0; |
525 | break; | 525 | break; |
526 | case 'F': | 526 | case 'F': |
527 | mopts.malloc_freenow = 1; | 527 | mopts.malloc_freecheck = 1; |
528 | mopts.malloc_freeunmap = 1; | 528 | mopts.malloc_freeunmap = 1; |
529 | break; | 529 | break; |
530 | case 'g': | 530 | case 'g': |
@@ -605,7 +605,7 @@ omalloc_init(void) | |||
605 | for (; p != NULL && *p != '\0'; p++) { | 605 | for (; p != NULL && *p != '\0'; p++) { |
606 | switch (*p) { | 606 | switch (*p) { |
607 | case 'S': | 607 | case 'S': |
608 | for (q = "CGJ"; *q != '\0'; q++) | 608 | for (q = "CFGJ"; *q != '\0'; q++) |
609 | omalloc_parseopt(*q); | 609 | omalloc_parseopt(*q); |
610 | mopts.malloc_cache = 0; | 610 | mopts.malloc_cache = 0; |
611 | break; | 611 | break; |
@@ -1046,10 +1046,12 @@ validate_canary(struct dir_info *d, u_char *ptr, size_t sz, size_t allocated) | |||
1046 | q = p + check_sz; | 1046 | q = p + check_sz; |
1047 | 1047 | ||
1048 | while (p < q) { | 1048 | while (p < q) { |
1049 | if (*p++ != SOME_JUNK) { | 1049 | if (*p != SOME_JUNK) { |
1050 | wrterror(d, "chunk canary corrupted %p %#tx@%#zx", | 1050 | wrterror(d, "chunk canary corrupted %p %#tx@%#zx%s", |
1051 | ptr, p - ptr - 1, sz); | 1051 | ptr, p - ptr, sz, *p == SOME_FREEJUNK ? |
1052 | " (double free?)" : ""); | ||
1052 | } | 1053 | } |
1054 | p++; | ||
1053 | } | 1055 | } |
1054 | } | 1056 | } |
1055 | 1057 | ||
@@ -1381,13 +1383,18 @@ ofree(struct dir_info *argpool, void *p, int clear, int check, size_t argsz) | |||
1381 | unmap(pool, p, PAGEROUND(sz), clear); | 1383 | unmap(pool, p, PAGEROUND(sz), clear); |
1382 | delete(pool, r); | 1384 | delete(pool, r); |
1383 | } else { | 1385 | } else { |
1384 | void *tmp; | 1386 | /* Validate and optionally canary check */ |
1385 | int i; | 1387 | find_chunknum(pool, r, p, mopts.chunk_canaries); |
1386 | 1388 | if (!clear) { | |
1387 | /* Delayed free or canaries? Extra check */ | 1389 | void *tmp; |
1388 | if (!mopts.malloc_freenow || mopts.chunk_canaries) | 1390 | int i; |
1389 | find_chunknum(pool, r, p, mopts.chunk_canaries); | 1391 | |
1390 | if (!clear && !mopts.malloc_freenow) { | 1392 | if (mopts.malloc_freecheck) { |
1393 | for (i = 0; i <= MALLOC_DELAYED_CHUNK_MASK; i++) | ||
1394 | if (p == pool->delayed_chunks[i]) | ||
1395 | wrterror(pool, | ||
1396 | "double free %p", p); | ||
1397 | } | ||
1391 | if (mopts.malloc_junk && sz > 0) | 1398 | if (mopts.malloc_junk && sz > 0) |
1392 | memset(p, SOME_FREEJUNK, sz); | 1399 | memset(p, SOME_FREEJUNK, sz); |
1393 | i = getrbyte(pool) & MALLOC_DELAYED_CHUNK_MASK; | 1400 | i = getrbyte(pool) & MALLOC_DELAYED_CHUNK_MASK; |
@@ -1395,13 +1402,11 @@ ofree(struct dir_info *argpool, void *p, int clear, int check, size_t argsz) | |||
1395 | p = pool->delayed_chunks[i]; | 1402 | p = pool->delayed_chunks[i]; |
1396 | if (tmp == p) | 1403 | if (tmp == p) |
1397 | wrterror(pool, "double free %p", tmp); | 1404 | wrterror(pool, "double free %p", tmp); |
1405 | pool->delayed_chunks[i] = tmp; | ||
1398 | if (mopts.malloc_junk) | 1406 | if (mopts.malloc_junk) |
1399 | validate_junk(pool, p); | 1407 | validate_junk(pool, p); |
1400 | pool->delayed_chunks[i] = tmp; | 1408 | } else if (sz > 0) |
1401 | } else { | 1409 | memset(p, 0, sz); |
1402 | if ((clear || mopts.malloc_junk) && sz > 0) | ||
1403 | memset(p, clear ? 0 : SOME_FREEJUNK, sz); | ||
1404 | } | ||
1405 | if (p != NULL) { | 1410 | if (p != NULL) { |
1406 | r = find(pool, p); | 1411 | r = find(pool, p); |
1407 | if (r == NULL) | 1412 | if (r == NULL) |
@@ -2348,7 +2353,7 @@ malloc_exit(void) | |||
2348 | snprintf(buf, sizeof(buf), | 2353 | snprintf(buf, sizeof(buf), |
2349 | "MT=%d I=%d F=%d U=%d J=%d R=%d X=%d C=%d cache=%u G=%zu\n", | 2354 | "MT=%d I=%d F=%d U=%d J=%d R=%d X=%d C=%d cache=%u G=%zu\n", |
2350 | mopts.malloc_mt, mopts.internal_funcs, | 2355 | mopts.malloc_mt, mopts.internal_funcs, |
2351 | mopts.malloc_freenow, | 2356 | mopts.malloc_freecheck, |
2352 | mopts.malloc_freeunmap, mopts.malloc_junk, | 2357 | mopts.malloc_freeunmap, mopts.malloc_junk, |
2353 | mopts.malloc_realloc, mopts.malloc_xmalloc, | 2358 | mopts.malloc_realloc, mopts.malloc_xmalloc, |
2354 | mopts.chunk_canaries, mopts.malloc_cache, | 2359 | mopts.chunk_canaries, mopts.malloc_cache, |