Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

random32: update the net random state on interrupt and activity

This modifies the first 32 bits out of the 128 bits of a random CPU's
net_rand_state on interrupt or CPU activity to complicate remote
observations that could lead to guessing the network RNG's internal
state.

Note that depending on some network devices' interrupt rate moderation
or binding, this re-seeding might happen on every packet or even almost
never.

In addition, with NOHZ some CPUs might not even get timer interrupts,
leaving their local state rarely updated, while they are running
networked processes making use of the random state. For this reason, we
also perform this update in update_process_times() in order to at least
update the state when there is user or system activity, since it's the
only case we care about.

Reported-by: Amit Klein <aksecurity@gmail.com>
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Eric Dumazet <edumazet@google.com>
Cc: "Jason A. Donenfeld" <Jason@zx2c4.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Kees Cook <keescook@chromium.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Willy Tarreau and committed by
Linus Torvalds
f227e3ec 6ba1b005

+13 -1
+1
drivers/char/random.c
··· 1277 1277 1278 1278 fast_mix(fast_pool); 1279 1279 add_interrupt_bench(cycles); 1280 + this_cpu_add(net_rand_state.s1, fast_pool->pool[cycles & 3]); 1280 1281 1281 1282 if (unlikely(crng_init == 0)) { 1282 1283 if ((fast_pool->count >= 64) &&
+3
include/linux/random.h
··· 11 11 #include <linux/kernel.h> 12 12 #include <linux/list.h> 13 13 #include <linux/once.h> 14 + #include <linux/percpu.h> 14 15 15 16 #include <uapi/linux/random.h> 16 17 ··· 119 118 struct rnd_state { 120 119 __u32 s1, s2, s3, s4; 121 120 }; 121 + 122 + DECLARE_PER_CPU(struct rnd_state, net_rand_state) __latent_entropy; 122 123 123 124 u32 prandom_u32_state(struct rnd_state *state); 124 125 void prandom_bytes_state(struct rnd_state *state, void *buf, size_t nbytes);
+8
kernel/time/timer.c
··· 43 43 #include <linux/sched/debug.h> 44 44 #include <linux/slab.h> 45 45 #include <linux/compat.h> 46 + #include <linux/random.h> 46 47 47 48 #include <linux/uaccess.h> 48 49 #include <asm/unistd.h> ··· 1743 1742 scheduler_tick(); 1744 1743 if (IS_ENABLED(CONFIG_POSIX_TIMERS)) 1745 1744 run_posix_cpu_timers(); 1745 + 1746 + /* The current CPU might make use of net randoms without receiving IRQs 1747 + * to renew them often enough. Let's update the net_rand_state from a 1748 + * non-constant value that's not affine to the number of calls to make 1749 + * sure it's updated when there's some activity (we don't care in idle). 1750 + */ 1751 + this_cpu_add(net_rand_state.s1, rol32(jiffies, 24) + user_tick); 1746 1752 } 1747 1753 1748 1754 /**
+1 -1
lib/random32.c
··· 48 48 } 49 49 #endif 50 50 51 - static DEFINE_PER_CPU(struct rnd_state, net_rand_state) __latent_entropy; 51 + DEFINE_PER_CPU(struct rnd_state, net_rand_state) __latent_entropy; 52 52 53 53 /** 54 54 * prandom_u32_state - seeded pseudo-random number generator.