From: Johannes Schneider <johannes.schneider@leica-geosystems.com>
To: barebox@lists.infradead.org
Cc: Marco Felsch <m.felsch@pengutronix.de>,
Johannes Schneider <johannes.schneider@leica-geosystems.com>
Subject: [PATCH v1 14/14] efi: loader: bootm: apply overlays carried by a UKI
Date: Sun, 4 Oct 2026 01:19:47 +0000 [thread overview]
Message-ID: <20261004011958.3255011-15-johannes.schneider@leica-geosystems.com> (raw)
In-Reply-To: <20261004011958.3255011-1-johannes.schneider@leica-geosystems.com>
A UKI has no place for the overlays a FIT image carries next to its
devicetrees, and systemd-stub knows nothing about overlays. Carry them
in a ".bbdtbo" PE section, covered by the image's Authenticode
signature: a devicetree whose child nodes each hold one overlay in a
"data" property, named like the overlay file.
Unpack them to /tmp/efi-overlays and point global.of.overlay.path there
while the payload runs, so EFI_DT_FIXUP_PROTOCOL applies them to the
devicetree systemd-stub installs, filtered by global.of.overlay.filter
and pattern like overlays from a FIT image. Without such a section the
path is empty for that time, as it may point at the boot partition,
which now holds the UKI. The previous value is restored when the payload
returns.
Refuse a UKI whose overlay section cannot be unpacked, which would
otherwise boot without the hardware its overlays describe.
Only with CONFIG_OFTREE, which EFI_DT_FIXUP_PROTOCOL depends on.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Johannes Schneider <johannes.schneider@leica-geosystems.com>
---
efi/loader/bootm.c | 86 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 85 insertions(+), 1 deletion(-)
diff --git a/efi/loader/bootm.c b/efi/loader/bootm.c
index 47f7a3d1e2..71c61935b1 100644
--- a/efi/loader/bootm.c
+++ b/efi/loader/bootm.c
@@ -37,6 +37,7 @@
#include <efi/devicepath.h>
#include <efi/loader/authenticode.h>
#include <efi/loader/pe.h>
+#include <globalvar.h>
#include <loadable.h>
#include <of.h>
#include <barebox-info.h>
@@ -223,6 +224,62 @@ static int efi_loader_verify(struct image_data *data, void *efi, size_t size)
return 0;
}
+#define EFI_UKI_OVERLAY_SECTION ".bbdtbo"
+#define EFI_UKI_OVERLAY_DIR "/tmp/efi-overlays"
+
+/*
+ * The overlay section is a devicetree whose child nodes each hold one overlay
+ * in a "data" property, named like the overlay file
+ */
+static int efi_uki_unpack_overlays(void *efi, size_t size)
+{
+ struct device_node *root, *np;
+ const void *blob, *ovl;
+ char *path;
+ size_t len;
+ int ovl_len, n = 0, ret = 0;
+
+ blob = efi_pe_find_section(efi, size, EFI_UKI_OVERLAY_SECTION, &len);
+ if (!blob)
+ return 0;
+
+ root = of_unflatten_dtb(blob, len);
+ if (IS_ERR(root))
+ return PTR_ERR(root);
+
+ unlink_recursive(EFI_UKI_OVERLAY_DIR, NULL);
+ ret = make_directory(EFI_UKI_OVERLAY_DIR);
+ if (ret)
+ goto out;
+
+ for_each_child_of_node(root, np) {
+ ovl = of_get_property(np, "data", &ovl_len);
+ if (!ovl)
+ continue;
+
+ path = basprintf(EFI_UKI_OVERLAY_DIR "/%s", np->name);
+ ret = write_file(path, ovl, ovl_len);
+ free(path);
+ if (ret)
+ goto out;
+ n++;
+ }
+
+ pr_info("unpacked %d overlay(s) to %s\n", n, EFI_UKI_OVERLAY_DIR);
+ ret = n;
+out:
+ of_delete_node(root);
+ return ret;
+}
+
+static bool efi_image_brings_devicetree(void *efi, size_t size)
+{
+ size_t len;
+
+ return efi_pe_find_section(efi, size, ".dtbauto", &len) ||
+ efi_pe_find_section(efi, size, ".dtb", &len);
+}
+
static const char *efi_machine_compatible(void)
{
const char *compat = barebox_get_of_machine_compatible();
@@ -361,8 +418,9 @@ static int efi_loader_bootm(struct image_data *data)
void *fdt;
int flags = 0;
size_t size, section_size;
+ char *overlay_path = NULL;
const char *compat;
- bool match;
+ bool match, uki;
memory_bank_first_find_space(&start, &end);
@@ -384,6 +442,11 @@ static int efi_loader_bootm(struct image_data *data)
match = IS_ENABLED(CONFIG_OFTREE) && compat &&
efi_uki_has_dtbauto_for((void *)os_res->start, size, compat);
+ uki = IS_ENABLED(CONFIG_OFTREE) &&
+ efi_image_brings_devicetree((void *)os_res->start, size);
+ if (uki)
+ overlay_path = xstrdup(getenv("global.of.overlay.path") ?: "");
+
/* systemd-stub passes the load options on as kernel command line */
if (filetype_is_linux_efi_image(data->kernel_type) ||
efi_pe_find_section((void *)os_res->start, size, ".linux",
@@ -432,6 +495,18 @@ static int efi_loader_bootm(struct image_data *data)
goto out;
}
+ if (uki) {
+ int n = efi_uki_unpack_overlays((void *)os_res->start, size);
+
+ if (n < 0) {
+ pr_err("cannot unpack the UKI overlays: %pe\n", ERR_PTR(n));
+ ret = n;
+ goto out;
+ }
+
+ globalvar_set("of.overlay.path", n ? EFI_UKI_OVERLAY_DIR : "");
+ }
+
efiret = efi_install_initrd(data, os_res->end + 1);
if(efiret != EFI_SUCCESS)
goto out;
@@ -502,9 +577,18 @@ static int efi_loader_bootm(struct image_data *data)
/* Control is returned to us, disable EFI watchdog */
efi_set_watchdog(0);
+ if (overlay_path) {
+ globalvar_set("of.overlay.path", overlay_path);
+ free(overlay_path);
+ }
+
return -efi_errno(efiret);
out:
+ if (overlay_path) {
+ globalvar_set("of.overlay.path", overlay_path);
+ free(overlay_path);
+ }
efi_initrd_unregister();
efi_install_configuration_table(&efi_fdt_guid, NULL);
efi_free_pool(file_path);
--
2.43.0
prev parent reply other threads:[~2026-10-04 1:25 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-04 1:19 [PATCH v1 00/14] efi: loader: boot Authenticode-signed UKIs Johannes Schneider
2026-10-04 1:19 ` [PATCH v1 01/14] mfd: hgs-efi: do not claim the name of the EFI loader's device Johannes Schneider
2026-10-04 1:19 ` [PATCH v1 02/14] efi: loader: file: report EFI_UNSUPPORTED for volumes without a filesystem Johannes Schneider
2026-10-04 1:19 ` [PATCH v1 03/14] efi: loader: bootm: free the devicetree after installing it Johannes Schneider
2026-10-04 1:19 ` [PATCH v1 04/14] efi: loader: provide EFI_DT_FIXUP_PROTOCOL Johannes Schneider
2026-10-04 1:19 ` [PATCH v1 05/14] efi: loader: pe: add helpers for the image size and a named section Johannes Schneider
2026-10-04 1:19 ` [PATCH v1 06/14] efi: loader: bootm: load only the PE image, not the whole file Johannes Schneider
2026-10-04 1:19 ` [PATCH v1 07/14] efi: loader: bootm: pass the kernel command line to UKIs Johannes Schneider
2026-10-05 17:18 ` Ahmad Fatoum
2026-10-04 1:19 ` [PATCH v1 08/14] efi: loader: verify Authenticode signatures against built-in keys Johannes Schneider
2026-10-05 5:33 ` Ahmad Fatoum
2026-10-05 5:45 ` SCHNEIDER Johannes
2026-10-09 0:07 ` SCHNEIDER Johannes
2026-10-04 1:19 ` [PATCH v1 09/14] efi: loader: authenticode: add a fuzz test Johannes Schneider
2026-10-04 1:19 ` [PATCH v1 10/14] efi: loader: authenticate LoadImage() images when signing is forced Johannes Schneider
2026-10-04 1:19 ` [PATCH v1 11/14] efi: loader: file: expose no filesystem when signed images are forced Johannes Schneider
2026-10-04 1:19 ` [PATCH v1 12/14] bootm: efi: boot signed EFI images " Johannes Schneider
2026-10-04 1:19 ` [PATCH v1 13/14] efi: loader: bootm: install a devicetree for matching UKI devicetrees Johannes Schneider
2026-10-04 1:19 ` Johannes Schneider [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261004011958.3255011-15-johannes.schneider@leica-geosystems.com \
--to=johannes.schneider@leica-geosystems.com \
--cc=barebox@lists.infradead.org \
--cc=m.felsch@pengutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox