Skip to content

Commit 3cae0d8

Browse files
committed
Merge tag 'random-5.19-rc2-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/crng/random
Pull random number generator fixes from Jason Donenfeld: - A fix for a 5.19 regression for a case in which early device tree initializes the RNG, which flips a static branch. On most plaforms, jump labels aren't initialized until much later, so this caused splats. On a few mailing list threads, we cooked up easy fixes for arm64, arm32, and risc-v. But then things looked slightly more involved for xtensa, powerpc, arc, and mips. And at that point, when we're patching 7 architectures in a place before the console is even available, it seems like the cost/risk just wasn't worth it. So random.c works around it now by checking the already exported `static_key_initialized` boolean, as though somebody already ran into this issue in the past. I'm not super jazzed about that; it'd be prettier to not have to complicate downstream code. But I suppose it's practical. - A few small code nits and adding a missing __init annotation. - A change to the default config values to use the cpu and bootloader's seeds for initializing the RNG earlier. This brings them into line with what all the distros do (Fedora/RHEL, Debian, Ubuntu, Gentoo, Arch, NixOS, Alpine, SUSE, and Void... at least), and moreover will now give us test coverage in various test beds that might have caught the above device tree bug earlier. - A change to WireGuard CI's configuration to increase test coverage around the RNG. - A documentation comment fix to unrelated maintainerless CRC code that I was asked to take, I guess because it has to do with polynomials (which the RNG thankfully no longer uses). * tag 'random-5.19-rc2-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/crng/random: wireguard: selftests: use maximum cpu features and allow rng seeding random: remove rng_has_arch_random() random: credit cpu and bootloader seeds by default random: do not use jump labels before they are initialized random: account for arch randomness in bits random: mark bootloader randomness code as __init random: avoid checking crng_ready() twice in random_init() crc-itu-t: fix typo in CRC ITU-T polynomial comment
2 parents 7a68065 + 17b0128 commit 3cae0d8

File tree

9 files changed

+71
-62
lines changed

9 files changed

+71
-62
lines changed

drivers/char/Kconfig

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -429,28 +429,40 @@ config ADI
429429
driver include crash and makedumpfile.
430430

431431
config RANDOM_TRUST_CPU
432-
bool "Trust the CPU manufacturer to initialize Linux's CRNG"
432+
bool "Initialize RNG using CPU RNG instructions"
433+
default y
433434
depends on ARCH_RANDOM
434-
default n
435435
help
436-
Assume that CPU manufacturer (e.g., Intel or AMD for RDSEED or
437-
RDRAND, IBM for the S390 and Power PC architectures) is trustworthy
438-
for the purposes of initializing Linux's CRNG. Since this is not
439-
something that can be independently audited, this amounts to trusting
440-
that CPU manufacturer (perhaps with the insistence or mandate
441-
of a Nation State's intelligence or law enforcement agencies)
442-
has not installed a hidden back door to compromise the CPU's
443-
random number generation facilities. This can also be configured
444-
at boot with "random.trust_cpu=on/off".
436+
Initialize the RNG using random numbers supplied by the CPU's
437+
RNG instructions (e.g. RDRAND), if supported and available. These
438+
random numbers are never used directly, but are rather hashed into
439+
the main input pool, and this happens regardless of whether or not
440+
this option is enabled. Instead, this option controls whether the
441+
they are credited and hence can initialize the RNG. Additionally,
442+
other sources of randomness are always used, regardless of this
443+
setting. Enabling this implies trusting that the CPU can supply high
444+
quality and non-backdoored random numbers.
445+
446+
Say Y here unless you have reason to mistrust your CPU or believe
447+
its RNG facilities may be faulty. This may also be configured at
448+
boot time with "random.trust_cpu=on/off".
445449

446450
config RANDOM_TRUST_BOOTLOADER
447-
bool "Trust the bootloader to initialize Linux's CRNG"
448-
help
449-
Some bootloaders can provide entropy to increase the kernel's initial
450-
device randomness. Say Y here to assume the entropy provided by the
451-
booloader is trustworthy so it will be added to the kernel's entropy
452-
pool. Otherwise, say N here so it will be regarded as device input that
453-
only mixes the entropy pool. This can also be configured at boot with
454-
"random.trust_bootloader=on/off".
451+
bool "Initialize RNG using bootloader-supplied seed"
452+
default y
453+
help
454+
Initialize the RNG using a seed supplied by the bootloader or boot
455+
environment (e.g. EFI or a bootloader-generated device tree). This
456+
seed is not used directly, but is rather hashed into the main input
457+
pool, and this happens regardless of whether or not this option is
458+
enabled. Instead, this option controls whether the seed is credited
459+
and hence can initialize the RNG. Additionally, other sources of
460+
randomness are always used, regardless of this setting. Enabling
461+
this implies trusting that the bootloader can supply high quality and
462+
non-backdoored seeds.
463+
464+
Say Y here unless you have reason to mistrust your bootloader or
465+
believe its RNG facilities may be faulty. This may also be configured
466+
at boot time with "random.trust_bootloader=on/off".
455467

456468
endmenu

drivers/char/random.c

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,8 @@ static void __cold _credit_init_bits(size_t bits)
650650

651651
if (orig < POOL_READY_BITS && new >= POOL_READY_BITS) {
652652
crng_reseed(); /* Sets crng_init to CRNG_READY under base_crng.lock. */
653-
execute_in_process_context(crng_set_ready, &set_ready);
653+
if (static_key_initialized)
654+
execute_in_process_context(crng_set_ready, &set_ready);
654655
wake_up_interruptible(&crng_init_wait);
655656
kill_fasync(&fasync, SIGIO, POLL_IN);
656657
pr_notice("crng init done\n");
@@ -724,9 +725,8 @@ static void __cold _credit_init_bits(size_t bits)
724725
*
725726
**********************************************************************/
726727

727-
static bool used_arch_random;
728-
static bool trust_cpu __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU);
729-
static bool trust_bootloader __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER);
728+
static bool trust_cpu __initdata = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU);
729+
static bool trust_bootloader __initdata = IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER);
730730
static int __init parse_trust_cpu(char *arg)
731731
{
732732
return kstrtobool(arg, &trust_cpu);
@@ -776,20 +776,20 @@ static struct notifier_block pm_notifier = { .notifier_call = random_pm_notifica
776776
int __init random_init(const char *command_line)
777777
{
778778
ktime_t now = ktime_get_real();
779-
unsigned int i, arch_bytes;
779+
unsigned int i, arch_bits;
780780
unsigned long entropy;
781781

782782
#if defined(LATENT_ENTROPY_PLUGIN)
783783
static const u8 compiletime_seed[BLAKE2S_BLOCK_SIZE] __initconst __latent_entropy;
784784
_mix_pool_bytes(compiletime_seed, sizeof(compiletime_seed));
785785
#endif
786786

787-
for (i = 0, arch_bytes = BLAKE2S_BLOCK_SIZE;
787+
for (i = 0, arch_bits = BLAKE2S_BLOCK_SIZE * 8;
788788
i < BLAKE2S_BLOCK_SIZE; i += sizeof(entropy)) {
789789
if (!arch_get_random_seed_long_early(&entropy) &&
790790
!arch_get_random_long_early(&entropy)) {
791791
entropy = random_get_entropy();
792-
arch_bytes -= sizeof(entropy);
792+
arch_bits -= sizeof(entropy) * 8;
793793
}
794794
_mix_pool_bytes(&entropy, sizeof(entropy));
795795
}
@@ -798,11 +798,18 @@ int __init random_init(const char *command_line)
798798
_mix_pool_bytes(command_line, strlen(command_line));
799799
add_latent_entropy();
800800

801+
/*
802+
* If we were initialized by the bootloader before jump labels are
803+
* initialized, then we should enable the static branch here, where
804+
* it's guaranteed that jump labels have been initialized.
805+
*/
806+
if (!static_branch_likely(&crng_is_ready) && crng_init >= CRNG_READY)
807+
crng_set_ready(NULL);
808+
801809
if (crng_ready())
802810
crng_reseed();
803811
else if (trust_cpu)
804-
credit_init_bits(arch_bytes * 8);
805-
used_arch_random = arch_bytes * 8 >= POOL_READY_BITS;
812+
_credit_init_bits(arch_bits);
806813

807814
WARN_ON(register_pm_notifier(&pm_notifier));
808815

@@ -811,17 +818,6 @@ int __init random_init(const char *command_line)
811818
return 0;
812819
}
813820

814-
/*
815-
* Returns whether arch randomness has been mixed into the initial
816-
* state of the RNG, regardless of whether or not that randomness
817-
* was credited. Knowing this is only good for a very limited set
818-
* of uses, such as early init printk pointer obfuscation.
819-
*/
820-
bool rng_has_arch_random(void)
821-
{
822-
return used_arch_random;
823-
}
824-
825821
/*
826822
* Add device- or boot-specific data to the input pool to help
827823
* initialize it.
@@ -865,13 +861,12 @@ EXPORT_SYMBOL_GPL(add_hwgenerator_randomness);
865861
* Handle random seed passed by bootloader, and credit it if
866862
* CONFIG_RANDOM_TRUST_BOOTLOADER is set.
867863
*/
868-
void __cold add_bootloader_randomness(const void *buf, size_t len)
864+
void __init add_bootloader_randomness(const void *buf, size_t len)
869865
{
870866
mix_pool_bytes(buf, len);
871867
if (trust_bootloader)
872868
credit_init_bits(len * 8);
873869
}
874-
EXPORT_SYMBOL_GPL(add_bootloader_randomness);
875870

876871
#if IS_ENABLED(CONFIG_VMGENID)
877872
static BLOCKING_NOTIFIER_HEAD(vmfork_chain);

include/linux/crc-itu-t.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*
55
* Implements the standard CRC ITU-T V.41:
66
* Width 16
7-
* Poly 0x1021 (x^16 + x^12 + x^15 + 1)
7+
* Poly 0x1021 (x^16 + x^12 + x^5 + 1)
88
* Init 0
99
*/
1010

include/linux/random.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
struct notifier_block;
1414

1515
void add_device_randomness(const void *buf, size_t len);
16-
void add_bootloader_randomness(const void *buf, size_t len);
16+
void __init add_bootloader_randomness(const void *buf, size_t len);
1717
void add_input_randomness(unsigned int type, unsigned int code,
1818
unsigned int value) __latent_entropy;
1919
void add_interrupt_randomness(int irq) __latent_entropy;
@@ -74,7 +74,6 @@ static inline unsigned long get_random_canary(void)
7474

7575
int __init random_init(const char *command_line);
7676
bool rng_is_initialized(void);
77-
bool rng_has_arch_random(void);
7877
int wait_for_random_bytes(void);
7978

8079
/* Calls wait_for_random_bytes() and then calls get_random_bytes(buf, nbytes).

lib/crc-itu-t.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include <linux/module.h>
88
#include <linux/crc-itu-t.h>
99

10-
/** CRC table for the CRC ITU-T V.41 0x1021 (x^16 + x^12 + x^15 + 1) */
10+
/* CRC table for the CRC ITU-T V.41 0x1021 (x^16 + x^12 + x^5 + 1) */
1111
const u16 crc_itu_t_table[256] = {
1212
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
1313
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,

lib/vsprintf.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -769,8 +769,7 @@ static inline int __ptr_to_hashval(const void *ptr, unsigned long *hashval_out)
769769
static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn);
770770
unsigned long flags;
771771

772-
if (!system_unbound_wq ||
773-
(!rng_is_initialized() && !rng_has_arch_random()) ||
772+
if (!system_unbound_wq || !rng_is_initialized() ||
774773
!spin_trylock_irqsave(&filling, flags))
775774
return -EAGAIN;
776775

tools/testing/selftests/wireguard/qemu/Makefile

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ QEMU_VPORT_RESULT := virtio-serial-device
6464
ifeq ($(HOST_ARCH),$(ARCH))
6565
QEMU_MACHINE := -cpu host -machine virt,gic_version=host,accel=kvm
6666
else
67-
QEMU_MACHINE := -cpu cortex-a53 -machine virt
68-
CFLAGS += -march=armv8-a -mtune=cortex-a53
67+
QEMU_MACHINE := -cpu max -machine virt
68+
CFLAGS += -march=armv8-a
6969
endif
7070
else ifeq ($(ARCH),aarch64_be)
7171
CHOST := aarch64_be-linux-musl
@@ -76,8 +76,8 @@ QEMU_VPORT_RESULT := virtio-serial-device
7676
ifeq ($(HOST_ARCH),$(ARCH))
7777
QEMU_MACHINE := -cpu host -machine virt,gic_version=host,accel=kvm
7878
else
79-
QEMU_MACHINE := -cpu cortex-a53 -machine virt
80-
CFLAGS += -march=armv8-a -mtune=cortex-a53
79+
QEMU_MACHINE := -cpu max -machine virt
80+
CFLAGS += -march=armv8-a
8181
endif
8282
else ifeq ($(ARCH),arm)
8383
CHOST := arm-linux-musleabi
@@ -88,8 +88,8 @@ QEMU_VPORT_RESULT := virtio-serial-device
8888
ifeq ($(HOST_ARCH),$(ARCH))
8989
QEMU_MACHINE := -cpu host -machine virt,gic_version=host,accel=kvm
9090
else
91-
QEMU_MACHINE := -cpu cortex-a15 -machine virt
92-
CFLAGS += -march=armv7-a -mtune=cortex-a15 -mabi=aapcs-linux
91+
QEMU_MACHINE := -cpu max -machine virt
92+
CFLAGS += -march=armv7-a -mabi=aapcs-linux
9393
endif
9494
else ifeq ($(ARCH),armeb)
9595
CHOST := armeb-linux-musleabi
@@ -100,8 +100,8 @@ QEMU_VPORT_RESULT := virtio-serial-device
100100
ifeq ($(HOST_ARCH),$(ARCH))
101101
QEMU_MACHINE := -cpu host -machine virt,gic_version=host,accel=kvm
102102
else
103-
QEMU_MACHINE := -cpu cortex-a15 -machine virt
104-
CFLAGS += -march=armv7-a -mabi=aapcs-linux # We don't pass -mtune=cortex-a15 due to a compiler bug on big endian.
103+
QEMU_MACHINE := -cpu max -machine virt
104+
CFLAGS += -march=armv7-a -mabi=aapcs-linux
105105
LDFLAGS += -Wl,--be8
106106
endif
107107
else ifeq ($(ARCH),x86_64)
@@ -112,8 +112,7 @@ KERNEL_BZIMAGE := $(KERNEL_BUILD_PATH)/arch/x86/boot/bzImage
112112
ifeq ($(HOST_ARCH),$(ARCH))
113113
QEMU_MACHINE := -cpu host -machine q35,accel=kvm
114114
else
115-
QEMU_MACHINE := -cpu Skylake-Server -machine q35
116-
CFLAGS += -march=skylake-avx512
115+
QEMU_MACHINE := -cpu max -machine q35
117116
endif
118117
else ifeq ($(ARCH),i686)
119118
CHOST := i686-linux-musl
@@ -123,8 +122,7 @@ KERNEL_BZIMAGE := $(KERNEL_BUILD_PATH)/arch/x86/boot/bzImage
123122
ifeq ($(subst x86_64,i686,$(HOST_ARCH)),$(ARCH))
124123
QEMU_MACHINE := -cpu host -machine q35,accel=kvm
125124
else
126-
QEMU_MACHINE := -cpu coreduo -machine q35
127-
CFLAGS += -march=prescott
125+
QEMU_MACHINE := -cpu max -machine q35
128126
endif
129127
else ifeq ($(ARCH),mips64)
130128
CHOST := mips64-linux-musl
@@ -182,7 +180,7 @@ KERNEL_BZIMAGE := $(KERNEL_BUILD_PATH)/vmlinux
182180
ifeq ($(HOST_ARCH),$(ARCH))
183181
QEMU_MACHINE := -cpu host,accel=kvm -machine pseries
184182
else
185-
QEMU_MACHINE := -machine pseries
183+
QEMU_MACHINE := -machine pseries -device spapr-rng,rng=rng -object rng-random,id=rng
186184
endif
187185
else ifeq ($(ARCH),powerpc64le)
188186
CHOST := powerpc64le-linux-musl
@@ -192,7 +190,7 @@ KERNEL_BZIMAGE := $(KERNEL_BUILD_PATH)/vmlinux
192190
ifeq ($(HOST_ARCH),$(ARCH))
193191
QEMU_MACHINE := -cpu host,accel=kvm -machine pseries
194192
else
195-
QEMU_MACHINE := -machine pseries
193+
QEMU_MACHINE := -machine pseries -device spapr-rng,rng=rng -object rng-random,id=rng
196194
endif
197195
else ifeq ($(ARCH),powerpc)
198196
CHOST := powerpc-linux-musl
@@ -247,7 +245,7 @@ QEMU_VPORT_RESULT := virtio-serial-ccw
247245
ifeq ($(HOST_ARCH),$(ARCH))
248246
QEMU_MACHINE := -cpu host,accel=kvm -machine s390-ccw-virtio -append $(KERNEL_CMDLINE)
249247
else
250-
QEMU_MACHINE := -machine s390-ccw-virtio -append $(KERNEL_CMDLINE)
248+
QEMU_MACHINE := -cpu max -machine s390-ccw-virtio -append $(KERNEL_CMDLINE)
251249
endif
252250
else
253251
$(error I only build: x86_64, i686, arm, armeb, aarch64, aarch64_be, mips, mipsel, mips64, mips64el, powerpc64, powerpc64le, powerpc, m68k, riscv64, riscv32, s390x)

tools/testing/selftests/wireguard/qemu/init.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <sys/utsname.h>
2222
#include <sys/sendfile.h>
2323
#include <sys/sysmacros.h>
24+
#include <sys/random.h>
2425
#include <linux/random.h>
2526
#include <linux/version.h>
2627

@@ -58,6 +59,8 @@ static void seed_rng(void)
5859
{
5960
int bits = 256, fd;
6061

62+
if (!getrandom(NULL, 0, GRND_NONBLOCK))
63+
return;
6164
pretty_message("[+] Fake seeding RNG...");
6265
fd = open("/dev/random", O_WRONLY);
6366
if (fd < 0)

tools/testing/selftests/wireguard/qemu/kernel.config

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ CONFIG_TTY=y
3131
CONFIG_BINFMT_ELF=y
3232
CONFIG_BINFMT_SCRIPT=y
3333
CONFIG_VDSO=y
34+
CONFIG_STRICT_KERNEL_RWX=y
3435
CONFIG_VIRTUALIZATION=y
3536
CONFIG_HYPERVISOR_GUEST=y
3637
CONFIG_PARAVIRT=y
@@ -65,6 +66,8 @@ CONFIG_PROC_FS=y
6566
CONFIG_PROC_SYSCTL=y
6667
CONFIG_SYSFS=y
6768
CONFIG_TMPFS=y
69+
CONFIG_RANDOM_TRUST_CPU=y
70+
CONFIG_RANDOM_TRUST_BOOTLOADER=y
6871
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
6972
CONFIG_LOG_BUF_SHIFT=18
7073
CONFIG_PRINTK_TIME=y

0 commit comments

Comments
 (0)