From 6c83f206dee6c7c646bf50105b41de858b5242d6 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sat, 23 Dec 2023 14:13:34 +0000 Subject: [PATCH] rand/rand.c (rand_getgood): Stretch the output buffer if necessary. It's possible to have `r->o == RAND_BUFSZ' in the main loop, while `r->obits' is larger than the requested size. The following program contrives this situation, though it can (and does) happen organically. #include #include #include "noise.h" #include "rand.h" int main(void) { rand_pool pool; unsigned char buf[64]; size_t n; rand_init(&pool); rand_noisesrc(&pool, &noise_source); rand_seed(&pool, 64); while (pool.obits < RAND_OBITS) rand_seed(&pool, RAND_IBITS); while (pool.o < RAND_BUFSZ) { n = RAND_BUFSZ - pool.o; if (n > sizeof(buf)) n = sizeof(buf); rand_getgood(&pool, buf, n); } rand_getgood(&pool, buf, 4); return (0); } When this happens, `rand_getgood' gets stuck in an infinite loop, trimming the chunk size to zero because the output buffer is exhausted, but not refilling it because there's still notional entropy remaining. Detect this situation and stretch the output buffer when there's nothing left, as in `rand_get'. --- rand/rand.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/rand/rand.c b/rand/rand.c index 6787c11a..e2211d54 100644 --- a/rand/rand.c +++ b/rand/rand.c @@ -482,11 +482,15 @@ void rand_getgood(rand_pool *r, void *p, size_t sz) chunk = r->obits / 8; } - if (chunk + r->o > RAND_BUFSZ) + if (chunk + r->o <= RAND_BUFSZ) { + memcpy(o, r->buf + r->o, chunk); + r->o += chunk; + } else { chunk = RAND_BUFSZ - r->o; + memcpy(o, r->buf + r->o, chunk); + rand_stretch(r); + } - memcpy(o, r->buf + r->o, chunk); - r->o += chunk; r->obits -= chunk * 8; o += chunk; sz -= chunk; -- 2.11.0