Skip to content

Commit

Permalink
um: seed rng using host OS rng
Browse files Browse the repository at this point in the history
commit 0b9ba61 upstream.

UML generally does not provide access to special CPU instructions like
RDRAND, and execution tends to be rather deterministic, with no real
hardware interrupts, making good randomness really very hard, if not
all together impossible. Not only is this a security eyebrow raiser, but
it's also quite annoying when trying to do various pieces of UML-based
automation that takes a long time to boot, if ever.

Fix this by trivially calling getrandom() in the host and using that
seed as "bootloader randomness", which initializes the rng immediately
at UML boot.

The old behavior can be restored the same way as on any other arch, by
way of CONFIG_TRUST_BOOTLOADER_RANDOMNESS=n or
random.trust_bootloader=0. So seen from that perspective, this just
makes UML act like other archs, which is positive in its own right.

Additionally, wire up arch_get_random_{int,long}() in the same way, so
that reseeds can also make use of the host RNG, controllable by
CONFIG_TRUST_CPU_RANDOMNESS and random.trust_cpu, per usual.

Cc: stable@vger.kernel.org
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Acked-By: Anton Ivanov <anton.ivanov@cambridgegreys.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
zx2c4 authored and gregkh committed Aug 17, 2022
1 parent 5d096e2 commit cac7ead
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 0 deletions.
30 changes: 30 additions & 0 deletions arch/um/include/asm/archrandom.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_UM_ARCHRANDOM_H__
#define __ASM_UM_ARCHRANDOM_H__

#include <linux/types.h>

/* This is from <os.h>, but better not to #include that in a global header here. */
ssize_t os_getrandom(void *buf, size_t len, unsigned int flags);

static inline bool __must_check arch_get_random_long(unsigned long *v)
{
return os_getrandom(v, sizeof(*v), 0) == sizeof(*v);
}

static inline bool __must_check arch_get_random_int(unsigned int *v)
{
return os_getrandom(v, sizeof(*v), 0) == sizeof(*v);
}

static inline bool __must_check arch_get_random_seed_long(unsigned long *v)
{
return false;
}

static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
{
return false;
}

#endif
7 changes: 7 additions & 0 deletions arch/um/include/shared/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
#include <irq_user.h>
#include <longjmp.h>
#include <mm_id.h>
/* This is to get size_t */
#ifndef __UM_HOST__
#include <linux/types.h>
#else
#include <sys/types.h>
#endif

#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR))

Expand Down Expand Up @@ -252,6 +258,7 @@ extern void stack_protections(unsigned long address);
extern int raw(int fd);
extern void setup_machinename(char *machine_out);
extern void setup_hostinfo(char *buf, int len);
extern ssize_t os_getrandom(void *buf, size_t len, unsigned int flags);
extern void os_dump_core(void) __attribute__ ((noreturn));
extern void um_early_printk(const char *s, unsigned int n);
extern void os_fix_helper_signals(void);
Expand Down
8 changes: 8 additions & 0 deletions arch/um/kernel/um_arch.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <linux/sched/task.h>
#include <linux/kmsg_dump.h>
#include <linux/suspend.h>
#include <linux/random.h>

#include <asm/processor.h>
#include <asm/cpufeature.h>
Expand Down Expand Up @@ -404,6 +405,8 @@ int __init __weak read_initrd(void)

void __init setup_arch(char **cmdline_p)
{
u8 rng_seed[32];

stack_protections((unsigned long) &init_thread_info);
setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
mem_total_pages(physmem_size, iomem_size, highmem);
Expand All @@ -413,6 +416,11 @@ void __init setup_arch(char **cmdline_p)
strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
*cmdline_p = command_line;
setup_hostinfo(host_info, sizeof host_info);

if (os_getrandom(rng_seed, sizeof(rng_seed), 0) == sizeof(rng_seed)) {
add_bootloader_randomness(rng_seed, sizeof(rng_seed));
memzero_explicit(rng_seed, sizeof(rng_seed));
}
}

void __init check_bugs(void)
Expand Down
6 changes: 6 additions & 0 deletions arch/um/os-Linux/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <sys/wait.h>
#include <sys/mman.h>
#include <sys/utsname.h>
#include <sys/random.h>
#include <init.h>
#include <os.h>

Expand Down Expand Up @@ -96,6 +97,11 @@ static inline void __attribute__ ((noreturn)) uml_abort(void)
exit(127);
}

ssize_t os_getrandom(void *buf, size_t len, unsigned int flags)
{
return getrandom(buf, len, flags);
}

/*
* UML helper threads must not handle SIGWINCH/INT/TERM
*/
Expand Down

0 comments on commit cac7ead

Please sign in to comment.