diff options
author | otto <> | 2014-06-02 08:49:38 +0000 |
---|---|---|
committer | otto <> | 2014-06-02 08:49:38 +0000 |
commit | b93d29bf1d710e4e9bdfd2fb2c3a1b99818deb34 (patch) | |
tree | 9bd39ceb7ba7c4e07e831447ad39766b03730236 /src/lib | |
parent | 95c0ce676f45c601e820a171f77a88e23dc3eacd (diff) | |
download | openbsd-b93d29bf1d710e4e9bdfd2fb2c3a1b99818deb34.tar.gz openbsd-b93d29bf1d710e4e9bdfd2fb2c3a1b99818deb34.tar.bz2 openbsd-b93d29bf1d710e4e9bdfd2fb2c3a1b99818deb34.zip |
move random bytes buffer to be part of mmaped pages; ok tedu@
Diffstat (limited to 'src/lib')
-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) { |