[PATCH] [v3] add kaslr-seed generation to extlinux.conf

1, add kaslrseed key word to extlinux.conf 2, check kaslrseed in extlinux boot label 3, generate ramdon number from hw rng 4, add kaslr-seed to fdt chosen
with this patch exlinux.conf boot item looks like
label l0 menu testing linux /boot/vmlinuz-5.15.16-arm initrd /boot/initramfs-5.15.16-arm.img fdtdir /boot/dtbs/5.15.16-arm/ kaslrseed append root=UUID=92ae1e50-eeeb-4c5b-8939-7e1cd6cfb059 ro
Signed-off-by: Zhang Ning zhangn1985@qq.com --- boot/pxe_utils.c | 75 +++++++++++++++++++++++++++++++++++++++++++++ include/pxe_utils.h | 2 ++ 2 files changed, 77 insertions(+)
diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c index bb231b11a2..0c24becae3 100644 --- a/boot/pxe_utils.c +++ b/boot/pxe_utils.c @@ -20,6 +20,11 @@ #include <errno.h> #include <linux/list.h>
+#ifdef CONFIG_DM_RNG +#include <dm.h> +#include <rng.h> +#endif + #include <splash.h> #include <asm/io.h>
@@ -311,6 +316,67 @@ static int label_localboot(struct pxe_label *label) return run_command_list(localcmd, strlen(localcmd), 0); }
+/* + * label_boot_kaslrseed generate kaslrseed from hw rng + */ + +static void label_boot_kaslrseed(void) +{ +#ifdef CONFIG_DM_RNG + ulong fdt_addr; + struct fdt_header *working_fdt; + size_t n = 0x8; + struct udevice *dev; + u64 *buf; + int nodeoffset; + int err; + + /* Get the main fdt and map it */ + fdt_addr = hextoul(env_get("fdt_addr_r"), NULL); + working_fdt = map_sysmem(fdt_addr, 0); + err = fdt_check_header(working_fdt); + if (err) + return; + + /* add extra size for holding kaslr-seed */ + /* err is new fdt size, 0 or negtive */ + err = fdt_shrink_to_minimum(working_fdt, 512); + if (err <= 0) + return; + + if (uclass_get_device(UCLASS_RNG, 0, &dev) || !dev) { + printf("No RNG device\n"); + return; + } + + nodeoffset = fdt_find_or_add_subnode(working_fdt, 0, "chosen"); + if (nodeoffset < 0) { + printf("Reading chosen node failed\n"); + return; + } + + buf = malloc(n); + if (!buf) { + printf("Out of memory\n"); + return; + } + + if (dm_rng_read(dev, buf, n)) { + printf("Reading RNG failed\n"); + goto err; + } + + err = fdt_setprop(working_fdt, nodeoffset, "kaslr-seed", buf, sizeof(buf)); + if (err < 0) { + printf("Unable to set kaslr-seed on chosen node: %s\n", fdt_strerror(err)); + goto err; + } +err: + free(buf); +#endif + return; +} + /** * label_boot_fdtoverlay() - Loads fdt overlays specified in 'fdtoverlays' * @@ -631,6 +697,9 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label) } }
+ if (label->kaslrseed) + label_boot_kaslrseed(); + #ifdef CONFIG_OF_LIBFDT_OVERLAY if (label->fdtoverlays) label_boot_fdtoverlay(ctx, label); @@ -710,6 +779,7 @@ enum token_type { T_ONTIMEOUT, T_IPAPPEND, T_BACKGROUND, + T_KASLRSEED, T_INVALID };
@@ -741,6 +811,7 @@ static const struct token keywords[] = { {"ontimeout", T_ONTIMEOUT,}, {"ipappend", T_IPAPPEND,}, {"background", T_BACKGROUND,}, + {"kaslrseed", T_KASLRSEED,}, {NULL, T_INVALID} };
@@ -1194,6 +1265,10 @@ static int parse_label(char **c, struct pxe_menu *cfg) err = parse_integer(c, &label->ipappend); break;
+ case T_KASLRSEED: + label->kaslrseed = 1; + break; + case T_EOL: break;
diff --git a/include/pxe_utils.h b/include/pxe_utils.h index dad2668818..4a73b2aace 100644 --- a/include/pxe_utils.h +++ b/include/pxe_utils.h @@ -33,6 +33,7 @@ * initrd - path to the initrd to use for this label. * attempted - 0 if we haven't tried to boot this label, 1 if we have. * localboot - 1 if this label specified 'localboot', 0 otherwise. + * kaslrseed - 1 if generate kaslrseed from hw_rng * list - lets these form a list, which a pxe_menu struct will hold. */ struct pxe_label { @@ -50,6 +51,7 @@ struct pxe_label { int attempted; int localboot; int localboot_val; + int kaslrseed; struct list_head list; };

Tested on Khadas VIM, with kernel 5.16.0-rc5-arm64, Debian 11
Here is kernel log near KALSR:
Jul 14 01:29:24 VIM kernel: devtmpfs: initialized Jul 14 01:29:24 VIM kernel: Registered cp15_barrier emulation handler Jul 14 01:29:24 VIM kernel: Registered setend emulation handler Jul 14 01:29:24 VIM kernel: KASLR enabled Jul 14 01:29:24 VIM kernel: clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns Jul 14 01:29:24 VIM kernel: futex hash table entries: 1024 (order: 4, 65536 bytes, linear) Jul 14 01:29:24 VIM kernel: pinctrl core: initialized pinctrl subsystem
Dear u-boot maintainers, this patch is ready for review, thank you.
On Mon, Jan 31, 2022 at 10:41:05PM +0800, Zhang Ning wrote:
1, add kaslrseed key word to extlinux.conf 2, check kaslrseed in extlinux boot label 3, generate ramdon number from hw rng 4, add kaslr-seed to fdt chosen
with this patch exlinux.conf boot item looks like
label l0 menu testing linux /boot/vmlinuz-5.15.16-arm initrd /boot/initramfs-5.15.16-arm.img fdtdir /boot/dtbs/5.15.16-arm/ kaslrseed append root=UUID=92ae1e50-eeeb-4c5b-8939-7e1cd6cfb059 ro
Signed-off-by: Zhang Ning zhangn1985@qq.com
boot/pxe_utils.c | 75 +++++++++++++++++++++++++++++++++++++++++++++ include/pxe_utils.h | 2 ++ 2 files changed, 77 insertions(+)
diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c index bb231b11a2..0c24becae3 100644 --- a/boot/pxe_utils.c +++ b/boot/pxe_utils.c @@ -20,6 +20,11 @@ #include <errno.h> #include <linux/list.h>
+#ifdef CONFIG_DM_RNG +#include <dm.h> +#include <rng.h> +#endif
#include <splash.h> #include <asm/io.h>
@@ -311,6 +316,67 @@ static int label_localboot(struct pxe_label *label) return run_command_list(localcmd, strlen(localcmd), 0); }
+/*
- label_boot_kaslrseed generate kaslrseed from hw rng
- */
+static void label_boot_kaslrseed(void) +{ +#ifdef CONFIG_DM_RNG
- ulong fdt_addr;
- struct fdt_header *working_fdt;
- size_t n = 0x8;
- struct udevice *dev;
- u64 *buf;
- int nodeoffset;
- int err;
- /* Get the main fdt and map it */
- fdt_addr = hextoul(env_get("fdt_addr_r"), NULL);
- working_fdt = map_sysmem(fdt_addr, 0);
- err = fdt_check_header(working_fdt);
- if (err)
return;
- /* add extra size for holding kaslr-seed */
- /* err is new fdt size, 0 or negtive */
- err = fdt_shrink_to_minimum(working_fdt, 512);
- if (err <= 0)
return;
- if (uclass_get_device(UCLASS_RNG, 0, &dev) || !dev) {
printf("No RNG device\n");
return;
- }
- nodeoffset = fdt_find_or_add_subnode(working_fdt, 0, "chosen");
- if (nodeoffset < 0) {
printf("Reading chosen node failed\n");
return;
- }
- buf = malloc(n);
- if (!buf) {
printf("Out of memory\n");
return;
- }
- if (dm_rng_read(dev, buf, n)) {
printf("Reading RNG failed\n");
goto err;
- }
- err = fdt_setprop(working_fdt, nodeoffset, "kaslr-seed", buf, sizeof(buf));
- if (err < 0) {
printf("Unable to set kaslr-seed on chosen node: %s\n", fdt_strerror(err));
goto err;
- }
+err:
- free(buf);
+#endif
- return;
+}
/**
- label_boot_fdtoverlay() - Loads fdt overlays specified in 'fdtoverlays'
@@ -631,6 +697,9 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label) } }
if (label->kaslrseed)
label_boot_kaslrseed();
#ifdef CONFIG_OF_LIBFDT_OVERLAY if (label->fdtoverlays) label_boot_fdtoverlay(ctx, label); @@ -710,6 +779,7 @@ enum token_type { T_ONTIMEOUT, T_IPAPPEND, T_BACKGROUND,
- T_KASLRSEED, T_INVALID
};
@@ -741,6 +811,7 @@ static const struct token keywords[] = { {"ontimeout", T_ONTIMEOUT,}, {"ipappend", T_IPAPPEND,}, {"background", T_BACKGROUND,},
- {"kaslrseed", T_KASLRSEED,}, {NULL, T_INVALID}
};
@@ -1194,6 +1265,10 @@ static int parse_label(char **c, struct pxe_menu *cfg) err = parse_integer(c, &label->ipappend); break;
case T_KASLRSEED:
label->kaslrseed = 1;
break;
- case T_EOL: break;
diff --git a/include/pxe_utils.h b/include/pxe_utils.h index dad2668818..4a73b2aace 100644 --- a/include/pxe_utils.h +++ b/include/pxe_utils.h @@ -33,6 +33,7 @@
- initrd - path to the initrd to use for this label.
- attempted - 0 if we haven't tried to boot this label, 1 if we have.
- localboot - 1 if this label specified 'localboot', 0 otherwise.
*/
- kaslrseed - 1 if generate kaslrseed from hw_rng
- list - lets these form a list, which a pxe_menu struct will hold.
struct pxe_label { @@ -50,6 +51,7 @@ struct pxe_label { int attempted; int localboot; int localboot_val;
- int kaslrseed; struct list_head list;
};
-- 2.34.1

On Mon, Jan 31, 2022 at 10:41:05PM +0800, Zhang Ning wrote:
1, add kaslrseed key word to extlinux.conf 2, check kaslrseed in extlinux boot label 3, generate ramdon number from hw rng 4, add kaslr-seed to fdt chosen
with this patch exlinux.conf boot item looks like
label l0 menu testing linux /boot/vmlinuz-5.15.16-arm initrd /boot/initramfs-5.15.16-arm.img fdtdir /boot/dtbs/5.15.16-arm/ kaslrseed append root=UUID=92ae1e50-eeeb-4c5b-8939-7e1cd6cfb059 ro
Signed-off-by: Zhang Ning zhangn1985@qq.com
So extlinux.conf support is https://systemd.io/BOOT_LOADER_SPECIFICATION/ so please work with upstream there as well to get kaslrseed added and documented. Thanks!

Hi, On Mon, Jan 31, 2022 at 09:53:43AM -0500, Tom Rini wrote:
On Mon, Jan 31, 2022 at 10:41:05PM +0800, Zhang Ning wrote:
1, add kaslrseed key word to extlinux.conf 2, check kaslrseed in extlinux boot label 3, generate ramdon number from hw rng 4, add kaslr-seed to fdt chosen
with this patch exlinux.conf boot item looks like
label l0 menu testing linux /boot/vmlinuz-5.15.16-arm initrd /boot/initramfs-5.15.16-arm.img fdtdir /boot/dtbs/5.15.16-arm/ kaslrseed append root=UUID=92ae1e50-eeeb-4c5b-8939-7e1cd6cfb059 ro
Signed-off-by: Zhang Ning zhangn1985@qq.com
So extlinux.conf support is https://systemd.io/BOOT_LOADER_SPECIFICATION/ so please work with upstream there as well to get kaslrseed added and documented. Thanks!
thank to remind document, but it not systemd.
just find a similor review: https://lists.denx.de/pipermail/u-boot/2021-October/464512.html I will send next version and add document to doc/README.pxe and also update patch title
-- Tom
participants (2)
-
Tom Rini
-
Zhang Ning