[PATCH 12/22] /dev/random: add pool for /dev/urandom to prevent starv

From: Matt Mackall
Date: Thu Mar 25 2004 - 19:21:54 EST



/dev/random add pool for /dev/urandom to prevent starvation

Prevent readers of /dev/urandom from starving readers of /dev/random
by adding a second output pool for nonblocking reads. /dev/urandom
will always leave enough entropy in input pool for /dev/random to
reseed itself.


tiny-mpm/drivers/char/random.c | 32 +++++++++++++++++---------------
1 files changed, 17 insertions(+), 15 deletions(-)

diff -puN drivers/char/random.c~nonblocking-pool drivers/char/random.c
--- tiny/drivers/char/random.c~nonblocking-pool 2004-03-20 13:38:28.000000000 -0600
+++ tiny-mpm/drivers/char/random.c 2004-03-20 13:38:28.000000000 -0600
@@ -399,8 +399,7 @@ static struct poolinfo {
/*
* Static global variables
*/
-static struct entropy_store *input_pool; /* The default global store */
-static struct entropy_store *blocking_pool; /* secondary store */
+static struct entropy_store *input_pool, *blocking_pool, *nonblocking_pool;
static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);

@@ -477,9 +476,11 @@ static inline __u32 int_ln_12bits(__u32
#endif

#if 0
-#define DEBUG_ENT(fmt, arg...) printk(KERN_DEBUG "random %04d %04d: " fmt,\
+#define DEBUG_ENT(fmt, arg...) \
+printk(KERN_DEBUG "random %04d %04d %04d: " fmt,\
input_pool->entropy_count,\
blocking_pool->entropy_count,\
+ nonblocking_pool->entropy_count,\
## arg)
#else
#define DEBUG_ENT(fmt, arg...) do {} while (0)
@@ -700,8 +701,7 @@ EXPORT_SYMBOL(batch_entropy_store);
*/
static void batch_entropy_process(void *private_)
{
- struct entropy_store *r = (struct entropy_store *) private_, *p;
- int max_entropy = r->poolinfo->POOLBITS;
+ struct entropy_store *r = input_pool;
unsigned head, tail;

/* Mixing into the pool is expensive, so copy over the batch
@@ -720,18 +720,17 @@ static void batch_entropy_process(void *

spin_unlock_irq(&batch_lock);

- p = r;
while (head != tail) {
- if (r->entropy_count >= max_entropy) {
- r = (r == blocking_pool) ? input_pool :
- blocking_pool;
- max_entropy = r->poolinfo->POOLBITS;
- }
+ if (r->entropy_count >= r->poolinfo->POOLBITS)
+ r = blocking_pool;
+ if (r->entropy_count >= r->poolinfo->POOLBITS)
+ r = nonblocking_pool;
+
add_entropy_words(r, batch_entropy_copy[tail].data, 2);
credit_entropy_store(r, batch_entropy_copy[tail].credit);
tail = (tail+1) & (batch_max-1);
}
- if (p->entropy_count >= random_read_wakeup_thresh)
+ if (input_pool->entropy_count >= random_read_wakeup_thresh)
wake_up_interruptible(&random_read_wait);
}

@@ -1427,7 +1426,7 @@ static ssize_t extract_entropy(struct en
void get_random_bytes(void *buf, int nbytes)
{
BUG_ON(!blocking_pool);
- extract_entropy(blocking_pool, buf, nbytes, 0, 0, 0);
+ extract_entropy(nonblocking_pool, buf, nbytes, 0, 0, 0);
}

EXPORT_SYMBOL(get_random_bytes);
@@ -1473,8 +1472,11 @@ static int __init rand_initialize(void)

input_pool = create_entropy_store(INPUT_POOL_SIZE, "input");
blocking_pool = create_entropy_store(BLOCKING_POOL_SIZE, "blocking");
+ nonblocking_pool = create_entropy_store(BLOCKING_POOL_SIZE,
+ "nonblocking");
+ nonblocking_pool->reserved = 1;

- if (!(input_pool && blocking_pool))
+ if (!(input_pool && blocking_pool && nonblocking_pool))
return -1;

if (batch_entropy_init(BATCH_ENTROPY_SIZE, input_pool))
@@ -1595,7 +1597,7 @@ static ssize_t
urandom_read(struct file * file, char * buf,
size_t nbytes, loff_t *ppos)
{
- return extract_entropy(blocking_pool, buf, nbytes, 0, 0,
+ return extract_entropy(nonblocking_pool, buf, nbytes, 0, 0,
EXTRACT_ENTROPY_USER);
}


_
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/