Commit 7005cd39 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 2f0bf925 61337054
...@@ -399,7 +399,6 @@ static DECLARE_WAIT_QUEUE_HEAD(random_read_wait); ...@@ -399,7 +399,6 @@ static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
static struct fasync_struct *fasync; static struct fasync_struct *fasync;
#if 0
static bool debug; static bool debug;
module_param(debug, bool, 0644); module_param(debug, bool, 0644);
#define DEBUG_ENT(fmt, arg...) do { \ #define DEBUG_ENT(fmt, arg...) do { \
...@@ -410,9 +409,6 @@ module_param(debug, bool, 0644); ...@@ -410,9 +409,6 @@ module_param(debug, bool, 0644);
blocking_pool.entropy_count,\ blocking_pool.entropy_count,\
nonblocking_pool.entropy_count,\ nonblocking_pool.entropy_count,\
## arg); } while (0) ## arg); } while (0)
#else
#define DEBUG_ENT(fmt, arg...) do {} while (0)
#endif
/********************************************************************** /**********************************************************************
* *
...@@ -437,6 +433,7 @@ struct entropy_store { ...@@ -437,6 +433,7 @@ struct entropy_store {
int entropy_count; int entropy_count;
int entropy_total; int entropy_total;
unsigned int initialized:1; unsigned int initialized:1;
bool last_data_init;
__u8 last_data[EXTRACT_SIZE]; __u8 last_data[EXTRACT_SIZE];
}; };
...@@ -829,7 +826,7 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) ...@@ -829,7 +826,7 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
bytes = min_t(int, bytes, sizeof(tmp)); bytes = min_t(int, bytes, sizeof(tmp));
DEBUG_ENT("going to reseed %s with %d bits " DEBUG_ENT("going to reseed %s with %d bits "
"(%d of %d requested)\n", "(%zu of %d requested)\n",
r->name, bytes * 8, nbytes * 8, r->entropy_count); r->name, bytes * 8, nbytes * 8, r->entropy_count);
bytes = extract_entropy(r->pull, tmp, bytes, 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,7 +857,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
spin_lock_irqsave(&r->lock, flags); spin_lock_irqsave(&r->lock, flags);
BUG_ON(r->entropy_count > r->poolinfo->POOLBITS); BUG_ON(r->entropy_count > r->poolinfo->POOLBITS);
DEBUG_ENT("trying to extract %d bits from %s\n", DEBUG_ENT("trying to extract %zu bits from %s\n",
nbytes * 8, r->name); nbytes * 8, r->name);
/* Can we pull enough? */ /* Can we pull enough? */
...@@ -882,7 +879,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, ...@@ -882,7 +879,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
} }
} }
DEBUG_ENT("debiting %d entropy credits from %s%s\n", DEBUG_ENT("debiting %zu entropy credits from %s%s\n",
nbytes * 8, r->name, r->limit ? "" : " (unlimited)"); nbytes * 8, r->name, r->limit ? "" : " (unlimited)");
spin_unlock_irqrestore(&r->lock, flags); spin_unlock_irqrestore(&r->lock, flags);
...@@ -957,6 +954,10 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, ...@@ -957,6 +954,10 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
ssize_t ret = 0, i; ssize_t ret = 0, i;
__u8 tmp[EXTRACT_SIZE]; __u8 tmp[EXTRACT_SIZE];
/* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */
if (fips_enabled && !r->last_data_init)
nbytes += EXTRACT_SIZE;
trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_); trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_);
xfer_secondary_pool(r, nbytes); xfer_secondary_pool(r, nbytes);
nbytes = account(r, nbytes, min, reserved); nbytes = account(r, nbytes, min, reserved);
...@@ -967,6 +968,17 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, ...@@ -967,6 +968,17 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
if (fips_enabled) { if (fips_enabled) {
unsigned long flags; unsigned long flags;
/* prime last_data value if need be, per fips 140-2 */
if (!r->last_data_init) {
spin_lock_irqsave(&r->lock, flags);
memcpy(r->last_data, tmp, EXTRACT_SIZE);
r->last_data_init = true;
nbytes -= EXTRACT_SIZE;
spin_unlock_irqrestore(&r->lock, flags);
extract_buf(r, tmp);
}
spin_lock_irqsave(&r->lock, flags); spin_lock_irqsave(&r->lock, flags);
if (!memcmp(tmp, r->last_data, EXTRACT_SIZE)) if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))
panic("Hardware RNG duplicated output!\n"); panic("Hardware RNG duplicated output!\n");
...@@ -1086,6 +1098,7 @@ static void init_std_data(struct entropy_store *r) ...@@ -1086,6 +1098,7 @@ static void init_std_data(struct entropy_store *r)
r->entropy_count = 0; r->entropy_count = 0;
r->entropy_total = 0; r->entropy_total = 0;
r->last_data_init = false;
mix_pool_bytes(r, &now, sizeof(now), NULL); mix_pool_bytes(r, &now, sizeof(now), NULL);
for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof(rv)) { for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof(rv)) {
if (!arch_get_random_long(&rv)) 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,11 +1155,16 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
if (n > SEC_XFER_SIZE) if (n > SEC_XFER_SIZE)
n = SEC_XFER_SIZE; n = SEC_XFER_SIZE;
DEBUG_ENT("reading %d bits\n", n*8); DEBUG_ENT("reading %zu bits\n", n*8);
n = extract_entropy_user(&blocking_pool, buf, n); n = extract_entropy_user(&blocking_pool, buf, n);
DEBUG_ENT("read got %d bits (%d still needed)\n", if (n < 0) {
retval = n;
break;
}
DEBUG_ENT("read got %zd bits (%zd still needed)\n",
n*8, (nbytes-n)*8); n*8, (nbytes-n)*8);
if (n == 0) { if (n == 0) {
...@@ -1171,10 +1189,6 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) ...@@ -1171,10 +1189,6 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
continue; continue;
} }
if (n < 0) {
retval = n;
break;
}
count += n; count += n;
buf += n; buf += n;
nbytes -= n; nbytes -= n;
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/kernel_stat.h> #include <linux/kernel_stat.h>
#include <trace/events/timer.h> #include <trace/events/timer.h>
#include <linux/random.h>
/* /*
* Called after updating RLIMIT_CPU to run cpu timer and update * Called after updating RLIMIT_CPU to run cpu timer and update
...@@ -470,6 +471,8 @@ static void cleanup_timers(struct list_head *head, ...@@ -470,6 +471,8 @@ static void cleanup_timers(struct list_head *head,
*/ */
void posix_cpu_timers_exit(struct task_struct *tsk) void posix_cpu_timers_exit(struct task_struct *tsk)
{ {
add_device_randomness((const void*) &tsk->se.sum_exec_runtime,
sizeof(unsigned long long));
cleanup_timers(tsk->cpu_timers, cleanup_timers(tsk->cpu_timers,
tsk->utime, tsk->stime, tsk->se.sum_exec_runtime); tsk->utime, tsk->stime, tsk->se.sum_exec_runtime);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment