From: Frieder Schrempf <[email protected]> The RAUC bootmeth boots a slot by running boot.scr or boot.scr.uimg from its boot partition. Nothing authenticates this partition, so with verified boot, whoever can write it can run any U-Boot command, for example booting an unsigned kernel or changing the kernel command line. Signing the script does not close this reliably as source skips all checks if the environment sets verify=no, which RAUC systems must keep writable for BOOT_ORDER and BOOT_x_LEFT, and it accepts a FIT script without configurations, whose signature is then only checked against keys required for images, not configurations.
Add CONFIG_BOOTMETH_RAUC_BOOTCMD to set a command built into U-Boot that boots the slot instead. It sees the same environment variables as the boot script. The boot partition then contains nothing that U-Boot executes, and the code that loads the script is left out of the build. The option is empty by default, which keeps loading the boot script. Assisted-by: LLM Signed-off-by: Frieder Schrempf <[email protected]> --- boot/Kconfig | 16 ++++++++++++++++ boot/bootmeth_rauc.c | 21 ++++++++++++++------- doc/develop/bootstd/rauc.rst | 8 ++++++++ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/boot/Kconfig b/boot/Kconfig index 5f89c9d86fa..b17f735937a 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -981,6 +981,22 @@ config BOOTMETH_RAUC_PART_NAMES names. Partition names are only available on GPT, so this rejects MBR devices. Leave this empty to not check the names. +config BOOTMETH_RAUC_BOOTCMD + string "RAUC built-in boot command" + default "" + help + Sets a command to boot the selected slot, for example + "run distro_boot_rauc". It is run instead of loading a boot script + from the slot's boot partition, and can use the same environment + variables as the boot script, such as distro_bootpart and raucargs. + + As the command is built into U-Boot, the boot partition does not + need to contain anything U-Boot executes, which helps with verified + boot. If the command runs an environment variable, that variable must + not be writable at runtime then, see ENV_WRITEABLE_LIST. + + Leave this empty to load the boot script. + config BOOTMETH_RAUC_DEFAULT_TRIES int "RAUC slot default tries" default 3 diff --git a/boot/bootmeth_rauc.c b/boot/bootmeth_rauc.c index ff2e2d48145..dca11500190 100644 --- a/boot/bootmeth_rauc.c +++ b/boot/bootmeth_rauc.c @@ -528,10 +528,12 @@ static int distro_rauc_boot(struct udevice *dev, struct bootflow *bflow) if (ret) return log_msg_ret("env", ret); - /* Load distro boot script */ - ret = distro_rauc_load_boot_script(bflow, slot); - if (ret) - return log_msg_ret("load", ret); + /* Load distro boot script, unless a built-in command boots the slot */ + if (!CONFIG_BOOTMETH_RAUC_BOOTCMD[0]) { + ret = distro_rauc_load_boot_script(bflow, slot); + if (ret) + return log_msg_ret("load", ret); + } log_info("INFO: Booting slot %s, %lu of %d tries left\n", slot->name, active_slot_tries, CONFIG_BOOTMETH_RAUC_DEFAULT_TRIES); @@ -552,9 +554,14 @@ static int distro_rauc_boot(struct udevice *dev, struct bootflow *bflow) } str_free_list(boot_order_list); - /* Run distro boot script */ - addr = map_to_sysmem(bflow->buf); - ret = cmd_source_script(addr, NULL, NULL); + if (CONFIG_BOOTMETH_RAUC_BOOTCMD[0]) { + /* Run built-in boot command */ + ret = run_command(CONFIG_BOOTMETH_RAUC_BOOTCMD, 0); + } else { + /* Run distro boot script */ + addr = map_to_sysmem(bflow->buf); + ret = cmd_source_script(addr, NULL, NULL); + } if (ret) return log_msg_ret("boot", ret); diff --git a/doc/develop/bootstd/rauc.rst b/doc/develop/bootstd/rauc.rst index dfbe010a60f..f4e7e02f37f 100644 --- a/doc/develop/bootstd/rauc.rst +++ b/doc/develop/bootstd/rauc.rst @@ -44,6 +44,13 @@ The boot script must be located in each boot partition. The bootmeth searches for ``boot.scr`` first, then ``boot.scr.uimg`` if not found. It will search in all directories of the bootstd list of prefixes (``"/", "/boot"`` by default). +Alternatively, ``CONFIG_BOOTMETH_RAUC_BOOTCMD`` sets a command built into +U-Boot, for example ``run distro_boot_rauc``, which boots the slot instead of a +boot script. The boot partitions then need no boot script, and the bootmeth +executes nothing from them. For verified boot, the command must load only +signed images, and any environment variable it runs must not be writable at +runtime (see ``CONFIG_ENV_WRITEABLE_LIST``). + When the bootflow is booted, the bootmeth sets these environment variables: devtype @@ -63,6 +70,7 @@ raucargs kernel command line arguments needed for RAUC to detect the currently booted slot +The boot script or the boot command can use these variables to boot the slot. The script file must be a FIT or a legacy uImage. It is loaded into memory and executed. -- 2.56.0
