diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c index 412d000a..ba8bd3ad 100644 --- a/src/lib/libc/stdlib/malloc.c +++ b/src/lib/libc/stdlib/malloc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: malloc.c,v 1.166 2014/05/26 06:19:07 otto Exp $ */ +/* $OpenBSD: malloc.c,v 1.167 2014/06/02 08:49:38 otto Exp $ */ /* * Copyright (c) 2008, 2010, 2011 Otto Moerbeek * Copyright (c) 2012 Matthew Dempsky @@ -117,6 +117,8 @@ struct dir_info { struct region_info free_regions[MALLOC_MAXCACHE]; /* delayed free chunk slots */ void *delayed_chunks[MALLOC_DELAYED_CHUNK_MASK + 1]; + size_t rbytesused; /* random bytes used */ + u_char rbytes[512]; /* random bytes */ u_short chunk_start; #ifdef MALLOC_STATS size_t inserts; @@ -191,14 +193,10 @@ static union { #define g_pool mopts.g_pool char *malloc_options; /* compile-time options */ - static char *malloc_func; /* current function */ static int malloc_active; /* status of malloc */ - -static size_t rbytesused; /* random bytes used */ -static u_char rbytes[512]; /* random bytes */ -static u_char getrbyte(void); +static u_char getrbyte(struct dir_info *d); extern char *__progname; @@ -275,20 +273,20 @@ wrterror(char *msg, void *p) } static void -rbytes_init(void) +rbytes_init(struct dir_info *d) { - arc4random_buf(rbytes, sizeof(rbytes)); - rbytesused = 0; + arc4random_buf(d->rbytes, sizeof(d->rbytes)); + d->rbytesused = 0; } static inline u_char -getrbyte(void) +getrbyte(struct dir_info *d) { u_char x; - if (rbytesused >= sizeof(rbytes)) - rbytes_init(); - x = rbytes[rbytesused++]; + if (d->rbytesused >= sizeof(d->rbytes)) + rbytes_init(d); + x = d->rbytes[d->rbytesused++]; return x; } @@ -322,7 +320,7 @@ unmap(struct dir_info *d, void *p, size_t sz) rsz = mopts.malloc_cache - d->free_regions_size; if (psz > rsz) tounmap = psz - rsz; - offset = getrbyte(); + offset = getrbyte(d); for (i = 0; tounmap > 0 && i < mopts.malloc_cache; i++) { r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)]; if (r->p != NULL) { @@ -403,7 +401,7 @@ map(struct dir_info *d, size_t sz, int zero_fill) /* zero fill not needed */ return p; } - offset = getrbyte(); + offset = getrbyte(d); for (i = 0; i < mopts.malloc_cache; i++) { r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)]; if (r->p != NULL) { @@ -461,8 +459,6 @@ omalloc_init(struct dir_info **dp) size_t d_avail, regioninfo_size; struct dir_info *d; - rbytes_init(); - /* * Default options */ @@ -616,6 +612,7 @@ omalloc_init(struct dir_info **dp) d = (struct dir_info *)(p + MALLOC_PAGESIZE + (arc4random_uniform(d_avail) << MALLOC_MINSHIFT)); + rbytes_init(d); d->regions_free = d->regions_total = MALLOC_INITIAL_REGIONS; regioninfo_size = d->regions_total * sizeof(struct region_info); d->r = MMAP(regioninfo_size); @@ -914,7 +911,7 @@ malloc_bytes(struct dir_info *d, size_t size, void *f) j++; } - listnum = getrbyte() % MALLOC_CHUNK_LISTS; + listnum = getrbyte(d) % MALLOC_CHUNK_LISTS; /* If it's empty, make a page more of that size chunks */ if ((bp = LIST_FIRST(&d->chunk_dir[j][listnum])) == NULL) { bp = omalloc_make_chunks(d, j, listnum); @@ -927,7 +924,7 @@ malloc_bytes(struct dir_info *d, size_t size, void *f) i = d->chunk_start; if (bp->free > 1) - i += getrbyte(); + i += getrbyte(d); if (i >= bp->total) i &= bp->total - 1; for (;;) { @@ -1016,7 +1013,7 @@ free_bytes(struct dir_info *d, struct region_info *r, void *ptr) if (info->free == 1) { /* Page became non-full */ - listnum = getrbyte() % MALLOC_CHUNK_LISTS; + listnum = getrbyte(d) % MALLOC_CHUNK_LISTS; if (info->size != 0) mp = &d->chunk_dir[info->shift][listnum]; else @@ -1224,7 +1221,7 @@ ofree(void *p) if (!mopts.malloc_freenow) { if (find_chunknum(g_pool, r, p) == -1) return; - i = getrbyte() & MALLOC_DELAYED_CHUNK_MASK; + i = getrbyte(g_pool) & MALLOC_DELAYED_CHUNK_MASK; tmp = p; p = g_pool->delayed_chunks[i]; if (tmp == p) {