diff options
author | Otto Moerbeek <otto@cvs.openbsd.org> | 2016-09-03 12:24:11 +0000 |
---|---|---|
committer | Otto Moerbeek <otto@cvs.openbsd.org> | 2016-09-03 12:24:11 +0000 |
commit | ee11b7ab9c5d1ea2dbe61c32a93a7562a4994b9d (patch) | |
tree | 93582dfebdf4e1fbd59c045a25cf3318f44198ab /libexec/ld.so | |
parent | df0375c456f160b0312f19ffa9cb9f8fe1f8cc86 (diff) |
cherry-pick a few diffs from libc malloc; ok guenther@
Diffstat (limited to 'libexec/ld.so')
-rw-r--r-- | libexec/ld.so/malloc.c | 104 |
1 files changed, 36 insertions, 68 deletions
diff --git a/libexec/ld.so/malloc.c b/libexec/ld.so/malloc.c index a234065ee71..121e1c18e03 100644 --- a/libexec/ld.so/malloc.c +++ b/libexec/ld.so/malloc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: malloc.c,v 1.9 2016/08/12 20:39:01 deraadt Exp $ */ +/* $OpenBSD: malloc.c,v 1.10 2016/09/03 12:24:10 otto Exp $ */ /* * Copyright (c) 2008, 2010, 2011 Otto Moerbeek <otto@drijf.net> * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> @@ -33,9 +33,7 @@ #include "archdep.h" #include "resolve.h" -#if defined(__sparc__) && !defined(__sparcv9__) -#define MALLOC_PAGESHIFT (13U) -#elif defined(__mips64__) +#if defined(__mips64__) #define MALLOC_PAGESHIFT (14U) #else #define MALLOC_PAGESHIFT (PAGE_SHIFT) @@ -87,6 +85,7 @@ LIST_HEAD(chunk_head, chunk_info); struct dir_info { u_int32_t canary1; + int active; /* status of malloc */ struct region_info *r; /* region slots */ size_t regions_total; /* number of region slots */ size_t regions_free; /* number of free slots */ @@ -100,6 +99,7 @@ struct dir_info { /* delayed free chunk slots */ void *delayed_chunks[MALLOC_DELAYED_CHUNK_MASK + 1]; size_t rbytesused; /* random bytes used */ + char *func; /* current function */ u_char rbytes[256]; /* random bytes */ u_short chunk_start; u_int32_t canary2; @@ -144,9 +144,6 @@ static union { #define mopts malloc_readonly.mopts #define g_pool mopts.g_pool -static char *malloc_func; /* current function */ -static int malloc_active; /* status of malloc */ - static u_char getrbyte(struct dir_info *d); /* low bits of r->p determine size: 0 means >= page size and p->size holding @@ -178,8 +175,8 @@ wrterror(char *msg) char *q = " error: "; struct iovec iov[4]; - iov[0].iov_base = malloc_func; - iov[0].iov_len = _dl_strlen(malloc_func); + iov[0].iov_base = g_pool->func; + iov[0].iov_len = _dl_strlen(g_pool->func); iov[1].iov_base = q; iov[1].iov_len = _dl_strlen(q); iov[2].iov_base = msg; @@ -197,7 +194,8 @@ static void rbytes_init(struct dir_info *d) { _dl_arc4randombuf(d->rbytes, sizeof(d->rbytes)); - d->rbytesused = 0; + /* add 1 to account for using d->rbytes[0] */ + d->rbytesused = 1 + d->rbytes[0] % (sizeof(d->rbytes) / 2); } static inline u_char @@ -226,10 +224,8 @@ unmap(struct dir_info *d, void *p, size_t sz) struct region_info *r; u_int i, offset; - if (sz != PAGEROUND(sz)) { + if (sz != PAGEROUND(sz)) wrterror("munmap round"); - return; - } if (psz > mopts.malloc_cache) { if (_dl_munmap(p, sz)) @@ -341,7 +337,7 @@ map(struct dir_info *d, size_t sz, int zero_fill) /* * Initialize a dir_info, which should have been cleared by caller */ -static int +static void omalloc_init(struct dir_info **dp) { char *p; @@ -370,7 +366,7 @@ omalloc_init(struct dir_info **dp) p = MMAP(DIR_INFO_RSZ + (MALLOC_PAGESIZE * 2)); p = MMAP_ERROR(p); if (p == MAP_FAILED) - return -1; + wrterror("malloc init mmap failed"); _dl_mprotect(p, MALLOC_PAGESIZE, PROT_NONE); _dl_mprotect(p + MALLOC_PAGESIZE + DIR_INFO_RSZ, MALLOC_PAGESIZE, PROT_NONE); @@ -385,11 +381,8 @@ omalloc_init(struct dir_info **dp) regioninfo_size = d->regions_total * sizeof(struct region_info); d->r = MMAP(regioninfo_size); d->r = MMAP_ERROR(d->r); - if (d->r == MAP_FAILED) { + if (d->r == MAP_FAILED) wrterror("malloc init mmap failed"); - d->regions_total = 0; - return 1; - } for (i = 0; i <= MALLOC_MAXSHIFT; i++) { LIST_INIT(&d->chunk_info_list[i]); for (j = 0; j < MALLOC_CHUNK_LISTS; j++) @@ -407,7 +400,6 @@ omalloc_init(struct dir_info **dp) if (((uintptr_t)&malloc_readonly & MALLOC_PAGEMASK) == 0) _dl_mprotect(&malloc_readonly, sizeof(malloc_readonly), PROT_READ); - return 0; } static int @@ -860,15 +852,7 @@ malloc_recurse(void) noprint = 1; wrterror("recursive call"); } - malloc_active--; -} - -static int -malloc_init(void) -{ - if (omalloc_init(&g_pool)) - return -1; - return 0; + g_pool->active--; } void * @@ -877,17 +861,15 @@ _dl_malloc(size_t size) void *r; _dl_thread_kern_stop(); - malloc_func = "malloc():"; - if (g_pool == NULL) { - if (malloc_init() != 0) - goto fail; - } - if (malloc_active++) { + if (g_pool == NULL) + omalloc_init(&g_pool); + g_pool->func = "malloc():"; + if (g_pool->active++) { malloc_recurse(); goto fail; } r = omalloc(size, 0); - malloc_active--; + g_pool->active--; _dl_thread_kern_go(); return r; fail: @@ -902,18 +884,14 @@ ofree(void *p) size_t sz; r = find(g_pool, p); - if (r == NULL) { + if (r == NULL) wrterror("bogus pointer (double free?)"); - return; - } REALSIZE(sz, r); if (sz > MALLOC_MAXCHUNK) { if (sz - mopts.malloc_guard >= MALLOC_PAGESIZE - MALLOC_LEEWAY) { - if (r->p != p) { + if (r->p != p) wrterror("bogus pointer"); - return; - } } else { #if notyetbecause_of_realloc /* shifted towards the end */ @@ -953,18 +931,14 @@ ofree(void *p) i = getrbyte(g_pool) & MALLOC_DELAYED_CHUNK_MASK; tmp = p; p = g_pool->delayed_chunks[i]; - if (tmp == p) { + if (tmp == p) wrterror("double free"); - return; - } g_pool->delayed_chunks[i] = tmp; } if (p != NULL) { r = find(g_pool, p); - if (r == NULL) { + if (r == NULL) wrterror("bogus pointer (double free?)"); - return; - } free_bytes(g_pool, r, p); } } @@ -978,17 +952,15 @@ _dl_free(void *ptr) return; _dl_thread_kern_stop(); - malloc_func = "free():"; - if (g_pool == NULL) { + if (g_pool == NULL) wrterror("free() called before allocation"); - goto fail; - } - if (malloc_active++) { + g_pool->func = "free():"; + if (g_pool->active++) { malloc_recurse(); goto fail; } ofree(ptr); - malloc_active--; + g_pool->active--; fail: _dl_thread_kern_go(); } @@ -1006,17 +978,15 @@ _dl_calloc(size_t nmemb, size_t size) void *r; _dl_thread_kern_stop(); - malloc_func = "calloc():"; - if (g_pool == NULL) { - if (malloc_init() != 0) - goto fail; - } + if (g_pool == NULL) + omalloc_init(&g_pool); + g_pool->func = "calloc():"; if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && nmemb > 0 && SIZE_MAX / nmemb < size) { goto fail; } - if (malloc_active++) { + if (g_pool->active++) { malloc_recurse(); goto fail; } @@ -1024,7 +994,7 @@ _dl_calloc(size_t nmemb, size_t size) size *= nmemb; r = omalloc(size, 1); - malloc_active--; + g_pool->active--; _dl_thread_kern_go(); return r; fail: @@ -1064,17 +1034,15 @@ _dl_realloc(void *ptr, size_t size) void *r; _dl_thread_kern_stop(); - malloc_func = "realloc():"; - if (g_pool == NULL) { - if (malloc_init() != 0) - goto fail; - } - if (malloc_active++) { + if (g_pool == NULL) + omalloc_init(&g_pool); + g_pool->func = "realloc():"; + if (g_pool->active++) { malloc_recurse(); goto fail; } r = orealloc(ptr, size); - malloc_active--; + g_pool->active--; _dl_thread_kern_go(); return r; fail: |