summaryrefslogtreecommitdiffstats
path: root/drivers/char/random.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2018-04-11 15:23:56 -0400
committerTheodore Ts'o <tytso@mit.edu>2018-04-14 11:59:19 -0400
commit8ef35c866f8862df074a49a93b0309725812dea8 (patch)
tree982e05c942d90c435fdb4dc0f303ae2c4cac22d6 /drivers/char/random.c
parentdc12baacb95f205948f64dc936a47d89ee110117 (diff)
random: set up the NUMA crng instances after the CRNG is fully initialized
Until the primary_crng is fully initialized, don't initialize the NUMA crng nodes. Otherwise users of /dev/urandom on NUMA systems before the CRNG is fully initialized can get very bad quality randomness. Of course everyone should move to getrandom(2) where this won't be an issue, but there's a lot of legacy code out there. This related to CVE-2018-1108. Reported-by: Jann Horn <jannh@google.com> Fixes: 1e7f583af67b ("random: make /dev/urandom scalable for silly...") Cc: stable@kernel.org # 4.8+ Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'drivers/char/random.c')
-rw-r--r--drivers/char/random.c46
1 files changed, 27 insertions, 19 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 6baa828c0493..02d792f7933f 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -787,6 +787,32 @@ static void crng_initialize(struct crng_state *crng)
787 crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1; 787 crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
788} 788}
789 789
790#ifdef CONFIG_NUMA
791static void numa_crng_init(void)
792{
793 int i;
794 struct crng_state *crng;
795 struct crng_state **pool;
796
797 pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL);
798 for_each_online_node(i) {
799 crng = kmalloc_node(sizeof(struct crng_state),
800 GFP_KERNEL | __GFP_NOFAIL, i);
801 spin_lock_init(&crng->lock);
802 crng_initialize(crng);
803 pool[i] = crng;
804 }
805 mb();
806 if (cmpxchg(&crng_node_pool, NULL, pool)) {
807 for_each_node(i)
808 kfree(pool[i]);
809 kfree(pool);
810 }
811}
812#else
813static void numa_crng_init(void) {}
814#endif
815
790/* 816/*
791 * crng_fast_load() can be called by code in the interrupt service 817 * crng_fast_load() can be called by code in the interrupt service
792 * path. So we can't afford to dilly-dally. 818 * path. So we can't afford to dilly-dally.
@@ -893,6 +919,7 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
893 spin_unlock_irqrestore(&primary_crng.lock, flags); 919 spin_unlock_irqrestore(&primary_crng.lock, flags);
894 if (crng == &primary_crng && crng_init < 2) { 920 if (crng == &primary_crng && crng_init < 2) {
895 invalidate_batched_entropy(); 921 invalidate_batched_entropy();
922 numa_crng_init();
896 crng_init = 2; 923 crng_init = 2;
897 process_random_ready_list(); 924 process_random_ready_list();
898 wake_up_interruptible(&crng_init_wait); 925 wake_up_interruptible(&crng_init_wait);
@@ -1727,28 +1754,9 @@ static void init_std_data(struct entropy_store *r)
1727 */ 1754 */
1728static int rand_initialize(void) 1755static int rand_initialize(void)
1729{ 1756{
1730#ifdef CONFIG_NUMA
1731 int i;
1732 struct crng_state *crng;
1733 struct crng_state **pool;
1734#endif
1735
1736 init_std_data(&input_pool); 1757 init_std_data(&input_pool);
1737 init_std_data(&blocking_pool); 1758 init_std_data(&blocking_pool);
1738 crng_initialize(&primary_crng); 1759 crng_initialize(&primary_crng);
1739
1740#ifdef CONFIG_NUMA
1741 pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL);
1742 for_each_online_node(i) {
1743 crng = kmalloc_node(sizeof(struct crng_state),
1744 GFP_KERNEL | __GFP_NOFAIL, i);
1745 spin_lock_init(&crng->lock);
1746 crng_initialize(crng);
1747 pool[i] = crng;
1748 }
1749 mb();
1750 crng_node_pool = pool;
1751#endif
1752 return 0; 1760 return 0;
1753} 1761}
1754early_initcall(rand_initialize); 1762early_initcall(rand_initialize);