All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 0/5] efi: Unified Xen hypervisor/kernel/initrd images
@ 2020-09-21 11:51 Trammell Hudson
  2020-09-21 11:51 ` [PATCH v6 1/5] efi/boot.c: Make file->ptr const void* Trammell Hudson
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Trammell Hudson @ 2020-09-21 11:51 UTC (permalink / raw)
  To: xen-devel; +Cc: roger.pau, jbeulich, andrew.cooper3, wl

This patch series adds support for bundling the xen.efi hypervisor,
the xen.cfg configuration file, the Linux kernel and initrd, as well
as the XSM, and architectural specific files into a single "unified"
EFI executable.  This allows an administrator to update the components
independently without requiring rebuilding xen, as well as to replace
the components in an existing image.

The resulting EFI executable can be invoked directly from the UEFI Boot
Manager, removing the need to use a separate loader like grub as well
as removing dependencies on local filesystem access.  And since it is
a single file, it can be signed and validated by UEFI Secure Boot without
requring the shim protocol.

It is inspired by systemd-boot's unified kernel technique and borrows the
function to locate PE sections from systemd's LGPL'ed code.  During EFI
boot, Xen looks at its own loaded image to locate the PE sections for
the Xen configuration (`.config`), dom0 kernel (`.kernel`), dom0 initrd
(`.ramdisk`), and XSM config (`.xsm`), which are included after building
xen.efi using objcopy to add named sections for each input file.

Trammell Hudson (5):
  efi/boot.c: Make file->ptr const void*
  efi/boot.c: add file.need_to_free
  efi/boot.c: add handle_file_info()
  efi: Enable booting unified hypervisor/kernel/initrd images
  efi: Do not use command line if unified config is included

 .gitignore                  |   1 +
 docs/misc/efi.pandoc        |  49 +++++++++++
 xen/arch/arm/efi/efi-boot.h |  25 ++++--
 xen/arch/x86/efi/Makefile   |   2 +-
 xen/arch/x86/efi/efi-boot.h |  11 ++-
 xen/common/efi/boot.c       | 155 +++++++++++++++++++++++++----------
 xen/common/efi/efi.h        |   3 +
 xen/common/efi/pe.c         | 159 ++++++++++++++++++++++++++++++++++++
 8 files changed, 353 insertions(+), 52 deletions(-)
 create mode 100644 xen/common/efi/pe.c

-- 
2.25.1



^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v6 1/5] efi/boot.c: Make file->ptr const void*
  2020-09-21 11:51 [PATCH v6 0/5] efi: Unified Xen hypervisor/kernel/initrd images Trammell Hudson
@ 2020-09-21 11:51 ` Trammell Hudson
  2020-09-21 11:51 ` [PATCH v6 2/5] efi/boot.c: add file.need_to_free Trammell Hudson
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 13+ messages in thread
From: Trammell Hudson @ 2020-09-21 11:51 UTC (permalink / raw)
  To: xen-devel; +Cc: Jan Beulich, Roger Pau Monné

Other than the config file parser that edits the image inplace,
no other users of the file sections requires write access to the
data.

Signed-off-by: Trammell Hudson <hudson@trmm.net>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
---
 xen/common/efi/boot.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index 0ac80e47bb..157fe0e8c5 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -41,7 +41,7 @@
 
 typedef EFI_STATUS
 (/* _not_ EFIAPI */ *EFI_SHIM_LOCK_VERIFY) (
-    IN VOID *Buffer,
+    IN const VOID *Buffer,
     IN UINT32 Size);
 
 typedef struct {
@@ -104,7 +104,8 @@ struct file {
     UINTN size;
     union {
         EFI_PHYSICAL_ADDRESS addr;
-        void *ptr;
+        char *str;
+        const void *ptr;
     };
 };
 
@@ -592,7 +593,7 @@ static bool __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
             efi_arch_handle_module(file, name, options);
         }
 
-        ret = FileHandle->Read(FileHandle, &file->size, file->ptr);
+        ret = FileHandle->Read(FileHandle, &file->size, file->str);
         if ( !EFI_ERROR(ret) && file->size != size )
             ret = EFI_ABORTED;
         if ( EFI_ERROR(ret) )
@@ -616,7 +617,7 @@ static bool __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
 
 static void __init pre_parse(const struct file *cfg)
 {
-    char *ptr = cfg->ptr, *end = ptr + cfg->size;
+    char *ptr = cfg->str, *end = ptr + cfg->size;
     bool start = true, comment = false;
 
     for ( ; ptr < end; ++ptr )
@@ -645,7 +646,7 @@ static void __init pre_parse(const struct file *cfg)
 static char *__init get_value(const struct file *cfg, const char *section,
                               const char *item)
 {
-    char *ptr = cfg->ptr, *end = ptr + cfg->size;
+    char *ptr = cfg->str, *end = ptr + cfg->size;
     size_t slen = section ? strlen(section) : 0, ilen = strlen(item);
     bool match = !slen;
 
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v6 2/5] efi/boot.c: add file.need_to_free
  2020-09-21 11:51 [PATCH v6 0/5] efi: Unified Xen hypervisor/kernel/initrd images Trammell Hudson
  2020-09-21 11:51 ` [PATCH v6 1/5] efi/boot.c: Make file->ptr const void* Trammell Hudson
@ 2020-09-21 11:51 ` Trammell Hudson
  2020-09-29 10:17   ` Jan Beulich
  2020-09-29 10:45   ` Roger Pau Monné
  2020-09-21 11:51 ` [PATCH v6 3/5] efi/boot.c: add handle_file_info() Trammell Hudson
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 13+ messages in thread
From: Trammell Hudson @ 2020-09-21 11:51 UTC (permalink / raw)
  To: xen-devel; +Cc: Roger Pau Monné

The config file, kernel, initrd, etc should only be freed if they
are allocated with the UEFI allocator.

Signed-off-by: Trammell Hudson <hudson@trmm.net>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
---
 xen/common/efi/boot.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index 157fe0e8c5..c2ce0c7294 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -102,6 +102,7 @@ union string {
 
 struct file {
     UINTN size;
+    bool need_to_free;
     union {
         EFI_PHYSICAL_ADDRESS addr;
         char *str;
@@ -280,13 +281,13 @@ void __init noreturn blexit(const CHAR16 *str)
     if ( !efi_bs )
         efi_arch_halt();
 
-    if ( cfg.addr )
+    if ( cfg.need_to_free )
         efi_bs->FreePages(cfg.addr, PFN_UP(cfg.size));
-    if ( kernel.addr )
+    if ( kernel.need_to_free )
         efi_bs->FreePages(kernel.addr, PFN_UP(kernel.size));
-    if ( ramdisk.addr )
+    if ( ramdisk.need_to_free )
         efi_bs->FreePages(ramdisk.addr, PFN_UP(ramdisk.size));
-    if ( xsm.addr )
+    if ( xsm.need_to_free )
         efi_bs->FreePages(xsm.addr, PFN_UP(xsm.size));
 
     efi_arch_blexit();
@@ -581,6 +582,7 @@ static bool __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
     }
     else
     {
+        file->need_to_free = true;
         file->size = size;
         if ( file != &cfg )
         {
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v6 3/5] efi/boot.c: add handle_file_info()
  2020-09-21 11:51 [PATCH v6 0/5] efi: Unified Xen hypervisor/kernel/initrd images Trammell Hudson
  2020-09-21 11:51 ` [PATCH v6 1/5] efi/boot.c: Make file->ptr const void* Trammell Hudson
  2020-09-21 11:51 ` [PATCH v6 2/5] efi/boot.c: add file.need_to_free Trammell Hudson
@ 2020-09-21 11:51 ` Trammell Hudson
  2020-09-21 11:51 ` [PATCH v6 4/5] efi: Enable booting unified hypervisor/kernel/initrd images Trammell Hudson
  2020-09-21 11:51 ` [PATCH v6 5/5] efi: Do not use command line if unified config is included Trammell Hudson
  4 siblings, 0 replies; 13+ messages in thread
From: Trammell Hudson @ 2020-09-21 11:51 UTC (permalink / raw)
  To: xen-devel; +Cc: Jan Beulich

Add a separate function to display the address ranges used by
the files and call `efi_arch_handle_module()` on the modules.

Signed-off-by: Trammell Hudson <hudson@trmm.net>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/efi/boot.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index c2ce0c7294..93cfeba7e1 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -540,6 +540,22 @@ static char * __init split_string(char *s)
     return NULL;
 }
 
+static void __init handle_file_info(CHAR16 *name,
+                                    const struct file *file, const char *options)
+{
+    if ( file == &cfg )
+        return;
+
+    PrintStr(name);
+    PrintStr(L": ");
+    DisplayUint(file->addr, 2 * sizeof(file->addr));
+    PrintStr(L"-");
+    DisplayUint(file->addr + file->size, 2 * sizeof(file->addr));
+    PrintStr(newline);
+
+    efi_arch_handle_module(file, name, options);
+}
+
 static bool __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
                              struct file *file, const char *options)
 {
@@ -584,16 +600,7 @@ static bool __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
     {
         file->need_to_free = true;
         file->size = size;
-        if ( file != &cfg )
-        {
-            PrintStr(name);
-            PrintStr(L": ");
-            DisplayUint(file->addr, 2 * sizeof(file->addr));
-            PrintStr(L"-");
-            DisplayUint(file->addr + size, 2 * sizeof(file->addr));
-            PrintStr(newline);
-            efi_arch_handle_module(file, name, options);
-        }
+        handle_file_info(name, file, options);
 
         ret = FileHandle->Read(FileHandle, &file->size, file->str);
         if ( !EFI_ERROR(ret) && file->size != size )
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v6 4/5] efi: Enable booting unified hypervisor/kernel/initrd images
  2020-09-21 11:51 [PATCH v6 0/5] efi: Unified Xen hypervisor/kernel/initrd images Trammell Hudson
                   ` (2 preceding siblings ...)
  2020-09-21 11:51 ` [PATCH v6 3/5] efi/boot.c: add handle_file_info() Trammell Hudson
@ 2020-09-21 11:51 ` Trammell Hudson
  2020-09-29 15:37   ` Jan Beulich
  2020-09-21 11:51 ` [PATCH v6 5/5] efi: Do not use command line if unified config is included Trammell Hudson
  4 siblings, 1 reply; 13+ messages in thread
From: Trammell Hudson @ 2020-09-21 11:51 UTC (permalink / raw)
  To: xen-devel; +Cc: Trammell hudson

This patch adds support for bundling the xen.efi hypervisor, the xen.cfg
configuration file, the Linux kernel and initrd, as well as the XSM,
and architectural specific files into a single "unified" EFI executable.
This allows an administrator to update the components independently
without requiring rebuilding xen, as well as to replace the components
in an existing image.

The resulting EFI executable can be invoked directly from the UEFI Boot
Manager, removing the need to use a separate loader like grub as well
as removing dependencies on local filesystem access.  And since it is
a single file, it can be signed and validated by UEFI Secure Boot without
requring the shim protocol.

It is inspired by systemd-boot's unified kernel technique and borrows the
function to locate PE sections from systemd's LGPL'ed code.  During EFI
boot, Xen looks at its own loaded image to locate the PE sections for
the Xen configuration (`.config`), dom0 kernel (`.kernel`), dom0 initrd
(`.ramdisk`), and XSM config (`.xsm`), which are included after building
xen.efi using objcopy to add named sections for each input file.

For x86, the CPU ucode can be included in a section named `.ucode`,
which is loaded in the efi_arch_cfg_file_late() stage of the boot process.

On ARM systems the Device Tree can be included in a section named
`.dtb`, which is loaded during the efi_arch_cfg_file_early() stage of
the boot process.

Note that the system will fall back to loading files from disk if
the named sections do not exist. This allows distributions to continue
with the status quo if they want a signed kernel + config, while still
allowing a user provided initrd (which is how the shim protocol currently
works as well).

This patch also adds constness to the section parameter of
efi_arch_cfg_file_early() and efi_arch_cfg_file_late()
and changes pe_find_section() to use a CHAR16 section name.

Signed-off-by: Trammell hudson <hudson@trmm.net>
---
 .gitignore                  |   1 +
 docs/misc/efi.pandoc        |  49 +++++++++++
 xen/arch/arm/efi/efi-boot.h |  25 ++++--
 xen/arch/x86/efi/Makefile   |   2 +-
 xen/arch/x86/efi/efi-boot.h |  11 ++-
 xen/common/efi/boot.c       |  66 +++++++++++----
 xen/common/efi/efi.h        |   3 +
 xen/common/efi/pe.c         | 159 ++++++++++++++++++++++++++++++++++++
 8 files changed, 287 insertions(+), 29 deletions(-)
 create mode 100644 xen/common/efi/pe.c

diff --git a/.gitignore b/.gitignore
index 823f4743dc..d568017804 100644
--- a/.gitignore
+++ b/.gitignore
@@ -299,6 +299,7 @@ xen/arch/*/efi/boot.c
 xen/arch/*/efi/compat.c
 xen/arch/*/efi/ebmalloc.c
 xen/arch/*/efi/efi.h
+xen/arch/*/efi/pe.c
 xen/arch/*/efi/runtime.c
 xen/common/config_data.S
 xen/common/config.gz
diff --git a/docs/misc/efi.pandoc b/docs/misc/efi.pandoc
index 23c1a2732d..ac3cd58cae 100644
--- a/docs/misc/efi.pandoc
+++ b/docs/misc/efi.pandoc
@@ -116,3 +116,52 @@ Filenames must be specified relative to the location of the EFI binary.
 
 Extra options to be passed to Xen can also be specified on the command line,
 following a `--` separator option.
+
+## Unified Xen kernel image
+
+The "Unified" kernel image can be generated by adding additional
+sections to the Xen EFI executable with objcopy, similar to how
+[systemd-boot uses the stub to add them to the Linux kernel](https://wiki.archlinux.org/index.php/systemd-boot#Preparing_a_unified_kernel_image)
+
+The sections for the xen configuration file, the dom0 kernel, dom0 initrd,
+XSM and CPU microcode should be added after the Xen `.pad` section, the
+ending address of which can be located with:
+
+```
+objdump -h xen.efi \
+	| perl -ane '/\.pad/ && printf "0x%016x\n", hex($F[2]) + hex($F[3])'
+```
+
+For all the examples the `.pad` section ended at 0xffff82d041000000.
+All the sections are optional (`.config`, `.kernel`, `.ramdisk`, `.xsm`,
+`.ucode` (x86) and `.dtb` (ARM)) and the order does not matter.
+The virtual addresses do not need to be contiguous, although they should not
+be overlapping and should all be greater than the last virtual address of the
+hypervisor components.
+
+```
+objcopy \
+	--add-section .config=xen.cfg \
+	--change-section-vma .config=0xffff82d041000000
+	--add-section .ucode=ucode.bin \
+	--change-section-vma .ucode=0xffff82d041010000 \
+	--add-section .xsm=xsm.cfg \
+	--change-section-vma .xsm=0xffff82d041080000 \
+	--add-section .kernel=vmlinux \
+	--change-section-vma .kernel=0xffff82d041100000 \
+	--add-section .ramdisk=initrd.img \
+	--change-section-vma .ramdisk=0xffff82d042000000 \
+	xen.efi \
+	xen.unified.efi
+```
+
+The unified executable can be signed with sbsigntool to make
+it usable with UEFI secure boot:
+
+```
+sbsign \
+	--key signing.key \
+	--cert cert.pem \
+	--output xen.signed.efi \
+	xen.unified.efi
+```
diff --git a/xen/arch/arm/efi/efi-boot.h b/xen/arch/arm/efi/efi-boot.h
index 27dd0b1a94..3653dfeabc 100644
--- a/xen/arch/arm/efi/efi-boot.h
+++ b/xen/arch/arm/efi/efi-boot.h
@@ -375,27 +375,36 @@ static void __init noreturn efi_arch_post_exit_boot(void)
     efi_xen_start(fdt, fdt_totalsize(fdt));
 }
 
-static void __init efi_arch_cfg_file_early(EFI_FILE_HANDLE dir_handle, char *section)
+static void __init efi_arch_cfg_file_early(const EFI_LOADED_IMAGE *image,
+                                           EFI_FILE_HANDLE dir_handle,
+                                           const char *section)
 {
     union string name;
 
     /*
      * The DTB must be processed before any other entries in the configuration
-     * file, as the DTB is updated as modules are loaded.
+     * file, as the DTB is updated as modules are loaded.  Prefer the one
+     * stored as a PE section in a unified image, and fall back to a file
+     * on disk if the section is not present.
      */
-    name.s = get_value(&cfg, section, "dtb");
-    if ( name.s )
+    if ( !read_section(image, L"dtb", &dtbfile, NULL) )
     {
-        split_string(name.s);
-        read_file(dir_handle, s2w(&name), &dtbfile, NULL);
-        efi_bs->FreePool(name.w);
+        name.s = get_value(&cfg, section, "dtb");
+        if ( name.s )
+        {
+            split_string(name.s);
+            read_file(dir_handle, s2w(&name), &dtbfile, NULL);
+            efi_bs->FreePool(name.w);
+        }
     }
     fdt = fdt_increase_size(&dtbfile, cfg.size + EFI_PAGE_SIZE);
     if ( !fdt )
         blexit(L"Unable to create new FDT");
 }
 
-static void __init efi_arch_cfg_file_late(EFI_FILE_HANDLE dir_handle, char *section)
+static void __init efi_arch_cfg_file_late(const EFI_LOADED_IMAGE *image,
+                                          EFI_FILE_HANDLE dir_handle,
+                                          const char *section)
 {
 }
 
diff --git a/xen/arch/x86/efi/Makefile b/xen/arch/x86/efi/Makefile
index 770438a029..e857c0f2cc 100644
--- a/xen/arch/x86/efi/Makefile
+++ b/xen/arch/x86/efi/Makefile
@@ -8,7 +8,7 @@ cmd_objcopy_o_ihex = $(OBJCOPY) -I ihex -O binary $< $@
 
 boot.init.o: buildid.o
 
-EFIOBJ := boot.init.o ebmalloc.o compat.o runtime.o
+EFIOBJ := boot.init.o pe.init.o ebmalloc.o compat.o runtime.o
 
 $(call cc-option-add,cflags-stack-boundary,CC,-mpreferred-stack-boundary=4)
 $(EFIOBJ): CFLAGS-stack-boundary := $(cflags-stack-boundary)
diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
index eef3f52789..d95f7122a0 100644
--- a/xen/arch/x86/efi/efi-boot.h
+++ b/xen/arch/x86/efi/efi-boot.h
@@ -272,14 +272,21 @@ static void __init noreturn efi_arch_post_exit_boot(void)
     unreachable();
 }
 
-static void __init efi_arch_cfg_file_early(EFI_FILE_HANDLE dir_handle, char *section)
+static void __init efi_arch_cfg_file_early(const EFI_LOADED_IMAGE *image,
+                                           EFI_FILE_HANDLE dir_handle,
+                                           const char *section)
 {
 }
 
-static void __init efi_arch_cfg_file_late(EFI_FILE_HANDLE dir_handle, char *section)
+static void __init efi_arch_cfg_file_late(const EFI_LOADED_IMAGE *image,
+                                          EFI_FILE_HANDLE dir_handle,
+                                          const char *section)
 {
     union string name;
 
+    if ( read_section(image, L"ucode", &ucode, NULL) )
+        return;
+
     name.s = get_value(&cfg, section, "ucode");
     if ( !name.s )
         name.s = get_value(&cfg, "global", "ucode");
diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index 93cfeba7e1..dcf939a05e 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -122,6 +122,8 @@ static CHAR16 *s2w(union string *str);
 static char *w2s(const union string *str);
 static bool read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
                       struct file *file, const char *options);
+static bool read_section(const EFI_LOADED_IMAGE *image,
+                         CHAR16 *name, struct file *file, const char *options);
 static size_t wstrlen(const CHAR16 * s);
 static int set_color(u32 mask, int bpp, u8 *pos, u8 *sz);
 static bool match_guid(const EFI_GUID *guid1, const EFI_GUID *guid2);
@@ -624,6 +626,22 @@ static bool __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
     return true;
 }
 
+static bool __init read_section(const EFI_LOADED_IMAGE *image,
+                                CHAR16 *name, struct file *file,
+                                const char *options)
+{
+    file->ptr = pe_find_section(image->ImageBase, image->ImageSize,
+                                name, &file->size);
+    if ( !file->ptr )
+        return false;
+
+    file->need_to_free = false;
+
+    handle_file_info(name, file, options);
+
+    return true;
+}
+
 static void __init pre_parse(const struct file *cfg)
 {
     char *ptr = cfg->str, *end = ptr + cfg->size;
@@ -1208,9 +1226,11 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
         /* Get the file system interface. */
         dir_handle = get_parent_handle(loaded_image, &file_name);
 
-        /* Read and parse the config file. */
-        if ( !cfg_file_name )
+        if ( read_section(loaded_image, L"config", &cfg, NULL) )
+            PrintStr(L"Using builtin config file\r\n");
+        else if ( !cfg_file_name )
         {
+            /* Read and parse the config file. */
             CHAR16 *tail;
 
             while ( (tail = point_tail(file_name)) != NULL )
@@ -1259,29 +1279,39 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
         if ( !name.s )
             blexit(L"No Dom0 kernel image specified.");
 
-        efi_arch_cfg_file_early(dir_handle, section.s);
+        efi_arch_cfg_file_early(loaded_image, dir_handle, section.s);
 
         option_str = split_string(name.s);
-        read_file(dir_handle, s2w(&name), &kernel, option_str);
-        efi_bs->FreePool(name.w);
-
-        if ( !EFI_ERROR(efi_bs->LocateProtocol(&shim_lock_guid, NULL,
-                        (void **)&shim_lock)) &&
-             (status = shim_lock->Verify(kernel.ptr, kernel.size)) != EFI_SUCCESS )
-            PrintErrMesg(L"Dom0 kernel image could not be verified", status);
 
-        name.s = get_value(&cfg, section.s, "ramdisk");
-        if ( name.s )
+        if ( !read_section(loaded_image, L"kernel", &kernel, option_str) )
         {
-            read_file(dir_handle, s2w(&name), &ramdisk, NULL);
+            read_file(dir_handle, s2w(&name), &kernel, option_str);
             efi_bs->FreePool(name.w);
+
+            if ( !EFI_ERROR(efi_bs->LocateProtocol(&shim_lock_guid, NULL,
+                            (void **)&shim_lock)) &&
+                 (status = shim_lock->Verify(kernel.ptr, kernel.size)) != EFI_SUCCESS )
+                PrintErrMesg(L"Dom0 kernel image could not be verified", status);
         }
 
-        name.s = get_value(&cfg, section.s, "xsm");
-        if ( name.s )
+        if ( !read_section(loaded_image, L"ramdisk", &ramdisk, NULL) )
         {
-            read_file(dir_handle, s2w(&name), &xsm, NULL);
-            efi_bs->FreePool(name.w);
+            name.s = get_value(&cfg, section.s, "ramdisk");
+            if ( name.s )
+            {
+                read_file(dir_handle, s2w(&name), &ramdisk, NULL);
+                efi_bs->FreePool(name.w);
+            }
+        }
+
+        if ( !read_section(loaded_image, L"xsm", &xsm, NULL) )
+        {
+            name.s = get_value(&cfg, section.s, "xsm");
+            if ( name.s )
+            {
+                read_file(dir_handle, s2w(&name), &xsm, NULL);
+                efi_bs->FreePool(name.w);
+            }
         }
 
         /*
@@ -1317,7 +1347,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
             }
         }
 
-        efi_arch_cfg_file_late(dir_handle, section.s);
+        efi_arch_cfg_file_late(loaded_image, dir_handle, section.s);
 
         efi_bs->FreePages(cfg.addr, PFN_UP(cfg.size));
         cfg.addr = 0;
diff --git a/xen/common/efi/efi.h b/xen/common/efi/efi.h
index 4845d84913..663a8b5000 100644
--- a/xen/common/efi/efi.h
+++ b/xen/common/efi/efi.h
@@ -47,3 +47,6 @@ const CHAR16 *wmemchr(const CHAR16 *s, CHAR16 c, UINTN n);
 /* EFI boot allocator. */
 void *ebmalloc(size_t size);
 void free_ebmalloc_unused_mem(void);
+
+const void *pe_find_section(const void *image_base, const size_t image_size,
+                            const CHAR16 *section_name, UINTN *size_out);
diff --git a/xen/common/efi/pe.c b/xen/common/efi/pe.c
new file mode 100644
index 0000000000..940f74aa03
--- /dev/null
+++ b/xen/common/efi/pe.c
@@ -0,0 +1,159 @@
+/*
+ * xen/common/efi/pe.c
+ *
+ * PE executable header parser.
+ *
+ * Derived from https://github.com/systemd/systemd/blob/master/src/boot/efi/pe.c
+ * commit 07d5ed536ec0a76b08229c7a80b910cb9acaf6b1
+ *
+ * Copyright (C) 2015 Kay Sievers <kay@vrfy.org>
+ * Copyright (C) 2020 Trammell Hudson <hudson@trmm.net>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ */
+
+
+#include "efi.h"
+
+struct DosFileHeader {
+    UINT8   Magic[2];
+    UINT16  LastSize;
+    UINT16  nBlocks;
+    UINT16  nReloc;
+    UINT16  HdrSize;
+    UINT16  MinAlloc;
+    UINT16  MaxAlloc;
+    UINT16  ss;
+    UINT16  sp;
+    UINT16  Checksum;
+    UINT16  ip;
+    UINT16  cs;
+    UINT16  RelocPos;
+    UINT16  nOverlay;
+    UINT16  reserved[4];
+    UINT16  OEMId;
+    UINT16  OEMInfo;
+    UINT16  reserved2[10];
+    UINT32  ExeHeader;
+};
+
+#if defined(__arm__) || defined (__aarch64__)
+#define PE_HEADER_MACHINE 0xaa64
+#elif defined(__x86_64__)
+#define PE_HEADER_MACHINE 0x8664
+#else
+#error "Unknown architecture"
+#endif
+
+struct PeFileHeader {
+    UINT16  Machine;
+    UINT16  NumberOfSections;
+    UINT32  TimeDateStamp;
+    UINT32  PointerToSymbolTable;
+    UINT32  NumberOfSymbols;
+    UINT16  SizeOfOptionalHeader;
+    UINT16  Characteristics;
+};
+
+struct PeHeader {
+    UINT8   Magic[4];
+    struct PeFileHeader FileHeader;
+};
+
+struct PeSectionHeader {
+    CHAR8   Name[8];
+    UINT32  VirtualSize;
+    UINT32  VirtualAddress;
+    UINT32  SizeOfRawData;
+    UINT32  PointerToRawData;
+    UINT32  PointerToRelocations;
+    UINT32  PointerToLinenumbers;
+    UINT16  NumberOfRelocations;
+    UINT16  NumberOfLinenumbers;
+    UINT32  Characteristics;
+};
+
+static int __init pe_name_compare(const struct PeSectionHeader *sect,
+                                  const CHAR16 *name)
+{
+    size_t i;
+
+    if ( sect->Name[0] != '.' )
+        return -1;
+
+    for ( i = 1; i < sizeof(sect->Name); i++ )
+    {
+        const char c = sect->Name[i];
+        const CHAR16 cw = name[i-1];
+        if ( cw == 0 && c == 0 )
+            return 0;
+        if ( cw < c )
+            return -1;
+        if ( cw > c )
+            return +1;
+     }
+
+     if ( name[i-1] < 0 )
+         return -1;
+     if ( name[i-1] > 0 )
+         return +1;
+     return 0;
+}
+
+const void *__init pe_find_section(const void *image, const UINTN image_size,
+                                   const CHAR16 *section_name, UINTN *size_out)
+{
+    const struct DosFileHeader *dos = image;
+    const struct PeHeader *pe;
+    const struct PeSectionHeader *sect;
+    UINTN offset, i;
+
+    if ( image_size < sizeof(*dos) ||
+         memcmp(dos->Magic, "MZ", 2) != 0 )
+        return NULL;
+
+    offset = dos->ExeHeader;
+    pe = image + offset;
+
+    offset += sizeof(*pe);
+    if ( image_size < offset ||
+         memcmp(pe->Magic, "PE\0\0", 4) != 0 )
+        return NULL;
+
+    /* PE32+ Subsystem type */
+    if ( pe->FileHeader.Machine != PE_HEADER_MACHINE )
+        return NULL;
+
+    offset += pe->FileHeader.SizeOfOptionalHeader;
+
+    for ( i = 0; i < pe->FileHeader.NumberOfSections; i++ )
+    {
+        sect = image + offset;
+        if ( image_size < offset + sizeof(*sect) )
+            return NULL;
+
+        if ( pe_name_compare(sect, section_name) != 0 )
+        {
+            offset += sizeof(*sect);
+            continue;
+        }
+
+        if ( image_size < sect->VirtualSize + sect->VirtualAddress )
+            blexit(L"PE invalid section size + address");
+
+        if ( size_out )
+            *size_out = sect->VirtualSize;
+
+        return image + sect->VirtualAddress;
+    }
+
+    return NULL;
+}
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v6 5/5] efi: Do not use command line if unified config is included
  2020-09-21 11:51 [PATCH v6 0/5] efi: Unified Xen hypervisor/kernel/initrd images Trammell Hudson
                   ` (3 preceding siblings ...)
  2020-09-21 11:51 ` [PATCH v6 4/5] efi: Enable booting unified hypervisor/kernel/initrd images Trammell Hudson
@ 2020-09-21 11:51 ` Trammell Hudson
  4 siblings, 0 replies; 13+ messages in thread
From: Trammell Hudson @ 2020-09-21 11:51 UTC (permalink / raw)
  To: xen-devel

If a unified Xen image is used, then the bundled configuration,
Xen command line, dom0 kernel, and ramdisk are prefered over
any files listed in the config file or provided on the command line.

Unlike the shim based verification, the PE signature on a unified image
covers all of the Xen+config+kernel+initrd modules linked into the
unified image. This also ensures that, on properly configured UEFI Secure Boot
platforms,  the entire runtime will be measured into the TPM for unsealing
secrets or remote attestation.

Signed-off-by: Trammell Hudson <hudson@trmm.net>
---
 xen/common/efi/boot.c | 43 ++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 38 insertions(+), 5 deletions(-)

diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index dcf939a05e..28903d6013 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -945,6 +945,35 @@ static void __init setup_efi_pci(void)
     efi_bs->FreePool(handles);
 }
 
+/*
+ * Logic should remain sync'ed with linux/arch/x86/xen/efi.c
+ * Secure Boot is enabled iff 'SecureBoot' is set and the system is
+ * not in Setup Mode.
+ */
+static bool __init efi_secure_boot(void)
+{
+    static __initdata EFI_GUID global_guid = EFI_GLOBAL_VARIABLE;
+    uint8_t secboot, setupmode;
+    UINTN secboot_size = sizeof(secboot);
+    UINTN setupmode_size = sizeof(setupmode);
+    EFI_STATUS rc;
+
+    rc = efi_rs->GetVariable(L"SecureBoot", &global_guid,
+                             NULL, &secboot_size, &secboot);
+    if ( rc != EFI_SUCCESS )
+        return false;
+
+    rc = efi_rs->GetVariable(L"SetupMode", &global_guid,
+                             NULL, &setupmode_size, &setupmode);
+    if ( rc != EFI_SUCCESS )
+        return false;
+
+    if ( secboot > 1 || setupmode > 1 )
+        blexit(L"Invalid SecureBoot/SetupMode variables");
+
+    return secboot == 1 && setupmode == 0;
+}
+
 static void __init efi_variables(void)
 {
     EFI_STATUS status;
@@ -1121,15 +1150,15 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     static EFI_GUID __initdata shim_lock_guid = SHIM_LOCK_PROTOCOL_GUID;
     EFI_LOADED_IMAGE *loaded_image;
     EFI_STATUS status;
-    unsigned int i, argc;
-    CHAR16 **argv, *file_name, *cfg_file_name = NULL, *options = NULL;
+    unsigned int i, argc = 0;
+    CHAR16 **argv = NULL, *file_name, *cfg_file_name = NULL, *options = NULL;
     UINTN gop_mode = ~0;
     EFI_SHIM_LOCK_PROTOCOL *shim_lock;
     EFI_GRAPHICS_OUTPUT_PROTOCOL *gop = NULL;
     union string section = { NULL }, name;
     bool base_video = false;
     const char *option_str;
-    bool use_cfg_file;
+    bool use_cfg_file, secure;
 
     __set_bit(EFI_BOOT, &efi_flags);
     __set_bit(EFI_LOADER, &efi_flags);
@@ -1148,8 +1177,10 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
         PrintErrMesg(L"No Loaded Image Protocol", status);
 
     efi_arch_load_addr_check(loaded_image);
+    secure = efi_secure_boot();
 
-    if ( use_cfg_file )
+    if ( use_cfg_file &&
+         !read_section(loaded_image, L"config", &cfg, NULL) )
     {
         UINTN offset = 0;
 
@@ -1207,6 +1238,8 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
 
     PrintStr(L"Xen " __stringify(XEN_VERSION) "." __stringify(XEN_SUBVERSION)
              XEN_EXTRAVERSION " (c/s " XEN_CHANGESET ") EFI loader\r\n");
+    if ( secure )
+        PrintStr(L"UEFI Secure Boot enabled\r\n");
 
     efi_arch_relocate_image(0);
 
@@ -1226,7 +1259,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
         /* Get the file system interface. */
         dir_handle = get_parent_handle(loaded_image, &file_name);
 
-        if ( read_section(loaded_image, L"config", &cfg, NULL) )
+        if ( cfg.ptr )
             PrintStr(L"Using builtin config file\r\n");
         else if ( !cfg_file_name )
         {
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v6 2/5] efi/boot.c: add file.need_to_free
  2020-09-21 11:51 ` [PATCH v6 2/5] efi/boot.c: add file.need_to_free Trammell Hudson
@ 2020-09-29 10:17   ` Jan Beulich
  2020-09-29 17:53     ` Trammell Hudson
  2020-09-29 10:45   ` Roger Pau Monné
  1 sibling, 1 reply; 13+ messages in thread
From: Jan Beulich @ 2020-09-29 10:17 UTC (permalink / raw)
  To: Trammell Hudson; +Cc: xen-devel, Roger Pau Monné

On 21.09.2020 13:51, Trammell Hudson wrote:
> The config file, kernel, initrd, etc should only be freed if they
> are allocated with the UEFI allocator.
> 
> Signed-off-by: Trammell Hudson <hudson@trmm.net>
> Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>

Strictly speaking with the changes done from v5 to v6 this tag
would have needed dropping. I guess Roger is fine with it being
kept, though.

> @@ -280,13 +281,13 @@ void __init noreturn blexit(const CHAR16 *str)
>      if ( !efi_bs )
>          efi_arch_halt();
>  
> -    if ( cfg.addr )
> +    if ( cfg.need_to_free )
>          efi_bs->FreePages(cfg.addr, PFN_UP(cfg.size));
> -    if ( kernel.addr )
> +    if ( kernel.need_to_free )
>          efi_bs->FreePages(kernel.addr, PFN_UP(kernel.size));
> -    if ( ramdisk.addr )
> +    if ( ramdisk.need_to_free )
>          efi_bs->FreePages(ramdisk.addr, PFN_UP(ramdisk.size));
> -    if ( xsm.addr )
> +    if ( xsm.need_to_free )
>          efi_bs->FreePages(xsm.addr, PFN_UP(xsm.size));
>  
>      efi_arch_blexit();

Doesn't this need similar changes in both efi_arch_blexit()?

Jan


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v6 2/5] efi/boot.c: add file.need_to_free
  2020-09-21 11:51 ` [PATCH v6 2/5] efi/boot.c: add file.need_to_free Trammell Hudson
  2020-09-29 10:17   ` Jan Beulich
@ 2020-09-29 10:45   ` Roger Pau Monné
  2020-09-29 11:00     ` Jan Beulich
  1 sibling, 1 reply; 13+ messages in thread
From: Roger Pau Monné @ 2020-09-29 10:45 UTC (permalink / raw)
  To: Trammell Hudson; +Cc: xen-devel

On Mon, Sep 21, 2020 at 07:51:10AM -0400, Trammell Hudson wrote:
> The config file, kernel, initrd, etc should only be freed if they
> are allocated with the UEFI allocator.
> 
> Signed-off-by: Trammell Hudson <hudson@trmm.net>
> Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
> ---
>  xen/common/efi/boot.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
> index 157fe0e8c5..c2ce0c7294 100644
> --- a/xen/common/efi/boot.c
> +++ b/xen/common/efi/boot.c
> @@ -102,6 +102,7 @@ union string {
>  
>  struct file {
>      UINTN size;
> +    bool need_to_free;
>      union {
>          EFI_PHYSICAL_ADDRESS addr;
>          char *str;
> @@ -280,13 +281,13 @@ void __init noreturn blexit(const CHAR16 *str)
>      if ( !efi_bs )
>          efi_arch_halt();
>  
> -    if ( cfg.addr )
> +    if ( cfg.need_to_free )

If you drop the addr check here...

>          efi_bs->FreePages(cfg.addr, PFN_UP(cfg.size));
> -    if ( kernel.addr )
> +    if ( kernel.need_to_free )
>          efi_bs->FreePages(kernel.addr, PFN_UP(kernel.size));
> -    if ( ramdisk.addr )
> +    if ( ramdisk.need_to_free )
>          efi_bs->FreePages(ramdisk.addr, PFN_UP(ramdisk.size));
> -    if ( xsm.addr )
> +    if ( xsm.need_to_free )
>          efi_bs->FreePages(xsm.addr, PFN_UP(xsm.size));
>  
>      efi_arch_blexit();
> @@ -581,6 +582,7 @@ static bool __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
>      }
>      else
>      {
> +        file->need_to_free = true;

... I think you need to clear need_to_free if AllocatePages fails?

Thanks, Roger.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v6 2/5] efi/boot.c: add file.need_to_free
  2020-09-29 10:45   ` Roger Pau Monné
@ 2020-09-29 11:00     ` Jan Beulich
  2020-09-29 11:06       ` Roger Pau Monné
  0 siblings, 1 reply; 13+ messages in thread
From: Jan Beulich @ 2020-09-29 11:00 UTC (permalink / raw)
  To: Roger Pau Monné; +Cc: Trammell Hudson, xen-devel

On 29.09.2020 12:45, Roger Pau Monné wrote:
> On Mon, Sep 21, 2020 at 07:51:10AM -0400, Trammell Hudson wrote:
>> --- a/xen/common/efi/boot.c
>> +++ b/xen/common/efi/boot.c
>> @@ -102,6 +102,7 @@ union string {
>>  
>>  struct file {
>>      UINTN size;
>> +    bool need_to_free;
>>      union {
>>          EFI_PHYSICAL_ADDRESS addr;
>>          char *str;
>> @@ -280,13 +281,13 @@ void __init noreturn blexit(const CHAR16 *str)
>>      if ( !efi_bs )
>>          efi_arch_halt();
>>  
>> -    if ( cfg.addr )
>> +    if ( cfg.need_to_free )
> 
> If you drop the addr check here...
> 
>>          efi_bs->FreePages(cfg.addr, PFN_UP(cfg.size));
>> -    if ( kernel.addr )
>> +    if ( kernel.need_to_free )
>>          efi_bs->FreePages(kernel.addr, PFN_UP(kernel.size));
>> -    if ( ramdisk.addr )
>> +    if ( ramdisk.need_to_free )
>>          efi_bs->FreePages(ramdisk.addr, PFN_UP(ramdisk.size));
>> -    if ( xsm.addr )
>> +    if ( xsm.need_to_free )
>>          efi_bs->FreePages(xsm.addr, PFN_UP(xsm.size));
>>  
>>      efi_arch_blexit();
>> @@ -581,6 +582,7 @@ static bool __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
>>      }
>>      else
>>      {
>> +        file->need_to_free = true;
> 
> ... I think you need to clear need_to_free if AllocatePages fails?

But this has been moved to the success path, or am I overlooking
anything?

Jan


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v6 2/5] efi/boot.c: add file.need_to_free
  2020-09-29 11:00     ` Jan Beulich
@ 2020-09-29 11:06       ` Roger Pau Monné
  0 siblings, 0 replies; 13+ messages in thread
From: Roger Pau Monné @ 2020-09-29 11:06 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Trammell Hudson, xen-devel

On Tue, Sep 29, 2020 at 01:00:06PM +0200, Jan Beulich wrote:
> On 29.09.2020 12:45, Roger Pau Monné wrote:
> > On Mon, Sep 21, 2020 at 07:51:10AM -0400, Trammell Hudson wrote:
> >> --- a/xen/common/efi/boot.c
> >> +++ b/xen/common/efi/boot.c
> >> @@ -102,6 +102,7 @@ union string {
> >>  
> >>  struct file {
> >>      UINTN size;
> >> +    bool need_to_free;
> >>      union {
> >>          EFI_PHYSICAL_ADDRESS addr;
> >>          char *str;
> >> @@ -280,13 +281,13 @@ void __init noreturn blexit(const CHAR16 *str)
> >>      if ( !efi_bs )
> >>          efi_arch_halt();
> >>  
> >> -    if ( cfg.addr )
> >> +    if ( cfg.need_to_free )
> > 
> > If you drop the addr check here...
> > 
> >>          efi_bs->FreePages(cfg.addr, PFN_UP(cfg.size));
> >> -    if ( kernel.addr )
> >> +    if ( kernel.need_to_free )
> >>          efi_bs->FreePages(kernel.addr, PFN_UP(kernel.size));
> >> -    if ( ramdisk.addr )
> >> +    if ( ramdisk.need_to_free )
> >>          efi_bs->FreePages(ramdisk.addr, PFN_UP(ramdisk.size));
> >> -    if ( xsm.addr )
> >> +    if ( xsm.need_to_free )
> >>          efi_bs->FreePages(xsm.addr, PFN_UP(xsm.size));
> >>  
> >>      efi_arch_blexit();
> >> @@ -581,6 +582,7 @@ static bool __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
> >>      }
> >>      else
> >>      {
> >> +        file->need_to_free = true;
> > 
> > ... I think you need to clear need_to_free if AllocatePages fails?
> 
> But this has been moved to the success path, or am I overlooking
> anything?

Oh yes, sorry, somehow I looked at the wrong context. Please ignore my
comment.

Roger.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v6 4/5] efi: Enable booting unified hypervisor/kernel/initrd images
  2020-09-21 11:51 ` [PATCH v6 4/5] efi: Enable booting unified hypervisor/kernel/initrd images Trammell Hudson
@ 2020-09-29 15:37   ` Jan Beulich
  2020-09-29 18:06     ` Trammell Hudson
  0 siblings, 1 reply; 13+ messages in thread
From: Jan Beulich @ 2020-09-29 15:37 UTC (permalink / raw)
  To: Trammell Hudson; +Cc: xen-devel

On 21.09.2020 13:51, Trammell Hudson wrote:
> @@ -624,6 +626,22 @@ static bool __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
>      return true;
>  }
>  
> +static bool __init read_section(const EFI_LOADED_IMAGE *image,
> +                                CHAR16 *name, struct file *file,
> +                                const char *options)
> +{
> +    file->ptr = pe_find_section(image->ImageBase, image->ImageSize,
> +                                name, &file->size);
> +    if ( !file->ptr )
> +        return false;
> +
> +    file->need_to_free = false;

In patch 2 you don't bother clearing the field, presumably because
it's static data and hence zero-filled anyway. This same assumption
would then hold here. Or else, to be consistent, the earlier patch
would want clearing added.

> +static int __init pe_name_compare(const struct PeSectionHeader *sect,
> +                                  const CHAR16 *name)
> +{
> +    size_t i;
> +
> +    if ( sect->Name[0] != '.' )
> +        return -1;
> +
> +    for ( i = 1; i < sizeof(sect->Name); i++ )
> +    {
> +        const char c = sect->Name[i];
> +        const CHAR16 cw = name[i-1];
> +        if ( cw == 0 && c == 0 )

Blank line between declarations and statements please.

> +            return 0;
> +        if ( cw < c )
> +            return -1;
> +        if ( cw > c )
> +            return +1;
> +     }
> +
> +     if ( name[i-1] < 0 )
> +         return -1;

I'm afraid this is liable to trigger compiler warnings, for checking
an unsigned quantity to be negative.

Also throughout here "i-1" wants spelling "i - 1".

> +const void *__init pe_find_section(const void *image, const UINTN image_size,
> +                                   const CHAR16 *section_name, UINTN *size_out)
> +{
> +    const struct DosFileHeader *dos = image;
> +    const struct PeHeader *pe;
> +    const struct PeSectionHeader *sect;
> +    UINTN offset, i;
> +
> +    if ( image_size < sizeof(*dos) ||
> +         memcmp(dos->Magic, "MZ", 2) != 0 )
> +        return NULL;
> +
> +    offset = dos->ExeHeader;
> +    pe = image + offset;
> +
> +    offset += sizeof(*pe);
> +    if ( image_size < offset ||
> +         memcmp(pe->Magic, "PE\0\0", 4) != 0 )
> +        return NULL;
> +
> +    /* PE32+ Subsystem type */
> +    if ( pe->FileHeader.Machine != PE_HEADER_MACHINE )
> +        return NULL;

Comment and code don't look to be in line.

Jan


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v6 2/5] efi/boot.c: add file.need_to_free
  2020-09-29 10:17   ` Jan Beulich
@ 2020-09-29 17:53     ` Trammell Hudson
  0 siblings, 0 replies; 13+ messages in thread
From: Trammell Hudson @ 2020-09-29 17:53 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel, Roger Pau Monné

On Tuesday, September 29, 2020 6:17 AM, Jan Beulich <jbeulich@suse.com> wrote:
> On 21.09.2020 13:51, Trammell Hudson wrote:
> [...]
> > Reviewed-by: Roger Pau Monné roger.pau@citrix.com
>
> Strictly speaking with the changes done from v5 to v6 this tag
> would have needed dropping. I guess Roger is fine with it being
> kept, though.

Ok.

> [...]
> Doesn't this need similar changes in both efi_arch_blexit()?

It does -- I had missed that there was a place to free them
and had assumed that they were just leaked.  Fixed in v7.

--
Trammell


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v6 4/5] efi: Enable booting unified hypervisor/kernel/initrd images
  2020-09-29 15:37   ` Jan Beulich
@ 2020-09-29 18:06     ` Trammell Hudson
  0 siblings, 0 replies; 13+ messages in thread
From: Trammell Hudson @ 2020-09-29 18:06 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel

On Tuesday, September 29, 2020 11:37 AM, Jan Beulich <jbeulich@suse.com> wrote:
> On 21.09.2020 13:51, Trammell Hudson wrote:
> [...]
> > -   file->need_to_free = false;
>
> In patch 2 you don't bother clearing the field, presumably because
> it's static data and hence zero-filled anyway. This same assumption
> would then hold here. Or else, to be consistent, the earlier patch
> would want clearing added.

Removed.

> [...]
> > -          const char c = sect->Name[i];
> > -          const CHAR16 cw = name[i-1];
> > -          if ( cw == 0 && c == 0 )
>
> Blank line between declarations and statements please.

Added.

> [...]
> > -       if ( name[i-1] < 0 )
> > -           return -1;
>
> I'm afraid this is liable to trigger compiler warnings, for checking
> an unsigned quantity to be negative.

The compare function had strcmp() like semantics, but since it was
not used, I've modified it to just return a 0 or -1 in all cases.
So the comparison against < 0 goes away.

> Also throughout here "i-1" wants spelling "i - 1".

Fixed in both places.

> > -   /* PE32+ Subsystem type */
> > -   if ( pe->FileHeader.Machine != PE_HEADER_MACHINE )
> > -          return NULL;
>
> Comment and code don't look to be in line.

Yeah, comment had drifted out of sync as some of the other tests
moved around.  I've removed it in the v7 version.

--
Trammell



^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2020-09-29 18:07 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-21 11:51 [PATCH v6 0/5] efi: Unified Xen hypervisor/kernel/initrd images Trammell Hudson
2020-09-21 11:51 ` [PATCH v6 1/5] efi/boot.c: Make file->ptr const void* Trammell Hudson
2020-09-21 11:51 ` [PATCH v6 2/5] efi/boot.c: add file.need_to_free Trammell Hudson
2020-09-29 10:17   ` Jan Beulich
2020-09-29 17:53     ` Trammell Hudson
2020-09-29 10:45   ` Roger Pau Monné
2020-09-29 11:00     ` Jan Beulich
2020-09-29 11:06       ` Roger Pau Monné
2020-09-21 11:51 ` [PATCH v6 3/5] efi/boot.c: add handle_file_info() Trammell Hudson
2020-09-21 11:51 ` [PATCH v6 4/5] efi: Enable booting unified hypervisor/kernel/initrd images Trammell Hudson
2020-09-29 15:37   ` Jan Beulich
2020-09-29 18:06     ` Trammell Hudson
2020-09-21 11:51 ` [PATCH v6 5/5] efi: Do not use command line if unified config is included Trammell Hudson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.