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

Thadeu Lima de Souza Cascardo cascardo at canonical.com
Wed Sep 16 16:20:42 UTC 2020


On Tue, Sep 15, 2020 at 11:56:42AM +0200, Kleber Souza wrote:
> 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>
> 
> This commit introduces build errors/warnings in some non-x86 arches
> which are fixed by the following commits:
> 
> 0c83b277ada7 powerpc: Fix circular dependency between percpu.h and mmu.h
> aa54ea903abb ARM: percpu.h: fix build error
> 1c9df907da83 random: fix circular include dependency on arm64 after addition of percpu.h
> 835d1c3a9879 arm64: Drop unnecessary include from asm/smp.h
> 
> We probably don't care about those as we build this kernel only
> for amd64, but have you considered including the following fixup?
> 
> 83bdc7275e62 random32: remove net_rand_state from the latent entropy gcc plugin
> 

Yes, I took those into consideration and ignored because they wouldn't cause
problems with oem-5.6. So, I went with the minimal backport, tested that it
builds on all supported architectures (that is, only amd64), and decided to
close the issue for a kernel that won't live too much more.

Thanks.
Cascardo.

> 
> Kleber
> 
> > ---
> >  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.
> > 
> 



More information about the kernel-team mailing list