[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