diff options
Diffstat (limited to 'random32-update-the-net-random-state-on-interrupt-and-activity.patch')
-rw-r--r-- | random32-update-the-net-random-state-on-interrupt-and-activity.patch | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/random32-update-the-net-random-state-on-interrupt-and-activity.patch b/random32-update-the-net-random-state-on-interrupt-and-activity.patch new file mode 100644 index 000000000..e929c9976 --- /dev/null +++ b/random32-update-the-net-random-state-on-interrupt-and-activity.patch @@ -0,0 +1,109 @@ +From f227e3ec3b5cad859ad15666874405e8c1bbc1d4 Mon Sep 17 00:00:00 2001 +From: Willy Tarreau <w@1wt.eu> +Date: Fri, 10 Jul 2020 15:23:19 +0200 +Subject: random32: update the net random state on interrupt and activity + +From: Willy Tarreau <w@1wt.eu> + +commit f227e3ec3b5cad859ad15666874405e8c1bbc1d4 upstream. + +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> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +--- + drivers/char/random.c | 1 + + include/linux/random.h | 3 +++ + kernel/time/timer.c | 8 ++++++++ + lib/random32.c | 2 +- + 4 files changed, 13 insertions(+), 1 deletion(-) + +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -1277,6 +1277,7 @@ void add_interrupt_randomness(int irq, i + + fast_mix(fast_pool); + add_interrupt_bench(cycles); ++ this_cpu_add(net_rand_state.s1, fast_pool->pool[cycles & 3]); + + if (unlikely(crng_init == 0)) { + if ((fast_pool->count >= 64) && +--- a/include/linux/random.h ++++ b/include/linux/random.h +@@ -11,6 +11,7 @@ + #include <linux/kernel.h> + #include <linux/list.h> + #include <linux/once.h> ++#include <linux/percpu.h> + + #include <uapi/linux/random.h> + +@@ -119,6 +120,8 @@ struct rnd_state { + __u32 s1, s2, s3, s4; + }; + ++DECLARE_PER_CPU(struct rnd_state, net_rand_state) __latent_entropy; ++ + u32 prandom_u32_state(struct rnd_state *state); + void prandom_bytes_state(struct rnd_state *state, void *buf, size_t nbytes); + void prandom_seed_full_state(struct rnd_state __percpu *pcpu_state); +--- a/kernel/time/timer.c ++++ b/kernel/time/timer.c +@@ -43,6 +43,7 @@ + #include <linux/sched/debug.h> + #include <linux/slab.h> + #include <linux/compat.h> ++#include <linux/random.h> + + #include <linux/uaccess.h> + #include <asm/unistd.h> +@@ -1743,6 +1744,13 @@ void update_process_times(int user_tick) + scheduler_tick(); + if (IS_ENABLED(CONFIG_POSIX_TIMERS)) + run_posix_cpu_timers(); ++ ++ /* The current CPU might make use of net randoms without receiving IRQs ++ * to renew them often enough. Let's update the net_rand_state from a ++ * non-constant value that's not affine to the number of calls to make ++ * sure it's updated when there's some activity (we don't care in idle). ++ */ ++ this_cpu_add(net_rand_state.s1, rol32(jiffies, 24) + user_tick); + } + + /** +--- a/lib/random32.c ++++ b/lib/random32.c +@@ -48,7 +48,7 @@ static inline void prandom_state_selftes + } + #endif + +-static DEFINE_PER_CPU(struct rnd_state, net_rand_state) __latent_entropy; ++DEFINE_PER_CPU(struct rnd_state, net_rand_state) __latent_entropy; + + /** + * prandom_u32_state - seeded pseudo-random number generator. |