A few /dev/random improvements for the v3.8 merge window.
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABCAAGBQJQz+SFAAoJENNvdpvBGATww0QP+gLGPbydQbW25SF2SUjcBdAA tGLTFmEIAATxfQihsuMsBjnNIuc9gLbQMTvEd0flhkxkc6wFAcaJA5Q6SuEv64jV frz+T36v1hLP3xCq2b0z93yHAadRq1twALgGzCjSQh9Od73kY4DOOqj/1DZO9CvA cPbP7FIqlVhHLYtfLv7m8OMVkTjgyKvDhWcKZyaN5ticVzZImSbOMHXQ7SX9jnpc ktz+vHc48Lnix8NGmodZF81QEtLWheGhKRwOiifpBq7BKmFyiUJNEDOaQHofcgCb LRjNvsGkhKo36xf/T84pXPj17fmhOHKChAfOABarGY8SzNRbgD7DcsEqT0YXO71r MV17L9kxS34ULYPdbXs8QRO9q0v0vS2YQletT/oykFdb895cp8oX4rFHu4TFgoPV S6oDR0UD7T/OsJ9nsvqjxxH2UJeCTrYMi5JD71ywsY805WOEn4gUc3TLsfscqmte gMVzxQP46JuNBVEsZVKf4oIeeRSMH/Ja8pHLPjOLvQ4nszqnLl+WaSqJQWSSfCv8 5hJfIpX+CX+mJuEiskiHatbam8anZYD5m/TXaizjAdG80YiAgaMBA7fh7oK/mgTq 1OjKAnEQhOAlDCTCp9szk7ye1f3ivdCy0Hr6MvvrGTdQEY5b3Y7lt74gEQmhjTrv Fhb2FX7lLcDv7NGvyBqQ =tTqL -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
7005cd3970
2 changed files with 30 additions and 13 deletions
|
@ -399,7 +399,6 @@ static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
|
|||
static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
|
||||
static struct fasync_struct *fasync;
|
||||
|
||||
#if 0
|
||||
static bool debug;
|
||||
module_param(debug, bool, 0644);
|
||||
#define DEBUG_ENT(fmt, arg...) do { \
|
||||
|
@ -410,9 +409,6 @@ module_param(debug, bool, 0644);
|
|||
blocking_pool.entropy_count,\
|
||||
nonblocking_pool.entropy_count,\
|
||||
## arg); } while (0)
|
||||
#else
|
||||
#define DEBUG_ENT(fmt, arg...) do {} while (0)
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
|
@ -437,6 +433,7 @@ struct entropy_store {
|
|||
int entropy_count;
|
||||
int entropy_total;
|
||||
unsigned int initialized:1;
|
||||
bool last_data_init;
|
||||
__u8 last_data[EXTRACT_SIZE];
|
||||
};
|
||||
|
||||
|
@ -829,7 +826,7 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
|
|||
bytes = min_t(int, bytes, sizeof(tmp));
|
||||
|
||||
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);
|
||||
|
||||
bytes = extract_entropy(r->pull, tmp, bytes,
|
||||
|
@ -860,7 +857,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
|
|||
spin_lock_irqsave(&r->lock, flags);
|
||||
|
||||
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);
|
||||
|
||||
/* Can we pull enough? */
|
||||
|
@ -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)");
|
||||
|
||||
spin_unlock_irqrestore(&r->lock, flags);
|
||||
|
@ -957,6 +954,10 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
|
|||
ssize_t ret = 0, i;
|
||||
__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_);
|
||||
xfer_secondary_pool(r, nbytes);
|
||||
nbytes = account(r, nbytes, min, reserved);
|
||||
|
@ -967,6 +968,17 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
|
|||
if (fips_enabled) {
|
||||
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);
|
||||
if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))
|
||||
panic("Hardware RNG duplicated output!\n");
|
||||
|
@ -1086,6 +1098,7 @@ static void init_std_data(struct entropy_store *r)
|
|||
|
||||
r->entropy_count = 0;
|
||||
r->entropy_total = 0;
|
||||
r->last_data_init = false;
|
||||
mix_pool_bytes(r, &now, sizeof(now), NULL);
|
||||
for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof(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)
|
|||
if (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);
|
||||
|
||||
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);
|
||||
|
||||
if (n == 0) {
|
||||
|
@ -1171,10 +1189,6 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (n < 0) {
|
||||
retval = n;
|
||||
break;
|
||||
}
|
||||
count += n;
|
||||
buf += n;
|
||||
nbytes -= n;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <asm/uaccess.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <trace/events/timer.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
/*
|
||||
* Called after updating RLIMIT_CPU to run cpu timer and update
|
||||
|
@ -470,6 +471,8 @@ static void cleanup_timers(struct list_head *head,
|
|||
*/
|
||||
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,
|
||||
tsk->utime, tsk->stime, tsk->se.sum_exec_runtime);
|
||||
|
||||
|
|
Loading…
Reference in a new issue