ACK: [SRU Focal:oem-5.6] random32: update the net random state on interrupt and activity

Stefan Bader stefan.bader at canonical.com
Thu Sep 17 07:38:30 UTC 2020


On 09.09.20 22:01, Thadeu Lima de Souza Cascardo wrote:
> From: Willy Tarreau <w at 1wt.eu>
> 
> 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 at gmail.com>
> Suggested-by: Linus Torvalds <torvalds at linux-foundation.org>
> Cc: Eric Dumazet <edumazet at google.com>
> Cc: "Jason A. Donenfeld" <Jason at zx2c4.com>
> Cc: Andy Lutomirski <luto at kernel.org>
> Cc: Kees Cook <keescook at chromium.org>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: Peter Zijlstra <peterz at infradead.org>
> Cc: <stable at vger.kernel.org>
> Signed-off-by: Willy Tarreau <w at 1wt.eu>
> Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
> (cherry picked from commit f227e3ec3b5cad859ad15666874405e8c1bbc1d4)
> CVE-2020-16166
> Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo at canonical.com>
Acked-by: Stefan Bader <stefan.bader at canonical.com>
> ---
>  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(-)
> 
> diff --git a/drivers/char/random.c b/drivers/char/random.c
> index 6cf5a5f416ff..eb5ed0455e34 100644
> --- a/drivers/char/random.c
> +++ b/drivers/char/random.c
> @@ -1249,6 +1249,7 @@ void add_interrupt_randomness(int irq, int irq_flags)
>  
>  	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) &&
> diff --git a/include/linux/random.h b/include/linux/random.h
> index d319f9a1e429..114db225ac3e 100644
> --- a/include/linux/random.h
> +++ b/include/linux/random.h
> @@ -9,6 +9,7 @@
>  
>  #include <linux/list.h>
>  #include <linux/once.h>
> +#include <linux/percpu.h>
>  
>  #include <uapi/linux/random.h>
>  
> @@ -117,6 +118,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);
> diff --git a/kernel/time/timer.c b/kernel/time/timer.c
> index 4820823515e9..226da9217f26 100644
> --- 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>
> @@ -1731,6 +1732,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);
>  }
>  
>  /**
> diff --git a/lib/random32.c b/lib/random32.c
> index 763b920a6206..c4d317be2997 100644
> --- a/lib/random32.c
> +++ b/lib/random32.c
> @@ -48,7 +48,7 @@ static inline void prandom_state_selftest(void)
>  }
>  #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.
> 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://lists.ubuntu.com/archives/kernel-team/attachments/20200917/a14d43da/attachment.sig>


More information about the kernel-team mailing list