diff options
author | Theodore Ts'o <tytso@mit.edu> | 2013-09-22 15:14:32 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2013-10-10 14:32:19 -0400 |
commit | f5c2742c23886e707f062881c5f206c1fc704782 (patch) | |
tree | 3acaa54c3f8e4dd55723b1c93ae36cbc648ad2bf /drivers/char | |
parent | c59974aea43fd292a0784dbf7b3d7347e2caf4e9 (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.c | 24 |
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; | |||
307 | static int random_write_wakeup_thresh = 128; | 307 | static 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 | */ | ||
314 | static 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, |