Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package grub2 for openSUSE:Factory checked 
in at 2021-02-07 15:13:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/grub2 (Old)
 and      /work/SRC/openSUSE:Factory/.grub2.new.28504 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "grub2"

Sun Feb  7 15:13:52 2021 rev:232 rq:868322 version:2.04

Changes:
--------
--- /work/SRC/openSUSE:Factory/grub2/grub2.changes      2020-11-05 
21:53:10.404419783 +0100
+++ /work/SRC/openSUSE:Factory/.grub2.new.28504/grub2.changes   2021-02-07 
15:13:54.721379579 +0100
@@ -1,0 +2,23 @@
+Wed Jan 27 04:13:32 UTC 2021 - Michael Chang <mch...@suse.com>
+
+- Complete Secure Boot support on aarch64 (jsc#SLE-15020)
+  * 0001-Add-support-for-Linux-EFI-stub-loading-on-aarch64.patch
+  * 0002-arm64-make-sure-fdt-has-address-cells-and-size-cells.patch
+  * 0003-Make-grub_error-more-verbose.patch
+  * 0004-arm-arm64-loader-Better-memory-allocation-and-error-.patch
+  * 0005-Make-linux_arm_kernel_header.hdr_offset-be-at-the-ri.patch
+  * 0006-efi-Set-image-base-address-before-jumping-to-the-PE-.patch
+  * 0007-linuxefi-fail-kernel-validation-without-shim-protoco.patch
+  * 0008-squash-Add-support-for-Linux-EFI-stub-loading-on-aar.patch
+  * 0009-squash-Add-support-for-linuxefi.patch
+
+-------------------------------------------------------------------
+Thu Jan 21 07:59:39 UTC 2021 - Michael Chang <mch...@suse.com>
+
+- Fix rpmlint 2.0 error for having arch specific path in noarch package aiming
+  for compatibility with old package (bsc#1179044)
+  * grub2.spec
+- Fix non POSIX sed argument which failed in sed from busybox (bsc#1181091)
+  * grub2-check-default.sh
+
+-------------------------------------------------------------------

New:
----
  0001-Add-support-for-Linux-EFI-stub-loading-on-aarch64.patch
  0002-arm64-make-sure-fdt-has-address-cells-and-size-cells.patch
  0003-Make-grub_error-more-verbose.patch
  0004-arm-arm64-loader-Better-memory-allocation-and-error-.patch
  0005-Make-linux_arm_kernel_header.hdr_offset-be-at-the-ri.patch
  0006-efi-Set-image-base-address-before-jumping-to-the-PE-.patch
  0007-linuxefi-fail-kernel-validation-without-shim-protoco.patch
  0008-squash-Add-support-for-Linux-EFI-stub-loading-on-aar.patch
  0009-squash-Add-support-for-linuxefi.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ grub2.spec ++++++
--- /var/tmp/diff_new_pack.DGEa6R/_old  2021-02-07 15:13:56.677381670 +0100
+++ /var/tmp/diff_new_pack.DGEa6R/_new  2021-02-07 15:13:56.681381675 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package grub2
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -336,6 +336,16 @@
 # (bsc#1176062)
 Patch722:       0001-Warn-if-MBR-gap-is-small-and-user-uses-advanced-modu.patch
 Patch723:       0002-grub-install-Avoid-incompleted-install-on-i386-pc.patch
+# Secure Boot support in GRUB on aarch64 (jsc#SLE-15864)
+Patch730:       0001-Add-support-for-Linux-EFI-stub-loading-on-aarch64.patch
+Patch731:       0002-arm64-make-sure-fdt-has-address-cells-and-size-cells.patch
+Patch732:       0003-Make-grub_error-more-verbose.patch
+Patch733:       0004-arm-arm64-loader-Better-memory-allocation-and-error-.patch
+Patch734:       0005-Make-linux_arm_kernel_header.hdr_offset-be-at-the-ri.patch
+Patch735:       0006-efi-Set-image-base-address-before-jumping-to-the-PE-.patch
+Patch736:       0007-linuxefi-fail-kernel-validation-without-shim-protoco.patch
+Patch737:       0008-squash-Add-support-for-Linux-EFI-stub-loading-on-aar.patch
+Patch738:       0009-squash-Add-support-for-linuxefi.patch
 
 Requires:       gettext-runtime
 %if 0%{?suse_version} >= 1140
@@ -458,6 +468,10 @@
 %endif
 Provides:       %{name}-efi = %{version}-%{release}
 Obsoletes:      %{name}-efi < %{version}-%{release}
+%ifarch x86_64
+Conflicts:      python2-kiwi < 9.17.12
+Conflicts:      python3-kiwi < 9.17.12
+%endif
 
 %description %{grubefiarch}
 The GRand Unified Bootloader (GRUB) is a highly configurable and customizable
@@ -490,6 +504,7 @@
 Provides:       %{name}-xen = %{version}-%{release}
 Obsoletes:      %{name}-xen < %{version}-%{release}
 BuildArch:      noarch
+Conflicts:      xen < 4.12.0_03
 
 %description %{grubxenarch}
 The GRand Unified Bootloader (GRUB) is a highly configurable and customizable
@@ -661,6 +676,15 @@
 %patch721 -p1
 %patch722 -p1
 %patch723 -p1
+%patch730 -p1
+%patch731 -p1
+%patch732 -p1
+%patch733 -p1
+%patch734 -p1
+%patch735 -p1
+%patch736 -p1
+%patch737 -p1
+%patch738 -p1
 
 %build
 # collect evidence to debug spurious build failure on SLE15
@@ -842,14 +866,6 @@
 cd build-xen
 %make_install
 install -m 644 grub.xen %{buildroot}/%{_datadir}/%{name}/%{grubxenarch}/.
-# provide compatibility sym-link for VM definitions pointing to old location
-install -d %{buildroot}%{_libdir}/%{name}/%{grubxenarch}
-ln -srf %{buildroot}%{_datadir}/%{name}/%{grubxenarch}/grub.xen 
%{buildroot}%{_libdir}/%{name}/%{grubxenarch}/grub.xen
-cat <<-EoM >%{buildroot}%{_libdir}/%{name}/%{grubxenarch}/DEPRECATED
-       This directory and its contents was moved to 
%{_datadir}/%{name}/%{grubxenarch}.
-       Individual symbolic links are provided for a smooth transition.
-       Please update your VM definition files to use the new location!
-EoM
 cd ..
 %endif
 
@@ -867,16 +883,6 @@
 %define sysefidir %{sysefibasedir}/%{_target_cpu} 
 install -d %{buildroot}/%{sysefidir}
 ln -sr %{buildroot}/%{_datadir}/%{name}/%{grubefiarch}/grub.efi 
%{buildroot}%{sysefidir}/grub.efi
-%ifarch x86_64
-# provide compatibility sym-link for previous shim-install and the like
-install -d %{buildroot}/usr/lib64/efi
-ln -srf %{buildroot}/%{_datadir}/%{name}/%{grubefiarch}/grub.efi 
%{buildroot}/usr/lib64/efi/grub.efi
-cat <<-EoM >%{buildroot}/usr/lib64/efi/DEPRECATED
-       This directory and its contents was moved to %{_datadir}/efi/x86_64.
-       Individual symbolic links are provided for a smooth transition and
-       may vanish at any point in time.  Please use the new location!
-EoM
-%endif
 
 %ifarch x86_64 aarch64
 %if 0%{?suse_version} >= 1230 || 0%{?suse_version} == 1110
@@ -1304,12 +1310,6 @@
 %dir %{sysefidir}
 %{sysefidir}/grub.efi
 %if 0%{?suse_version} < 1600
-%ifarch x86_64
-# provide compatibility sym-link for previous shim-install and kiwi
-%dir /usr/lib64/efi
-/usr/lib64/efi/DEPRECATED
-/usr/lib64/efi/grub.efi
-%endif
 %endif
 
 %ifarch x86_64 aarch64
@@ -1338,9 +1338,6 @@
 %defattr(-,root,root,-)
 %dir %{_datadir}/%{name}/%{grubxenarch}
 %{_datadir}/%{name}/%{grubxenarch}/*
-# provide compatibility sym-link for VM definitions pointing to old location
-%dir %{_libdir}/%{name}
-%{_libdir}/%{name}/%{grubxenarch}
 %endif
 
 %if 0%{?has_systemd:1}

++++++ 0001-Add-support-for-Linux-EFI-stub-loading-on-aarch64.patch ++++++
>From db4da8095b5ba722d22502c8d090e66816a5577d Mon Sep 17 00:00:00 2001
From: Matthew Garrett <m...@redhat.com>
Date: Fri, 6 Nov 2020 08:36:36 +0000
Subject: [PATCH 1/9] Add support for Linux EFI stub loading on aarch64.

Add support for Linux EFI stub loading on aarch64.
---
 grub-core/Makefile.core.def        |   4 +-
 grub-core/loader/arm64/efi/linux.c | 443 +++++++++++++++++++++++++++++
 include/grub/arm/linux.h           |   9 +
 include/grub/arm64/linux.h         |  10 +
 4 files changed, 465 insertions(+), 1 deletion(-)
 create mode 100644 grub-core/loader/arm64/efi/linux.c

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 3ea9dace0..cfdd31431 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1854,9 +1854,11 @@ module = {
 
 module = {
   name = linuxefi;
-  efi = lib/fake_module.c;
+  x86 = lib/fake_module.c;
+  arm64 = loader/arm64/efi/linux.c;
   enable = i386_efi;
   enable = x86_64_efi;
+  enable = arm64_efi;
 };
 
 module = {
diff --git a/grub-core/loader/arm64/efi/linux.c 
b/grub-core/loader/arm64/efi/linux.c
new file mode 100644
index 000000000..d81a6d843
--- /dev/null
+++ b/grub-core/loader/arm64/efi/linux.c
@@ -0,0 +1,443 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/charset.h>
+#include <grub/command.h>
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/fdt.h>
+#include <grub/linux.h>
+#include <grub/loader.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+#include <grub/cpu/linux.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/fdtload.h>
+#include <grub/efi/memory.h>
+#include <grub/efi/pe32.h>
+#include <grub/i18n.h>
+#include <grub/lib/cmdline.h>
+#include <grub/verify.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+static grub_dl_t my_mod;
+static int loaded;
+
+static void *kernel_addr;
+static grub_uint64_t kernel_size;
+static grub_uint32_t handover_offset;
+
+static char *linux_args;
+static grub_uint32_t cmdline_size;
+
+static grub_addr_t initrd_start;
+static grub_addr_t initrd_end;
+
+#define SHIM_LOCK_GUID \
+ { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 
0x23} }
+
+struct grub_efi_shim_lock
+{
+  grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size);
+};
+typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
+
+static grub_efi_boolean_t
+grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
+{
+  grub_efi_guid_t guid = SHIM_LOCK_GUID;
+  grub_efi_shim_lock_t *shim_lock;
+
+  shim_lock = grub_efi_locate_protocol(&guid, NULL);
+
+  if (!shim_lock)
+    return 1;
+
+  if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS)
+    return 1;
+
+  return 0;
+}
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+
+typedef void (*handover_func) (void *, grub_efi_system_table_t *, void *);
+
+static grub_err_t
+grub_efi_linux_boot (void *kernel_address, grub_off_t offset,
+                    void *kernel_params)
+{
+  handover_func hf;
+
+  hf = (handover_func)((char *)kernel_address + offset);
+  hf (grub_efi_image_handle, grub_efi_system_table, kernel_params);
+
+  return GRUB_ERR_BUG;
+}
+
+#pragma GCC diagnostic pop
+
+/* FIXME: This is copy of grub_arch_efi_linux_check_image () */
+static grub_err_t
+grub_arch_efi_linux_check_image_XX (struct linux_arch_kernel_header * lh)
+{
+  if (lh->magic != GRUB_LINUX_ARMXX_MAGIC_SIGNATURE)
+    return grub_error(GRUB_ERR_BAD_OS, "invalid magic number");
+
+  if ((lh->code0 & 0xffff) != GRUB_PE32_MAGIC)
+    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                      N_("plain image kernel not supported - rebuild with 
CONFIG_(U)EFI_STUB enabled"));
+
+  grub_dprintf ("linux", "UEFI stub kernel:\n");
+  grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+finalize_params_linux (void)
+{
+  grub_efi_loaded_image_t *loaded_image = NULL;
+  int node, retval, len;
+
+  void *fdt;
+
+  fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
+
+  if (!fdt)
+    goto failure;
+
+  node = grub_fdt_find_subnode (fdt, 0, "chosen");
+  if (node < 0)
+    node = grub_fdt_add_subnode (fdt, 0, "chosen");
+
+  if (node < 1)
+    goto failure;
+
+  /* Set initrd info */
+  if (initrd_start && initrd_end > initrd_start)
+    {
+      grub_dprintf ("linux", "Initrd @ %p-%p\n",
+                   (void *) initrd_start, (void *) initrd_end);
+
+      retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start",
+                                   initrd_start);
+      if (retval)
+       goto failure;
+      retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end",
+                                   initrd_end);
+      if (retval)
+       goto failure;
+    }
+
+  if (grub_fdt_install() != GRUB_ERR_NONE)
+    goto failure;
+
+  grub_dprintf ("linux", "Installed/updated FDT configuration table @ %p\n",
+               fdt);
+
+  /* Convert command line to UCS-2 */
+  loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
+  if (!loaded_image)
+    goto failure;
+
+  loaded_image->load_options_size = len =
+    (grub_strlen (linux_args) + 1) * sizeof (grub_efi_char16_t);
+  loaded_image->load_options =
+    grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES 
(loaded_image->load_options_size));
+  if (!loaded_image->load_options)
+    return grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters");
+
+  loaded_image->load_options_size =
+    2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
+                           (grub_uint8_t *) linux_args, len, NULL);
+
+  return GRUB_ERR_NONE;
+
+failure:
+  grub_fdt_unload();
+  return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
+}
+
+static void
+free_params (void)
+{
+  grub_efi_loaded_image_t *loaded_image = NULL;
+
+  loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
+  if (loaded_image)
+    {
+      if (loaded_image->load_options)
+       grub_efi_free_pages 
((grub_efi_physical_address_t)(grub_efi_uintn_t)loaded_image->load_options,
+                            GRUB_EFI_BYTES_TO_PAGES 
(loaded_image->load_options_size));
+      loaded_image->load_options = NULL;
+      loaded_image->load_options_size = 0;
+    }
+}
+
+/* FIXME: This is to replace grub_arch_efi_linux_boot_image */
+static grub_err_t
+grub_arch_efi_linux_boot_image_XX (grub_addr_t addr, char *args)
+{
+  grub_err_t retval;
+
+  retval = finalize_params_linux ();
+  if (retval != GRUB_ERR_NONE)
+    return grub_errno;
+
+  grub_dprintf ("linux", "linux command line: '%s'\n", args);
+
+  retval = grub_efi_linux_boot ((char *)addr, handover_offset, (void *)addr);
+
+  /* Never reached... */
+  free_params();
+  return retval;
+}
+
+static grub_err_t
+grub_linux_boot (void)
+{
+  return (grub_arch_efi_linux_boot_image_XX ((grub_addr_t)kernel_addr, 
linux_args));
+}
+
+static grub_err_t
+grub_linux_unload (void)
+{
+  grub_dl_unref (my_mod);
+  loaded = 0;
+  if (initrd_start)
+    grub_efi_free_pages ((grub_efi_physical_address_t) initrd_start,
+                        GRUB_EFI_BYTES_TO_PAGES (initrd_end - initrd_start));
+  initrd_start = initrd_end = 0;
+  grub_free (linux_args);
+  if (kernel_addr)
+    grub_efi_free_pages ((grub_addr_t) kernel_addr,
+                        GRUB_EFI_BYTES_TO_PAGES (kernel_size));
+  grub_fdt_unload ();
+  return GRUB_ERR_NONE;
+}
+
+/*
+ * As per linux/Documentation/arm/Booting
+ * ARM initrd needs to be covered by kernel linear mapping,
+ * so place it in the first 512MB of DRAM.
+ *
+ * As per linux/Documentation/arm64/booting.txt
+ * ARM64 initrd needs to be contained entirely within a 1GB aligned window
+ * of up to 32GB of size that covers the kernel image as well.
+ * Since the EFI stub loader will attempt to load the kernel near start of
+ * RAM, place the buffer in the first 32GB of RAM.
+ */
+#ifdef __arm__
+#define INITRD_MAX_ADDRESS_OFFSET (512U * 1024 * 1024)
+#else /* __aarch64__ */
+#define INITRD_MAX_ADDRESS_OFFSET (32ULL * 1024 * 1024 * 1024)
+#endif
+
+/*
+ * This function returns a pointer to a legally allocated initrd buffer,
+ * or NULL if unsuccessful
+ */
+static void *
+allocate_initrd_mem (int initrd_pages)
+{
+  grub_addr_t max_addr;
+
+  if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE)
+    return NULL;
+
+  max_addr += INITRD_MAX_ADDRESS_OFFSET - 1;
+
+  return grub_efi_allocate_pages_real (max_addr, initrd_pages,
+                                      GRUB_EFI_ALLOCATE_MAX_ADDRESS,
+                                      GRUB_EFI_LOADER_DATA);
+}
+
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+                int argc, char *argv[])
+{
+  struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 };
+  int initrd_size, initrd_pages;
+  void *initrd_mem = NULL;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
+      goto fail;
+    }
+
+  if (!loaded)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT,
+                 N_("you need to load the kernel first"));
+      goto fail;
+    }
+
+  if (grub_initrd_init (argc, argv, &initrd_ctx))
+    goto fail;
+
+  initrd_size = grub_get_initrd_size (&initrd_ctx);
+  grub_dprintf ("linux", "Loading initrd\n");
+
+  initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size));
+  initrd_mem = allocate_initrd_mem (initrd_pages);
+
+  if (!initrd_mem)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+      goto fail;
+    }
+
+  if (grub_initrd_load (&initrd_ctx, argv, initrd_mem))
+    goto fail;
+
+  initrd_start = (grub_addr_t) initrd_mem;
+  initrd_end = initrd_start + initrd_size;
+  grub_dprintf ("linux", "[addr=%p, size=0x%x]\n",
+               (void *) initrd_start, initrd_size);
+
+ fail:
+  grub_initrd_close (&initrd_ctx);
+  if (initrd_mem && !initrd_start)
+    grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+               int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  struct linux_arch_kernel_header lh;
+  struct grub_armxx_linux_pe_header *pe;
+  grub_err_t err;
+
+  grub_dl_ref (my_mod);
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
+      goto fail;
+    }
+
+  file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
+  if (!file)
+    goto fail;
+
+  kernel_size = grub_file_size (file);
+
+  if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh))
+    return grub_errno;
+
+  if (grub_arch_efi_linux_check_image_XX (&lh) != GRUB_ERR_NONE)
+    goto fail;
+
+  grub_loader_unset();
+
+  grub_dprintf ("linux", "kernel file size: %lld\n", (long long) kernel_size);
+  kernel_addr = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES 
(kernel_size));
+  grub_dprintf ("linux", "kernel numpages: %lld\n",
+               (long long) GRUB_EFI_BYTES_TO_PAGES (kernel_size));
+  if (!kernel_addr)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+      goto fail;
+    }
+
+  grub_file_seek (file, 0);
+  if (grub_file_read (file, kernel_addr, kernel_size)
+      < (grub_int64_t) kernel_size)
+    {
+      if (!grub_errno)
+       grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]);
+      goto fail;
+    }
+
+  grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
+
+  if (!grub_linuxefi_secure_validate (kernel_addr, kernel_size))
+    {
+      grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), 
argv[0]);
+      goto fail;
+    }
+
+  pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
+  handover_offset = pe->opt.entry_addr;
+
+  cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE);
+  linux_args = grub_malloc (cmdline_size);
+  if (!linux_args)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+      goto fail;
+    }
+  grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
+  err = grub_create_loader_cmdline (argc, argv,
+                                   linux_args + sizeof (LINUX_IMAGE) - 1,
+                                   cmdline_size,
+                                   GRUB_VERIFY_KERNEL_CMDLINE);
+  if (err)
+    goto fail;
+
+  if (grub_errno == GRUB_ERR_NONE)
+    {
+      grub_loader_set (grub_linux_boot, grub_linux_unload, 0);
+      loaded = 1;
+    }
+
+fail:
+  if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_dl_unref (my_mod);
+      loaded = 0;
+    }
+
+  if (linux_args && !loaded)
+    grub_free (linux_args);
+
+  if (kernel_addr && !loaded)
+    grub_efi_free_pages ((grub_addr_t) kernel_addr,
+                        GRUB_EFI_BYTES_TO_PAGES (kernel_size));
+
+  return grub_errno;
+}
+
+
+static grub_command_t cmd_linux, cmd_initrd;
+
+GRUB_MOD_INIT (linux)
+{
+  cmd_linux = grub_register_command ("linuxefi", grub_cmd_linux, 0,
+                                    N_("Load Linux."));
+  cmd_initrd = grub_register_command ("initrdefi", grub_cmd_initrd, 0,
+                                     N_("Load initrd."));
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI (linux)
+{
+  grub_unregister_command (cmd_linux);
+  grub_unregister_command (cmd_initrd);
+}
diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h
index 2e98a6689..775297db8 100644
--- a/include/grub/arm/linux.h
+++ b/include/grub/arm/linux.h
@@ -20,6 +20,7 @@
 #ifndef GRUB_ARM_LINUX_HEADER
 #define GRUB_ARM_LINUX_HEADER 1
 
+#include <grub/efi/pe32.h>
 #include "system.h"
 
 #define GRUB_LINUX_ARM_MAGIC_SIGNATURE 0x016f2818
@@ -34,9 +35,17 @@ struct linux_arm_kernel_header {
   grub_uint32_t hdr_offset;
 };
 
+struct grub_arm_linux_pe_header
+{
+  grub_uint32_t magic;
+  struct grub_pe32_coff_header coff;
+  struct grub_pe32_optional_header opt;
+};
+
 #if defined(__arm__)
 # define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM_MAGIC_SIGNATURE
 # define linux_arch_kernel_header linux_arm_kernel_header
+# define grub_armxx_linux_pe_header grub_arm_linux_pe_header
 #endif
 
 #if defined GRUB_MACHINE_UBOOT
diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h
index 4269adc6d..a3be9dd70 100644
--- a/include/grub/arm64/linux.h
+++ b/include/grub/arm64/linux.h
@@ -19,6 +19,8 @@
 #ifndef GRUB_ARM64_LINUX_HEADER
 #define GRUB_ARM64_LINUX_HEADER 1
 
+#include <grub/efi/pe32.h>
+
 #define GRUB_LINUX_ARM64_MAGIC_SIGNATURE 0x644d5241 /* 'ARM\x64' */
 
 /* From linux/Documentation/arm64/booting.txt */
@@ -36,9 +38,17 @@ struct linux_arm64_kernel_header
   grub_uint32_t hdr_offset;    /* Offset of PE/COFF header */
 };
 
+struct grub_arm64_linux_pe_header
+{
+  grub_uint32_t magic;
+  struct grub_pe32_coff_header coff;
+  struct grub_pe64_optional_header opt;
+};
+
 #if defined(__aarch64__)
 # define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM64_MAGIC_SIGNATURE
 # define linux_arch_kernel_header linux_arm64_kernel_header
+# define grub_armxx_linux_pe_header grub_arm64_linux_pe_header
 #endif
 
 #endif /* ! GRUB_ARM64_LINUX_HEADER */
-- 
2.26.2

++++++ 0002-arm64-make-sure-fdt-has-address-cells-and-size-cells.patch ++++++
>From e27acddebd30175587155613042abffd2e9a5de8 Mon Sep 17 00:00:00 2001
From: Mark Salter <msal...@redhat.com>
Date: Mon, 17 Apr 2017 08:44:29 -0400
Subject: [PATCH 2/9] arm64: make sure fdt has #address-cells and #size-cells
 properties

Recent upstream changes to kexec-tools relies on #address-cells
and #size-cells properties in the FDT. If grub2 needs to create
a chosen node, it is likely because firmware did not provide one.
In that case, set #address-cells and #size-cells properties to
make sure they exist.
---
 grub-core/loader/arm64/efi/linux.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/grub-core/loader/arm64/efi/linux.c 
b/grub-core/loader/arm64/efi/linux.c
index d81a6d843..98c4f038b 100644
--- a/grub-core/loader/arm64/efi/linux.c
+++ b/grub-core/loader/arm64/efi/linux.c
@@ -126,7 +126,21 @@ finalize_params_linux (void)
 
   node = grub_fdt_find_subnode (fdt, 0, "chosen");
   if (node < 0)
-    node = grub_fdt_add_subnode (fdt, 0, "chosen");
+    {
+      /*
+       * If we have to create a chosen node, Make sure we
+       * have #address-cells and #size-cells properties.
+       */
+      retval = grub_fdt_set_prop32(fdt, 0, "#address-cells", 2);
+      if (retval)
+       goto failure;
+
+      retval = grub_fdt_set_prop32(fdt, 0, "#size-cells", 2);
+      if (retval)
+       goto failure;
+
+      node = grub_fdt_add_subnode (fdt, 0, "chosen");
+    }
 
   if (node < 1)
     goto failure;
-- 
2.26.2

++++++ 0003-Make-grub_error-more-verbose.patch ++++++
>From 3526c4e467ee01a3cfd2f4d627433d078a1ab780 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjo...@redhat.com>
Date: Mon, 27 Aug 2018 13:14:06 -0400
Subject: [PATCH 3/9] Make grub_error() more verbose

Signed-off-by: Peter Jones <pjo...@redhat.com>
---
 grub-core/kern/efi/mm.c | 17 ++++++++++++++---
 grub-core/kern/err.c    | 13 +++++++++++--
 include/grub/err.h      |  5 ++++-
 3 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
index a9e37108c..15595a46e 100644
--- a/grub-core/kern/efi/mm.c
+++ b/grub-core/kern/efi/mm.c
@@ -157,12 +157,20 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t 
address,
 
   /* Limit the memory access to less than 4GB for 32-bit platforms.  */
   if (address > GRUB_EFI_MAX_USABLE_ADDRESS)
-    return 0;
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT,
+                 N_("invalid memory address (0x%llx > 0x%llx)"),
+                 address, GRUB_EFI_MAX_USABLE_ADDRESS);
+      return NULL;
+    }
 
   b = grub_efi_system_table->boot_services;
   status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
   if (status != GRUB_EFI_SUCCESS)
-    return 0;
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+      return NULL;
+    }
 
   if (address == 0)
     {
@@ -172,7 +180,10 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t 
address,
       status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, 
&address);
       grub_efi_free_pages (0, pages);
       if (status != GRUB_EFI_SUCCESS)
-       return 0;
+       {
+         grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+         return NULL;
+       }
     }
 
   grub_efi_store_alloc (address, pages);
diff --git a/grub-core/kern/err.c b/grub-core/kern/err.c
index 53c734de7..aebfe0cf8 100644
--- a/grub-core/kern/err.c
+++ b/grub-core/kern/err.c
@@ -33,15 +33,24 @@ static struct grub_error_saved 
grub_error_stack_items[GRUB_ERROR_STACK_SIZE];
 static int grub_error_stack_pos;
 static int grub_error_stack_assert;
 
+#ifdef grub_error
+#undef grub_error
+#endif
+
 grub_err_t
-grub_error (grub_err_t n, const char *fmt, ...)
+grub_error (grub_err_t n, const char *file, const int line, const char *fmt, 
...)
 {
   va_list ap;
+  int m;
 
   grub_errno = n;
 
+  m = grub_snprintf (grub_errmsg, sizeof (grub_errmsg), "%s:%d:", file, line);
+  if (m < 0)
+    m = 0;
+
   va_start (ap, fmt);
-  grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), _(fmt), ap);
+  grub_vsnprintf (grub_errmsg + m, sizeof (grub_errmsg) - m, _(fmt), ap);
   va_end (ap);
 
   return n;
diff --git a/include/grub/err.h b/include/grub/err.h
index 24ba9f5f5..b68bbec3c 100644
--- a/include/grub/err.h
+++ b/include/grub/err.h
@@ -85,7 +85,10 @@ struct grub_error_saved
 extern grub_err_t EXPORT_VAR(grub_errno);
 extern char EXPORT_VAR(grub_errmsg)[GRUB_MAX_ERRMSG];
 
-grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *fmt, ...);
+grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *file, const int 
line, const char *fmt, ...);
+
+#define grub_error(n, fmt, ...) grub_error (n, __FILE__, __LINE__, fmt, 
##__VA_ARGS__)
+
 void EXPORT_FUNC(grub_fatal) (const char *fmt, ...) __attribute__ ((noreturn));
 void EXPORT_FUNC(grub_error_push) (void);
 int EXPORT_FUNC(grub_error_pop) (void);
-- 
2.26.2

++++++ 0004-arm-arm64-loader-Better-memory-allocation-and-error-.patch ++++++
>From 5d417346956bc3108183020a8a9f20ddda034b48 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjo...@redhat.com>
Date: Thu, 11 Jul 2019 14:38:57 +0200
Subject: [PATCH 4/9] arm/arm64 loader: Better memory allocation and error
 messages.

On mustang, our memory map looks like:

Type      Physical start  - end             #Pages        Size Attributes
reserved  0000004000000000-00000040001fffff 00000200      2MiB UC WC WT WB
conv-mem  0000004000200000-0000004393ffffff 00393e00  14654MiB UC WC WT WB
ldr-code  0000004394000000-00000043f7ffffff 00064000   1600MiB UC WC WT WB
BS-data   00000043f8000000-00000043f801ffff 00000020    128KiB UC WC WT WB
conv-mem  00000043f8020000-00000043fa15bfff 0000213c  34032KiB UC WC WT WB
ldr-code  00000043fa15c000-00000043fa2a1fff 00000146   1304KiB UC WC WT WB
ldr-data  00000043fa2a2000-00000043fa3e8fff 00000147   1308KiB UC WC WT WB
conv-mem  00000043fa3e9000-00000043fa3e9fff 00000001      4KiB UC WC WT WB
ldr-data  00000043fa3ea000-00000043fa3eafff 00000001      4KiB UC WC WT WB
ldr-code  00000043fa3eb000-00000043fa4affff 000000c5    788KiB UC WC WT WB
BS-code   00000043fa4b0000-00000043fa59ffff 000000f0    960KiB UC WC WT WB
RT-code   00000043fa5a0000-00000043fa5affff 00000010     64KiB RT UC WC WT WB
RT-data   00000043fa5b0000-00000043fa5bffff 00000010     64KiB RT UC WC WT WB
RT-code   00000043fa5c0000-00000043fa5cffff 00000010     64KiB RT UC WC WT WB
ldr-data  00000043fa5d0000-00000043fa5d0fff 00000001      4KiB UC WC WT WB
BS-code   00000043fa5d1000-00000043fa5ddfff 0000000d     52KiB UC WC WT WB
reserved  00000043fa5de000-00000043fa60ffff 00000032    200KiB UC WC WT WB
ACPI-rec  00000043fa610000-00000043fa6affff 000000a0    640KiB UC WC WT WB
ACPI-nvs  00000043fa6b0000-00000043fa6bffff 00000010     64KiB UC WC WT WB
ACPI-rec  00000043fa6c0000-00000043fa70ffff 00000050    320KiB UC WC WT WB
RT-code   00000043fa710000-00000043fa72ffff 00000020    128KiB RT UC WC WT WB
RT-data   00000043fa730000-00000043fa78ffff 00000060    384KiB RT UC WC WT WB
RT-code   00000043fa790000-00000043fa79ffff 00000010     64KiB RT UC WC WT WB
RT-data   00000043fa7a0000-00000043fa99ffff 00000200      2MiB RT UC WC WT WB
RT-code   00000043fa9a0000-00000043fa9affff 00000010     64KiB RT UC WC WT WB
RT-data   00000043fa9b0000-00000043fa9cffff 00000020    128KiB RT UC WC WT WB
BS-code   00000043fa9d0000-00000043fa9d9fff 0000000a     40KiB UC WC WT WB
reserved  00000043fa9da000-00000043fa9dbfff 00000002      8KiB UC WC WT WB
conv-mem  00000043fa9dc000-00000043fc29dfff 000018c2  25352KiB UC WC WT WB
BS-data   00000043fc29e000-00000043fc78afff 000004ed   5044KiB UC WC WT WB
conv-mem  00000043fc78b000-00000043fca01fff 00000277   2524KiB UC WC WT WB
BS-data   00000043fca02000-00000043fcea3fff 000004a2   4744KiB UC WC WT WB
conv-mem  00000043fcea4000-00000043fcea4fff 00000001      4KiB UC WC WT WB
BS-data   00000043fcea5000-00000043fd192fff 000002ee   3000KiB UC WC WT WB
conv-mem  00000043fd193000-00000043fd2b0fff 0000011e   1144KiB UC WC WT WB
BS-data   00000043fd2b1000-00000043ff80ffff 0000255f  38268KiB UC WC WT WB
BS-code   00000043ff810000-00000043ff99ffff 00000190   1600KiB UC WC WT WB
RT-code   00000043ff9a0000-00000043ff9affff 00000010     64KiB RT UC WC WT WB
conv-mem  00000043ff9b0000-00000043ff9bffff 00000010     64KiB UC WC WT WB
RT-data   00000043ff9c0000-00000043ff9effff 00000030    192KiB RT UC WC WT WB
conv-mem  00000043ff9f0000-00000043ffa05fff 00000016     88KiB UC WC WT WB
BS-data   00000043ffa06000-00000043ffffffff 000005fa   6120KiB UC WC WT WB
MMIO      0000000010510000-0000000010510fff 00000001      4KiB RT
MMIO      0000000010548000-0000000010549fff 00000002      8KiB RT
MMIO      0000000017000000-0000000017001fff 00000002      8KiB RT
MMIO      000000001c025000-000000001c025fff 00000001      4KiB RT

This patch adds a requirement when we're trying to find the base of ram, that
the memory we choose is actually /allocatable/ conventional memory, not merely
write-combining.  On this machine that means we wind up with an allocation
around 0x4392XXXXXX, which is a reasonable address.

This also changes grub_efi_allocate_pages_real() so that if 0 is allocated, it
tries to allocate again starting with the same max address it did the first
time, rather than interposing GRUB_EFI_MAX_USABLE_ADDRESS there, so that any
per-platform constraints on its given address are maintained.

Signed-off-by: Peter Jones <pjo...@redhat.com>

squash! arm/arm64 loader: Better memory allocation and error messages.

Use PRIxGRUB_* conversion specifier in printf's format string to
correspond properly to the data type of arguments.

Signed-off-by: Michael Chang <mch...@suse.com>
---
 grub-core/kern/efi/mm.c            | 33 ++++++++++---
 grub-core/loader/arm64/efi/linux.c | 78 ++++++++++++++++++++++--------
 2 files changed, 84 insertions(+), 27 deletions(-)

diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
index 15595a46e..324e1dca0 100644
--- a/grub-core/kern/efi/mm.c
+++ b/grub-core/kern/efi/mm.c
@@ -154,6 +154,7 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t 
address,
 {
   grub_efi_status_t status;
   grub_efi_boot_services_t *b;
+  grub_efi_physical_address_t ret = address;
 
   /* Limit the memory access to less than 4GB for 32-bit platforms.  */
   if (address > GRUB_EFI_MAX_USABLE_ADDRESS)
@@ -165,19 +166,22 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t 
address,
     }
 
   b = grub_efi_system_table->boot_services;
-  status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
+  status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &ret);
   if (status != GRUB_EFI_SUCCESS)
     {
+      grub_dprintf ("efi",
+                   "allocate_pages(%d, %d, 0x%0" PRIxGRUB_SIZE ", 0x%016" 
PRIxGRUB_UINT64_T ") = 0x%016" PRIxGRUB_SIZE "\n",
+                   alloctype, memtype, pages, address, status);
       grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
       return NULL;
     }
 
-  if (address == 0)
+  if (ret == 0)
     {
       /* Uggh, the address 0 was allocated... This is too annoying,
         so reallocate another one.  */
-      address = GRUB_EFI_MAX_USABLE_ADDRESS;
-      status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, 
&address);
+      ret = address;
+      status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &ret);
       grub_efi_free_pages (0, pages);
       if (status != GRUB_EFI_SUCCESS)
        {
@@ -186,9 +190,9 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t 
address,
        }
     }
 
-  grub_efi_store_alloc (address, pages);
+  grub_efi_store_alloc (ret, pages);
 
-  return (void *) ((grub_addr_t) address);
+  return (void *) ((grub_addr_t) ret);
 }
 
 void *
@@ -699,8 +703,21 @@ grub_efi_get_ram_base(grub_addr_t *base_addr)
   for (desc = memory_map, *base_addr = GRUB_EFI_MAX_USABLE_ADDRESS;
        (grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size);
        desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
-    if (desc->attribute & GRUB_EFI_MEMORY_WB)
-      *base_addr = grub_min (*base_addr, desc->physical_start);
+    {
+      if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY &&
+          (desc->attribute & GRUB_EFI_MEMORY_WB))
+        {
+          *base_addr = grub_min (*base_addr, desc->physical_start);
+          grub_dprintf ("efi", "setting base_addr=0x%016" PRIxGRUB_ADDR "\n", 
*base_addr);
+        }
+      else
+        {
+          grub_dprintf ("efi", "ignoring address 0x%016" PRIxGRUB_UINT64_T 
"\n", desc->physical_start);
+        }
+    }
+
+  if (*base_addr == GRUB_EFI_MAX_USABLE_ADDRESS)
+    grub_dprintf ("efi", "base_addr 0x%016" PRIxGRUB_ADDR " is probably 
wrong.\n", *base_addr);
 
   grub_free(memory_map);
 
diff --git a/grub-core/loader/arm64/efi/linux.c 
b/grub-core/loader/arm64/efi/linux.c
index 98c4f038b..4d084950a 100644
--- a/grub-core/loader/arm64/efi/linux.c
+++ b/grub-core/loader/arm64/efi/linux.c
@@ -116,13 +116,15 @@ finalize_params_linux (void)
 {
   grub_efi_loaded_image_t *loaded_image = NULL;
   int node, retval, len;
-
+  grub_err_t err = GRUB_ERR_NONE;
   void *fdt;
 
   fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
-
   if (!fdt)
-    goto failure;
+    {
+      err = grub_error(GRUB_ERR_BAD_OS, "failed to load FDT");
+      goto failure;
+    }
 
   node = grub_fdt_find_subnode (fdt, 0, "chosen");
   if (node < 0)
@@ -133,17 +135,26 @@ finalize_params_linux (void)
        */
       retval = grub_fdt_set_prop32(fdt, 0, "#address-cells", 2);
       if (retval)
-       goto failure;
+       {
+         err = grub_error(retval, "Could not find #address-cells");
+         goto failure;
+       }
 
       retval = grub_fdt_set_prop32(fdt, 0, "#size-cells", 2);
       if (retval)
-       goto failure;
+       {
+         err = grub_error(retval, "Could not find #size-cells");
+         goto failure;
+       }
 
       node = grub_fdt_add_subnode (fdt, 0, "chosen");
     }
 
   if (node < 1)
-    goto failure;
+    {
+      err = grub_error(grub_errno, "failed to load chosen fdt node.");
+      goto failure;
+    }
 
   /* Set initrd info */
   if (initrd_start && initrd_end > initrd_start)
@@ -154,15 +165,26 @@ finalize_params_linux (void)
       retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start",
                                    initrd_start);
       if (retval)
-       goto failure;
+       {
+         err = grub_error(retval, "Failed to set linux,initrd-start property");
+         goto failure;
+       }
+
       retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end",
                                    initrd_end);
       if (retval)
-       goto failure;
+       {
+         err = grub_error(retval, "Failed to set linux,initrd-end property");
+         goto failure;
+       }
     }
 
-  if (grub_fdt_install() != GRUB_ERR_NONE)
-    goto failure;
+  retval = grub_fdt_install();
+  if (retval != GRUB_ERR_NONE)
+    {
+      err = grub_error(retval, "Failed to install fdt");
+      goto failure;
+    }
 
   grub_dprintf ("linux", "Installed/updated FDT configuration table @ %p\n",
                fdt);
@@ -170,14 +192,20 @@ finalize_params_linux (void)
   /* Convert command line to UCS-2 */
   loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
   if (!loaded_image)
-    goto failure;
+    {
+      err = grub_error(grub_errno, "Failed to install fdt");
+      goto failure;
+    }
 
   loaded_image->load_options_size = len =
     (grub_strlen (linux_args) + 1) * sizeof (grub_efi_char16_t);
   loaded_image->load_options =
     grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES 
(loaded_image->load_options_size));
   if (!loaded_image->load_options)
-    return grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters");
+    {
+      err = grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters");
+      goto failure;
+    }
 
   loaded_image->load_options_size =
     2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
@@ -187,7 +215,7 @@ finalize_params_linux (void)
 
 failure:
   grub_fdt_unload();
-  return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
+  return err;
 }
 
 static void
@@ -272,16 +300,28 @@ grub_linux_unload (void)
 static void *
 allocate_initrd_mem (int initrd_pages)
 {
-  grub_addr_t max_addr;
+  grub_addr_t max_addr = 0;
+  grub_err_t err;
+  void *ret;
+
+  err = grub_efi_get_ram_base (&max_addr);
+  if (err != GRUB_ERR_NONE)
+    {
+      grub_error (err, "grub_efi_get_ram_base() failed");
+      return NULL;
+    }
 
-  if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE)
-    return NULL;
+  grub_dprintf ("linux", "max_addr: 0x%016lx, INITRD_MAX_ADDRESS_OFFSET: 
0x%016llx\n",
+               max_addr, INITRD_MAX_ADDRESS_OFFSET);
 
   max_addr += INITRD_MAX_ADDRESS_OFFSET - 1;
+  grub_dprintf ("linux", "calling grub_efi_allocate_pages_real (0x%016lx, 
0x%08x, EFI_ALLOCATE_MAX_ADDRESS, EFI_LOADER_DATA)", max_addr, initrd_pages);
 
-  return grub_efi_allocate_pages_real (max_addr, initrd_pages,
-                                      GRUB_EFI_ALLOCATE_MAX_ADDRESS,
-                                      GRUB_EFI_LOADER_DATA);
+  ret = grub_efi_allocate_pages_real (max_addr, initrd_pages,
+                                     GRUB_EFI_ALLOCATE_MAX_ADDRESS,
+                                     GRUB_EFI_LOADER_DATA);
+  grub_dprintf ("linux", "got 0x%016llx\n", (unsigned long long)ret);
+  return ret;
 }
 
 static grub_err_t
-- 
2.26.2

++++++ 0005-Make-linux_arm_kernel_header.hdr_offset-be-at-the-ri.patch ++++++
>From 669aa440ca34f6d8982c92b79fa2ee84c20618c6 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjo...@redhat.com>
Date: Thu, 16 Aug 2018 11:08:11 -0400
Subject: [PATCH 5/9] Make linux_arm_kernel_header.hdr_offset be at the right
 place

The kernel in front of me (slightly edited to make objdump work) looks like:

00000000  4d 5a 10 13 4d 5a 10 13  4d 5a 10 13 4d 5a 10 13  |MZ..MZ..MZ..MZ..|
00000010  4d 5a 10 13 4d 5a 10 13  4d 5a 10 13 00 00 a0 e1  |MZ..MZ..MZ......|
00000020  f6 03 00 ea 18 28 6f 01  00 00 00 00 00 32 74 00  |.....(o......2t.|
00000030  01 02 03 04 45 45 45 45  74 a2 00 00 40 00 00 00  |....EEEEt...@...|
00000040  50 45 00 00 4c 01 04 00  00 00 00 00 00 00 00 00  |PE..L...........|
00000050  00 00 00 00 90 00 06 03  0b 01 02 14 00 20 74 00  |............. t.|
00000060  00 14 00 00 00 00 00 00  b4 19 00 00 00 10 00 00  |................|
00000070  00 30 74 00 00 00 00 00  00 10 00 00 00 02 00 00  |.0t.............|
00000080  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000090  00 44 74 00 00 10 00 00  00 00 00 00 0a 00 00 00  |.Dt.............|
000000a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000000b0  00 00 00 00 06 00 00 00  00 00 00 00 00 00 00 00  |................|
000000c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*

(I don't know why the MZ header is there 7 times, but the offsets work out, so
it's merely a surprising distraction.)

If linux_arm_kernel_header.reserved2 is 16 bytes, that means hdr_offset is
here:

00000030  01 02 03 04 45 45 45 45  74 a2 00 00 40 00 00 00  |....EEEEt...@...|
00000040  50 45 00 00 4c 01 04 00  00 00 00 00 00 00 00 00  |PE..L...........|
          ^^^^^^^^^^^

But it's supposed to be 4 bytes before that.

This patch makes the reserved field be 3*32 instead of 4*32, and that means we
can find the PE header correcrtly at 0x40 by reading the value at 0x3c.

Signed-off-by: Peter Jones <pjo...@redhat.com>
---
 grub-core/loader/arm64/efi/linux.c | 3 +++
 include/grub/arm/linux.h           | 2 +-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/grub-core/loader/arm64/efi/linux.c 
b/grub-core/loader/arm64/efi/linux.c
index 4d084950a..83d09b7e5 100644
--- a/grub-core/loader/arm64/efi/linux.c
+++ b/grub-core/loader/arm64/efi/linux.c
@@ -86,7 +86,10 @@ grub_efi_linux_boot (void *kernel_address, grub_off_t offset,
 {
   handover_func hf;
 
+  grub_dprintf ("linux", "kernel_addr: %p handover_offset: %p params: %p\n",
+               kernel_address, (void *)(grub_efi_uintn_t)offset, 
kernel_params);
   hf = (handover_func)((char *)kernel_address + offset);
+  grub_dprintf ("linux", "handover_func() = %p\n", hf);
   hf (grub_efi_image_handle, grub_efi_system_table, kernel_params);
 
   return GRUB_ERR_BUG;
diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h
index 775297db8..b582f67f6 100644
--- a/include/grub/arm/linux.h
+++ b/include/grub/arm/linux.h
@@ -31,7 +31,7 @@ struct linux_arm_kernel_header {
   grub_uint32_t magic;
   grub_uint32_t start; /* _start */
   grub_uint32_t end;   /* _edata */
-  grub_uint32_t reserved2[4];
+  grub_uint32_t reserved2[3];
   grub_uint32_t hdr_offset;
 };
 
-- 
2.26.2

++++++ 0006-efi-Set-image-base-address-before-jumping-to-the-PE-.patch ++++++
>From 3741c6807923ae97b0d87e61c59c8de8af544484 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javi...@redhat.com>
Date: Thu, 23 Apr 2020 15:06:46 +0200
Subject: [PATCH 6/9] efi: Set image base address before jumping to the PE/COFF
 entry point

Upstream GRUB uses the EFI LoadImage() and StartImage() to boot the Linux
kernel. But our custom EFI loader that supports Secure Boot instead uses
the EFI handover protocol (for x86) or jumping directly to the PE/COFF
entry point (for aarch64).

This is done to allow the bootloader to verify the images using the shim
lock protocol to avoid booting untrusted binaries.

Since the bootloader loads the kernel from the boot media instead of using
LoadImage(), it is responsible to set the Loaded Image base address before
booting the kernel.

Otherwise the kernel EFI stub will complain that it was not set correctly
and print the following warning message:

EFI stub: ERROR: FIRMWARE BUG: efi_loaded_image_t::image_base has bogus value

Resolves: rhbz#1825411

Signed-off-by: Javier Martinez Canillas <javi...@redhat.com>
---
 grub-core/loader/arm64/efi/linux.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/grub-core/loader/arm64/efi/linux.c 
b/grub-core/loader/arm64/efi/linux.c
index 83d09b7e5..a4041be5c 100644
--- a/grub-core/loader/arm64/efi/linux.c
+++ b/grub-core/loader/arm64/efi/linux.c
@@ -84,8 +84,20 @@ static grub_err_t
 grub_efi_linux_boot (void *kernel_address, grub_off_t offset,
                     void *kernel_params)
 {
+  grub_efi_loaded_image_t *loaded_image = NULL;
   handover_func hf;
 
+  /*
+   * Since the EFI loader is not calling the LoadImage() and StartImage()
+   * services for loading the kernel and booting respectively, it has to
+   * set the Loaded Image base address.
+   */
+  loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
+  if (loaded_image)
+    loaded_image->image_base = kernel_addr;
+  else
+    grub_dprintf ("linux", "Loaded Image base address could not be set\n");
+
   grub_dprintf ("linux", "kernel_addr: %p handover_offset: %p params: %p\n",
                kernel_address, (void *)(grub_efi_uintn_t)offset, 
kernel_params);
   hf = (handover_func)((char *)kernel_address + offset);
-- 
2.26.2

++++++ 0007-linuxefi-fail-kernel-validation-without-shim-protoco.patch ++++++
>From 496890ebd2605eb1ff15f8d96c30b5d617f1bb85 Mon Sep 17 00:00:00 2001
From: Michael Chang <mch...@suse.com>
Date: Fri, 6 Nov 2020 11:19:06 +0000
Subject: [PATCH 7/9] linuxefi: fail kernel validation without shim protocol.

If certificates that signed grub are installed into db, grub can be
booted directly. It will then boot any kernel without signature
validation. The booted kernel will think it was booted in secureboot
mode and will implement lockdown, yet it could have been tampered.

This version of the patch skips calling verification, when booted
without secureboot. And is indented with gnu ident.

CVE-2020-15705

Reported-by: Mathieu Trudel-Lapierre <cypher...@ubuntu.com>
Signed-off-by: Michael Chang <mch...@suse.com>
---
 grub-core/loader/arm64/efi/linux.c | 38 +++++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 9 deletions(-)

diff --git a/grub-core/loader/arm64/efi/linux.c 
b/grub-core/loader/arm64/efi/linux.c
index a4041be5c..0e5782caa 100644
--- a/grub-core/loader/arm64/efi/linux.c
+++ b/grub-core/loader/arm64/efi/linux.c
@@ -58,21 +58,35 @@ struct grub_efi_shim_lock
 };
 typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
 
-static grub_efi_boolean_t
+// Returns 1 on success, -1 on error, 0 when not available
+static int
 grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
 {
   grub_efi_guid_t guid = SHIM_LOCK_GUID;
   grub_efi_shim_lock_t *shim_lock;
+  grub_efi_status_t status;
 
   shim_lock = grub_efi_locate_protocol(&guid, NULL);
-
+  grub_dprintf ("secureboot", "shim_lock: %p\n", shim_lock);
   if (!shim_lock)
-    return 1;
+    {
+      grub_dprintf ("secureboot", "shim not available\n");
+      return 0;
+    }
 
-  if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS)
-    return 1;
+  grub_dprintf ("secureboot", "Asking shim to verify kernel signature\n");
+  status = shim_lock->verify (data, size);
+  grub_dprintf ("secureboot", "shim_lock->verify(): %ld\n", (long int)status);
+  if (status == GRUB_EFI_SUCCESS)
+    {
+      grub_dprintf ("secureboot", "Kernel signature verification passed\n");
+      return 1;
+    }
 
-  return 0;
+  grub_dprintf ("secureboot", "Kernel signature verification failed (0x%lx)\n",
+               (unsigned long) status);
+
+  return -1;
 }
 
 #pragma GCC diagnostic push
@@ -399,6 +413,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
   struct linux_arch_kernel_header lh;
   struct grub_armxx_linux_pe_header *pe;
   grub_err_t err;
+  int rc;
 
   grub_dl_ref (my_mod);
 
@@ -443,10 +458,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ 
((unused)),
 
   grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
 
-  if (!grub_linuxefi_secure_validate (kernel_addr, kernel_size))
+  if (grub_efi_secure_boot ())
     {
-      grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), 
argv[0]);
-      goto fail;
+      rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size);
+      if (rc <= 0)
+       {
+         grub_error (GRUB_ERR_INVALID_COMMAND,
+                     N_("%s has invalid signature"), argv[0]);
+         goto fail;
+       }
     }
 
   pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
-- 
2.26.2

++++++ 0008-squash-Add-support-for-Linux-EFI-stub-loading-on-aar.patch ++++++
>From 5f98e139f74a1280dee4f1579eeab05e08541e8c Mon Sep 17 00:00:00 2001
From: Michael Chang <mch...@suse.com>
Date: Tue, 10 Nov 2020 04:33:21 +0000
Subject: [PATCH 8/9] squash! Add support for Linux EFI stub loading on
 aarch64.

Make efi handoff the default loader for arm64 platform.

Signed-off-by: Michael Chang <mch...@suse.com>
---
 grub-core/Makefile.core.def        |  4 +---
 grub-core/loader/arm64/efi/linux.c | 20 ++++++++++----------
 2 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index cfdd31431..ce4f71ebe 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1787,7 +1787,7 @@ module = {
   arm_coreboot = loader/arm/linux.c;
   arm_efi = loader/arm64/linux.c;
   arm_uboot = loader/arm/linux.c;
-  arm64 = loader/arm64/linux.c;
+  arm64 = loader/arm64/efi/linux.c;
   riscv32 = loader/riscv/linux.c;
   riscv64 = loader/riscv/linux.c;
   emu = loader/emu/linux.c;
@@ -1855,10 +1855,8 @@ module = {
 module = {
   name = linuxefi;
   x86 = lib/fake_module.c;
-  arm64 = loader/arm64/efi/linux.c;
   enable = i386_efi;
   enable = x86_64_efi;
-  enable = arm64_efi;
 };
 
 module = {
diff --git a/grub-core/loader/arm64/efi/linux.c 
b/grub-core/loader/arm64/efi/linux.c
index 0e5782caa..7a8c6dfe4 100644
--- a/grub-core/loader/arm64/efi/linux.c
+++ b/grub-core/loader/arm64/efi/linux.c
@@ -123,9 +123,8 @@ grub_efi_linux_boot (void *kernel_address, grub_off_t 
offset,
 
 #pragma GCC diagnostic pop
 
-/* FIXME: This is copy of grub_arch_efi_linux_check_image () */
-static grub_err_t
-grub_arch_efi_linux_check_image_XX (struct linux_arch_kernel_header * lh)
+grub_err_t
+grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
 {
   if (lh->magic != GRUB_LINUX_ARMXX_MAGIC_SIGNATURE)
     return grub_error(GRUB_ERR_BAD_OS, "invalid magic number");
@@ -263,9 +262,10 @@ free_params (void)
     }
 }
 
-/* FIXME: This is to replace grub_arch_efi_linux_boot_image */
-static grub_err_t
-grub_arch_efi_linux_boot_image_XX (grub_addr_t addr, char *args)
+grub_err_t
+grub_arch_efi_linux_boot_image (grub_addr_t addr,
+                               grub_size_t size __attribute__ ((unused)),
+                               char *args)
 {
   grub_err_t retval;
 
@@ -285,7 +285,7 @@ grub_arch_efi_linux_boot_image_XX (grub_addr_t addr, char 
*args)
 static grub_err_t
 grub_linux_boot (void)
 {
-  return (grub_arch_efi_linux_boot_image_XX ((grub_addr_t)kernel_addr, 
linux_args));
+  return (grub_arch_efi_linux_boot_image ((grub_addr_t)kernel_addr, 
kernel_size, linux_args));
 }
 
 static grub_err_t
@@ -432,7 +432,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
   if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh))
     return grub_errno;
 
-  if (grub_arch_efi_linux_check_image_XX (&lh) != GRUB_ERR_NONE)
+  if (grub_arch_efi_linux_check_image (&lh) != GRUB_ERR_NONE)
     goto fail;
 
   grub_loader_unset();
@@ -518,9 +518,9 @@ static grub_command_t cmd_linux, cmd_initrd;
 
 GRUB_MOD_INIT (linux)
 {
-  cmd_linux = grub_register_command ("linuxefi", grub_cmd_linux, 0,
+  cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0,
                                     N_("Load Linux."));
-  cmd_initrd = grub_register_command ("initrdefi", grub_cmd_initrd, 0,
+  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, 0,
                                      N_("Load initrd."));
   my_mod = mod;
 }
-- 
2.26.2

++++++ 0009-squash-Add-support-for-linuxefi.patch ++++++
>From 5d72f1ccbedcfc883e5f4cda60ea456cdc2b5dcd Mon Sep 17 00:00:00 2001
From: Michael Chang <mch...@suse.com>
Date: Sat, 30 Jan 2021 12:34:17 +0800
Subject: [PATCH 9/9] squash! Add support for linuxefi

The upstream commit

df84d6e94 efi: Print error messages to grub_efi_allocate_pages_real()

adds grub_error() to set error message and return grub_errno. We have to
unset the grub_errno if we want to ignore the error and proceed, or
the inadvertently provoked error handler would lead to unspecified
consequence.

Signed-off-by: Michael Chang <mch...@suse.com>
---
 grub-core/loader/i386/efi/linux.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/grub-core/loader/i386/efi/linux.c 
b/grub-core/loader/i386/efi/linux.c
index 3f6d51519..742b215a3 100644
--- a/grub-core/loader/i386/efi/linux.c
+++ b/grub-core/loader/i386/efi/linux.c
@@ -283,8 +283,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ 
((unused)),
                                       BYTES_TO_PAGES(lh.init_size));
 
   if (!kernel_mem)
-    kernel_mem = grub_efi_allocate_pages_max(0x3fffffff,
+    {
+      grub_errno = GRUB_ERR_NONE;
+      kernel_mem = grub_efi_allocate_pages_max(0x3fffffff,
                                             BYTES_TO_PAGES(lh.init_size));
+    }
 
   if (!kernel_mem)
     {
-- 
2.26.2


++++++ grub2-check-default.sh ++++++
--- /var/tmp/diff_new_pack.DGEa6R/_old  2021-02-07 15:13:56.957381970 +0100
+++ /var/tmp/diff_new_pack.DGEa6R/_new  2021-02-07 15:13:56.961381974 +0100
@@ -5,7 +5,7 @@
 fallback_entry () {
 
   local saved=$1
-  local FALLBACK_MATCH=`echo $saved | sed -e '/>/!d' -e '/>/s/>.*$//'`
+  local FALLBACK_MATCH=`echo $saved | sed -e '/>/!d' -e '/>.*$/s///'`
 
   if [ -n "$FALLBACK_MATCH" ]; then
     for i in $MENU_ENTRIES; do
@@ -35,7 +35,7 @@
 GRUB_EDITENV="/usr/bin/grub2-editenv"
 GRUB_SET_DEFAULT="/usr/sbin/grub2-set-default"
 
-SAVED_ENTRY=`${GRUB_EDITENV} list | sed -ne 
"/^saved_entry=/{s@\"\(.*\)\"@\1@;t 1;s@'\(.*\)'@\1@;: 1;s@^[^=]\+=@@;p;b}"`
+SAVED_ENTRY=`${GRUB_EDITENV} list | sed -ne "/^saved_entry=/s///p"`
 
 debug_print "SAVED_ENTRY=$SAVED_ENTRY"
 
@@ -101,7 +101,7 @@
 
 source /etc/os-release
 
-NEW_SAVED_ENTRY=`echo $SAVED_ENTRY | sed -ne "s/$NAME [0-9a-zA-Z_.-]\\+/$NAME 
$VERSION/pg"`
+NEW_SAVED_ENTRY=`echo $SAVED_ENTRY | sed -ne "s/$NAME 
[0-9a-zA-Z_.-]\{1,\}/$NAME $VERSION/pg"`
 
 debug_print "NEW_SAVED_ENTRY=$NEW_SAVED_ENTRY"
 

Reply via email to