diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2004-07-05 20:57:51 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2004-07-05 20:57:51 +0000 |
commit | 37478d684c8a1111b3e792947e96e63d2b87051b (patch) | |
tree | d1f656a6c3b857ba18ea3cd0e4061a0d72250a3a /sys/dev/rnd.c | |
parent | 2425593056956c6ff8b8bf1a8a696ff0b3b92b1e (diff) |
Allocate buffers in randomread and randomwrite via malloc instead
of from the stack. Keeps us from running out of kernel stack during
stack-heavy networking load. The bug manifests as a panic during
bootup with an fpu-related assertion failure on i386.
Fix from Christopher Pascoe; commit requested by deraadt@
Diffstat (limited to 'sys/dev/rnd.c')
-rw-r--r-- | sys/dev/rnd.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/sys/dev/rnd.c b/sys/dev/rnd.c index 5639fed4b3a..458a0507d68 100644 --- a/sys/dev/rnd.c +++ b/sys/dev/rnd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rnd.c,v 1.70 2004/05/07 14:42:27 millert Exp $ */ +/* $OpenBSD: rnd.c,v 1.71 2004/07/05 20:57:50 millert Exp $ */ /* * rnd.c -- A strong random number generator @@ -266,6 +266,7 @@ int rnd_debug = 0x0000; * For a pool of size 64, try x^64+x^62+x^38+x^10+x^6+x+1. */ #define POOLBITS (POOLWORDS*32) +#define POOLBYTES (POOLWORDS*4) #if POOLWORDS == 2048 #define TAP1 1638 #define TAP2 1231 @@ -957,15 +958,17 @@ randomread(dev, uio, ioflag) struct uio *uio; int ioflag; { - int ret = 0; - int i; + int ret = 0; + int i; + u_int32_t *buf; if (uio->uio_resid == 0) return 0; + buf = malloc(POOLBYTES, M_TEMP, M_WAITOK); + while (!ret && uio->uio_resid > 0) { - u_int32_t buf[ POOLWORDS ]; - int n = min(sizeof(buf), uio->uio_resid); + int n = min(POOLBYTES, uio->uio_resid); switch(minor(dev)) { case RND_RND: @@ -1027,6 +1030,8 @@ randomread(dev, uio, ioflag) if (n != 0 && ret == 0) ret = uiomove((caddr_t)buf, n, uio); } + + free(buf, M_TEMP); return ret; } @@ -1120,7 +1125,8 @@ randomwrite(dev, uio, flags) struct uio *uio; int flags; { - int ret = 0; + int ret = 0; + u_int32_t *buf; if (minor(dev) == RND_RND || minor(dev) == RND_PRND) return ENXIO; @@ -1128,9 +1134,10 @@ randomwrite(dev, uio, flags) if (uio->uio_resid == 0) return 0; + buf = malloc(POOLBYTES, M_TEMP, M_WAITOK); + while (!ret && uio->uio_resid > 0) { - u_int32_t buf[ POOLWORDS ]; - u_short n = min(sizeof(buf),uio->uio_resid); + u_short n = min(POOLBYTES, uio->uio_resid); ret = uiomove((caddr_t)buf, n, uio); if (!ret) { @@ -1143,6 +1150,7 @@ randomwrite(dev, uio, flags) if (minor(dev) == RND_ARND && !ret) arc4random_initialized = 0; + free(buf, M_TEMP); return ret; } |