diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-19 23:23:37 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-19 23:23:37 -0500 |
commit | 7005cd39707ba59b5b1d3e70da2c448d3235eb3e (patch) | |
tree | 89ed68e2cfd68f038d58f86a0eb5fe7eea279103 | |
parent | 2f0bf92513be58d2d65c0a4cc05c5779a7cd81e1 (diff) | |
parent | 6133705494bb02953e1e2cc3018a4373981b3c97 (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.c | 40 | ||||
-rw-r--r-- | kernel/posix-cpu-timers.c | 3 |
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); | |||
399 | static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); | 399 | static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); |
400 | static struct fasync_struct *fasync; | 400 | static struct fasync_struct *fasync; |
401 | 401 | ||
402 | #if 0 | ||
403 | static bool debug; | 402 | static bool debug; |
404 | module_param(debug, bool, 0644); | 403 | module_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 | */ |
471 | void posix_cpu_timers_exit(struct task_struct *tsk) | 472 | void 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 | ||