[PATCH 10/22] /dev/random: entropy reserve logic for starvation preve

From: Matt Mackall
Date: Thu Mar 25 2004 - 19:05:40 EST



/dev/random entropy reserve logic for starvation prevention

Additional parameter to allow keeping an entropy reserve in the input
pool. Groundwork for /dev/urandom vs /dev/random starvation prevention.

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

diff -puN drivers/char/random.c~debit-entropy drivers/char/random.c
--- tiny/drivers/char/random.c~debit-entropy 2004-03-20 13:38:26.000000000 -0600
+++ tiny-mpm/drivers/char/random.c 2004-03-20 13:38:26.000000000 -0600
@@ -1264,7 +1264,7 @@ static void MD5Transform(__u32 buf[HASH_
#define SEC_XFER_SIZE (TMP_BUF_SIZE*4)

static ssize_t extract_entropy(struct entropy_store *r, void * buf,
- size_t nbytes, int min, int flags);
+ size_t nbytes, int min, int rsvd, int flags);

/*
* This utility inline function is responsible for transfering entropy
@@ -1283,7 +1283,7 @@ static inline void xfer_secondary_pool(s
bytes * 8, nbytes * 8, r->entropy_count);

bytes=extract_entropy(input_pool, tmp, bytes,
- random_read_wakeup_thresh / 8,
+ random_read_wakeup_thresh / 8, 0,
EXTRACT_ENTROPY_LIMIT);
add_entropy_words(r, tmp, bytes);
credit_entropy_store(r, bytes*8);
@@ -1297,13 +1297,15 @@ static inline void xfer_secondary_pool(s
* number of bytes that are actually obtained. If the EXTRACT_ENTROPY_USER
* flag is given, then the buf pointer is assumed to be in user space.
*
- * If we have less than min bytes of entropy available, exit without
- * transferring any. This helps avoid racing when reseeding.
+ * The min parameter specifies the minimum amount we can pull before
+ * failing to avoid races that defeat catastrophic reseeding while the
+ * reserved parameter indicates how much entropy we must leave in the
+ * pool after each pull to avoid starving other readers.
*
* Note: extract_entropy() assumes that .poolwords is a multiple of 16 words.
*/
static ssize_t extract_entropy(struct entropy_store *r, void * buf,
- size_t nbytes, int min, int flags)
+ size_t nbytes, int min, int reserved, int flags)
{
ssize_t ret, i;
__u32 tmp[TMP_BUF_SIZE];
@@ -1323,17 +1325,19 @@ static ssize_t extract_entropy(struct en

DEBUG_ENT("trying to extract %d bits from %s\n", nbytes * 8, r->name);

- if (r->entropy_count / 8 < min) {
+ /* Can we pull enough? */
+ if (r->entropy_count / 8 < min + reserved) {
nbytes = 0;
} else {
+ /* If limited, never pull more than available */
if (flags & EXTRACT_ENTROPY_LIMIT &&
- nbytes >= r->entropy_count / 8)
- nbytes = r->entropy_count / 8;
+ nbytes + reserved >= r->entropy_count / 8)
+ nbytes = r->entropy_count/8 - reserved;

- if (r->entropy_count / 8 >= nbytes)
+ if(r->entropy_count / 8 >= nbytes + reserved)
r->entropy_count -= nbytes*8;
else
- r->entropy_count = 0;
+ r->entropy_count = reserved;

if (r->entropy_count < random_write_wakeup_thresh)
wake_up_interruptible(&random_write_wait);
@@ -1421,7 +1425,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);
+ extract_entropy(blocking_pool, buf, nbytes, 0, 0, 0);
}

EXPORT_SYMBOL(get_random_bytes);
@@ -1536,7 +1540,7 @@ random_read(struct file * file, char * b

DEBUG_ENT("reading %d bits\n", n*8);

- n = extract_entropy(blocking_pool, buf, n, 0,
+ n = extract_entropy(blocking_pool, buf, n, 0, 0,
EXTRACT_ENTROPY_USER |
EXTRACT_ENTROPY_LIMIT);

@@ -1589,7 +1593,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,
+ return extract_entropy(blocking_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/