aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2013-09-22 15:14:32 -0400
committerTheodore Ts'o <tytso@mit.edu>2013-10-10 14:32:19 -0400
commitf5c2742c23886e707f062881c5f206c1fc704782 (patch)
tree3acaa54c3f8e4dd55723b1c93ae36cbc648ad2bf /drivers/char
parentc59974aea43fd292a0784dbf7b3d7347e2caf4e9 (diff)
random: cap the rate which the /dev/urandom pool gets reseeded
In order to avoid draining the input pool of its entropy at too high of a rate, enforce a minimum time interval between reseedings of the urandom pool. This is set to 60 seconds by default. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/random.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index b8809d4ae186..a68b4a093272 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -307,6 +307,13 @@ static int random_read_wakeup_thresh = 64;
307static int random_write_wakeup_thresh = 128; 307static int random_write_wakeup_thresh = 128;
308 308
309/* 309/*
310 * The minimum number of seconds between urandom pool resending. We
311 * do this to limit the amount of entropy that can be drained from the
312 * input pool even if there are heavy demands on /dev/urandom.
313 */
314static int random_min_urandom_seed = 60;
315
316/*
310 * When the input pool goes over trickle_thresh, start dropping most 317 * When the input pool goes over trickle_thresh, start dropping most
311 * samples to avoid wasting CPU time and reduce lock contention. 318 * samples to avoid wasting CPU time and reduce lock contention.
312 */ 319 */
@@ -438,6 +445,7 @@ struct entropy_store {
438 struct entropy_store *pull; 445 struct entropy_store *pull;
439 446
440 /* read-write data: */ 447 /* read-write data: */
448 unsigned long last_pulled;
441 spinlock_t lock; 449 spinlock_t lock;
442 unsigned short add_ptr; 450 unsigned short add_ptr;
443 unsigned short input_rotate; 451 unsigned short input_rotate;
@@ -887,6 +895,14 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
887{ 895{
888 __u32 tmp[OUTPUT_POOL_WORDS]; 896 __u32 tmp[OUTPUT_POOL_WORDS];
889 897
898 if (r->limit == 0 && random_min_urandom_seed) {
899 unsigned long now = jiffies;
900
901 if (time_before(now,
902 r->last_pulled + random_min_urandom_seed * HZ))
903 return;
904 r->last_pulled = now;
905 }
890 if (r->pull && 906 if (r->pull &&
891 r->entropy_count < (nbytes << (ENTROPY_SHIFT + 3)) && 907 r->entropy_count < (nbytes << (ENTROPY_SHIFT + 3)) &&
892 r->entropy_count < r->poolinfo->poolfracbits) { 908 r->entropy_count < r->poolinfo->poolfracbits) {
@@ -1190,6 +1206,7 @@ static void init_std_data(struct entropy_store *r)
1190 r->entropy_count = 0; 1206 r->entropy_count = 0;
1191 r->entropy_total = 0; 1207 r->entropy_total = 0;
1192 r->last_data_init = 0; 1208 r->last_data_init = 0;
1209 r->last_pulled = jiffies;
1193 mix_pool_bytes(r, &now, sizeof(now), NULL); 1210 mix_pool_bytes(r, &now, sizeof(now), NULL);
1194 for (i = r->poolinfo->poolbytes; i > 0; i -= sizeof(rv)) { 1211 for (i = r->poolinfo->poolbytes; i > 0; i -= sizeof(rv)) {
1195 if (!arch_get_random_long(&rv)) 1212 if (!arch_get_random_long(&rv))
@@ -1541,6 +1558,13 @@ struct ctl_table random_table[] = {
1541 .extra2 = &max_write_thresh, 1558 .extra2 = &max_write_thresh,
1542 }, 1559 },
1543 { 1560 {
1561 .procname = "urandom_min_reseed_secs",
1562 .data = &random_min_urandom_seed,
1563 .maxlen = sizeof(int),
1564 .mode = 0644,
1565 .proc_handler = proc_dointvec,
1566 },
1567 {
1544 .procname = "boot_id", 1568 .procname = "boot_id",
1545 .data = &sysctl_bootid, 1569 .data = &sysctl_bootid,
1546 .maxlen = 16, 1570 .maxlen = 16,