Skip to content

Commit 50e0aec

Browse files
wtarreauSomasundaram Krishnasamy
authored andcommitted
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 <[email protected]> Suggested-by: Linus Torvalds <[email protected]> Cc: Eric Dumazet <[email protected]> Cc: "Jason A. Donenfeld" <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Kees Cook <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: <[email protected]> Signed-off-by: Willy Tarreau <[email protected]> Signed-off-by: Linus Torvalds <[email protected]> (cherry picked from commit f227e3e) Orabug: 31698084 CVE: CVE-2020-16166 Signed-off-by: Vijayendra Suman <[email protected]> Reviewed-by: Darren Kenny <[email protected]> Conflicts: kernel/time/timer.c Signed-off-by: Somasundaram Krishnasamy <[email protected]>
1 parent 91bce76 commit 50e0aec

File tree

4 files changed

+13
-1
lines changed

4 files changed

+13
-1
lines changed

drivers/char/random.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,6 +1246,7 @@ void add_interrupt_randomness(int irq, int irq_flags)
12461246

12471247
fast_mix(fast_pool);
12481248
add_interrupt_bench(cycles);
1249+
this_cpu_add(net_rand_state.s1, fast_pool->pool[cycles & 3]);
12491250

12501251
if (unlikely(crng_init == 0)) {
12511252
if ((fast_pool->count >= 64) &&

include/linux/random.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <linux/list.h>
1111
#include <linux/once.h>
12+
#include <linux/percpu.h>
1213

1314
#include <uapi/linux/random.h>
1415

@@ -116,6 +117,8 @@ struct rnd_state {
116117
__u32 s1, s2, s3, s4;
117118
};
118119

120+
DECLARE_PER_CPU(struct rnd_state, net_rand_state) __latent_entropy;
121+
119122
u32 prandom_u32_state(struct rnd_state *state);
120123
void prandom_bytes_state(struct rnd_state *state, void *buf, size_t nbytes);
121124
void prandom_seed_full_state(struct rnd_state __percpu *pcpu_state);

kernel/time/timer.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include <linux/slab.h>
4646
#include <linux/compat.h>
4747
#include <linux/sdt.h>
48+
#include <linux/random.h>
4849

4950
#include <linux/uaccess.h>
5051
#include <asm/unistd.h>
@@ -1597,6 +1598,13 @@ void update_process_times(int user_tick)
15971598
scheduler_tick();
15981599
if (IS_ENABLED(CONFIG_POSIX_TIMERS))
15991600
run_posix_cpu_timers(p);
1601+
1602+
/* The current CPU might make use of net randoms without receiving IRQs
1603+
* to renew them often enough. Let's update the net_rand_state from a
1604+
* non-constant value that's not affine to the number of calls to make
1605+
* sure it's updated when there's some activity (we don't care in idle).
1606+
*/
1607+
this_cpu_add(net_rand_state.s1, rol32(jiffies, 24) + user_tick);
16001608
}
16011609

16021610
/**

lib/random32.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static inline void prandom_state_selftest(void)
4848
}
4949
#endif
5050

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;
5252

5353
/**
5454
* prandom_u32_state - seeded pseudo-random number generator.

0 commit comments

Comments
 (0)