Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/stand/efiboot Implement rndseed support in efiboot and f...
details: https://anonhg.NetBSD.org/src/rev/26ede2405be6
branches: trunk
changeset: 967703:26ede2405be6
user: riastradh <riastradh%NetBSD.org@localhost>
date: Wed Dec 18 21:46:03 2019 +0000
description:
Implement rndseed support in efiboot and fdt arm.
The EFI environment variable `rndseed' specifies the path to the
random seed. It is loaded only for fdt platforms at the moment.
Since the rndseed (an rndsave_t object as defined in <sys/rndio.h>)
is 536 bytes long (for hysterical raisins), and to avoid having to
erase parts of the fdt tree, we load it into a physical page whose
address is passed in the fdt tree, rather than passing the content of
the file as an fdt node directly; the kernel then reserves the page
from uvm, and maps it into kva to call rnd_seed.
For now, the only kernel that does use efiboot with fdt is evbarm,
which knows to handle the rndseed. Any new kernels that use efiboot
with fdt must do the same; otherwise uvm may hand out the page with
the secret key on it for a normal page allocation in the kernel --
which should be OK if there are no kernel memory disclosure bugs, but
would lead to worse consequences than simply loading the seed late in
userland with /etc/rc.d/random_seed otherwise.
ok jmcneill
diffstat:
sys/arch/evbarm/fdt/fdt_machdep.c | 79 ++++++++++++++++++++++++++++++++++++++-
sys/stand/efiboot/boot.c | 35 ++++++++++++++++-
sys/stand/efiboot/efiboot.h | 4 +-
sys/stand/efiboot/efifdt.c | 24 +++++++++++-
sys/stand/efiboot/efifdt.h | 3 +-
sys/stand/efiboot/exec.c | 16 ++++++-
sys/stand/efiboot/version | 3 +-
7 files changed, 154 insertions(+), 10 deletions(-)
diffs (truncated from 342 to 300 lines):
diff -r d5f807f65aef -r 26ede2405be6 sys/arch/evbarm/fdt/fdt_machdep.c
--- a/sys/arch/evbarm/fdt/fdt_machdep.c Wed Dec 18 21:45:43 2019 +0000
+++ b/sys/arch/evbarm/fdt/fdt_machdep.c Wed Dec 18 21:46:03 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fdt_machdep.c,v 1.64 2019/07/16 14:41:45 skrll Exp $ */
+/* $NetBSD: fdt_machdep.c,v 1.65 2019/12/18 21:46:03 riastradh Exp $ */
/*-
* Copyright (c) 2015-2017 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.64 2019/07/16 14:41:45 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.65 2019/12/18 21:46:03 riastradh Exp $");
#include "opt_machdep.h"
#include "opt_bootconfig.h"
@@ -64,6 +64,7 @@
#include <sys/disk.h>
#include <sys/md5.h>
#include <sys/pserialize.h>
+#include <sys/rnd.h>
#include <net/if.h>
#include <net/if_dl.h>
@@ -117,6 +118,7 @@
const uint8_t *fdt_addr_r __attribute__((__section__(".data")));
static uint64_t initrd_start, initrd_end;
+static uint64_t rndseed_start, rndseed_end;
#include <libfdt.h>
#include <dev/fdt/fdtvar.h>
@@ -311,6 +313,10 @@
if (initrd_size > 0)
fdt_memory_remove_range(initrd_start, initrd_size);
+ const uint64_t rndseed_size = rndseed_end - rndseed_start;
+ if (rndseed_size > 0)
+ fdt_memory_remove_range(rndseed_start, rndseed_size);
+
const int framebuffer = OF_finddevice("/chosen/framebuffer");
if (framebuffer >= 0) {
for (index = 0;
@@ -390,6 +396,65 @@
#endif
}
+static void
+fdt_probe_rndseed(uint64_t *pstart, uint64_t *pend)
+{
+ int chosen, len;
+ const void *start_data, *end_data;
+
+ *pstart = *pend = 0;
+ chosen = OF_finddevice("/chosen");
+ if (chosen < 0)
+ return;
+
+ start_data = fdtbus_get_prop(chosen, "netbsd,rndseed-start", &len);
+ end_data = fdtbus_get_prop(chosen, "netbsd,rndseed-end", NULL);
+ if (start_data == NULL || end_data == NULL)
+ return;
+
+ switch (len) {
+ case 4:
+ *pstart = be32dec(start_data);
+ *pend = be32dec(end_data);
+ break;
+ case 8:
+ *pstart = be64dec(start_data);
+ *pend = be64dec(end_data);
+ break;
+ default:
+ printf("Unsupported len %d for /chosen/rndseed-start\n", len);
+ return;
+ }
+}
+
+static void
+fdt_setup_rndseed(void)
+{
+ const uint64_t rndseed_size = rndseed_end - rndseed_start;
+ const paddr_t startpa = trunc_page(rndseed_start);
+ const paddr_t endpa = round_page(rndseed_end);
+ paddr_t pa;
+ vaddr_t va;
+ void *rndseed;
+
+ if (rndseed_size == 0)
+ return;
+
+ va = uvm_km_alloc(kernel_map, endpa - startpa, 0,
+ UVM_KMF_VAONLY | UVM_KMF_NOWAIT);
+ if (va == 0) {
+ printf("Failed to allocate VA for rndseed\n");
+ return;
+ }
+ rndseed = (void *)va;
+
+ for (pa = startpa; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE)
+ pmap_kenter_pa(va, pa, VM_PROT_READ|VM_PROT_WRITE, 0);
+ pmap_update(pmap_kernel());
+
+ rnd_seed(rndseed, rndseed_size);
+}
+
#ifdef EFI_RUNTIME
static void
fdt_map_efi_runtime(const char *prop, enum arm_efirt_mem_type type)
@@ -518,6 +583,9 @@
/* Parse ramdisk info */
fdt_probe_initrd(&initrd_start, &initrd_end);
+ /* Parse rndseed */
+ fdt_probe_rndseed(&rndseed_start, &rndseed_end);
+
/*
* Populate bootconfig structure for the benefit of
* dodumpsys
@@ -629,6 +697,13 @@
}
void
+cpu_startup_hook(void)
+{
+
+ fdt_setup_rndseed();
+}
+
+void
delay(u_int us)
{
const struct arm_platform *plat = arm_fdt_platform();
diff -r d5f807f65aef -r 26ede2405be6 sys/stand/efiboot/boot.c
--- a/sys/stand/efiboot/boot.c Wed Dec 18 21:45:43 2019 +0000
+++ b/sys/stand/efiboot/boot.c Wed Dec 18 21:46:03 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: boot.c,v 1.18 2019/04/21 22:30:41 thorpej Exp $ */
+/* $NetBSD: boot.c,v 1.19 2019/12/18 21:46:03 riastradh Exp $ */
/*-
* Copyright (c) 2016 Kimihiro Nonaka <nonaka%netbsd.org@localhost>
@@ -75,6 +75,7 @@
static char efibootplist_path[255];
static char netbsd_path[255];
static char netbsd_args[255];
+static char rndseed_path[255];
#define DEFTIMEOUT 5
#define DEFFILENAME names[0]
@@ -87,6 +88,7 @@
void command_dtb(char *);
void command_plist(char *);
void command_initrd(char *);
+void command_rndseed(char *);
void command_ls(char *);
void command_mem(char *);
void command_printenv(char *);
@@ -103,6 +105,7 @@
{ "dtb", command_dtb, "dtb [dev:][filename]" },
{ "plist", command_plist, "plist [dev:][filename]" },
{ "initrd", command_initrd, "initrd [dev:][filename]" },
+ { "rndseed", command_rndseed, "rndseed [dev:][filename]" },
{ "ls", command_ls, "ls [hdNn:/path]" },
{ "mem", command_mem, "mem" },
{ "printenv", command_printenv, "printenv [key]" },
@@ -182,6 +185,12 @@
}
void
+command_rndseed(char *arg)
+{
+ set_rndseed_path(arg);
+}
+
+void
command_ls(char *arg)
{
ls(arg);
@@ -348,6 +357,21 @@
}
int
+set_rndseed_path(const char *arg)
+{
+ if (strlen(arg) + 1 > sizeof(rndseed_path))
+ return ERANGE;
+ strcpy(rndseed_path, arg);
+ return 0;
+}
+
+char *
+get_rndseed_path(void)
+{
+ return rndseed_path;
+}
+
+int
set_bootfile(const char *arg)
{
if (strlen(arg) + 1 > sizeof(netbsd_path))
@@ -437,6 +461,15 @@
set_bootargs(s);
FreePool(s);
}
+
+ s = efi_env_get("rndseed");
+ if (s) {
+#ifdef EFIBOOT_DEBUG
+ printf(">> Setting rndseed path to '%s' from environment\n", s);
+#endif
+ set_rndseed_path(s);
+ FreePool(s);
+ }
}
void
diff -r d5f807f65aef -r 26ede2405be6 sys/stand/efiboot/efiboot.h
--- a/sys/stand/efiboot/efiboot.h Wed Dec 18 21:45:43 2019 +0000
+++ b/sys/stand/efiboot/efiboot.h Wed Dec 18 21:46:03 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: efiboot.h,v 1.10 2019/04/21 22:30:41 thorpej Exp $ */
+/* $NetBSD: efiboot.h,v 1.11 2019/12/18 21:46:03 riastradh Exp $ */
/*-
* Copyright (c) 2016 Kimihiro Nonaka <nonaka%netbsd.org@localhost>
@@ -64,6 +64,8 @@
char *get_dtb_path(void);
int set_efibootplist_path(const char *);
char *get_efibootplist_path(void);
+int set_rndseed_path(const char *);
+char *get_rndseed_path(void);
/* console.c */
int ischar(void);
diff -r d5f807f65aef -r 26ede2405be6 sys/stand/efiboot/efifdt.c
--- a/sys/stand/efiboot/efifdt.c Wed Dec 18 21:45:43 2019 +0000
+++ b/sys/stand/efiboot/efifdt.c Wed Dec 18 21:46:03 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: efifdt.c,v 1.19 2019/08/30 00:01:33 jmcneill Exp $ */
+/* $NetBSD: efifdt.c,v 1.20 2019/12/18 21:46:03 riastradh Exp $ */
/*-
* Copyright (c) 2019 Jason R. Thorpe
@@ -383,3 +383,25 @@
fdt_setprop_u64(fdt_data, chosen, "linux,initrd-start", initrd_addr);
fdt_setprop_u64(fdt_data, chosen, "linux,initrd-end", initrd_addr + initrd_size);
}
+
+void
+efi_fdt_rndseed(u_long rndseed_addr, u_long rndseed_size)
+{
+ int chosen;
+
+ if (rndseed_size == 0)
+ return;
+
+ chosen = fdt_path_offset(fdt_data, FDT_CHOSEN_NODE_PATH);
+ if (chosen < 0)
+ chosen = fdt_add_subnode(fdt_data,
+ fdt_path_offset(fdt_data, "/"),
+ FDT_CHOSEN_NODE_NAME);
+ if (chosen < 0)
+ panic("FDT: Failed to create " FDT_CHOSEN_NODE_PATH " node");
+
+ fdt_setprop_u64(fdt_data, chosen, "netbsd,rndseed-start",
+ rndseed_addr);
+ fdt_setprop_u64(fdt_data, chosen, "netbsd,rndseed-end",
+ rndseed_addr + rndseed_size);
+}
diff -r d5f807f65aef -r 26ede2405be6 sys/stand/efiboot/efifdt.h
--- a/sys/stand/efiboot/efifdt.h Wed Dec 18 21:45:43 2019 +0000
+++ b/sys/stand/efiboot/efifdt.h Wed Dec 18 21:46:03 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: efifdt.h,v 1.6 2019/07/24 11:40:36 jmcneill Exp $ */
+/* $NetBSD: efifdt.h,v 1.7 2019/12/18 21:46:03 riastradh Exp $ */
/*-
* Copyright (c) 2018 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -37,5 +37,6 @@
void efi_fdt_show(void);
void efi_fdt_bootargs(const char *);
void efi_fdt_initrd(u_long, u_long);
+void efi_fdt_rndseed(u_long, u_long);
void efi_fdt_init(u_long, u_long);
void efi_fdt_fini(void);
diff -r d5f807f65aef -r 26ede2405be6 sys/stand/efiboot/exec.c
--- a/sys/stand/efiboot/exec.c Wed Dec 18 21:45:43 2019 +0000
+++ b/sys/stand/efiboot/exec.c Wed Dec 18 21:46:03 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: exec.c,v 1.11 2019/07/24 11:40:36 jmcneill Exp $ */
+/* $NetBSD: exec.c,v 1.12 2019/12/18 21:46:03 riastradh Exp $ */
/*-
* Copyright (c) 2019 Jason R. Thorpe
@@ -39,8 +39,8 @@
#define FDT_SPACE (4 * 1024 * 1024)
#define FDT_ALIGN ((2 * 1024 * 1024) - 1)
Home |
Main Index |
Thread Index |
Old Index