diff options
| -rw-r--r-- | src/lib/libc/stdlib/malloc.c | 39 |
1 files changed, 18 insertions, 21 deletions
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c index 412d000a11..ba8bd3ad8f 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.166 2014/05/26 06:19:07 otto Exp $ */ | 1 | /* $OpenBSD: malloc.c,v 1.167 2014/06/02 08:49:38 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> |
| @@ -117,6 +117,8 @@ struct dir_info { | |||
| 117 | struct region_info free_regions[MALLOC_MAXCACHE]; | 117 | struct region_info free_regions[MALLOC_MAXCACHE]; |
| 118 | /* delayed free chunk slots */ | 118 | /* delayed free chunk slots */ |
| 119 | void *delayed_chunks[MALLOC_DELAYED_CHUNK_MASK + 1]; | 119 | void *delayed_chunks[MALLOC_DELAYED_CHUNK_MASK + 1]; |
| 120 | size_t rbytesused; /* random bytes used */ | ||
| 121 | u_char rbytes[512]; /* random bytes */ | ||
| 120 | u_short chunk_start; | 122 | u_short chunk_start; |
| 121 | #ifdef MALLOC_STATS | 123 | #ifdef MALLOC_STATS |
| 122 | size_t inserts; | 124 | size_t inserts; |
| @@ -191,14 +193,10 @@ static union { | |||
| 191 | #define g_pool mopts.g_pool | 193 | #define g_pool mopts.g_pool |
| 192 | 194 | ||
| 193 | char *malloc_options; /* compile-time options */ | 195 | char *malloc_options; /* compile-time options */ |
| 194 | |||
| 195 | static char *malloc_func; /* current function */ | 196 | static char *malloc_func; /* current function */ |
| 196 | static int malloc_active; /* status of malloc */ | 197 | static int malloc_active; /* status of malloc */ |
| 197 | 198 | ||
| 198 | 199 | static u_char getrbyte(struct dir_info *d); | |
| 199 | static size_t rbytesused; /* random bytes used */ | ||
| 200 | static u_char rbytes[512]; /* random bytes */ | ||
| 201 | static u_char getrbyte(void); | ||
| 202 | 200 | ||
| 203 | extern char *__progname; | 201 | extern char *__progname; |
| 204 | 202 | ||
| @@ -275,20 +273,20 @@ wrterror(char *msg, void *p) | |||
| 275 | } | 273 | } |
| 276 | 274 | ||
| 277 | static void | 275 | static void |
| 278 | rbytes_init(void) | 276 | rbytes_init(struct dir_info *d) |
| 279 | { | 277 | { |
| 280 | arc4random_buf(rbytes, sizeof(rbytes)); | 278 | arc4random_buf(d->rbytes, sizeof(d->rbytes)); |
| 281 | rbytesused = 0; | 279 | d->rbytesused = 0; |
| 282 | } | 280 | } |
| 283 | 281 | ||
| 284 | static inline u_char | 282 | static inline u_char |
| 285 | getrbyte(void) | 283 | getrbyte(struct dir_info *d) |
| 286 | { | 284 | { |
| 287 | u_char x; | 285 | u_char x; |
| 288 | 286 | ||
| 289 | if (rbytesused >= sizeof(rbytes)) | 287 | if (d->rbytesused >= sizeof(d->rbytes)) |
| 290 | rbytes_init(); | 288 | rbytes_init(d); |
| 291 | x = rbytes[rbytesused++]; | 289 | x = d->rbytes[d->rbytesused++]; |
| 292 | return x; | 290 | return x; |
| 293 | } | 291 | } |
| 294 | 292 | ||
| @@ -322,7 +320,7 @@ unmap(struct dir_info *d, void *p, size_t sz) | |||
| 322 | rsz = mopts.malloc_cache - d->free_regions_size; | 320 | rsz = mopts.malloc_cache - d->free_regions_size; |
| 323 | if (psz > rsz) | 321 | if (psz > rsz) |
| 324 | tounmap = psz - rsz; | 322 | tounmap = psz - rsz; |
| 325 | offset = getrbyte(); | 323 | offset = getrbyte(d); |
| 326 | for (i = 0; tounmap > 0 && i < mopts.malloc_cache; i++) { | 324 | for (i = 0; tounmap > 0 && i < mopts.malloc_cache; i++) { |
| 327 | r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)]; | 325 | r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)]; |
| 328 | if (r->p != NULL) { | 326 | if (r->p != NULL) { |
| @@ -403,7 +401,7 @@ map(struct dir_info *d, size_t sz, int zero_fill) | |||
| 403 | /* zero fill not needed */ | 401 | /* zero fill not needed */ |
| 404 | return p; | 402 | return p; |
| 405 | } | 403 | } |
| 406 | offset = getrbyte(); | 404 | offset = getrbyte(d); |
| 407 | for (i = 0; i < mopts.malloc_cache; i++) { | 405 | for (i = 0; i < mopts.malloc_cache; i++) { |
| 408 | r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)]; | 406 | r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)]; |
| 409 | if (r->p != NULL) { | 407 | if (r->p != NULL) { |
| @@ -461,8 +459,6 @@ omalloc_init(struct dir_info **dp) | |||
| 461 | size_t d_avail, regioninfo_size; | 459 | size_t d_avail, regioninfo_size; |
| 462 | struct dir_info *d; | 460 | struct dir_info *d; |
| 463 | 461 | ||
| 464 | rbytes_init(); | ||
| 465 | |||
| 466 | /* | 462 | /* |
| 467 | * Default options | 463 | * Default options |
| 468 | */ | 464 | */ |
| @@ -616,6 +612,7 @@ omalloc_init(struct dir_info **dp) | |||
| 616 | d = (struct dir_info *)(p + MALLOC_PAGESIZE + | 612 | d = (struct dir_info *)(p + MALLOC_PAGESIZE + |
| 617 | (arc4random_uniform(d_avail) << MALLOC_MINSHIFT)); | 613 | (arc4random_uniform(d_avail) << MALLOC_MINSHIFT)); |
| 618 | 614 | ||
| 615 | rbytes_init(d); | ||
| 619 | d->regions_free = d->regions_total = MALLOC_INITIAL_REGIONS; | 616 | d->regions_free = d->regions_total = MALLOC_INITIAL_REGIONS; |
| 620 | regioninfo_size = d->regions_total * sizeof(struct region_info); | 617 | regioninfo_size = d->regions_total * sizeof(struct region_info); |
| 621 | d->r = MMAP(regioninfo_size); | 618 | d->r = MMAP(regioninfo_size); |
| @@ -914,7 +911,7 @@ malloc_bytes(struct dir_info *d, size_t size, void *f) | |||
| 914 | j++; | 911 | j++; |
| 915 | } | 912 | } |
| 916 | 913 | ||
| 917 | listnum = getrbyte() % MALLOC_CHUNK_LISTS; | 914 | listnum = getrbyte(d) % MALLOC_CHUNK_LISTS; |
| 918 | /* If it's empty, make a page more of that size chunks */ | 915 | /* If it's empty, make a page more of that size chunks */ |
| 919 | if ((bp = LIST_FIRST(&d->chunk_dir[j][listnum])) == NULL) { | 916 | if ((bp = LIST_FIRST(&d->chunk_dir[j][listnum])) == NULL) { |
| 920 | bp = omalloc_make_chunks(d, j, listnum); | 917 | bp = omalloc_make_chunks(d, j, listnum); |
| @@ -927,7 +924,7 @@ malloc_bytes(struct dir_info *d, size_t size, void *f) | |||
| 927 | 924 | ||
| 928 | i = d->chunk_start; | 925 | i = d->chunk_start; |
| 929 | if (bp->free > 1) | 926 | if (bp->free > 1) |
| 930 | i += getrbyte(); | 927 | i += getrbyte(d); |
| 931 | if (i >= bp->total) | 928 | if (i >= bp->total) |
| 932 | i &= bp->total - 1; | 929 | i &= bp->total - 1; |
| 933 | for (;;) { | 930 | for (;;) { |
| @@ -1016,7 +1013,7 @@ free_bytes(struct dir_info *d, struct region_info *r, void *ptr) | |||
| 1016 | 1013 | ||
| 1017 | if (info->free == 1) { | 1014 | if (info->free == 1) { |
| 1018 | /* Page became non-full */ | 1015 | /* Page became non-full */ |
| 1019 | listnum = getrbyte() % MALLOC_CHUNK_LISTS; | 1016 | listnum = getrbyte(d) % MALLOC_CHUNK_LISTS; |
| 1020 | if (info->size != 0) | 1017 | if (info->size != 0) |
| 1021 | mp = &d->chunk_dir[info->shift][listnum]; | 1018 | mp = &d->chunk_dir[info->shift][listnum]; |
| 1022 | else | 1019 | else |
| @@ -1224,7 +1221,7 @@ ofree(void *p) | |||
| 1224 | if (!mopts.malloc_freenow) { | 1221 | if (!mopts.malloc_freenow) { |
| 1225 | if (find_chunknum(g_pool, r, p) == -1) | 1222 | if (find_chunknum(g_pool, r, p) == -1) |
| 1226 | return; | 1223 | return; |
| 1227 | i = getrbyte() & MALLOC_DELAYED_CHUNK_MASK; | 1224 | i = getrbyte(g_pool) & MALLOC_DELAYED_CHUNK_MASK; |
| 1228 | tmp = p; | 1225 | tmp = p; |
| 1229 | p = g_pool->delayed_chunks[i]; | 1226 | p = g_pool->delayed_chunks[i]; |
| 1230 | if (tmp == p) { | 1227 | if (tmp == p) { |
