Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 35a490a3 authored by Jason A. Donenfeld's avatar Jason A. Donenfeld Committed by Greg Kroah-Hartman
Browse files

random: access input_pool_data directly rather than through pointer



commit 6c0eace6e1499712583b6ee62d95161e8b3449f5 upstream.

This gets rid of another abstraction we no longer need. It would be nice
if we could instead make pool an array rather than a pointer, but the
latent entropy plugin won't be able to do its magic in that case. So
instead we put all accesses to the input pool's actual data through the
input_pool_data array directly.

Reviewed-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: default avatarJason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 5501511b
Loading
Loading
Loading
Loading
+101 −116
Original line number Diff line number Diff line
@@ -497,17 +497,12 @@ MODULE_PARM_DESC(ratelimit_disable, "Disable random ratelimit suppression");
static u32 input_pool_data[POOL_WORDS] __latent_entropy;

static struct {
	/* read-only data: */
	u32 *pool;

	/* read-write data: */
	spinlock_t lock;
	u16 add_ptr;
	u16 input_rotate;
	int entropy_count;
} input_pool = {
	.lock = __SPIN_LOCK_UNLOCKED(input_pool.lock),
	.pool = input_pool_data
};

static ssize_t extract_entropy(void *buf, size_t nbytes, int min);
@@ -515,7 +510,7 @@ static ssize_t _extract_entropy(void *buf, size_t nbytes);

static void crng_reseed(struct crng_state *crng, bool use_input_pool);

static u32 const twist_table[8] = {
static const u32 twist_table[8] = {
	0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
	0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 };

@@ -545,15 +540,15 @@ static void _mix_pool_bytes(const void *in, int nbytes)
		i = (i - 1) & POOL_WORDMASK;

		/* XOR in the various taps */
		w ^= input_pool.pool[i];
		w ^= input_pool.pool[(i + POOL_TAP1) & POOL_WORDMASK];
		w ^= input_pool.pool[(i + POOL_TAP2) & POOL_WORDMASK];
		w ^= input_pool.pool[(i + POOL_TAP3) & POOL_WORDMASK];
		w ^= input_pool.pool[(i + POOL_TAP4) & POOL_WORDMASK];
		w ^= input_pool.pool[(i + POOL_TAP5) & POOL_WORDMASK];
		w ^= input_pool_data[i];
		w ^= input_pool_data[(i + POOL_TAP1) & POOL_WORDMASK];
		w ^= input_pool_data[(i + POOL_TAP2) & POOL_WORDMASK];
		w ^= input_pool_data[(i + POOL_TAP3) & POOL_WORDMASK];
		w ^= input_pool_data[(i + POOL_TAP4) & POOL_WORDMASK];
		w ^= input_pool_data[(i + POOL_TAP5) & POOL_WORDMASK];

		/* Mix the result back in with a twist */
		input_pool.pool[i] = (w >> 3) ^ twist_table[w & 7];
		input_pool_data[i] = (w >> 3) ^ twist_table[w & 7];

		/*
		 * Normally, we add 7 bits of rotation to the pool.
@@ -1039,8 +1034,7 @@ static void crng_reseed(struct crng_state *crng, bool use_input_pool)
	crng_finalize_init(crng);
}

static void _extract_crng(struct crng_state *crng,
			  u8 out[CHACHA20_BLOCK_SIZE])
static void _extract_crng(struct crng_state *crng, u8 out[CHACHA20_BLOCK_SIZE])
{
	unsigned long flags, init_time;

@@ -1126,7 +1120,6 @@ static ssize_t extract_crng_user(void __user *buf, size_t nbytes)
	return ret;
}


/*********************************************************************
 *
 * Entropy input management
@@ -1295,8 +1288,8 @@ void add_interrupt_randomness(int irq)
	fast_pool->pool[1] ^= now ^ c_high;
	ip = regs ? instruction_pointer(regs) : _RET_IP_;
	fast_pool->pool[2] ^= ip;
	fast_pool->pool[3] ^= (sizeof(ip) > 4) ? ip >> 32 :
		get_reg(fast_pool, regs);
	fast_pool->pool[3] ^=
		(sizeof(ip) > 4) ? ip >> 32 : get_reg(fast_pool, regs);

	fast_mix(fast_pool);
	add_interrupt_bench(cycles);
@@ -1310,8 +1303,7 @@ void add_interrupt_randomness(int irq)
		return;
	}

	if ((fast_pool->count < 64) &&
	    !time_after(now, fast_pool->last + HZ))
	if ((fast_pool->count < 64) && !time_after(now, fast_pool->last + HZ))
		return;

	if (!spin_trylock(&input_pool.lock))
@@ -1420,7 +1412,7 @@ static void extract_buf(u8 *out)

	/* Generate a hash across the pool */
	spin_lock_irqsave(&input_pool.lock, flags);
	blake2s_update(&state, (const u8 *)input_pool.pool, POOL_BYTES);
	blake2s_update(&state, (const u8 *)input_pool_data, POOL_BYTES);
	blake2s_final(&state, hash); /* final zeros out state */

	/*
@@ -1480,8 +1472,7 @@ static ssize_t extract_entropy(void *buf, size_t nbytes, int min)
#define warn_unseeded_randomness(previous) \
	_warn_unseeded_randomness(__func__, (void *)_RET_IP_, (previous))

static void _warn_unseeded_randomness(const char *func_name, void *caller,
				      void **previous)
static void _warn_unseeded_randomness(const char *func_name, void *caller, void **previous)
{
#ifdef CONFIG_WARN_ALL_UNSEEDED_RANDOM
	const bool print_once = false;
@@ -1489,8 +1480,7 @@ static void _warn_unseeded_randomness(const char *func_name, void *caller,
	static bool print_once __read_mostly;
#endif

	if (print_once ||
	    crng_ready() ||
	if (print_once || crng_ready() ||
	    (previous && (caller == READ_ONCE(*previous))))
		return;
	WRITE_ONCE(*previous, caller);
@@ -1542,7 +1532,6 @@ void get_random_bytes(void *buf, int nbytes)
}
EXPORT_SYMBOL(get_random_bytes);


/*
 * Each time the timer fires, we expect that we got an unpredictable
 * jump in the cycle counter. Even if the timer is running on another
@@ -1791,9 +1780,8 @@ void rand_initialize_disk(struct gendisk *disk)
}
#endif

static ssize_t
urandom_read_nowarn(struct file *file, char __user *buf, size_t nbytes,
		    loff_t *ppos)
static ssize_t urandom_read_nowarn(struct file *file, char __user *buf,
				   size_t nbytes, loff_t *ppos)
{
	int ret;

@@ -1803,8 +1791,8 @@ urandom_read_nowarn(struct file *file, char __user *buf, size_t nbytes,
	return ret;
}

static ssize_t
urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
static ssize_t urandom_read(struct file *file, char __user *buf, size_t nbytes,
			    loff_t *ppos)
{
	static int maxwarn = 10;

@@ -1818,8 +1806,8 @@ urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
	return urandom_read_nowarn(file, buf, nbytes, ppos);
}

static ssize_t
random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
static ssize_t random_read(struct file *file, char __user *buf, size_t nbytes,
			   loff_t *ppos)
{
	int ret;

@@ -1829,8 +1817,7 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
	return urandom_read_nowarn(file, buf, nbytes, ppos);
}

static unsigned int
random_poll(struct file *file, poll_table * wait)
static unsigned int random_poll(struct file *file, poll_table *wait)
{
	unsigned int mask;

@@ -1844,8 +1831,7 @@ random_poll(struct file *file, poll_table * wait)
	return mask;
}

static int
write_pool(const char __user *buffer, size_t count)
static int write_pool(const char __user *buffer, size_t count)
{
	size_t bytes;
	u32 t, buf[16];
@@ -1963,8 +1949,8 @@ const struct file_operations urandom_fops = {
	.llseek = noop_llseek,
};

SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count,
		unsigned int, flags)
SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, unsigned int,
		flags)
{
	int ret;

@@ -2229,8 +2215,7 @@ static void invalidate_batched_entropy(void)
 * Return: A page aligned address within [start, start + range).  On error,
 * @start is returned.
 */
unsigned long
randomize_page(unsigned long start, unsigned long range)
unsigned long randomize_page(unsigned long start, unsigned long range)
{
	if (!PAGE_ALIGNED(start)) {
		range -= PAGE_ALIGN(start) - start;