summaryrefslogtreecommitdiff
path: root/libexec/ld.so/malloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'libexec/ld.so/malloc.c')
-rw-r--r--libexec/ld.so/malloc.c104
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: