aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-19 23:23:37 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-19 23:23:37 -0500
commit7005cd39707ba59b5b1d3e70da2c448d3235eb3e (patch)
tree89ed68e2cfd68f038d58f86a0eb5fe7eea279103
parent2f0bf92513be58d2d65c0a4cc05c5779a7cd81e1 (diff)
parent6133705494bb02953e1e2cc3018a4373981b3c97 (diff)
Merge tag 'random_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random
Pull random updates from Ted Ts'o: "A few /dev/random improvements for the v3.8 merge window." * tag 'random_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random: random: Mix cputime from each thread that exits to the pool random: prime last_data value per fips requirements random: fix debug format strings random: make it possible to enable debugging without rebuild
-rw-r--r--drivers/char/random.c40
-rw-r--r--kernel/posix-cpu-timers.c3
2 files changed, 30 insertions, 13 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index b86eae9b77df..85e81ec1451e 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -399,7 +399,6 @@ static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
399static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); 399static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
400static struct fasync_struct *fasync; 400static struct fasync_struct *fasync;
401 401
402#if 0
403static bool debug; 402static bool debug;
404module_param(debug, bool, 0644); 403module_param(debug, bool, 0644);
405#define DEBUG_ENT(fmt, arg...) do { \ 404#define DEBUG_ENT(fmt, arg...) do { \
@@ -410,9 +409,6 @@ module_param(debug, bool, 0644);
410 blocking_pool.entropy_count,\ 409 blocking_pool.entropy_count,\
411 nonblocking_pool.entropy_count,\ 410 nonblocking_pool.entropy_count,\
412 ## arg); } while (0) 411 ## arg); } while (0)
413#else
414#define DEBUG_ENT(fmt, arg...) do {} while (0)
415#endif
416 412
417/********************************************************************** 413/**********************************************************************
418 * 414 *
@@ -437,6 +433,7 @@ struct entropy_store {
437 int entropy_count; 433 int entropy_count;
438 int entropy_total; 434 int entropy_total;
439 unsigned int initialized:1; 435 unsigned int initialized:1;
436 bool last_data_init;
440 __u8 last_data[EXTRACT_SIZE]; 437 __u8 last_data[EXTRACT_SIZE];
441}; 438};
442 439
@@ -829,7 +826,7 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
829 bytes = min_t(int, bytes, sizeof(tmp)); 826 bytes = min_t(int, bytes, sizeof(tmp));
830 827
831 DEBUG_ENT("going to reseed %s with %d bits " 828 DEBUG_ENT("going to reseed %s with %d bits "
832 "(%d of %d requested)\n", 829 "(%zu of %d requested)\n",
833 r->name, bytes * 8, nbytes * 8, r->entropy_count); 830 r->name, bytes * 8, nbytes * 8, r->entropy_count);
834 831
835 bytes = extract_entropy(r->pull, tmp, bytes, 832 bytes = extract_entropy(r->pull, tmp, bytes,
@@ -860,7 +857,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
860 spin_lock_irqsave(&r->lock, flags); 857 spin_lock_irqsave(&r->lock, flags);
861 858
862 BUG_ON(r->entropy_count > r->poolinfo->POOLBITS); 859 BUG_ON(r->entropy_count > r->poolinfo->POOLBITS);
863 DEBUG_ENT("trying to extract %d bits from %s\n", 860 DEBUG_ENT("trying to extract %zu bits from %s\n",
864 nbytes * 8, r->name); 861 nbytes * 8, r->name);
865 862
866 /* Can we pull enough? */ 863 /* Can we pull enough? */
@@ -882,7 +879,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
882 } 879 }
883 } 880 }
884 881
885 DEBUG_ENT("debiting %d entropy credits from %s%s\n", 882 DEBUG_ENT("debiting %zu entropy credits from %s%s\n",
886 nbytes * 8, r->name, r->limit ? "" : " (unlimited)"); 883 nbytes * 8, r->name, r->limit ? "" : " (unlimited)");
887 884
888 spin_unlock_irqrestore(&r->lock, flags); 885 spin_unlock_irqrestore(&r->lock, flags);
@@ -957,6 +954,10 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
957 ssize_t ret = 0, i; 954 ssize_t ret = 0, i;
958 __u8 tmp[EXTRACT_SIZE]; 955 __u8 tmp[EXTRACT_SIZE];
959 956
957 /* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */
958 if (fips_enabled && !r->last_data_init)
959 nbytes += EXTRACT_SIZE;
960
960 trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_); 961 trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_);
961 xfer_secondary_pool(r, nbytes); 962 xfer_secondary_pool(r, nbytes);
962 nbytes = account(r, nbytes, min, reserved); 963 nbytes = account(r, nbytes, min, reserved);
@@ -967,6 +968,17 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
967 if (fips_enabled) { 968 if (fips_enabled) {
968 unsigned long flags; 969 unsigned long flags;
969 970
971
972 /* prime last_data value if need be, per fips 140-2 */
973 if (!r->last_data_init) {
974 spin_lock_irqsave(&r->lock, flags);
975 memcpy(r->last_data, tmp, EXTRACT_SIZE);
976 r->last_data_init = true;
977 nbytes -= EXTRACT_SIZE;
978 spin_unlock_irqrestore(&r->lock, flags);
979 extract_buf(r, tmp);
980 }
981
970 spin_lock_irqsave(&r->lock, flags); 982 spin_lock_irqsave(&r->lock, flags);
971 if (!memcmp(tmp, r->last_data, EXTRACT_SIZE)) 983 if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))
972 panic("Hardware RNG duplicated output!\n"); 984 panic("Hardware RNG duplicated output!\n");
@@ -1086,6 +1098,7 @@ static void init_std_data(struct entropy_store *r)
1086 1098
1087 r->entropy_count = 0; 1099 r->entropy_count = 0;
1088 r->entropy_total = 0; 1100 r->entropy_total = 0;
1101 r->last_data_init = false;
1089 mix_pool_bytes(r, &now, sizeof(now), NULL); 1102 mix_pool_bytes(r, &now, sizeof(now), NULL);
1090 for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof(rv)) { 1103 for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof(rv)) {
1091 if (!arch_get_random_long(&rv)) 1104 if (!arch_get_random_long(&rv))
@@ -1142,11 +1155,16 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
1142 if (n > SEC_XFER_SIZE) 1155 if (n > SEC_XFER_SIZE)
1143 n = SEC_XFER_SIZE; 1156 n = SEC_XFER_SIZE;
1144 1157
1145 DEBUG_ENT("reading %d bits\n", n*8); 1158 DEBUG_ENT("reading %zu bits\n", n*8);
1146 1159
1147 n = extract_entropy_user(&blocking_pool, buf, n); 1160 n = extract_entropy_user(&blocking_pool, buf, n);
1148 1161
1149 DEBUG_ENT("read got %d bits (%d still needed)\n", 1162 if (n < 0) {
1163 retval = n;
1164 break;
1165 }
1166
1167 DEBUG_ENT("read got %zd bits (%zd still needed)\n",
1150 n*8, (nbytes-n)*8); 1168 n*8, (nbytes-n)*8);
1151 1169
1152 if (n == 0) { 1170 if (n == 0) {
@@ -1171,10 +1189,6 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
1171 continue; 1189 continue;
1172 } 1190 }
1173 1191
1174 if (n < 0) {
1175 retval = n;
1176 break;
1177 }
1178 count += n; 1192 count += n;
1179 buf += n; 1193 buf += n;
1180 nbytes -= n; 1194 nbytes -= n;
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index d73840271dce..a278cad1d5d6 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -9,6 +9,7 @@
9#include <asm/uaccess.h> 9#include <asm/uaccess.h>
10#include <linux/kernel_stat.h> 10#include <linux/kernel_stat.h>
11#include <trace/events/timer.h> 11#include <trace/events/timer.h>
12#include <linux/random.h>
12 13
13/* 14/*
14 * Called after updating RLIMIT_CPU to run cpu timer and update 15 * Called after updating RLIMIT_CPU to run cpu timer and update
@@ -470,6 +471,8 @@ static void cleanup_timers(struct list_head *head,
470 */ 471 */
471void posix_cpu_timers_exit(struct task_struct *tsk) 472void posix_cpu_timers_exit(struct task_struct *tsk)
472{ 473{
474 add_device_randomness((const void*) &tsk->se.sum_exec_runtime,
475 sizeof(unsigned long long));
473 cleanup_timers(tsk->cpu_timers, 476 cleanup_timers(tsk->cpu_timers,
474 tsk->utime, tsk->stime, tsk->se.sum_exec_runtime); 477 tsk->utime, tsk->stime, tsk->se.sum_exec_runtime);
475 478