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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'random_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random

Pull /dev/random fixes from Ted Ts'o:
"Fix some bugs in the /dev/random driver which causes getrandom(2) to
unblock earlier than designed.

Thanks to Jann Horn from Google's Project Zero for pointing this out
to me"

* tag 'random_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random:
random: add new ioctl RNDRESEEDCRNG
random: crng_reseed() should lock the crng instance that it is modifying
random: set up the NUMA crng instances after the CRNG is fully initialized
random: use a different mixing algorithm for add_device_randomness()
random: fix crng_ready() test

+100 -31
+97 -31
drivers/char/random.c
··· 427 427 * its value (from 0->1->2). 428 428 */ 429 429 static int crng_init = 0; 430 - #define crng_ready() (likely(crng_init > 0)) 430 + #define crng_ready() (likely(crng_init > 1)) 431 431 static int crng_init_cnt = 0; 432 + static unsigned long crng_global_init_time = 0; 432 433 #define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE) 433 434 static void _extract_crng(struct crng_state *crng, 434 435 __u32 out[CHACHA20_BLOCK_WORDS]); ··· 788 787 crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1; 789 788 } 790 789 790 + #ifdef CONFIG_NUMA 791 + static 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 813 + static void numa_crng_init(void) {} 814 + #endif 815 + 816 + /* 817 + * crng_fast_load() can be called by code in the interrupt service 818 + * path. So we can't afford to dilly-dally. 819 + */ 791 820 static int crng_fast_load(const char *cp, size_t len) 792 821 { 793 822 unsigned long flags; ··· 825 794 826 795 if (!spin_trylock_irqsave(&primary_crng.lock, flags)) 827 796 return 0; 828 - if (crng_ready()) { 797 + if (crng_init != 0) { 829 798 spin_unlock_irqrestore(&primary_crng.lock, flags); 830 799 return 0; 831 800 } ··· 841 810 wake_up_interruptible(&crng_init_wait); 842 811 pr_notice("random: fast init done\n"); 843 812 } 813 + return 1; 814 + } 815 + 816 + /* 817 + * crng_slow_load() is called by add_device_randomness, which has two 818 + * attributes. (1) We can't trust the buffer passed to it is 819 + * guaranteed to be unpredictable (so it might not have any entropy at 820 + * all), and (2) it doesn't have the performance constraints of 821 + * crng_fast_load(). 822 + * 823 + * So we do something more comprehensive which is guaranteed to touch 824 + * all of the primary_crng's state, and which uses a LFSR with a 825 + * period of 255 as part of the mixing algorithm. Finally, we do 826 + * *not* advance crng_init_cnt since buffer we may get may be something 827 + * like a fixed DMI table (for example), which might very well be 828 + * unique to the machine, but is otherwise unvarying. 829 + */ 830 + static int crng_slow_load(const char *cp, size_t len) 831 + { 832 + unsigned long flags; 833 + static unsigned char lfsr = 1; 834 + unsigned char tmp; 835 + unsigned i, max = CHACHA20_KEY_SIZE; 836 + const char * src_buf = cp; 837 + char * dest_buf = (char *) &primary_crng.state[4]; 838 + 839 + if (!spin_trylock_irqsave(&primary_crng.lock, flags)) 840 + return 0; 841 + if (crng_init != 0) { 842 + spin_unlock_irqrestore(&primary_crng.lock, flags); 843 + return 0; 844 + } 845 + if (len > max) 846 + max = len; 847 + 848 + for (i = 0; i < max ; i++) { 849 + tmp = lfsr; 850 + lfsr >>= 1; 851 + if (tmp & 1) 852 + lfsr ^= 0xE1; 853 + tmp = dest_buf[i % CHACHA20_KEY_SIZE]; 854 + dest_buf[i % CHACHA20_KEY_SIZE] ^= src_buf[i % len] ^ lfsr; 855 + lfsr += (tmp << 3) | (tmp >> 5); 856 + } 857 + spin_unlock_irqrestore(&primary_crng.lock, flags); 844 858 return 1; 845 859 } 846 860 ··· 907 831 _crng_backtrack_protect(&primary_crng, buf.block, 908 832 CHACHA20_KEY_SIZE); 909 833 } 910 - spin_lock_irqsave(&primary_crng.lock, flags); 834 + spin_lock_irqsave(&crng->lock, flags); 911 835 for (i = 0; i < 8; i++) { 912 836 unsigned long rv; 913 837 if (!arch_get_random_seed_long(&rv) && ··· 917 841 } 918 842 memzero_explicit(&buf, sizeof(buf)); 919 843 crng->init_time = jiffies; 920 - spin_unlock_irqrestore(&primary_crng.lock, flags); 844 + spin_unlock_irqrestore(&crng->lock, flags); 921 845 if (crng == &primary_crng && crng_init < 2) { 922 846 invalidate_batched_entropy(); 847 + numa_crng_init(); 923 848 crng_init = 2; 924 849 process_random_ready_list(); 925 850 wake_up_interruptible(&crng_init_wait); ··· 933 856 { 934 857 unsigned long v, flags; 935 858 936 - if (crng_init > 1 && 937 - time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL)) 859 + if (crng_ready() && 860 + (time_after(crng_global_init_time, crng->init_time) || 861 + time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL))) 938 862 crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL); 939 863 spin_lock_irqsave(&crng->lock, flags); 940 864 if (arch_get_random_long(&v)) ··· 1059 981 unsigned long time = random_get_entropy() ^ jiffies; 1060 982 unsigned long flags; 1061 983 1062 - if (!crng_ready()) { 1063 - crng_fast_load(buf, size); 1064 - return; 1065 - } 984 + if (!crng_ready() && size) 985 + crng_slow_load(buf, size); 1066 986 1067 987 trace_add_device_randomness(size, _RET_IP_); 1068 988 spin_lock_irqsave(&input_pool.lock, flags); ··· 1215 1139 fast_mix(fast_pool); 1216 1140 add_interrupt_bench(cycles); 1217 1141 1218 - if (!crng_ready()) { 1142 + if (unlikely(crng_init == 0)) { 1219 1143 if ((fast_pool->count >= 64) && 1220 1144 crng_fast_load((char *) fast_pool->pool, 1221 1145 sizeof(fast_pool->pool))) { ··· 1756 1680 */ 1757 1681 static int rand_initialize(void) 1758 1682 { 1759 - #ifdef CONFIG_NUMA 1760 - int i; 1761 - struct crng_state *crng; 1762 - struct crng_state **pool; 1763 - #endif 1764 - 1765 1683 init_std_data(&input_pool); 1766 1684 init_std_data(&blocking_pool); 1767 1685 crng_initialize(&primary_crng); 1768 - 1769 - #ifdef CONFIG_NUMA 1770 - pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL); 1771 - for_each_online_node(i) { 1772 - crng = kmalloc_node(sizeof(struct crng_state), 1773 - GFP_KERNEL | __GFP_NOFAIL, i); 1774 - spin_lock_init(&crng->lock); 1775 - crng_initialize(crng); 1776 - pool[i] = crng; 1777 - } 1778 - mb(); 1779 - crng_node_pool = pool; 1780 - #endif 1686 + crng_global_init_time = jiffies; 1781 1687 return 0; 1782 1688 } 1783 1689 early_initcall(rand_initialize); ··· 1932 1874 return -EPERM; 1933 1875 input_pool.entropy_count = 0; 1934 1876 blocking_pool.entropy_count = 0; 1877 + return 0; 1878 + case RNDRESEEDCRNG: 1879 + if (!capable(CAP_SYS_ADMIN)) 1880 + return -EPERM; 1881 + if (crng_init < 2) 1882 + return -ENODATA; 1883 + crng_reseed(&primary_crng, NULL); 1884 + crng_global_init_time = jiffies - 1; 1935 1885 return 0; 1936 1886 default: 1937 1887 return -EINVAL; ··· 2278 2212 { 2279 2213 struct entropy_store *poolp = &input_pool; 2280 2214 2281 - if (!crng_ready()) { 2215 + if (unlikely(crng_init == 0)) { 2282 2216 crng_fast_load(buffer, count); 2283 2217 return; 2284 2218 }
+3
include/uapi/linux/random.h
··· 35 35 /* Clear the entropy pool and associated counters. (Superuser only.) */ 36 36 #define RNDCLEARPOOL _IO( 'R', 0x06 ) 37 37 38 + /* Reseed CRNG. (Superuser only.) */ 39 + #define RNDRESEEDCRNG _IO( 'R', 0x07 ) 40 + 38 41 struct rand_pool_info { 39 42 int entropy_count; 40 43 int buf_size;