Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

random: Fix crashes with sparse node ids

On a system with sparse node ids, eg. a powerpc system with 4 nodes
numbered like so:

node 0: [mem 0x0000000000000000-0x00000007ffffffff]
node 1: [mem 0x0000000800000000-0x0000000fffffffff]
node 16: [mem 0x0000001000000000-0x00000017ffffffff]
node 17: [mem 0x0000001800000000-0x0000001fffffffff]

The code in rand_initialize() will allocate 4 pointers for the pool
array, and initialise them correctly.

However when go to use the pool, in eg. extract_crng(), we use the
numa_node_id() to index into the array. For the higher numbered node ids
this leads to random memory corruption, depending on what was kmalloc'ed
adjacent to the pool array.

Fix it by using nr_node_ids to size the pool array.

Fixes: 1e7f583af67b ("random: make /dev/urandom scalable for silly userspace programs")
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Michael Ellerman and committed by
Linus Torvalds
dd0f0cf5 7f155c70

+2 -3
+2 -3
drivers/char/random.c
··· 249 249 #include <linux/genhd.h> 250 250 #include <linux/interrupt.h> 251 251 #include <linux/mm.h> 252 + #include <linux/nodemask.h> 252 253 #include <linux/spinlock.h> 253 254 #include <linux/kthread.h> 254 255 #include <linux/percpu.h> ··· 1657 1656 { 1658 1657 #ifdef CONFIG_NUMA 1659 1658 int i; 1660 - int num_nodes = num_possible_nodes(); 1661 1659 struct crng_state *crng; 1662 1660 struct crng_state **pool; 1663 1661 #endif ··· 1666 1666 crng_initialize(&primary_crng); 1667 1667 1668 1668 #ifdef CONFIG_NUMA 1669 - pool = kmalloc(num_nodes * sizeof(void *), 1670 - GFP_KERNEL|__GFP_NOFAIL|__GFP_ZERO); 1669 + pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL); 1671 1670 for_each_online_node(i) { 1672 1671 crng = kmalloc_node(sizeof(struct crng_state), 1673 1672 GFP_KERNEL | __GFP_NOFAIL, i);