diff --git a/h_malloc.c b/h_malloc.c index 409fa2b..517af02 100644 --- a/h_malloc.c +++ b/h_malloc.c @@ -1093,7 +1093,7 @@ COLD static void init_slow_path(void) { struct region_allocator *ra = ro.region_allocator; mutex_init(&ra->lock); - random_state_init(&ra->rng); + random_state_init_from_random_state(&ra->rng, rng); ro.regions[0] = allocator_state->regions_a; ro.regions[1] = allocator_state->regions_b; ra->regions = ro.regions[0]; @@ -1116,7 +1116,7 @@ COLD static void init_slow_path(void) { struct size_class *c = &ro.size_class_metadata[arena][class]; mutex_init(&c->lock); - random_state_init(&c->rng); + random_state_init_from_random_state(&c->rng, rng); size_t bound = (REAL_CLASS_REGION_SIZE - CLASS_REGION_SIZE) / PAGE_SIZE - 1; size_t gap = (get_random_u64_uniform(rng, bound) + 1) * PAGE_SIZE; diff --git a/random.c b/random.c index ae242c4..c6dc759 100644 --- a/random.c +++ b/random.c @@ -44,6 +44,16 @@ void random_state_init(struct random_state *state) { state->reseed = 0; } +void random_state_init_from_random_state(struct random_state *state, struct random_state *source) { + u8 rnd[CHACHA_KEY_SIZE + CHACHA_IV_SIZE]; + get_random_bytes(source, rnd, sizeof(rnd)); + chacha_keysetup(&state->ctx, rnd); + chacha_ivsetup(&state->ctx, rnd + CHACHA_KEY_SIZE); + chacha_keystream_bytes(&state->ctx, state->cache, RANDOM_CACHE_SIZE); + state->index = 0; + state->reseed = 0; +} + static void refill(struct random_state *state) { if (state->reseed < RANDOM_RESEED_SIZE) { chacha_keystream_bytes(&state->ctx, state->cache, RANDOM_CACHE_SIZE); diff --git a/random.h b/random.h index 629b18a..14703bb 100644 --- a/random.h +++ b/random.h @@ -15,6 +15,7 @@ struct random_state { }; void random_state_init(struct random_state *state); +void random_state_init_from_random_state(struct random_state *state, struct random_state *source); void get_random_bytes(struct random_state *state, void *buf, size_t size); u16 get_random_u16(struct random_state *state); u16 get_random_u16_uniform(struct random_state *state, u16 bound);