linux-efi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ardb@kernel.org>
To: linux-efi@vger.kernel.org
Cc: Ard Biesheuvel <ardb@kernel.org>,
	Daan De Meyer <daandemeyer@fb.com>,
	Jeremy Linton <jeremy.linton@arm.com>
Subject: [PATCH] efi: zboot: create MemoryMapped() device path for the parent if needed
Date: Thu, 22 Sep 2022 12:12:58 +0200	[thread overview]
Message-ID: <20220922101258.1010763-1-ardb@kernel.org> (raw)

LoadImage() is supposed to install an instance of the protocol
EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL onto the loaded image's handle so
that the program can figure out where it was loaded from. The reference
implementation even does this (with a NULL protocol pointer) if the call
to LoadImage() used the source buffer and size arguments, and passed
NULL for the image device path. Hand rolled implementations of LoadImage
may behave differently, though, and so it is better to tolerate
situations where the protocol is missing. And actually, concatenating an
Offset() node to a NULL device path (as we do currently) is also not
great either.

So in cases where the protocol is absent, or when it points to NULL,
construct a MemoryMapped() device node as the base node that describes
the parent image's footprint in memory.

Cc: Daan De Meyer <daandemeyer@fb.com>
Cc: Jeremy Linton <jeremy.linton@arm.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 drivers/firmware/efi/libstub/zboot.c | 20 ++++++++++++++++----
 include/linux/efi.h                  |  7 +++++++
 2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/efi/libstub/zboot.c b/drivers/firmware/efi/libstub/zboot.c
index a9f41902c908..d65bf942dcd0 100644
--- a/drivers/firmware/efi/libstub/zboot.c
+++ b/drivers/firmware/efi/libstub/zboot.c
@@ -162,6 +162,11 @@ static void append_end_node(efi_device_path_protocol_t **dp)
 asmlinkage efi_status_t __efiapi
 efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
 {
+	struct efi_mem_mapped_dev_path mmdp = {
+		.header.type		= EFI_DEV_HW,
+		.header.sub_type	= EFI_DEV_MEM_MAPPED,
+		.header.length		= sizeof(struct efi_mem_mapped_dev_path),
+	};
 	efi_device_path_protocol_t *parent_dp, *dpp, *lf2_dp, *li_dp;
 	efi_load_file2_protocol_t zboot_load_file2;
 	efi_loaded_image_t *parent, *child;
@@ -191,13 +196,20 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
 	status = efi_bs_call(handle_protocol, handle,
 			     &LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID,
 			     (void **)&parent_dp);
-	if (status != EFI_SUCCESS) {
-		log(L"Failed to locate parent's loaded image device path protocol");
-		return status;
+	if (status != EFI_SUCCESS || parent_dp == NULL) {
+		// Create a MemoryMapped() device path node to describe
+		// the parent image if no device path was provided.
+		mmdp.memory_type	= parent->image_code_type;
+		mmdp.starting_addr	= (unsigned long)parent->image_base;
+		mmdp.ending_addr	= (unsigned long)parent->image_base +
+					  parent->image_size - 1;
+		parent_dp = &mmdp.header;
+		dp_len = sizeof(mmdp);
+	} else {
+		dp_len = device_path_length(parent_dp);
 	}
 
 	// Allocate some pool memory for device path protocol data
-	dp_len = parent_dp ? device_path_length(parent_dp) : 0;
 	status = efi_bs_call(allocate_pool, EFI_LOADER_DATA,
 			     2 * (dp_len + sizeof(struct efi_rel_offset_dev_path) +
 			          sizeof(struct efi_generic_dev_path)) +
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 89f16ec3ebab..da3974bf05d3 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1004,6 +1004,13 @@ struct efi_rel_offset_dev_path {
 	u64				ending_offset;
 } __packed;
 
+struct efi_mem_mapped_dev_path {
+	struct efi_generic_dev_path	header;
+	u32				memory_type;
+	u64				starting_addr;
+	u64				ending_addr;
+} __packed;
+
 struct efi_dev_path {
 	union {
 		struct efi_generic_dev_path	header;
-- 
2.35.1


                 reply	other threads:[~2022-09-22 10:13 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20220922101258.1010763-1-ardb@kernel.org \
    --to=ardb@kernel.org \
    --cc=daandemeyer@fb.com \
    --cc=jeremy.linton@arm.com \
    --cc=linux-efi@vger.kernel.org \
    /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;
as well as URLs for NNTP newsgroup(s).