diff --git a/README.debrand b/README.debrand
deleted file mode 100644
index 01c46d2..0000000
--- a/README.debrand
+++ /dev/null
@@ -1,2 +0,0 @@
-Warning: This package was configured for automatic debranding, but the changes
-failed to apply.
diff --git a/SOURCES/0501-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch b/SOURCES/0501-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch
new file mode 100644
index 0000000..a2d6ebc
--- /dev/null
+++ b/SOURCES/0501-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch
@@ -0,0 +1,221 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Stefan Berger <stefanb@linux.ibm.com>
+Date: Sun, 15 Mar 2020 12:37:10 -0400
+Subject: [PATCH] ibmvtpm: Add support for trusted boot using a vTPM 2.0
+
+Add support for trusted boot using a vTPM 2.0 on the IBM IEEE1275
+PowerPC platform. With this patch grub now measures text and binary data
+into the TPM's PCRs 8 and 9 in the same way as the x86_64 platform
+does.
+
+This patch requires Daniel Axtens's patches for claiming more memory.
+
+For vTPM support to work on PowerVM, system driver levels 1010.30
+or 1020.00 are required.
+
+Note: Previous versions of firmware levels with the 2hash-ext-log
+API call have a bug that, once this API call is invoked, has the
+effect of disabling the vTPM driver under Linux causing an error
+message to be displayed in the Linux kernel log. Those users will
+have to update their machines to the firmware levels mentioned
+above.
+
+Cc: Eric Snowberg <eric.snowberg@oracle.com>
+Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
+---
+ grub-core/Makefile.core.def           |   7 ++
+ grub-core/commands/ieee1275/ibmvtpm.c | 152 ++++++++++++++++++++++++++++++++++
+ include/grub/ieee1275/ieee1275.h      |   3 +
+ 3 files changed, 162 insertions(+)
+ create mode 100644 grub-core/commands/ieee1275/ibmvtpm.c
+
+diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
+index ef06f8c95a..b11f74e6b2 100644
+--- a/grub-core/Makefile.core.def
++++ b/grub-core/Makefile.core.def
+@@ -1104,6 +1104,13 @@ module = {
+   enable = powerpc_ieee1275;
+ };
+ 
++module = {
++  name = tpm;
++  common = commands/tpm.c;
++  ieee1275 = commands/ieee1275/ibmvtpm.c;
++  enable = powerpc_ieee1275;
++};
++
+ module = {
+   name = terminal;
+   common = commands/terminal.c;
+diff --git a/grub-core/commands/ieee1275/ibmvtpm.c b/grub-core/commands/ieee1275/ibmvtpm.c
+new file mode 100644
+index 0000000000..e68b8448bc
+--- /dev/null
++++ b/grub-core/commands/ieee1275/ibmvtpm.c
+@@ -0,0 +1,152 @@
++/*
++ *  GRUB  --  GRand Unified Bootloader
++ *  Copyright (C) 2021  Free Software Foundation, Inc.
++ *  Copyright (C) 2021  IBM Corporation
++ *
++ *  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/>.
++ *
++ *  IBM vTPM support code.
++ */
++
++#include <grub/err.h>
++#include <grub/types.h>
++#include <grub/tpm.h>
++#include <grub/ieee1275/ieee1275.h>
++#include <grub/mm.h>
++#include <grub/misc.h>
++
++static grub_ieee1275_ihandle_t tpm_ihandle;
++static grub_uint8_t tpm_version;
++
++#define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_ihandle_t)0)
++
++static void
++tpm_get_tpm_version (void)
++{
++  grub_ieee1275_phandle_t vtpm;
++  char buffer[20];
++
++  if (!grub_ieee1275_finddevice ("/vdevice/vtpm", &vtpm) &&
++      !grub_ieee1275_get_property (vtpm, "compatible", buffer,
++				   sizeof (buffer), NULL) &&
++      !grub_strcmp (buffer, "IBM,vtpm20"))
++    tpm_version = 2;
++}
++
++static grub_err_t
++tpm_init (void)
++{
++  static int init_success = 0;
++
++  if (!init_success)
++    {
++      if (grub_ieee1275_open ("/vdevice/vtpm", &tpm_ihandle) < 0) {
++        tpm_ihandle = IEEE1275_IHANDLE_INVALID;
++        return GRUB_ERR_UNKNOWN_DEVICE;
++      }
++
++      init_success = 1;
++
++      tpm_get_tpm_version ();
++    }
++
++  return GRUB_ERR_NONE;
++}
++
++static int
++ibmvtpm_2hash_ext_log (grub_uint8_t pcrindex,
++		       grub_uint32_t eventtype,
++		       const char *description,
++		       grub_size_t description_size,
++		       void *buf, grub_size_t size)
++{
++  struct tpm_2hash_ext_log
++  {
++    struct grub_ieee1275_common_hdr common;
++    grub_ieee1275_cell_t method;
++    grub_ieee1275_cell_t ihandle;
++    grub_ieee1275_cell_t size;
++    grub_ieee1275_cell_t buf;
++    grub_ieee1275_cell_t description_size;
++    grub_ieee1275_cell_t description;
++    grub_ieee1275_cell_t eventtype;
++    grub_ieee1275_cell_t pcrindex;
++    grub_ieee1275_cell_t catch_result;
++    grub_ieee1275_cell_t rc;
++  }
++  args;
++
++  INIT_IEEE1275_COMMON (&args.common, "call-method", 8, 2);
++  args.method = (grub_ieee1275_cell_t) "2hash-ext-log";
++  args.ihandle = tpm_ihandle;
++  args.pcrindex = pcrindex;
++  args.eventtype = eventtype;
++  args.description = (grub_ieee1275_cell_t) description;
++  args.description_size = description_size;
++  args.buf = (grub_ieee1275_cell_t) buf;
++  args.size = (grub_ieee1275_cell_t) size;
++
++  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
++    return -1;
++
++  /*
++   * catch_result is set if firmware does not support 2hash-ext-log
++   * rc is GRUB_IEEE1275_CELL_FALSE (0) on failure
++   */
++  if ((args.catch_result) || args.rc == GRUB_IEEE1275_CELL_FALSE)
++    return -1;
++
++  return 0;
++}
++
++static grub_err_t
++tpm2_log_event (unsigned char *buf,
++		grub_size_t size, grub_uint8_t pcr,
++		const char *description)
++{
++  static int error_displayed = 0;
++  int err;
++
++  err = ibmvtpm_2hash_ext_log (pcr, EV_IPL,
++			       description,
++			       grub_strlen(description) + 1,
++			       buf, size);
++  if (err && !error_displayed)
++    {
++      error_displayed++;
++      return grub_error (GRUB_ERR_BAD_DEVICE,
++	      "2HASH-EXT-LOG failed: Firmware is likely too old.\n");
++    }
++
++  return GRUB_ERR_NONE;
++}
++
++grub_err_t
++grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
++		  const char *description)
++{
++  grub_err_t err = tpm_init();
++
++  /* Absence of a TPM isn't a failure. */
++  if (err != GRUB_ERR_NONE)
++    return GRUB_ERR_NONE;
++
++  grub_dprintf ("tpm", "log_event, pcr = %d, size = 0x%" PRIxGRUB_SIZE ", %s\n",
++		pcr, size, description);
++
++  if (tpm_version == 2)
++    return tpm2_log_event (buf, size, pcr, description);
++
++  return GRUB_ERR_NONE;
++}
+diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h
+index 131808d619..87b9f95d34 100644
+--- a/include/grub/ieee1275/ieee1275.h
++++ b/include/grub/ieee1275/ieee1275.h
+@@ -24,6 +24,9 @@
+ #include <grub/types.h>
+ #include <grub/machine/ieee1275.h>
+ 
++#define GRUB_IEEE1275_CELL_FALSE       ((grub_ieee1275_cell_t) 0)
++#define GRUB_IEEE1275_CELL_TRUE        ((grub_ieee1275_cell_t) -1)
++
+ struct grub_ieee1275_mem_region
+ {
+   unsigned int start;
diff --git a/SOURCES/0501-loader-efi-chainloader-grub_load_and_start_image-doe.patch b/SOURCES/0501-loader-efi-chainloader-grub_load_and_start_image-doe.patch
deleted file mode 100644
index 1383d29..0000000
--- a/SOURCES/0501-loader-efi-chainloader-grub_load_and_start_image-doe.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Chris Coulson <chris.coulson@canonical.com>
-Date: Thu, 28 Apr 2022 21:53:36 +0100
-Subject: [PATCH] loader/efi/chainloader: grub_load_and_start_image doesn't
- load and start
-
-grub_load_and_start_image only loads an image - it still requires the
-caller to start it. This renames it to grub_load_image.
-
-It's called from 2 places:
-- grub_cmd_chainloader when not using the shim protocol.
-- grub_secureboot_chainloader_boot if handle_image returns an error.
-In this case, the image is loaded and then nothing else happens which
-seems strange. I assume the intention is that it falls back to LoadImage
-and StartImage if handle_image fails, so I've made it do that.
-
-Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
-(cherry picked from commit b4d70820a65c00561045856b7b8355461a9545f6)
-(cherry picked from commit 05b16a6be50b1910609740a66b561276fa490538)
-(cherry picked from commit 16486a34f3aa41a94e334e86db1a1e21e9b0a45f)
-(cherry picked from commit 4a23f40cb6400d94621de688a7e79dfe124f5a63)
----
- grub-core/loader/efi/chainloader.c | 16 +++++++++++++---
- 1 file changed, 13 insertions(+), 3 deletions(-)
-
-diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
-index 29663f7180..d75d345003 100644
---- a/grub-core/loader/efi/chainloader.c
-+++ b/grub-core/loader/efi/chainloader.c
-@@ -835,7 +835,7 @@ grub_secureboot_chainloader_unload (void)
- }
- 
- static grub_err_t
--grub_load_and_start_image(void *boot_image)
-+grub_load_image(void *boot_image)
- {
-   grub_efi_boot_services_t *b;
-   grub_efi_status_t status;
-@@ -877,13 +877,23 @@ grub_load_and_start_image(void *boot_image)
- static grub_err_t
- grub_secureboot_chainloader_boot (void)
- {
-+  grub_efi_boot_services_t *b;
-   int rc;
-+
-   rc = handle_image ((void *)(unsigned long)address, fsize);
-   if (rc == 0)
-     {
--      grub_load_and_start_image((void *)(unsigned long)address);
-+      /* We weren't able to attempt to execute the image, so fall back
-+       * to LoadImage / StartImage.
-+       */
-+      rc = grub_load_image((void *)(unsigned long)address);
-+      if (rc == 0)
-+        grub_chainloader_boot ();
-     }
- 
-+  b = grub_efi_system_table->boot_services;
-+  efi_call_1 (b->unload_image, image_handle);
-+
-   grub_loader_unset ();
-   return grub_errno;
- }
-@@ -1072,7 +1082,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
-     }
-   else if (rc == 0)
-     {
--      grub_load_and_start_image(boot_image);
-+      grub_load_image(boot_image);
-       grub_file_close (file);
-       grub_device_close (dev);
-       grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
diff --git a/SOURCES/0502-ibmvtpm-Backport-ibmvtpm-support-to-grub-2.02.patch b/SOURCES/0502-ibmvtpm-Backport-ibmvtpm-support-to-grub-2.02.patch
new file mode 100644
index 0000000..ba6a869
--- /dev/null
+++ b/SOURCES/0502-ibmvtpm-Backport-ibmvtpm-support-to-grub-2.02.patch
@@ -0,0 +1,94 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Stefan Berger <stefanb@linux.vnet.ibm.com>
+Date: Fri, 11 Feb 2022 16:34:23 -0500
+Subject: [PATCH] ibmvtpm: Backport ibmvtpm support to grub 2.02
+
+Backport ibmvtpm support to grub 2.02 by making as few changes to the
+source as possible and building it into the core.
+
+Since ibmvtpm support is built into grub 2.02 do not print the error
+message we would typically print if it was a module and the user had
+a choice to not use vTPM support if there was no vTPM by avoiding
+to use the module.
+
+Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
+---
+ grub-core/Makefile.core.def           |  8 +-------
+ grub-core/commands/ieee1275/ibmvtpm.c | 13 ++++++++++---
+ include/grub/tpm.h                    |  2 +-
+ 3 files changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
+index b11f74e6b2..637d7203e3 100644
+--- a/grub-core/Makefile.core.def
++++ b/grub-core/Makefile.core.def
+@@ -298,6 +298,7 @@ kernel = {
+   powerpc_ieee1275 = kern/powerpc/cache.S;
+   powerpc_ieee1275 = kern/powerpc/dl.c;
+   powerpc_ieee1275 = kern/powerpc/compiler-rt.S;
++  powerpc_ieee1275 = commands/ieee1275/ibmvtpm.c;
+ 
+   sparc64_ieee1275 = kern/sparc64/cache.S;
+   sparc64_ieee1275 = kern/sparc64/dl.c;
+@@ -1104,13 +1105,6 @@ module = {
+   enable = powerpc_ieee1275;
+ };
+ 
+-module = {
+-  name = tpm;
+-  common = commands/tpm.c;
+-  ieee1275 = commands/ieee1275/ibmvtpm.c;
+-  enable = powerpc_ieee1275;
+-};
+-
+ module = {
+   name = terminal;
+   common = commands/terminal.c;
+diff --git a/grub-core/commands/ieee1275/ibmvtpm.c b/grub-core/commands/ieee1275/ibmvtpm.c
+index e68b8448bc..728b2cbdcd 100644
+--- a/grub-core/commands/ieee1275/ibmvtpm.c
++++ b/grub-core/commands/ieee1275/ibmvtpm.c
+@@ -115,7 +115,8 @@ tpm2_log_event (unsigned char *buf,
+ 		grub_size_t size, grub_uint8_t pcr,
+ 		const char *description)
+ {
+-  static int error_displayed = 0;
++  /* Do not print error since vTPM support is built-in */
++  static int error_displayed = 1;
+   int err;
+ 
+   err = ibmvtpm_2hash_ext_log (pcr, EV_IPL,
+@@ -132,8 +133,8 @@ tpm2_log_event (unsigned char *buf,
+   return GRUB_ERR_NONE;
+ }
+ 
+-grub_err_t
+-grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
++static grub_err_t
++_grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
+ 		  const char *description)
+ {
+   grub_err_t err = tpm_init();
+@@ -150,3 +151,9 @@ grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
+ 
+   return GRUB_ERR_NONE;
+ }
++
++grub_err_t grub_tpm_log_event(unsigned char *buf, grub_size_t size,
++			      grub_uint8_t pcr, const char *description)
++{
++   return _grub_tpm_measure(buf, size, pcr, description);
++}
+diff --git a/include/grub/tpm.h b/include/grub/tpm.h
+index ce52be4ff7..52af2b8448 100644
+--- a/include/grub/tpm.h
++++ b/include/grub/tpm.h
+@@ -69,7 +69,7 @@ typedef struct {
+ grub_err_t EXPORT_FUNC(grub_tpm_measure) (unsigned char *buf, grub_size_t size,
+ 					  grub_uint8_t pcr, const char *kind,
+ 					  const char *description);
+-#if defined (GRUB_MACHINE_EFI)
++#if defined (GRUB_MACHINE_EFI) || defined (GRUB_MACHINE_IEEE1275)
+ grub_err_t grub_tpm_execute(PassThroughToTPM_InputParamBlock *inbuf,
+ 			    PassThroughToTPM_OutputParamBlock *outbuf);
+ grub_err_t grub_tpm_log_event(unsigned char *buf, grub_size_t size,
diff --git a/SOURCES/0502-loader-efi-chainloader-simplify-the-loader-state.patch b/SOURCES/0502-loader-efi-chainloader-simplify-the-loader-state.patch
deleted file mode 100644
index 4eb34ff..0000000
--- a/SOURCES/0502-loader-efi-chainloader-simplify-the-loader-state.patch
+++ /dev/null
@@ -1,335 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Chris Coulson <chris.coulson@canonical.com>
-Date: Fri, 29 Apr 2022 21:13:08 +0100
-Subject: [PATCH] loader/efi/chainloader: simplify the loader state
-
-When not using the shim lock protocol, the chainloader command retains
-the source buffer and device path passed to LoadImage, requiring the
-unload hook passed to grub_loader_set to free them. It isn't required
-to retain this state though - they aren't required by StartImage or
-anything else in the boot hook, so clean them up before
-grub_cmd_chainloader finishes.
-
-This also wraps the loader state when using the shim lock protocol
-inside a struct.
-
-Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
-(cherry picked from commit fa39862933b3be1553a580a3a5c28073257d8046)
-(cherry picked from commit 0333343ee99c4e88f062789263c94291c057251b)
-[rharwood: verifying twice]
-(cherry picked from commit 6080ad5d91d6a80d5f67c592dd33b6dd413e9453)
-[rharwood: double frees and unintialized, context fuzz - orig_dp]
-Signed-off-by: Robbie Harwood <rharwood@redhat.com>
-(cherry picked from commit b44b88ae45008611ec0469fb47139f4c0d1ee233)
----
- grub-core/loader/efi/chainloader.c | 160 +++++++++++++++++++++++--------------
- 1 file changed, 102 insertions(+), 58 deletions(-)
-
-diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
-index d75d345003..afeb1fc97e 100644
---- a/grub-core/loader/efi/chainloader.c
-+++ b/grub-core/loader/efi/chainloader.c
-@@ -47,38 +47,21 @@ GRUB_MOD_LICENSE ("GPLv3+");
- 
- static grub_dl_t my_mod;
- 
--static grub_efi_physical_address_t address;
--static grub_efi_uintn_t pages;
--static grub_ssize_t fsize;
--static grub_efi_device_path_t *file_path;
- static grub_efi_handle_t image_handle;
--static grub_efi_char16_t *cmdline;
--static grub_ssize_t cmdline_len;
--static grub_efi_handle_t dev_handle;
- 
--static grub_efi_status_t (*entry_point) (grub_efi_handle_t image_handle, grub_efi_system_table_t *system_table);
-+struct grub_secureboot_chainloader_context {
-+  grub_efi_physical_address_t address;
-+  grub_efi_uintn_t pages;
-+  grub_ssize_t fsize;
-+  grub_efi_device_path_t *file_path;
-+  grub_efi_char16_t *cmdline;
-+  grub_ssize_t cmdline_len;
-+  grub_efi_handle_t dev_handle;
-+};
-+static struct grub_secureboot_chainloader_context *sb_context;
- 
- static grub_err_t
--grub_chainloader_unload (void)
--{
--  grub_efi_boot_services_t *b;
--
--  b = grub_efi_system_table->boot_services;
--  efi_call_1 (b->unload_image, image_handle);
--  grub_efi_free_pages (address, pages);
--
--  grub_free (file_path);
--  grub_free (cmdline);
--  cmdline = 0;
--  file_path = 0;
--  dev_handle = 0;
--
--  grub_dl_unref (my_mod);
--  return GRUB_ERR_NONE;
--}
--
--static grub_err_t
--grub_chainloader_boot (void)
-+grub_start_image (grub_efi_handle_t handle)
- {
-   grub_efi_boot_services_t *b;
-   grub_efi_status_t status;
-@@ -86,7 +69,7 @@ grub_chainloader_boot (void)
-   grub_efi_char16_t *exit_data = NULL;
- 
-   b = grub_efi_system_table->boot_services;
--  status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data);
-+  status = efi_call_3 (b->start_image, handle, &exit_data_size, &exit_data);
-   if (status != GRUB_EFI_SUCCESS)
-     {
-       if (exit_data)
-@@ -110,11 +93,37 @@ grub_chainloader_boot (void)
-   if (exit_data)
-     grub_efi_free_pool (exit_data);
- 
--  grub_loader_unset ();
--
-   return grub_errno;
- }
- 
-+static grub_err_t
-+grub_chainloader_unload (void)
-+{
-+  grub_efi_loaded_image_t *loaded_image;
-+  grub_efi_boot_services_t *b;
-+
-+  loaded_image = grub_efi_get_loaded_image (image_handle);
-+  if (loaded_image != NULL)
-+    grub_free (loaded_image->load_options);
-+
-+  b = grub_efi_system_table->boot_services;
-+  efi_call_1 (b->unload_image, image_handle);
-+
-+  grub_dl_unref (my_mod);
-+  return GRUB_ERR_NONE;
-+}
-+
-+static grub_err_t
-+grub_chainloader_boot (void)
-+{
-+  grub_err_t err;
-+
-+  err = grub_start_image (image_handle);
-+
-+  grub_loader_unset ();
-+  return err;
-+}
-+
- static grub_err_t
- copy_file_path (grub_efi_file_path_device_path_t *fp,
- 		const char *str, grub_efi_uint16_t len)
-@@ -149,7 +158,7 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
-   char *dir_start;
-   char *dir_end;
-   grub_size_t size;
--  grub_efi_device_path_t *d;
-+  grub_efi_device_path_t *d, *file_path;
- 
-   dir_start = grub_strchr (filename, ')');
-   if (! dir_start)
-@@ -520,10 +529,12 @@ grub_efi_get_media_file_path (grub_efi_device_path_t *dp)
- }
- 
- static grub_efi_boolean_t
--handle_image (void *data, grub_efi_uint32_t datasize)
-+handle_image (struct grub_secureboot_chainloader_context *load_context)
- {
-   grub_efi_loaded_image_t *li, li_bak;
-   grub_efi_status_t efi_status;
-+  void *data = (void *)(unsigned long)load_context->address;
-+  grub_efi_uint32_t datasize = load_context->fsize;
-   void *buffer = NULL;
-   char *buffer_aligned = NULL;
-   grub_efi_uint32_t i;
-@@ -534,6 +545,7 @@ handle_image (void *data, grub_efi_uint32_t datasize)
-   grub_uint32_t buffer_size;
-   int found_entry_point = 0;
-   int rc;
-+  grub_efi_status_t (*entry_point) (grub_efi_handle_t image_handle, grub_efi_system_table_t *system_table);
- 
-   rc = read_header (data, datasize, &context);
-   if (rc < 0)
-@@ -791,10 +803,10 @@ handle_image (void *data, grub_efi_uint32_t datasize)
-   grub_memcpy (&li_bak, li, sizeof (grub_efi_loaded_image_t));
-   li->image_base = buffer_aligned;
-   li->image_size = context.image_size;
--  li->load_options = cmdline;
--  li->load_options_size = cmdline_len;
--  li->file_path = grub_efi_get_media_file_path (file_path);
--  li->device_handle = dev_handle;
-+  li->load_options = load_context->cmdline;
-+  li->load_options_size = load_context->cmdline_len;
-+  li->file_path = grub_efi_get_media_file_path (load_context->file_path);
-+  li->device_handle = load_context->dev_handle;
-   if (!li->file_path)
-     {
-       grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching file path found");
-@@ -823,19 +835,22 @@ error_exit:
- static grub_err_t
- grub_secureboot_chainloader_unload (void)
- {
--  grub_efi_free_pages (address, pages);
--  grub_free (file_path);
--  grub_free (cmdline);
--  cmdline = 0;
--  file_path = 0;
--  dev_handle = 0;
-+  grub_efi_free_pages (sb_context->address, sb_context->pages);
-+  grub_free (sb_context->file_path);
-+  grub_free (sb_context->cmdline);
-+  grub_free (sb_context);
-+
-+  sb_context = 0;
- 
-   grub_dl_unref (my_mod);
-   return GRUB_ERR_NONE;
- }
- 
- static grub_err_t
--grub_load_image(void *boot_image)
-+grub_load_image(grub_efi_device_path_t *file_path, void *boot_image,
-+		grub_efi_uintn_t image_size, grub_efi_handle_t dev_handle,
-+		grub_efi_char16_t *cmdline, grub_ssize_t cmdline_len,
-+		grub_efi_handle_t *image_handle_out)
- {
-   grub_efi_boot_services_t *b;
-   grub_efi_status_t status;
-@@ -844,7 +859,7 @@ grub_load_image(void *boot_image)
-   b = grub_efi_system_table->boot_services;
- 
-   status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path,
--		       boot_image, fsize, &image_handle);
-+		       boot_image, image_size, image_handle_out);
-   if (status != GRUB_EFI_SUCCESS)
-     {
-       if (status == GRUB_EFI_OUT_OF_RESOURCES)
-@@ -857,7 +872,7 @@ grub_load_image(void *boot_image)
-   /* LoadImage does not set a device handler when the image is
-      loaded from memory, so it is necessary to set it explicitly here.
-      This is a mess.  */
--  loaded_image = grub_efi_get_loaded_image (image_handle);
-+  loaded_image = grub_efi_get_loaded_image (*image_handle_out);
-   if (! loaded_image)
-     {
-       grub_error (GRUB_ERR_BAD_OS, "no loaded image available");
-@@ -879,20 +894,25 @@ grub_secureboot_chainloader_boot (void)
- {
-   grub_efi_boot_services_t *b;
-   int rc;
-+  grub_efi_handle_t handle = 0;
- 
--  rc = handle_image ((void *)(unsigned long)address, fsize);
-+  rc = handle_image (sb_context);
-   if (rc == 0)
-     {
-       /* We weren't able to attempt to execute the image, so fall back
-        * to LoadImage / StartImage.
-        */
--      rc = grub_load_image((void *)(unsigned long)address);
-+      rc = grub_load_image(sb_context->file_path,
-+			   (void *)(unsigned long)sb_context->address,
-+			   sb_context->fsize, sb_context->dev_handle,
-+			   sb_context->cmdline, sb_context->cmdline_len,
-+			   &handle);
-       if (rc == 0)
--        grub_chainloader_boot ();
-+	grub_start_image (handle);
-     }
- 
-   b = grub_efi_system_table->boot_services;
--  efi_call_1 (b->unload_image, image_handle);
-+  efi_call_1 (b->unload_image, handle);
- 
-   grub_loader_unset ();
-   return grub_errno;
-@@ -906,10 +926,16 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
-   grub_efi_status_t status;
-   grub_efi_boot_services_t *b;
-   grub_device_t dev = 0;
--  grub_efi_device_path_t *dp = 0;
-+  grub_efi_device_path_t *dp = 0, *file_path = 0;
-   char *filename;
-   void *boot_image = 0;
-   int rc;
-+  grub_efi_physical_address_t address = 0;
-+  grub_ssize_t fsize;
-+  grub_efi_uintn_t pages = 0;
-+  grub_efi_char16_t *cmdline = 0;
-+  grub_ssize_t cmdline_len = 0;
-+  grub_efi_handle_t dev_handle = 0;
- 
-   if (argc == 0)
-     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
-@@ -917,12 +943,6 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
- 
-   grub_dl_ref (my_mod);
- 
--  /* Initialize some global variables.  */
--  address = 0;
--  image_handle = 0;
--  file_path = 0;
--  dev_handle = 0;
--
-   b = grub_efi_system_table->boot_services;
- 
-   if (argc > 1)
-@@ -1074,17 +1094,35 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
-   grub_dprintf ("chain", "linuxefi_secure_validate: %d\n", rc);
-   if (rc > 0)
-     {
-+      sb_context = grub_malloc (sizeof (*sb_context));
-+      if (sb_context == NULL)
-+        goto fail;
-+      sb_context->address = address;
-+      sb_context->fsize = fsize;
-+      sb_context->pages = pages;
-+      sb_context->file_path = file_path;
-+      sb_context->cmdline = cmdline;
-+      sb_context->cmdline_len = cmdline_len;
-+      sb_context->dev_handle = dev_handle;
-+
-       grub_file_close (file);
-       grub_device_close (dev);
-+
-       grub_loader_set (grub_secureboot_chainloader_boot,
- 		       grub_secureboot_chainloader_unload, 0);
-       return 0;
-     }
-   else if (rc == 0)
-     {
--      grub_load_image(boot_image);
-+      grub_load_image(file_path, boot_image, fsize, dev_handle, cmdline,
-+		      cmdline_len, &image_handle);
-       grub_file_close (file);
-       grub_device_close (dev);
-+
-+      /* We're finished with the source image buffer and file path now */
-+      efi_call_2 (b->free_pages, address, pages);
-+      grub_free (file_path);
-+
-       grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
- 
-       return 0;
-@@ -1106,6 +1144,12 @@ fail:
-   if (cmdline)
-     grub_free (cmdline);
- 
-+  if (image_handle != 0)
-+    {
-+      efi_call_1 (b->unload_image, image_handle);
-+      image_handle = 0;
-+    }
-+
-   grub_dl_unref (my_mod);
- 
-   return grub_errno;
diff --git a/SOURCES/0503-commands-boot-Add-API-to-pass-context-to-loader.patch b/SOURCES/0503-commands-boot-Add-API-to-pass-context-to-loader.patch
deleted file mode 100644
index 4270078..0000000
--- a/SOURCES/0503-commands-boot-Add-API-to-pass-context-to-loader.patch
+++ /dev/null
@@ -1,161 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Chris Coulson <chris.coulson@canonical.com>
-Date: Fri, 29 Apr 2022 21:16:02 +0100
-Subject: [PATCH] commands/boot: Add API to pass context to loader
-
-Loaders rely on global variables for saving context which is consumed
-in the boot hook and freed in the unload hook. In the case where a loader
-command is executed twice, calling grub_loader_set a second time executes
-the unload hook, but in some cases this runs when the loader's global
-context has already been updated, resulting in the updated context being
-freed and potential use-after-free bugs when the boot hook is subsequently
-called.
-
-This adds a new API (grub_loader_set_ex) which allows a loader to specify
-context that is passed to its boot and unload hooks. This is an alternative
-to requiring that loaders call grub_loader_unset before mutating their
-global context.
-
-Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
-(cherry picked from commit 4322a64dde7e8fedb58e50b79408667129d45dd3)
-(cherry picked from commit 937ad0e2159b6b8cb0d2ce3515da3a8b797c7927)
-(cherry picked from commit 873038ae7048f6cae8a3ebb2f97a8d361a080e13)
-(cherry picked from commit 7eefe9ba7e8f1557705f0f854ab7a3014d6cb5e2)
----
- grub-core/commands/boot.c | 66 +++++++++++++++++++++++++++++++++++++++++------
- include/grub/loader.h     |  5 ++++
- 2 files changed, 63 insertions(+), 8 deletions(-)
-
-diff --git a/grub-core/commands/boot.c b/grub-core/commands/boot.c
-index bbca81e947..53691a62d9 100644
---- a/grub-core/commands/boot.c
-+++ b/grub-core/commands/boot.c
-@@ -27,10 +27,20 @@
- 
- GRUB_MOD_LICENSE ("GPLv3+");
- 
--static grub_err_t (*grub_loader_boot_func) (void);
--static grub_err_t (*grub_loader_unload_func) (void);
-+static grub_err_t (*grub_loader_boot_func) (void *);
-+static grub_err_t (*grub_loader_unload_func) (void *);
-+static void *grub_loader_context;
- static int grub_loader_flags;
- 
-+struct grub_simple_loader_hooks
-+{
-+  grub_err_t (*boot) (void);
-+  grub_err_t (*unload) (void);
-+};
-+
-+/* Don't heap allocate this to avoid making grub_loader_set fallible. */
-+static struct grub_simple_loader_hooks simple_loader_hooks;
-+
- struct grub_preboot
- {
-   grub_err_t (*preboot_func) (int);
-@@ -44,6 +54,29 @@ static int grub_loader_loaded;
- static struct grub_preboot *preboots_head = 0,
-   *preboots_tail = 0;
- 
-+static grub_err_t
-+grub_simple_boot_hook (void *context)
-+{
-+  struct grub_simple_loader_hooks *hooks;
-+
-+  hooks = (struct grub_simple_loader_hooks *) context;
-+  return hooks->boot ();
-+}
-+
-+static grub_err_t
-+grub_simple_unload_hook (void *context)
-+{
-+  struct grub_simple_loader_hooks *hooks;
-+  grub_err_t ret;
-+
-+  hooks = (struct grub_simple_loader_hooks *) context;
-+
-+  ret = hooks->unload ();
-+  grub_memset (hooks, 0, sizeof (*hooks));
-+
-+  return ret;
-+}
-+
- int
- grub_loader_is_loaded (void)
- {
-@@ -110,28 +143,45 @@ grub_loader_unregister_preboot_hook (struct grub_preboot *hnd)
- }
- 
- void
--grub_loader_set (grub_err_t (*boot) (void),
--		 grub_err_t (*unload) (void),
--		 int flags)
-+grub_loader_set_ex (grub_err_t (*boot) (void *),
-+		    grub_err_t (*unload) (void *),
-+		    void *context,
-+		    int flags)
- {
-   if (grub_loader_loaded && grub_loader_unload_func)
--    grub_loader_unload_func ();
-+    grub_loader_unload_func (grub_loader_context);
- 
-   grub_loader_boot_func = boot;
-   grub_loader_unload_func = unload;
-+  grub_loader_context = context;
-   grub_loader_flags = flags;
- 
-   grub_loader_loaded = 1;
- }
- 
-+void
-+grub_loader_set (grub_err_t (*boot) (void),
-+		 grub_err_t (*unload) (void),
-+		 int flags)
-+{
-+  grub_loader_set_ex (grub_simple_boot_hook,
-+		      grub_simple_unload_hook,
-+		      &simple_loader_hooks,
-+		      flags);
-+
-+  simple_loader_hooks.boot = boot;
-+  simple_loader_hooks.unload = unload;
-+}
-+
- void
- grub_loader_unset(void)
- {
-   if (grub_loader_loaded && grub_loader_unload_func)
--    grub_loader_unload_func ();
-+    grub_loader_unload_func (grub_loader_context);
- 
-   grub_loader_boot_func = 0;
-   grub_loader_unload_func = 0;
-+  grub_loader_context = 0;
- 
-   grub_loader_loaded = 0;
- }
-@@ -158,7 +208,7 @@ grub_loader_boot (void)
- 	  return err;
- 	}
-     }
--  err = (grub_loader_boot_func) ();
-+  err = (grub_loader_boot_func) (grub_loader_context);
- 
-   for (cur = preboots_tail; cur; cur = cur->prev)
-     if (! err)
-diff --git a/include/grub/loader.h b/include/grub/loader.h
-index b208642821..1846fa6c5f 100644
---- a/include/grub/loader.h
-+++ b/include/grub/loader.h
-@@ -40,6 +40,11 @@ void EXPORT_FUNC (grub_loader_set) (grub_err_t (*boot) (void),
- 				    grub_err_t (*unload) (void),
- 				    int flags);
- 
-+void EXPORT_FUNC (grub_loader_set_ex) (grub_err_t (*boot) (void *),
-+				       grub_err_t (*unload) (void *),
-+				       void *context,
-+				       int flags);
-+
- /* Unset current loader, if any.  */
- void EXPORT_FUNC (grub_loader_unset) (void);
- 
diff --git a/SOURCES/0503-powerpc-do-CAS-in-a-more-compatible-way.patch b/SOURCES/0503-powerpc-do-CAS-in-a-more-compatible-way.patch
new file mode 100644
index 0000000..b33cab3
--- /dev/null
+++ b/SOURCES/0503-powerpc-do-CAS-in-a-more-compatible-way.patch
@@ -0,0 +1,112 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Fri, 8 Apr 2022 12:35:28 +1000
+Subject: [PATCH] powerpc: do CAS in a more compatible way
+
+I wrongly assumed that the most compatible way to perform CAS
+negotiation was to only set the minimum number of vectors required
+to ask for more memory. It turns out that this messes up booting
+if the minimum VP capacity would be less than the default 10% in
+vector 4.
+
+Linux configures the minimum capacity to be 1%, so copy it for that
+and for vector 3 which we now need to specify as well.
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+(cherry picked from commit e6f02ad4e75cd995a8ee2954d28949c415b6cbfe)
+(cherry picked from commit 9f825ebc319c56ca503741e6dc1a0f27ff36fe2d)
+---
+ grub-core/kern/ieee1275/init.c | 54 ++++++++++++++++++++++++------------------
+ 1 file changed, 31 insertions(+), 23 deletions(-)
+
+diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
+index adf4bd5a88..1414695cc6 100644
+--- a/grub-core/kern/ieee1275/init.c
++++ b/grub-core/kern/ieee1275/init.c
+@@ -294,33 +294,37 @@ grub_ieee1275_total_mem (grub_uint64_t *total)
+ 
+ /* Based on linux - arch/powerpc/kernel/prom_init.c */
+ struct option_vector2 {
+-	grub_uint8_t byte1;
+-	grub_uint16_t reserved;
+-	grub_uint32_t real_base;
+-	grub_uint32_t real_size;
+-	grub_uint32_t virt_base;
+-	grub_uint32_t virt_size;
+-	grub_uint32_t load_base;
+-	grub_uint32_t min_rma;
+-	grub_uint32_t min_load;
+-	grub_uint8_t min_rma_percent;
+-	grub_uint8_t max_pft_size;
++  grub_uint8_t byte1;
++  grub_uint16_t reserved;
++  grub_uint32_t real_base;
++  grub_uint32_t real_size;
++  grub_uint32_t virt_base;
++  grub_uint32_t virt_size;
++  grub_uint32_t load_base;
++  grub_uint32_t min_rma;
++  grub_uint32_t min_load;
++  grub_uint8_t min_rma_percent;
++  grub_uint8_t max_pft_size;
+ } __attribute__((packed));
+ 
+ struct pvr_entry {
+-	  grub_uint32_t mask;
+-	  grub_uint32_t entry;
++  grub_uint32_t mask;
++  grub_uint32_t entry;
+ };
+ 
+ struct cas_vector {
+-    struct {
+-      struct pvr_entry terminal;
+-    } pvr_list;
+-    grub_uint8_t num_vecs;
+-    grub_uint8_t vec1_size;
+-    grub_uint8_t vec1;
+-    grub_uint8_t vec2_size;
+-    struct option_vector2 vec2;
++  struct {
++    struct pvr_entry terminal;
++  } pvr_list;
++  grub_uint8_t num_vecs;
++  grub_uint8_t vec1_size;
++  grub_uint8_t vec1;
++  grub_uint8_t vec2_size;
++  struct option_vector2 vec2;
++  grub_uint8_t vec3_size;
++  grub_uint16_t vec3;
++  grub_uint8_t vec4_size;
++  grub_uint16_t vec4;
+ } __attribute__((packed));
+ 
+ /* Call ibm,client-architecture-support to try to get more RMA.
+@@ -341,13 +345,17 @@ grub_ieee1275_ibm_cas (void)
+   } args;
+   struct cas_vector vector = {
+     .pvr_list = { { 0x00000000, 0xffffffff } }, /* any processor */
+-    .num_vecs = 2 - 1,
++    .num_vecs = 4 - 1,
+     .vec1_size = 0,
+     .vec1 = 0x80, /* ignore */
+     .vec2_size = 1 + sizeof(struct option_vector2) - 2,
+     .vec2 = {
+       0, 0, -1, -1, -1, -1, -1, 512, -1, 0, 48
+     },
++    .vec3_size = 2 - 1,
++    .vec3 = 0x00e0, // ask for FP + VMX + DFP but don't halt if unsatisfied
++    .vec4_size = 2 - 1,
++    .vec4 = 0x0001, // set required minimum capacity % to the lowest value
+   };
+ 
+   INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2);
+@@ -360,7 +368,7 @@ grub_ieee1275_ibm_cas (void)
+   args.ihandle = root;
+   args.cas_addr = (grub_ieee1275_cell_t)&vector;
+ 
+-  grub_printf("Calling ibm,client-architecture-support...");
++  grub_printf("Calling ibm,client-architecture-support from grub...");
+   IEEE1275_CALL_ENTRY_FN (&args);
+   grub_printf("done\n");
+ 
diff --git a/SOURCES/0504-loader-efi-chainloader-Use-grub_loader_set_ex.patch b/SOURCES/0504-loader-efi-chainloader-Use-grub_loader_set_ex.patch
deleted file mode 100644
index 4ccc6df..0000000
--- a/SOURCES/0504-loader-efi-chainloader-Use-grub_loader_set_ex.patch
+++ /dev/null
@@ -1,150 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Chris Coulson <chris.coulson@canonical.com>
-Date: Fri, 29 Apr 2022 21:30:56 +0100
-Subject: [PATCH] loader/efi/chainloader: Use grub_loader_set_ex
-
-This ports the EFI chainloader to use grub_loader_set_ex in order to fix
-a use-after-free bug that occurs when grub_cmd_chainloader is executed
-more than once before a boot attempt is performed.
-
-Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
-(cherry picked from commit 4b7f0402b7cb0f67a93be736f2b75b818d7f44c9)
-(cherry picked from commit fc1a79bf0e0bc019362ace46d908a92b48dcd55b)
-(cherry picked from commit f5b653dfe00271384ff7fbd82db926ab95dbd80e)
-(cherry picked from commit 535a9d787f71ed6eb43e7c3a136a149684ec62ea)
-[rharwood: context sludge from previous commit]
-Signed-off-by: Robbie Harwood <rharwood@redhat.com>
----
- grub-core/loader/efi/chainloader.c | 38 ++++++++++++++++++++++----------------
- 1 file changed, 22 insertions(+), 16 deletions(-)
-
-diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
-index afeb1fc97e..720f6181e5 100644
---- a/grub-core/loader/efi/chainloader.c
-+++ b/grub-core/loader/efi/chainloader.c
-@@ -47,8 +47,6 @@ GRUB_MOD_LICENSE ("GPLv3+");
- 
- static grub_dl_t my_mod;
- 
--static grub_efi_handle_t image_handle;
--
- struct grub_secureboot_chainloader_context {
-   grub_efi_physical_address_t address;
-   grub_efi_uintn_t pages;
-@@ -58,7 +56,6 @@ struct grub_secureboot_chainloader_context {
-   grub_ssize_t cmdline_len;
-   grub_efi_handle_t dev_handle;
- };
--static struct grub_secureboot_chainloader_context *sb_context;
- 
- static grub_err_t
- grub_start_image (grub_efi_handle_t handle)
-@@ -97,11 +94,14 @@ grub_start_image (grub_efi_handle_t handle)
- }
- 
- static grub_err_t
--grub_chainloader_unload (void)
-+grub_chainloader_unload (void *context)
- {
-+  grub_efi_handle_t image_handle;
-   grub_efi_loaded_image_t *loaded_image;
-   grub_efi_boot_services_t *b;
- 
-+  image_handle = (grub_efi_handle_t) context;
-+
-   loaded_image = grub_efi_get_loaded_image (image_handle);
-   if (loaded_image != NULL)
-     grub_free (loaded_image->load_options);
-@@ -114,10 +114,12 @@ grub_chainloader_unload (void)
- }
- 
- static grub_err_t
--grub_chainloader_boot (void)
-+grub_chainloader_boot (void *context)
- {
-+  grub_efi_handle_t image_handle;
-   grub_err_t err;
- 
-+  image_handle = (grub_efi_handle_t) context;
-   err = grub_start_image (image_handle);
- 
-   grub_loader_unset ();
-@@ -833,15 +835,17 @@ error_exit:
- }
- 
- static grub_err_t
--grub_secureboot_chainloader_unload (void)
-+grub_secureboot_chainloader_unload (void *context)
- {
-+  struct grub_secureboot_chainloader_context *sb_context;
-+
-+  sb_context = (struct grub_secureboot_chainloader_context *) context;
-+
-   grub_efi_free_pages (sb_context->address, sb_context->pages);
-   grub_free (sb_context->file_path);
-   grub_free (sb_context->cmdline);
-   grub_free (sb_context);
- 
--  sb_context = 0;
--
-   grub_dl_unref (my_mod);
-   return GRUB_ERR_NONE;
- }
-@@ -890,12 +894,15 @@ grub_load_image(grub_efi_device_path_t *file_path, void *boot_image,
- }
- 
- static grub_err_t
--grub_secureboot_chainloader_boot (void)
-+grub_secureboot_chainloader_boot (void *context)
- {
-+  struct grub_secureboot_chainloader_context *sb_context;
-   grub_efi_boot_services_t *b;
-   int rc;
-   grub_efi_handle_t handle = 0;
- 
-+  sb_context = (struct grub_secureboot_chainloader_context *) context;
-+
-   rc = handle_image (sb_context);
-   if (rc == 0)
-     {
-@@ -936,6 +943,8 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
-   grub_efi_char16_t *cmdline = 0;
-   grub_ssize_t cmdline_len = 0;
-   grub_efi_handle_t dev_handle = 0;
-+  grub_efi_handle_t image_handle = 0;
-+  struct grub_secureboot_chainloader_context *sb_context = 0;
- 
-   if (argc == 0)
-     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
-@@ -1108,8 +1117,8 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
-       grub_file_close (file);
-       grub_device_close (dev);
- 
--      grub_loader_set (grub_secureboot_chainloader_boot,
--		       grub_secureboot_chainloader_unload, 0);
-+      grub_loader_set_ex (grub_secureboot_chainloader_boot,
-+			  grub_secureboot_chainloader_unload, sb_context, 0);
-       return 0;
-     }
-   else if (rc == 0)
-@@ -1123,7 +1132,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
-       efi_call_2 (b->free_pages, address, pages);
-       grub_free (file_path);
- 
--      grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
-+      grub_loader_set_ex (grub_chainloader_boot, grub_chainloader_unload, image_handle, 0);
- 
-       return 0;
-     }
-@@ -1145,10 +1154,7 @@ fail:
-     grub_free (cmdline);
- 
-   if (image_handle != 0)
--    {
--      efi_call_1 (b->unload_image, image_handle);
--      image_handle = 0;
--    }
-+    efi_call_1 (b->unload_image, image_handle);
- 
-   grub_dl_unref (my_mod);
- 
diff --git a/SOURCES/0504-powerpc-prefix-detection-support-device-names-with-c.patch b/SOURCES/0504-powerpc-prefix-detection-support-device-names-with-c.patch
new file mode 100644
index 0000000..50a5d64
--- /dev/null
+++ b/SOURCES/0504-powerpc-prefix-detection-support-device-names-with-c.patch
@@ -0,0 +1,73 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Thu, 24 Mar 2022 14:34:32 +1100
+Subject: [PATCH] powerpc: prefix detection: support device names with commas
+
+Frustratingly, the device name itself can contain an embedded comma:
+e.g /pci@800000020000015/pci1014,034A@0/sas/disk@5000c50098a0ee8b
+
+So my previous approach was wrong: we cannot rely upon the presence
+of a comma to say that a partition has been specified!
+
+It turns out for prefixes like (,gpt2)/grub2 we really want to make
+up a full (device,partition)/patch prefix, because root discovery code
+in 10_linux will reset the root variable and use search to fill it again.
+If you have run grub-install, you probably don't have search built in,
+and if you don't have prefix containing (device,partition), grub will
+construct ($root)$prefix/powerpc-ieee1275/search.mod - but because $root
+has just been changed, this will no longer work, and the boot will fail!
+
+Retain the gist of the logic, but instead of looking for a comma, look for
+a leading '('. This matches the earlier code better anyway.
+
+There's certainly a better fix to be had. But any time you chose to build
+with a bare prefix like '/grub2', you're almost certainly going to build in
+search anyway, so this will do.
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+(cherry picked from commit 80b6eb5e55e6d1a4c9896361e61de31c29e6939d)
+(cherry picked from commit f3df9f1c2335df22d020e80583d932e254594f0e)
+---
+ grub-core/kern/main.c | 27 +++++++++++++++++++++------
+ 1 file changed, 21 insertions(+), 6 deletions(-)
+
+diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
+index 40a709117f..abbf8af9e6 100644
+--- a/grub-core/kern/main.c
++++ b/grub-core/kern/main.c
+@@ -241,14 +241,29 @@ grub_set_prefix_and_root (void)
+ 	    what sorts of paths represent disks with partition tables and those
+ 	    without partition tables.
+ 
+-	 So we act unless there is a comma in the device, which would indicate
+-	 a partition has already been specified.
++          - Frustratingly, the device name itself can contain an embedded comma:
++            /pci@800000020000015/pci1014,034A@0/sas/disk@5000c50098a0ee8b
++            So we cannot even rely upon the presence of a comma to say that a
++            partition has been specified!
+ 
+-	 (If we only have a path, the code in normal to discover config files
+-	 will try both without partitions and then with any partitions so we
+-	 will cover both CDs and HDs.)
++         If we only have a path in $prefix, the code in normal to discover
++	 config files will try all disks, both without partitions and then with
++	 any partitions so we will cover both CDs and HDs.
++
++         However, it doesn't then set the prefix to be something like
++         (discovered partition)/path, and so it is fragile against runtime
++         changes to $root. For example some of the stuff done in 10_linux to
++         reload $root sets root differently and then uses search to find it
++         again. If the search module is not built in, when we change root, grub
++         will look in (new root)/path/powerpc-ieee1275, that won't work, and we
++         will not be able to load the search module and the boot will fail.
++
++         This is particularly likely to hit us in the grub-install
++         (,msdos2)/grub2 case, so we act unless the supplied prefix starts with
++         '(', which would likely indicate a partition has already been
++         specified.
+        */
+-      if (grub_strchr (device, ',') == NULL)
++      if (prefix && prefix[0] != '(')
+         grub_env_set ("prefix", path);
+       else
+ #endif
diff --git a/SOURCES/0505-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch b/SOURCES/0505-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch
deleted file mode 100644
index cdbd769..0000000
--- a/SOURCES/0505-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Chris Coulson <chris.coulson@canonical.com>
-Date: Mon, 2 May 2022 14:39:31 +0200
-Subject: [PATCH] loader/i386/efi/linux: Avoid a use-after-free in the linuxefi
- loader
-
-In some error paths in grub_cmd_linux, the pointer to lh may be
-dereferenced after the buffer it points to has been freed. There aren't
-any security implications from this because nothing else uses the
-allocator after the buffer is freed and before the pointer is
-dereferenced, but fix it anyway.
-
-Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
-(cherry picked from commit 8224f5a71af94bec8697de17e7e579792db9f9e2)
-(cherry picked from commit 4744b62e20d07674017213ac54d7442d679f9d1a)
-(cherry picked from commit 329633cb060957c3d2aca677ac733f07b213a63f)
-(cherry picked from commit 47b839b0a801ee4852447a85fb5de91dc7d2c856)
----
- grub-core/loader/i386/efi/linux.c | 5 ++---
- 1 file changed, 2 insertions(+), 3 deletions(-)
-
-diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
-index a043df891f..c9a2b47370 100644
---- a/grub-core/loader/i386/efi/linux.c
-+++ b/grub-core/loader/i386/efi/linux.c
-@@ -482,9 +482,6 @@ fail:
-   if (file)
-     grub_file_close (file);
- 
--  if (kernel)
--    grub_free (kernel);
--
-   if (grub_errno != GRUB_ERR_NONE)
-     {
-       grub_dl_unref (my_mod);
-@@ -500,6 +497,8 @@ fail:
-       kernel_free (params, sizeof(*params));
-     }
- 
-+  grub_free (kernel);
-+
-   return grub_errno;
- }
- 
diff --git a/SOURCES/0505-make-ofdisk_retries-optional.patch b/SOURCES/0505-make-ofdisk_retries-optional.patch
new file mode 100644
index 0000000..fce9702
--- /dev/null
+++ b/SOURCES/0505-make-ofdisk_retries-optional.patch
@@ -0,0 +1,43 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Diego Domingos <diegdo@br.ibm.com>
+Date: Thu, 24 Mar 2022 13:14:42 -0400
+Subject: [PATCH] make ofdisk_retries optional
+
+The feature Retry on Fail added to GRUB can cause a LPM to take
+longer if the SAN is slow.
+
+When a LPM to external site occur, the path of the disk can change
+and thus the disk search function on grub can take some time since
+it is used as a hint. This can cause the Retry on Fail feature to
+try to access the disk 20x times (since this is hardcoded number)
+and, if the SAN is slow, the boot time can increase a lot.
+In some situations not acceptable.
+
+The following patch enables a configuration at user space of the
+maximum number of retries we want for this feature.
+
+The variable ofdisk_retries should be set using grub2-editenv
+and will be checked by retry function. If the variable is not set,
+so the default number of retries will be used instead.
+---
+ include/grub/ieee1275/ofdisk.h | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/include/grub/ieee1275/ofdisk.h b/include/grub/ieee1275/ofdisk.h
+index 7d2d540930..0074d55eee 100644
+--- a/include/grub/ieee1275/ofdisk.h
++++ b/include/grub/ieee1275/ofdisk.h
+@@ -25,7 +25,12 @@ extern void grub_ofdisk_fini (void);
+ #define MAX_RETRIES 20
+ 
+ 
+-#define RETRY_IEEE1275_OFDISK_OPEN(device, last_ihandle) unsigned retry_i=0;for(retry_i=0; retry_i < MAX_RETRIES; retry_i++){ \
++#define RETRY_IEEE1275_OFDISK_OPEN(device, last_ihandle) \
++	                                        unsigned max_retries = MAX_RETRIES; \
++                                                if(grub_env_get("ofdisk_retries") != NULL) \
++                                                     max_retries = grub_strtoul(grub_env_get("ofdisk_retries"), 0, 10)+1; \
++                                                grub_dprintf("ofdisk","MAX_RETRIES set to %u\n",max_retries); \
++                                                unsigned retry_i=0;for(retry_i=0; retry_i < max_retries; retry_i++){ \
+ 						if(!grub_ieee1275_open(device, last_ihandle)) \
+ 						break; \
+ 						grub_dprintf("ofdisk","Opening disk %s failed. Retrying...\n",device); }
diff --git a/SOURCES/0506-loader-efi-chainloader-grub_load_and_start_image-doe.patch b/SOURCES/0506-loader-efi-chainloader-grub_load_and_start_image-doe.patch
new file mode 100644
index 0000000..6472129
--- /dev/null
+++ b/SOURCES/0506-loader-efi-chainloader-grub_load_and_start_image-doe.patch
@@ -0,0 +1,71 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Chris Coulson <chris.coulson@canonical.com>
+Date: Thu, 28 Apr 2022 21:53:36 +0100
+Subject: [PATCH] loader/efi/chainloader: grub_load_and_start_image doesn't
+ load and start
+
+grub_load_and_start_image only loads an image - it still requires the
+caller to start it. This renames it to grub_load_image.
+
+It's called from 2 places:
+- grub_cmd_chainloader when not using the shim protocol.
+- grub_secureboot_chainloader_boot if handle_image returns an error.
+In this case, the image is loaded and then nothing else happens which
+seems strange. I assume the intention is that it falls back to LoadImage
+and StartImage if handle_image fails, so I've made it do that.
+
+Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
+(cherry picked from commit b4d70820a65c00561045856b7b8355461a9545f6)
+(cherry picked from commit 05b16a6be50b1910609740a66b561276fa490538)
+(cherry picked from commit 16486a34f3aa41a94e334e86db1a1e21e9b0a45f)
+---
+ grub-core/loader/efi/chainloader.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
+index 29663f7180..d75d345003 100644
+--- a/grub-core/loader/efi/chainloader.c
++++ b/grub-core/loader/efi/chainloader.c
+@@ -835,7 +835,7 @@ grub_secureboot_chainloader_unload (void)
+ }
+ 
+ static grub_err_t
+-grub_load_and_start_image(void *boot_image)
++grub_load_image(void *boot_image)
+ {
+   grub_efi_boot_services_t *b;
+   grub_efi_status_t status;
+@@ -877,13 +877,23 @@ grub_load_and_start_image(void *boot_image)
+ static grub_err_t
+ grub_secureboot_chainloader_boot (void)
+ {
++  grub_efi_boot_services_t *b;
+   int rc;
++
+   rc = handle_image ((void *)(unsigned long)address, fsize);
+   if (rc == 0)
+     {
+-      grub_load_and_start_image((void *)(unsigned long)address);
++      /* We weren't able to attempt to execute the image, so fall back
++       * to LoadImage / StartImage.
++       */
++      rc = grub_load_image((void *)(unsigned long)address);
++      if (rc == 0)
++        grub_chainloader_boot ();
+     }
+ 
++  b = grub_efi_system_table->boot_services;
++  efi_call_1 (b->unload_image, image_handle);
++
+   grub_loader_unset ();
+   return grub_errno;
+ }
+@@ -1072,7 +1082,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
+     }
+   else if (rc == 0)
+     {
+-      grub_load_and_start_image(boot_image);
++      grub_load_image(boot_image);
+       grub_file_close (file);
+       grub_device_close (dev);
+       grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
diff --git a/SOURCES/0506-loader-i386-efi-linux-Use-grub_loader_set_ex.patch b/SOURCES/0506-loader-i386-efi-linux-Use-grub_loader_set_ex.patch
deleted file mode 100644
index a0f04a2..0000000
--- a/SOURCES/0506-loader-i386-efi-linux-Use-grub_loader_set_ex.patch
+++ /dev/null
@@ -1,300 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Chris Coulson <chris.coulson@canonical.com>
-Date: Mon, 2 May 2022 17:04:23 +0200
-Subject: [PATCH] loader/i386/efi/linux: Use grub_loader_set_ex
-
-This ports the linuxefi loader to use grub_loader_set_ex in order to fix
-a use-after-fre bug that occurs when grub_cmd_linux is executed more than
-once before a boot attempt is performed.
-
-This is more complicated than for the chainloader command, as the initrd
-command needs access to the loader state. To solve this, the linuxefi
-module registers a dummy initrd command at startup that returns an error.
-The linuxefi command then registers a proper initrd command with a higher
-priority that is passed the loader state.
-
-Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
-(cherry picked from commit 7cf736436b4c934df5ddfa6f44b46a7e07d99fdc)
-[rharwood/pjones: set kernel_size in context]
-(cherry picked from commit 9c056391f7a36ea480de9a759c12e55a90f2040a)
-[rharwood: verifying twice]
-Signed-off-by: Robbie Harwood <rharwood@redhat.com>
-(cherry picked from commit df804892f1a754d88a9779320f9429bf40d2a1b3)
-(cherry picked from commit d1b506f6c910b96ad47a20247b438c6402a74948)
----
- grub-core/loader/i386/efi/linux.c | 146 +++++++++++++++++++++++---------------
- 1 file changed, 87 insertions(+), 59 deletions(-)
-
-diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
-index c9a2b47370..77a0734786 100644
---- a/grub-core/loader/i386/efi/linux.c
-+++ b/grub-core/loader/i386/efi/linux.c
-@@ -34,13 +34,19 @@
- GRUB_MOD_LICENSE ("GPLv3+");
- 
- static grub_dl_t my_mod;
--static int loaded;
--static void *kernel_mem;
--static grub_uint64_t kernel_size;
--static void *initrd_mem;
--static grub_uint32_t handover_offset;
--struct linux_kernel_params *params;
--static char *linux_cmdline;
-+
-+static grub_command_t cmd_linux, cmd_initrd;
-+static grub_command_t cmd_linuxefi, cmd_initrdefi;
-+
-+struct grub_linuxefi_context {
-+  void *kernel_mem;
-+  grub_uint64_t kernel_size;
-+  grub_uint32_t handover_offset;
-+  struct linux_kernel_params *params;
-+  char *cmdline;
-+
-+  void *initrd_mem;
-+};
- 
- #define MIN(a, b) \
-   ({ typeof (a) _a = (a); \
-@@ -123,25 +129,32 @@ kernel_alloc(grub_efi_uintn_t size, const char * const errmsg)
- }
- 
- static grub_err_t
--grub_linuxefi_boot (void)
-+grub_linuxefi_boot (void *data)
- {
-+  struct grub_linuxefi_context *context = (struct grub_linuxefi_context *) data;
-+
-   asm volatile ("cli");
- 
--  return grub_efi_linux_boot ((char *)kernel_mem,
--			      handover_offset,
--			      params);
-+  return grub_efi_linux_boot ((char *)context->kernel_mem,
-+			      context->handover_offset,
-+			      context->params);
- }
- 
- static grub_err_t
--grub_linuxefi_unload (void)
-+grub_linuxefi_unload (void *data)
- {
-+  struct grub_linuxefi_context *context = (struct grub_linuxefi_context *) data;
-+  struct linux_kernel_params *params = context->params;
-+
-   grub_dl_unref (my_mod);
--  loaded = 0;
- 
--  kernel_free(initrd_mem, params->ramdisk_size);
--  kernel_free(linux_cmdline, params->cmdline_size + 1);
--  kernel_free(kernel_mem, kernel_size);
--  kernel_free(params, sizeof(*params));
-+  kernel_free (context->initrd_mem, params->ramdisk_size);
-+  kernel_free (context->cmdline, params->cmdline_size + 1);
-+  kernel_free (context->kernel_mem, context->kernel_size);
-+  kernel_free (params, sizeof(*params));
-+  cmd_initrd->data = 0;
-+  cmd_initrdefi->data = 0;
-+  grub_free (context);
- 
-   return GRUB_ERR_NONE;
- }
-@@ -188,13 +201,14 @@ read(grub_file_t file, grub_uint8_t *bufp, grub_size_t len)
- #define HIGH_U32(val) ((grub_uint32_t)(((grub_addr_t)(val) >> 32) & 0xffffffffull))
- 
- static grub_err_t
--grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
--                 int argc, char *argv[])
-+grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
- {
-   grub_file_t *files = 0;
-   int i, nfiles = 0;
-   grub_size_t size = 0;
-   grub_uint8_t *ptr;
-+  struct grub_linuxefi_context *context = (struct grub_linuxefi_context *) cmd->data;
-+  struct linux_kernel_params *params;
- 
-   if (argc == 0)
-     {
-@@ -202,12 +216,14 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
-       goto fail;
-     }
- 
--  if (!loaded)
-+  if (!context)
-     {
-       grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first"));
-       goto fail;
-     }
- 
-+  params = context->params;
-+
-   files = grub_calloc (argc, sizeof (files[0]));
-   if (!files)
-     goto fail;
-@@ -226,19 +242,19 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
- 	}
-     }
- 
--  initrd_mem = kernel_alloc(size, N_("can't allocate initrd"));
--  if (initrd_mem == NULL)
-+  context->initrd_mem = kernel_alloc(size, N_("can't allocate initrd"));
-+  if (context->initrd_mem == NULL)
-     goto fail;
--  grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem);
-+  grub_dprintf ("linux", "initrd_mem = %p\n", context->initrd_mem);
- 
-   params->ramdisk_size = LOW_U32(size);
--  params->ramdisk_image = LOW_U32(initrd_mem);
-+  params->ramdisk_image = LOW_U32(context->initrd_mem);
- #if defined(__x86_64__)
-   params->ext_ramdisk_size = HIGH_U32(size);
--  params->ext_ramdisk_image = HIGH_U32(initrd_mem);
-+  params->ext_ramdisk_image = HIGH_U32(context->initrd_mem);
- #endif
- 
--  ptr = initrd_mem;
-+  ptr = context->initrd_mem;
- 
-   for (i = 0; i < nfiles; i++)
-     {
-@@ -264,8 +280,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
-     grub_file_close (files[i]);
-   grub_free (files);
- 
--  if (initrd_mem && grub_errno)
--    grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)initrd_mem,
-+  if (context->initrd_mem && grub_errno)
-+    grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)context->initrd_mem,
- 			 BYTES_TO_PAGES(size));
- 
-   return grub_errno;
-@@ -281,6 +297,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-   void *kernel = NULL;
-   int setup_header_end_offset;
-   int rc;
-+  void *kernel_mem = 0;
-+  grub_uint64_t kernel_size = 0;
-+  grub_uint32_t handover_offset;
-+  struct linux_kernel_params *params = 0;
-+  char *cmdline = 0;
-+  struct grub_linuxefi_context *context = 0;
- 
-   grub_dl_ref (my_mod);
- 
-@@ -407,27 +429,27 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-   grub_dprintf ("linux", "new lh is at %p\n", lh);
- 
-   grub_dprintf ("linux", "setting up cmdline\n");
--  linux_cmdline = kernel_alloc (lh->cmdline_size + 1, N_("can't allocate cmdline"));
--  if (!linux_cmdline)
-+  cmdline = kernel_alloc (lh->cmdline_size + 1, N_("can't allocate cmdline"));
-+  if (!cmdline)
-     goto fail;
--  grub_dprintf ("linux", "linux_cmdline = %p\n", linux_cmdline);
-+  grub_dprintf ("linux", "cmdline = %p\n", cmdline);
- 
--  grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE));
-+  grub_memcpy (cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE));
-   grub_create_loader_cmdline (argc, argv,
--                              linux_cmdline + sizeof (LINUX_IMAGE) - 1,
-+                              cmdline + sizeof (LINUX_IMAGE) - 1,
- 			      lh->cmdline_size - (sizeof (LINUX_IMAGE) - 1),
- 			      GRUB_VERIFY_KERNEL_CMDLINE);
- 
--  grub_dprintf ("linux", "cmdline:%s\n", linux_cmdline);
-+  grub_dprintf ("linux", "cmdline:%s\n", cmdline);
-   grub_dprintf ("linux", "setting lh->cmd_line_ptr to 0x%08x\n",
--		LOW_U32(linux_cmdline));
--  lh->cmd_line_ptr = LOW_U32(linux_cmdline);
-+		LOW_U32(cmdline));
-+  lh->cmd_line_ptr = LOW_U32(cmdline);
- #if defined(__x86_64__)
--  if ((grub_efi_uintn_t)linux_cmdline > 0xffffffffull)
-+  if ((grub_efi_uintn_t)cmdline > 0xffffffffull)
-     {
-       grub_dprintf ("linux", "setting params->ext_cmd_line_ptr to 0x%08x\n",
--		    HIGH_U32(linux_cmdline));
--      params->ext_cmd_line_ptr = HIGH_U32(linux_cmdline);
-+		    HIGH_U32(cmdline));
-+      params->ext_cmd_line_ptr = HIGH_U32(cmdline);
-     }
- #endif
- 
-@@ -452,16 +474,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-     }
-   max_addresses[1].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
-   max_addresses[2].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
--  kernel_mem = kernel_alloc (lh->init_size, N_("can't allocate kernel"));
-+  kernel_size = lh->init_size;
-+  kernel_mem = kernel_alloc (kernel_size, N_("can't allocate kernel"));
-   restore_addresses();
-   if (!kernel_mem)
-     goto fail;
-   grub_dprintf("linux", "kernel_mem = %p\n", kernel_mem);
- 
--  grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0);
--
--  loaded = 1;
--
-   grub_dprintf ("linux", "setting lh->code32_start to 0x%08x\n",
- 		LOW_U32(kernel_mem));
-   lh->code32_start = LOW_U32(kernel_mem);
-@@ -478,33 +497,42 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- 		"setting lh->ext_loader_{type,ver} = {0x%02x,0x%02x}\n",
- 		params->ext_loader_type, params->ext_loader_ver);
- 
-+  context = grub_zalloc (sizeof (*context));
-+  if (!context)
-+    goto fail;
-+  context->kernel_mem = kernel_mem;
-+  context->kernel_size = kernel_size;
-+  context->handover_offset = handover_offset;
-+  context->params = params;
-+  context->cmdline = cmdline;
-+
-+  grub_loader_set_ex (grub_linuxefi_boot, grub_linuxefi_unload, context, 0);
-+
-+  cmd_initrd->data = context;
-+  cmd_initrdefi->data = context;
-+
-+  grub_file_close (file);
-+  grub_free (kernel);
-+  return 0;
-+
- fail:
-   if (file)
-     grub_file_close (file);
- 
--  if (grub_errno != GRUB_ERR_NONE)
--    {
--      grub_dl_unref (my_mod);
--      loaded = 0;
--    }
-+  grub_dl_unref (my_mod);
- 
--  if (!loaded)
--    {
--      if (lh)
--	kernel_free (linux_cmdline, lh->cmdline_size + 1);
-+  if (lh)
-+    kernel_free (cmdline, lh->cmdline_size + 1);
- 
--      kernel_free (kernel_mem, kernel_size);
--      kernel_free (params, sizeof(*params));
--    }
-+  kernel_free (kernel_mem, kernel_size);
-+  kernel_free (params, sizeof(*params));
- 
-+  grub_free (context);
-   grub_free (kernel);
- 
-   return grub_errno;
- }
- 
--static grub_command_t cmd_linux, cmd_initrd;
--static grub_command_t cmd_linuxefi, cmd_initrdefi;
--
- GRUB_MOD_INIT(linux)
- {
-   cmd_linux =
diff --git a/SOURCES/0507-loader-efi-chainloader-simplify-the-loader-state.patch b/SOURCES/0507-loader-efi-chainloader-simplify-the-loader-state.patch
new file mode 100644
index 0000000..83b8823
--- /dev/null
+++ b/SOURCES/0507-loader-efi-chainloader-simplify-the-loader-state.patch
@@ -0,0 +1,334 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Chris Coulson <chris.coulson@canonical.com>
+Date: Fri, 29 Apr 2022 21:13:08 +0100
+Subject: [PATCH] loader/efi/chainloader: simplify the loader state
+
+When not using the shim lock protocol, the chainloader command retains
+the source buffer and device path passed to LoadImage, requiring the
+unload hook passed to grub_loader_set to free them. It isn't required
+to retain this state though - they aren't required by StartImage or
+anything else in the boot hook, so clean them up before
+grub_cmd_chainloader finishes.
+
+This also wraps the loader state when using the shim lock protocol
+inside a struct.
+
+Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
+(cherry picked from commit fa39862933b3be1553a580a3a5c28073257d8046)
+(cherry picked from commit 0333343ee99c4e88f062789263c94291c057251b)
+[rharwood: verifying twice]
+(cherry picked from commit 6080ad5d91d6a80d5f67c592dd33b6dd413e9453)
+[rharwood: double frees and unintialized, context fuzz - orig_dp]
+Signed-off-by: Robbie Harwood <rharwood@redhat.com>
+---
+ grub-core/loader/efi/chainloader.c | 160 +++++++++++++++++++++++--------------
+ 1 file changed, 102 insertions(+), 58 deletions(-)
+
+diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
+index d75d345003..afeb1fc97e 100644
+--- a/grub-core/loader/efi/chainloader.c
++++ b/grub-core/loader/efi/chainloader.c
+@@ -47,38 +47,21 @@ GRUB_MOD_LICENSE ("GPLv3+");
+ 
+ static grub_dl_t my_mod;
+ 
+-static grub_efi_physical_address_t address;
+-static grub_efi_uintn_t pages;
+-static grub_ssize_t fsize;
+-static grub_efi_device_path_t *file_path;
+ static grub_efi_handle_t image_handle;
+-static grub_efi_char16_t *cmdline;
+-static grub_ssize_t cmdline_len;
+-static grub_efi_handle_t dev_handle;
+ 
+-static grub_efi_status_t (*entry_point) (grub_efi_handle_t image_handle, grub_efi_system_table_t *system_table);
++struct grub_secureboot_chainloader_context {
++  grub_efi_physical_address_t address;
++  grub_efi_uintn_t pages;
++  grub_ssize_t fsize;
++  grub_efi_device_path_t *file_path;
++  grub_efi_char16_t *cmdline;
++  grub_ssize_t cmdline_len;
++  grub_efi_handle_t dev_handle;
++};
++static struct grub_secureboot_chainloader_context *sb_context;
+ 
+ static grub_err_t
+-grub_chainloader_unload (void)
+-{
+-  grub_efi_boot_services_t *b;
+-
+-  b = grub_efi_system_table->boot_services;
+-  efi_call_1 (b->unload_image, image_handle);
+-  grub_efi_free_pages (address, pages);
+-
+-  grub_free (file_path);
+-  grub_free (cmdline);
+-  cmdline = 0;
+-  file_path = 0;
+-  dev_handle = 0;
+-
+-  grub_dl_unref (my_mod);
+-  return GRUB_ERR_NONE;
+-}
+-
+-static grub_err_t
+-grub_chainloader_boot (void)
++grub_start_image (grub_efi_handle_t handle)
+ {
+   grub_efi_boot_services_t *b;
+   grub_efi_status_t status;
+@@ -86,7 +69,7 @@ grub_chainloader_boot (void)
+   grub_efi_char16_t *exit_data = NULL;
+ 
+   b = grub_efi_system_table->boot_services;
+-  status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data);
++  status = efi_call_3 (b->start_image, handle, &exit_data_size, &exit_data);
+   if (status != GRUB_EFI_SUCCESS)
+     {
+       if (exit_data)
+@@ -110,11 +93,37 @@ grub_chainloader_boot (void)
+   if (exit_data)
+     grub_efi_free_pool (exit_data);
+ 
+-  grub_loader_unset ();
+-
+   return grub_errno;
+ }
+ 
++static grub_err_t
++grub_chainloader_unload (void)
++{
++  grub_efi_loaded_image_t *loaded_image;
++  grub_efi_boot_services_t *b;
++
++  loaded_image = grub_efi_get_loaded_image (image_handle);
++  if (loaded_image != NULL)
++    grub_free (loaded_image->load_options);
++
++  b = grub_efi_system_table->boot_services;
++  efi_call_1 (b->unload_image, image_handle);
++
++  grub_dl_unref (my_mod);
++  return GRUB_ERR_NONE;
++}
++
++static grub_err_t
++grub_chainloader_boot (void)
++{
++  grub_err_t err;
++
++  err = grub_start_image (image_handle);
++
++  grub_loader_unset ();
++  return err;
++}
++
+ static grub_err_t
+ copy_file_path (grub_efi_file_path_device_path_t *fp,
+ 		const char *str, grub_efi_uint16_t len)
+@@ -149,7 +158,7 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
+   char *dir_start;
+   char *dir_end;
+   grub_size_t size;
+-  grub_efi_device_path_t *d;
++  grub_efi_device_path_t *d, *file_path;
+ 
+   dir_start = grub_strchr (filename, ')');
+   if (! dir_start)
+@@ -520,10 +529,12 @@ grub_efi_get_media_file_path (grub_efi_device_path_t *dp)
+ }
+ 
+ static grub_efi_boolean_t
+-handle_image (void *data, grub_efi_uint32_t datasize)
++handle_image (struct grub_secureboot_chainloader_context *load_context)
+ {
+   grub_efi_loaded_image_t *li, li_bak;
+   grub_efi_status_t efi_status;
++  void *data = (void *)(unsigned long)load_context->address;
++  grub_efi_uint32_t datasize = load_context->fsize;
+   void *buffer = NULL;
+   char *buffer_aligned = NULL;
+   grub_efi_uint32_t i;
+@@ -534,6 +545,7 @@ handle_image (void *data, grub_efi_uint32_t datasize)
+   grub_uint32_t buffer_size;
+   int found_entry_point = 0;
+   int rc;
++  grub_efi_status_t (*entry_point) (grub_efi_handle_t image_handle, grub_efi_system_table_t *system_table);
+ 
+   rc = read_header (data, datasize, &context);
+   if (rc < 0)
+@@ -791,10 +803,10 @@ handle_image (void *data, grub_efi_uint32_t datasize)
+   grub_memcpy (&li_bak, li, sizeof (grub_efi_loaded_image_t));
+   li->image_base = buffer_aligned;
+   li->image_size = context.image_size;
+-  li->load_options = cmdline;
+-  li->load_options_size = cmdline_len;
+-  li->file_path = grub_efi_get_media_file_path (file_path);
+-  li->device_handle = dev_handle;
++  li->load_options = load_context->cmdline;
++  li->load_options_size = load_context->cmdline_len;
++  li->file_path = grub_efi_get_media_file_path (load_context->file_path);
++  li->device_handle = load_context->dev_handle;
+   if (!li->file_path)
+     {
+       grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching file path found");
+@@ -823,19 +835,22 @@ error_exit:
+ static grub_err_t
+ grub_secureboot_chainloader_unload (void)
+ {
+-  grub_efi_free_pages (address, pages);
+-  grub_free (file_path);
+-  grub_free (cmdline);
+-  cmdline = 0;
+-  file_path = 0;
+-  dev_handle = 0;
++  grub_efi_free_pages (sb_context->address, sb_context->pages);
++  grub_free (sb_context->file_path);
++  grub_free (sb_context->cmdline);
++  grub_free (sb_context);
++
++  sb_context = 0;
+ 
+   grub_dl_unref (my_mod);
+   return GRUB_ERR_NONE;
+ }
+ 
+ static grub_err_t
+-grub_load_image(void *boot_image)
++grub_load_image(grub_efi_device_path_t *file_path, void *boot_image,
++		grub_efi_uintn_t image_size, grub_efi_handle_t dev_handle,
++		grub_efi_char16_t *cmdline, grub_ssize_t cmdline_len,
++		grub_efi_handle_t *image_handle_out)
+ {
+   grub_efi_boot_services_t *b;
+   grub_efi_status_t status;
+@@ -844,7 +859,7 @@ grub_load_image(void *boot_image)
+   b = grub_efi_system_table->boot_services;
+ 
+   status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path,
+-		       boot_image, fsize, &image_handle);
++		       boot_image, image_size, image_handle_out);
+   if (status != GRUB_EFI_SUCCESS)
+     {
+       if (status == GRUB_EFI_OUT_OF_RESOURCES)
+@@ -857,7 +872,7 @@ grub_load_image(void *boot_image)
+   /* LoadImage does not set a device handler when the image is
+      loaded from memory, so it is necessary to set it explicitly here.
+      This is a mess.  */
+-  loaded_image = grub_efi_get_loaded_image (image_handle);
++  loaded_image = grub_efi_get_loaded_image (*image_handle_out);
+   if (! loaded_image)
+     {
+       grub_error (GRUB_ERR_BAD_OS, "no loaded image available");
+@@ -879,20 +894,25 @@ grub_secureboot_chainloader_boot (void)
+ {
+   grub_efi_boot_services_t *b;
+   int rc;
++  grub_efi_handle_t handle = 0;
+ 
+-  rc = handle_image ((void *)(unsigned long)address, fsize);
++  rc = handle_image (sb_context);
+   if (rc == 0)
+     {
+       /* We weren't able to attempt to execute the image, so fall back
+        * to LoadImage / StartImage.
+        */
+-      rc = grub_load_image((void *)(unsigned long)address);
++      rc = grub_load_image(sb_context->file_path,
++			   (void *)(unsigned long)sb_context->address,
++			   sb_context->fsize, sb_context->dev_handle,
++			   sb_context->cmdline, sb_context->cmdline_len,
++			   &handle);
+       if (rc == 0)
+-        grub_chainloader_boot ();
++	grub_start_image (handle);
+     }
+ 
+   b = grub_efi_system_table->boot_services;
+-  efi_call_1 (b->unload_image, image_handle);
++  efi_call_1 (b->unload_image, handle);
+ 
+   grub_loader_unset ();
+   return grub_errno;
+@@ -906,10 +926,16 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
+   grub_efi_status_t status;
+   grub_efi_boot_services_t *b;
+   grub_device_t dev = 0;
+-  grub_efi_device_path_t *dp = 0;
++  grub_efi_device_path_t *dp = 0, *file_path = 0;
+   char *filename;
+   void *boot_image = 0;
+   int rc;
++  grub_efi_physical_address_t address = 0;
++  grub_ssize_t fsize;
++  grub_efi_uintn_t pages = 0;
++  grub_efi_char16_t *cmdline = 0;
++  grub_ssize_t cmdline_len = 0;
++  grub_efi_handle_t dev_handle = 0;
+ 
+   if (argc == 0)
+     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
+@@ -917,12 +943,6 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
+ 
+   grub_dl_ref (my_mod);
+ 
+-  /* Initialize some global variables.  */
+-  address = 0;
+-  image_handle = 0;
+-  file_path = 0;
+-  dev_handle = 0;
+-
+   b = grub_efi_system_table->boot_services;
+ 
+   if (argc > 1)
+@@ -1074,17 +1094,35 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
+   grub_dprintf ("chain", "linuxefi_secure_validate: %d\n", rc);
+   if (rc > 0)
+     {
++      sb_context = grub_malloc (sizeof (*sb_context));
++      if (sb_context == NULL)
++        goto fail;
++      sb_context->address = address;
++      sb_context->fsize = fsize;
++      sb_context->pages = pages;
++      sb_context->file_path = file_path;
++      sb_context->cmdline = cmdline;
++      sb_context->cmdline_len = cmdline_len;
++      sb_context->dev_handle = dev_handle;
++
+       grub_file_close (file);
+       grub_device_close (dev);
++
+       grub_loader_set (grub_secureboot_chainloader_boot,
+ 		       grub_secureboot_chainloader_unload, 0);
+       return 0;
+     }
+   else if (rc == 0)
+     {
+-      grub_load_image(boot_image);
++      grub_load_image(file_path, boot_image, fsize, dev_handle, cmdline,
++		      cmdline_len, &image_handle);
+       grub_file_close (file);
+       grub_device_close (dev);
++
++      /* We're finished with the source image buffer and file path now */
++      efi_call_2 (b->free_pages, address, pages);
++      grub_free (file_path);
++
+       grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
+ 
+       return 0;
+@@ -1106,6 +1144,12 @@ fail:
+   if (cmdline)
+     grub_free (cmdline);
+ 
++  if (image_handle != 0)
++    {
++      efi_call_1 (b->unload_image, image_handle);
++      image_handle = 0;
++    }
++
+   grub_dl_unref (my_mod);
+ 
+   return grub_errno;
diff --git a/SOURCES/0507-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch b/SOURCES/0507-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch
deleted file mode 100644
index 6236395..0000000
--- a/SOURCES/0507-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Chris Coulson <chris.coulson@canonical.com>
-Date: Tue, 3 May 2022 09:47:35 +0200
-Subject: [PATCH] loader/i386/efi/linux: Fix a memory leak in the initrd
- command
-
-Subsequent invocations of the initrd command result in the previous
-initrd being leaked, so fix that.
-
-Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
-(cherry picked from commit d98af31ce1e31bb22163960d53f5eb28c66582a0)
-(cherry picked from commit 62234d6a00e6d1dd8e017ff161d359feb5234082)
-(cherry picked from commit bda5a10716dc9676400dce1374232452f46d0bc4)
-(cherry picked from commit b862299a8502282a09af8e6c6189edd5b0a368b0)
----
- grub-core/loader/i386/efi/linux.c | 21 ++++++++++++---------
- 1 file changed, 12 insertions(+), 9 deletions(-)
-
-diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
-index 77a0734786..8337191921 100644
---- a/grub-core/loader/i386/efi/linux.c
-+++ b/grub-core/loader/i386/efi/linux.c
-@@ -209,6 +209,7 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
-   grub_uint8_t *ptr;
-   struct grub_linuxefi_context *context = (struct grub_linuxefi_context *) cmd->data;
-   struct linux_kernel_params *params;
-+  void *initrd_mem = 0;
- 
-   if (argc == 0)
-     {
-@@ -242,19 +243,19 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
- 	}
-     }
- 
--  context->initrd_mem = kernel_alloc(size, N_("can't allocate initrd"));
--  if (context->initrd_mem == NULL)
-+  initrd_mem = kernel_alloc(size, N_("can't allocate initrd"));
-+  if (initrd_mem == NULL)
-     goto fail;
--  grub_dprintf ("linux", "initrd_mem = %p\n", context->initrd_mem);
-+  grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem);
- 
-   params->ramdisk_size = LOW_U32(size);
--  params->ramdisk_image = LOW_U32(context->initrd_mem);
-+  params->ramdisk_image = LOW_U32(initrd_mem);
- #if defined(__x86_64__)
-   params->ext_ramdisk_size = HIGH_U32(size);
--  params->ext_ramdisk_image = HIGH_U32(context->initrd_mem);
-+  params->ext_ramdisk_image = HIGH_U32(initrd_mem);
- #endif
- 
--  ptr = context->initrd_mem;
-+  ptr = initrd_mem;
- 
-   for (i = 0; i < nfiles; i++)
-     {
-@@ -273,6 +274,9 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
-       ptr += ALIGN_UP_OVERHEAD (cursize, 4);
-     }
- 
-+  kernel_free(context->initrd_mem, params->ramdisk_size);
-+
-+  context->initrd_mem = initrd_mem;
-   params->ramdisk_size = size;
- 
-  fail:
-@@ -280,9 +284,8 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
-     grub_file_close (files[i]);
-   grub_free (files);
- 
--  if (context->initrd_mem && grub_errno)
--    grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)context->initrd_mem,
--			 BYTES_TO_PAGES(size));
-+  if (initrd_mem && grub_errno)
-+    kernel_free (initrd_mem, size);
- 
-   return grub_errno;
- }
diff --git a/SOURCES/0508-commands-boot-Add-API-to-pass-context-to-loader.patch b/SOURCES/0508-commands-boot-Add-API-to-pass-context-to-loader.patch
new file mode 100644
index 0000000..a036524
--- /dev/null
+++ b/SOURCES/0508-commands-boot-Add-API-to-pass-context-to-loader.patch
@@ -0,0 +1,160 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Chris Coulson <chris.coulson@canonical.com>
+Date: Fri, 29 Apr 2022 21:16:02 +0100
+Subject: [PATCH] commands/boot: Add API to pass context to loader
+
+Loaders rely on global variables for saving context which is consumed
+in the boot hook and freed in the unload hook. In the case where a loader
+command is executed twice, calling grub_loader_set a second time executes
+the unload hook, but in some cases this runs when the loader's global
+context has already been updated, resulting in the updated context being
+freed and potential use-after-free bugs when the boot hook is subsequently
+called.
+
+This adds a new API (grub_loader_set_ex) which allows a loader to specify
+context that is passed to its boot and unload hooks. This is an alternative
+to requiring that loaders call grub_loader_unset before mutating their
+global context.
+
+Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
+(cherry picked from commit 4322a64dde7e8fedb58e50b79408667129d45dd3)
+(cherry picked from commit 937ad0e2159b6b8cb0d2ce3515da3a8b797c7927)
+(cherry picked from commit 873038ae7048f6cae8a3ebb2f97a8d361a080e13)
+---
+ grub-core/commands/boot.c | 66 +++++++++++++++++++++++++++++++++++++++++------
+ include/grub/loader.h     |  5 ++++
+ 2 files changed, 63 insertions(+), 8 deletions(-)
+
+diff --git a/grub-core/commands/boot.c b/grub-core/commands/boot.c
+index bbca81e947..53691a62d9 100644
+--- a/grub-core/commands/boot.c
++++ b/grub-core/commands/boot.c
+@@ -27,10 +27,20 @@
+ 
+ GRUB_MOD_LICENSE ("GPLv3+");
+ 
+-static grub_err_t (*grub_loader_boot_func) (void);
+-static grub_err_t (*grub_loader_unload_func) (void);
++static grub_err_t (*grub_loader_boot_func) (void *);
++static grub_err_t (*grub_loader_unload_func) (void *);
++static void *grub_loader_context;
+ static int grub_loader_flags;
+ 
++struct grub_simple_loader_hooks
++{
++  grub_err_t (*boot) (void);
++  grub_err_t (*unload) (void);
++};
++
++/* Don't heap allocate this to avoid making grub_loader_set fallible. */
++static struct grub_simple_loader_hooks simple_loader_hooks;
++
+ struct grub_preboot
+ {
+   grub_err_t (*preboot_func) (int);
+@@ -44,6 +54,29 @@ static int grub_loader_loaded;
+ static struct grub_preboot *preboots_head = 0,
+   *preboots_tail = 0;
+ 
++static grub_err_t
++grub_simple_boot_hook (void *context)
++{
++  struct grub_simple_loader_hooks *hooks;
++
++  hooks = (struct grub_simple_loader_hooks *) context;
++  return hooks->boot ();
++}
++
++static grub_err_t
++grub_simple_unload_hook (void *context)
++{
++  struct grub_simple_loader_hooks *hooks;
++  grub_err_t ret;
++
++  hooks = (struct grub_simple_loader_hooks *) context;
++
++  ret = hooks->unload ();
++  grub_memset (hooks, 0, sizeof (*hooks));
++
++  return ret;
++}
++
+ int
+ grub_loader_is_loaded (void)
+ {
+@@ -110,28 +143,45 @@ grub_loader_unregister_preboot_hook (struct grub_preboot *hnd)
+ }
+ 
+ void
+-grub_loader_set (grub_err_t (*boot) (void),
+-		 grub_err_t (*unload) (void),
+-		 int flags)
++grub_loader_set_ex (grub_err_t (*boot) (void *),
++		    grub_err_t (*unload) (void *),
++		    void *context,
++		    int flags)
+ {
+   if (grub_loader_loaded && grub_loader_unload_func)
+-    grub_loader_unload_func ();
++    grub_loader_unload_func (grub_loader_context);
+ 
+   grub_loader_boot_func = boot;
+   grub_loader_unload_func = unload;
++  grub_loader_context = context;
+   grub_loader_flags = flags;
+ 
+   grub_loader_loaded = 1;
+ }
+ 
++void
++grub_loader_set (grub_err_t (*boot) (void),
++		 grub_err_t (*unload) (void),
++		 int flags)
++{
++  grub_loader_set_ex (grub_simple_boot_hook,
++		      grub_simple_unload_hook,
++		      &simple_loader_hooks,
++		      flags);
++
++  simple_loader_hooks.boot = boot;
++  simple_loader_hooks.unload = unload;
++}
++
+ void
+ grub_loader_unset(void)
+ {
+   if (grub_loader_loaded && grub_loader_unload_func)
+-    grub_loader_unload_func ();
++    grub_loader_unload_func (grub_loader_context);
+ 
+   grub_loader_boot_func = 0;
+   grub_loader_unload_func = 0;
++  grub_loader_context = 0;
+ 
+   grub_loader_loaded = 0;
+ }
+@@ -158,7 +208,7 @@ grub_loader_boot (void)
+ 	  return err;
+ 	}
+     }
+-  err = (grub_loader_boot_func) ();
++  err = (grub_loader_boot_func) (grub_loader_context);
+ 
+   for (cur = preboots_tail; cur; cur = cur->prev)
+     if (! err)
+diff --git a/include/grub/loader.h b/include/grub/loader.h
+index b208642821..1846fa6c5f 100644
+--- a/include/grub/loader.h
++++ b/include/grub/loader.h
+@@ -40,6 +40,11 @@ void EXPORT_FUNC (grub_loader_set) (grub_err_t (*boot) (void),
+ 				    grub_err_t (*unload) (void),
+ 				    int flags);
+ 
++void EXPORT_FUNC (grub_loader_set_ex) (grub_err_t (*boot) (void *),
++				       grub_err_t (*unload) (void *),
++				       void *context,
++				       int flags);
++
+ /* Unset current loader, if any.  */
+ void EXPORT_FUNC (grub_loader_unset) (void);
+ 
diff --git a/SOURCES/0508-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch b/SOURCES/0508-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch
deleted file mode 100644
index 3afccaf..0000000
--- a/SOURCES/0508-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Axtens <dja@axtens.net>
-Date: Fri, 25 Jun 2021 02:19:05 +1000
-Subject: [PATCH] kern/file: Do not leak device_name on error in
- grub_file_open()
-
-If we have an error in grub_file_open() before we free device_name, we
-will leak it.
-
-Free device_name in the error path and null out the pointer in the good
-path once we free it there.
-
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit 1499a5068839fa37cb77ecef4b5bdacbd1ed12ea)
-(cherry picked from commit 2ec50b289d8b24922433439533113087f111f110)
-(cherry picked from commit 17c36ae88d7d6040cabc01cd4a21e71ff4731668)
-(cherry picked from commit 723e7dbedb7669343e564d453d21b8ed2ab81216)
----
- grub-core/kern/file.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c
-index 2efc31da94..f062fc21e7 100644
---- a/grub-core/kern/file.c
-+++ b/grub-core/kern/file.c
-@@ -81,6 +81,7 @@ grub_file_open (const char *name, enum grub_file_type type)
- 
-   device = grub_device_open (device_name);
-   grub_free (device_name);
-+  device_name = NULL;
-   if (! device)
-     goto fail;
- 
-@@ -135,6 +136,7 @@ grub_file_open (const char *name, enum grub_file_type type)
-   return file;
- 
-  fail:
-+  grub_free (device_name);
-   if (device)
-     grub_device_close (device);
- 
diff --git a/SOURCES/0509-loader-efi-chainloader-Use-grub_loader_set_ex.patch b/SOURCES/0509-loader-efi-chainloader-Use-grub_loader_set_ex.patch
new file mode 100644
index 0000000..d494a85
--- /dev/null
+++ b/SOURCES/0509-loader-efi-chainloader-Use-grub_loader_set_ex.patch
@@ -0,0 +1,149 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Chris Coulson <chris.coulson@canonical.com>
+Date: Fri, 29 Apr 2022 21:30:56 +0100
+Subject: [PATCH] loader/efi/chainloader: Use grub_loader_set_ex
+
+This ports the EFI chainloader to use grub_loader_set_ex in order to fix
+a use-after-free bug that occurs when grub_cmd_chainloader is executed
+more than once before a boot attempt is performed.
+
+Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
+(cherry picked from commit 4b7f0402b7cb0f67a93be736f2b75b818d7f44c9)
+(cherry picked from commit fc1a79bf0e0bc019362ace46d908a92b48dcd55b)
+(cherry picked from commit f5b653dfe00271384ff7fbd82db926ab95dbd80e)
+[rharwood: context sludge from previous commit]
+Signed-off-by: Robbie Harwood <rharwood@redhat.com>
+---
+ grub-core/loader/efi/chainloader.c | 38 ++++++++++++++++++++++----------------
+ 1 file changed, 22 insertions(+), 16 deletions(-)
+
+diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
+index afeb1fc97e..720f6181e5 100644
+--- a/grub-core/loader/efi/chainloader.c
++++ b/grub-core/loader/efi/chainloader.c
+@@ -47,8 +47,6 @@ GRUB_MOD_LICENSE ("GPLv3+");
+ 
+ static grub_dl_t my_mod;
+ 
+-static grub_efi_handle_t image_handle;
+-
+ struct grub_secureboot_chainloader_context {
+   grub_efi_physical_address_t address;
+   grub_efi_uintn_t pages;
+@@ -58,7 +56,6 @@ struct grub_secureboot_chainloader_context {
+   grub_ssize_t cmdline_len;
+   grub_efi_handle_t dev_handle;
+ };
+-static struct grub_secureboot_chainloader_context *sb_context;
+ 
+ static grub_err_t
+ grub_start_image (grub_efi_handle_t handle)
+@@ -97,11 +94,14 @@ grub_start_image (grub_efi_handle_t handle)
+ }
+ 
+ static grub_err_t
+-grub_chainloader_unload (void)
++grub_chainloader_unload (void *context)
+ {
++  grub_efi_handle_t image_handle;
+   grub_efi_loaded_image_t *loaded_image;
+   grub_efi_boot_services_t *b;
+ 
++  image_handle = (grub_efi_handle_t) context;
++
+   loaded_image = grub_efi_get_loaded_image (image_handle);
+   if (loaded_image != NULL)
+     grub_free (loaded_image->load_options);
+@@ -114,10 +114,12 @@ grub_chainloader_unload (void)
+ }
+ 
+ static grub_err_t
+-grub_chainloader_boot (void)
++grub_chainloader_boot (void *context)
+ {
++  grub_efi_handle_t image_handle;
+   grub_err_t err;
+ 
++  image_handle = (grub_efi_handle_t) context;
+   err = grub_start_image (image_handle);
+ 
+   grub_loader_unset ();
+@@ -833,15 +835,17 @@ error_exit:
+ }
+ 
+ static grub_err_t
+-grub_secureboot_chainloader_unload (void)
++grub_secureboot_chainloader_unload (void *context)
+ {
++  struct grub_secureboot_chainloader_context *sb_context;
++
++  sb_context = (struct grub_secureboot_chainloader_context *) context;
++
+   grub_efi_free_pages (sb_context->address, sb_context->pages);
+   grub_free (sb_context->file_path);
+   grub_free (sb_context->cmdline);
+   grub_free (sb_context);
+ 
+-  sb_context = 0;
+-
+   grub_dl_unref (my_mod);
+   return GRUB_ERR_NONE;
+ }
+@@ -890,12 +894,15 @@ grub_load_image(grub_efi_device_path_t *file_path, void *boot_image,
+ }
+ 
+ static grub_err_t
+-grub_secureboot_chainloader_boot (void)
++grub_secureboot_chainloader_boot (void *context)
+ {
++  struct grub_secureboot_chainloader_context *sb_context;
+   grub_efi_boot_services_t *b;
+   int rc;
+   grub_efi_handle_t handle = 0;
+ 
++  sb_context = (struct grub_secureboot_chainloader_context *) context;
++
+   rc = handle_image (sb_context);
+   if (rc == 0)
+     {
+@@ -936,6 +943,8 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
+   grub_efi_char16_t *cmdline = 0;
+   grub_ssize_t cmdline_len = 0;
+   grub_efi_handle_t dev_handle = 0;
++  grub_efi_handle_t image_handle = 0;
++  struct grub_secureboot_chainloader_context *sb_context = 0;
+ 
+   if (argc == 0)
+     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
+@@ -1108,8 +1117,8 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
+       grub_file_close (file);
+       grub_device_close (dev);
+ 
+-      grub_loader_set (grub_secureboot_chainloader_boot,
+-		       grub_secureboot_chainloader_unload, 0);
++      grub_loader_set_ex (grub_secureboot_chainloader_boot,
++			  grub_secureboot_chainloader_unload, sb_context, 0);
+       return 0;
+     }
+   else if (rc == 0)
+@@ -1123,7 +1132,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
+       efi_call_2 (b->free_pages, address, pages);
+       grub_free (file_path);
+ 
+-      grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
++      grub_loader_set_ex (grub_chainloader_boot, grub_chainloader_unload, image_handle, 0);
+ 
+       return 0;
+     }
+@@ -1145,10 +1154,7 @@ fail:
+     grub_free (cmdline);
+ 
+   if (image_handle != 0)
+-    {
+-      efi_call_1 (b->unload_image, image_handle);
+-      image_handle = 0;
+-    }
++    efi_call_1 (b->unload_image, image_handle);
+ 
+   grub_dl_unref (my_mod);
+ 
diff --git a/SOURCES/0509-video-readers-png-Abort-sooner-if-a-read-operation-f.patch b/SOURCES/0509-video-readers-png-Abort-sooner-if-a-read-operation-f.patch
deleted file mode 100644
index db3764a..0000000
--- a/SOURCES/0509-video-readers-png-Abort-sooner-if-a-read-operation-f.patch
+++ /dev/null
@@ -1,201 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Axtens <dja@axtens.net>
-Date: Tue, 6 Jul 2021 14:02:55 +1000
-Subject: [PATCH] video/readers/png: Abort sooner if a read operation fails
-
-Fuzzing revealed some inputs that were taking a long time, potentially
-forever, because they did not bail quickly upon encountering an I/O error.
-
-Try to catch I/O errors sooner and bail out.
-
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit 882be97d1df6449b9fd4d593f0cb70005fde3494)
-(cherry picked from commit 3f6fc3ebfd58fcdb3fe6c2f7a5a4fa05772ae786)
-(cherry picked from commit aac5b8257d4078c3f764216aeae3367bdc19043f)
-(cherry picked from commit e9e58c9711de334fcf48a651ee20c21f2855a4bd)
----
- grub-core/video/readers/png.c | 55 ++++++++++++++++++++++++++++++++++++-------
- 1 file changed, 47 insertions(+), 8 deletions(-)
-
-diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
-index 0157ff7420..e2a6b1cf3c 100644
---- a/grub-core/video/readers/png.c
-+++ b/grub-core/video/readers/png.c
-@@ -142,6 +142,7 @@ static grub_uint8_t
- grub_png_get_byte (struct grub_png_data *data)
- {
-   grub_uint8_t r;
-+  grub_ssize_t bytes_read = 0;
- 
-   if ((data->inside_idat) && (data->idat_remain == 0))
-     {
-@@ -175,7 +176,14 @@ grub_png_get_byte (struct grub_png_data *data)
-     }
- 
-   r = 0;
--  grub_file_read (data->file, &r, 1);
-+  bytes_read = grub_file_read (data->file, &r, 1);
-+
-+  if (bytes_read != 1)
-+    {
-+      grub_error (GRUB_ERR_BAD_FILE_TYPE,
-+		  "png: unexpected end of data");
-+      return 0;
-+    }
- 
-   if (data->inside_idat)
-     data->idat_remain--;
-@@ -231,15 +239,16 @@ grub_png_decode_image_palette (struct grub_png_data *data,
-   if (len == 0)
-     return GRUB_ERR_NONE;
- 
--  for (i = 0; 3 * i < len && i < 256; i++)
-+  grub_errno = GRUB_ERR_NONE;
-+  for (i = 0; 3 * i < len && i < 256 && grub_errno == GRUB_ERR_NONE; i++)
-     for (j = 0; j < 3; j++)
-       data->palette[i][j] = grub_png_get_byte (data);
--  for (i *= 3; i < len; i++)
-+  for (i *= 3; i < len && grub_errno == GRUB_ERR_NONE; i++)
-     grub_png_get_byte (data);
- 
-   grub_png_get_dword (data);
- 
--  return GRUB_ERR_NONE;
-+  return grub_errno;
- }
- 
- static grub_err_t
-@@ -256,9 +265,13 @@ grub_png_decode_image_header (struct grub_png_data *data)
-     return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: invalid image size");
- 
-   color_bits = grub_png_get_byte (data);
-+  if (grub_errno != GRUB_ERR_NONE)
-+    return grub_errno;
-   data->is_16bit = (color_bits == 16);
- 
-   color_type = grub_png_get_byte (data);
-+  if (grub_errno != GRUB_ERR_NONE)
-+    return grub_errno;
- 
-   /* According to PNG spec, no other types are valid.  */
-   if ((color_type & ~(PNG_COLOR_MASK_ALPHA | PNG_COLOR_MASK_COLOR))
-@@ -340,14 +353,20 @@ grub_png_decode_image_header (struct grub_png_data *data)
-   if (grub_png_get_byte (data) != PNG_COMPRESSION_BASE)
-     return grub_error (GRUB_ERR_BAD_FILE_TYPE,
- 		       "png: compression method not supported");
-+  if (grub_errno != GRUB_ERR_NONE)
-+    return grub_errno;
- 
-   if (grub_png_get_byte (data) != PNG_FILTER_TYPE_BASE)
-     return grub_error (GRUB_ERR_BAD_FILE_TYPE,
- 		       "png: filter method not supported");
-+  if (grub_errno != GRUB_ERR_NONE)
-+    return grub_errno;
- 
-   if (grub_png_get_byte (data) != PNG_INTERLACE_NONE)
-     return grub_error (GRUB_ERR_BAD_FILE_TYPE,
- 		       "png: interlace method not supported");
-+  if (grub_errno != GRUB_ERR_NONE)
-+    return grub_errno;
- 
-   /* Skip crc checksum.  */
-   grub_png_get_dword (data);
-@@ -449,7 +468,7 @@ grub_png_get_huff_code (struct grub_png_data *data, struct huff_table *ht)
-   int code, i;
- 
-   code = 0;
--  for (i = 0; i < ht->max_length; i++)
-+  for (i = 0; i < ht->max_length && grub_errno == GRUB_ERR_NONE; i++)
-     {
-       code = (code << 1) + grub_png_get_bits (data, 1);
-       if (code < ht->maxval[i])
-@@ -504,8 +523,14 @@ grub_png_init_dynamic_block (struct grub_png_data *data)
-   grub_uint8_t lens[DEFLATE_HCLEN_MAX];
- 
-   nl = DEFLATE_HLIT_BASE + grub_png_get_bits (data, 5);
-+  if (grub_errno != GRUB_ERR_NONE)
-+    return grub_errno;
-   nd = DEFLATE_HDIST_BASE + grub_png_get_bits (data, 5);
-+  if (grub_errno != GRUB_ERR_NONE)
-+    return grub_errno;
-   nb = DEFLATE_HCLEN_BASE + grub_png_get_bits (data, 4);
-+  if (grub_errno != GRUB_ERR_NONE)
-+    return grub_errno;
- 
-   if ((nl > DEFLATE_HLIT_MAX) || (nd > DEFLATE_HDIST_MAX) ||
-       (nb > DEFLATE_HCLEN_MAX))
-@@ -533,7 +558,7 @@ grub_png_init_dynamic_block (struct grub_png_data *data)
- 			    data->dist_offset);
- 
-   prev = 0;
--  for (i = 0; i < nl + nd; i++)
-+  for (i = 0; i < nl + nd && grub_errno == GRUB_ERR_NONE; i++)
-     {
-       int n, code;
-       struct huff_table *ht;
-@@ -721,17 +746,21 @@ grub_png_read_dynamic_block (struct grub_png_data *data)
- 	  len = cplens[n];
- 	  if (cplext[n])
- 	    len += grub_png_get_bits (data, cplext[n]);
-+	  if (grub_errno != GRUB_ERR_NONE)
-+	    return grub_errno;
- 
- 	  n = grub_png_get_huff_code (data, &data->dist_table);
- 	  dist = cpdist[n];
- 	  if (cpdext[n])
- 	    dist += grub_png_get_bits (data, cpdext[n]);
-+	  if (grub_errno != GRUB_ERR_NONE)
-+	    return grub_errno;
- 
- 	  pos = data->wp - dist;
- 	  if (pos < 0)
- 	    pos += WSIZE;
- 
--	  while (len > 0)
-+	  while (len > 0 && grub_errno == GRUB_ERR_NONE)
- 	    {
- 	      data->slide[data->wp] = data->slide[pos];
- 	      grub_png_output_byte (data, data->slide[data->wp]);
-@@ -759,7 +788,11 @@ grub_png_decode_image_data (struct grub_png_data *data)
-   int final;
- 
-   cmf = grub_png_get_byte (data);
-+  if (grub_errno != GRUB_ERR_NONE)
-+    return grub_errno;
-   flg = grub_png_get_byte (data);
-+  if (grub_errno != GRUB_ERR_NONE)
-+    return grub_errno;
- 
-   if ((cmf & 0xF) != Z_DEFLATED)
-     return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-@@ -774,7 +807,11 @@ grub_png_decode_image_data (struct grub_png_data *data)
-       int block_type;
- 
-       final = grub_png_get_bits (data, 1);
-+      if (grub_errno != GRUB_ERR_NONE)
-+	return grub_errno;
-       block_type = grub_png_get_bits (data, 2);
-+      if (grub_errno != GRUB_ERR_NONE)
-+	return grub_errno;
- 
-       switch (block_type)
- 	{
-@@ -790,7 +827,7 @@ grub_png_decode_image_data (struct grub_png_data *data)
- 	    grub_png_get_byte (data);
- 	    grub_png_get_byte (data);
- 
--	    for (i = 0; i < len; i++)
-+	    for (i = 0; i < len && grub_errno == GRUB_ERR_NONE; i++)
- 	      grub_png_output_byte (data, grub_png_get_byte (data));
- 
- 	    break;
-@@ -1045,6 +1082,8 @@ grub_png_decode_png (struct grub_png_data *data)
- 
-       len = grub_png_get_dword (data);
-       type = grub_png_get_dword (data);
-+      if (grub_errno != GRUB_ERR_NONE)
-+	break;
-       data->next_offset = data->file->offset + len + 4;
- 
-       switch (type)
diff --git a/SOURCES/0510-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch b/SOURCES/0510-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch
new file mode 100644
index 0000000..f8809e6
--- /dev/null
+++ b/SOURCES/0510-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch
@@ -0,0 +1,43 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Chris Coulson <chris.coulson@canonical.com>
+Date: Mon, 2 May 2022 14:39:31 +0200
+Subject: [PATCH] loader/i386/efi/linux: Avoid a use-after-free in the linuxefi
+ loader
+
+In some error paths in grub_cmd_linux, the pointer to lh may be
+dereferenced after the buffer it points to has been freed. There aren't
+any security implications from this because nothing else uses the
+allocator after the buffer is freed and before the pointer is
+dereferenced, but fix it anyway.
+
+Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
+(cherry picked from commit 8224f5a71af94bec8697de17e7e579792db9f9e2)
+(cherry picked from commit 4744b62e20d07674017213ac54d7442d679f9d1a)
+(cherry picked from commit 329633cb060957c3d2aca677ac733f07b213a63f)
+---
+ grub-core/loader/i386/efi/linux.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
+index a043df891f..c9a2b47370 100644
+--- a/grub-core/loader/i386/efi/linux.c
++++ b/grub-core/loader/i386/efi/linux.c
+@@ -482,9 +482,6 @@ fail:
+   if (file)
+     grub_file_close (file);
+ 
+-  if (kernel)
+-    grub_free (kernel);
+-
+   if (grub_errno != GRUB_ERR_NONE)
+     {
+       grub_dl_unref (my_mod);
+@@ -500,6 +497,8 @@ fail:
+       kernel_free (params, sizeof(*params));
+     }
+ 
++  grub_free (kernel);
++
+   return grub_errno;
+ }
+ 
diff --git a/SOURCES/0510-video-readers-png-Refuse-to-handle-multiple-image-he.patch b/SOURCES/0510-video-readers-png-Refuse-to-handle-multiple-image-he.patch
deleted file mode 100644
index f882341..0000000
--- a/SOURCES/0510-video-readers-png-Refuse-to-handle-multiple-image-he.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Axtens <dja@axtens.net>
-Date: Tue, 6 Jul 2021 14:13:40 +1000
-Subject: [PATCH] video/readers/png: Refuse to handle multiple image headers
-
-This causes the bitmap to be leaked. Do not permit multiple image headers.
-
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit 8ce433557adeadbc46429aabb9f850b02ad2bdfb)
-(cherry picked from commit 6e10bba6a4cbfd6c7bf116f41fd4e037465e19d8)
-(cherry picked from commit 812272d919ecfd368c008f15b677d369616ada54)
-(cherry picked from commit c04569b35600aa29d5b4cd8990a8ee1dd1162c72)
----
- grub-core/video/readers/png.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
-index e2a6b1cf3c..8955b8ecfd 100644
---- a/grub-core/video/readers/png.c
-+++ b/grub-core/video/readers/png.c
-@@ -258,6 +258,9 @@ grub_png_decode_image_header (struct grub_png_data *data)
-   int color_bits;
-   enum grub_video_blit_format blt;
- 
-+  if (data->image_width || data->image_height)
-+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: two image headers found");
-+
-   data->image_width = grub_png_get_dword (data);
-   data->image_height = grub_png_get_dword (data);
- 
diff --git a/SOURCES/0511-loader-i386-efi-linux-Use-grub_loader_set_ex.patch b/SOURCES/0511-loader-i386-efi-linux-Use-grub_loader_set_ex.patch
new file mode 100644
index 0000000..981ea45
--- /dev/null
+++ b/SOURCES/0511-loader-i386-efi-linux-Use-grub_loader_set_ex.patch
@@ -0,0 +1,299 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Chris Coulson <chris.coulson@canonical.com>
+Date: Mon, 2 May 2022 17:04:23 +0200
+Subject: [PATCH] loader/i386/efi/linux: Use grub_loader_set_ex
+
+This ports the linuxefi loader to use grub_loader_set_ex in order to fix
+a use-after-fre bug that occurs when grub_cmd_linux is executed more than
+once before a boot attempt is performed.
+
+This is more complicated than for the chainloader command, as the initrd
+command needs access to the loader state. To solve this, the linuxefi
+module registers a dummy initrd command at startup that returns an error.
+The linuxefi command then registers a proper initrd command with a higher
+priority that is passed the loader state.
+
+Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
+(cherry picked from commit 7cf736436b4c934df5ddfa6f44b46a7e07d99fdc)
+[rharwood/pjones: set kernel_size in context]
+(cherry picked from commit 9c056391f7a36ea480de9a759c12e55a90f2040a)
+[rharwood: verifying twice]
+Signed-off-by: Robbie Harwood <rharwood@redhat.com>
+(cherry picked from commit df804892f1a754d88a9779320f9429bf40d2a1b3)
+---
+ grub-core/loader/i386/efi/linux.c | 146 +++++++++++++++++++++++---------------
+ 1 file changed, 87 insertions(+), 59 deletions(-)
+
+diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
+index c9a2b47370..77a0734786 100644
+--- a/grub-core/loader/i386/efi/linux.c
++++ b/grub-core/loader/i386/efi/linux.c
+@@ -34,13 +34,19 @@
+ GRUB_MOD_LICENSE ("GPLv3+");
+ 
+ static grub_dl_t my_mod;
+-static int loaded;
+-static void *kernel_mem;
+-static grub_uint64_t kernel_size;
+-static void *initrd_mem;
+-static grub_uint32_t handover_offset;
+-struct linux_kernel_params *params;
+-static char *linux_cmdline;
++
++static grub_command_t cmd_linux, cmd_initrd;
++static grub_command_t cmd_linuxefi, cmd_initrdefi;
++
++struct grub_linuxefi_context {
++  void *kernel_mem;
++  grub_uint64_t kernel_size;
++  grub_uint32_t handover_offset;
++  struct linux_kernel_params *params;
++  char *cmdline;
++
++  void *initrd_mem;
++};
+ 
+ #define MIN(a, b) \
+   ({ typeof (a) _a = (a); \
+@@ -123,25 +129,32 @@ kernel_alloc(grub_efi_uintn_t size, const char * const errmsg)
+ }
+ 
+ static grub_err_t
+-grub_linuxefi_boot (void)
++grub_linuxefi_boot (void *data)
+ {
++  struct grub_linuxefi_context *context = (struct grub_linuxefi_context *) data;
++
+   asm volatile ("cli");
+ 
+-  return grub_efi_linux_boot ((char *)kernel_mem,
+-			      handover_offset,
+-			      params);
++  return grub_efi_linux_boot ((char *)context->kernel_mem,
++			      context->handover_offset,
++			      context->params);
+ }
+ 
+ static grub_err_t
+-grub_linuxefi_unload (void)
++grub_linuxefi_unload (void *data)
+ {
++  struct grub_linuxefi_context *context = (struct grub_linuxefi_context *) data;
++  struct linux_kernel_params *params = context->params;
++
+   grub_dl_unref (my_mod);
+-  loaded = 0;
+ 
+-  kernel_free(initrd_mem, params->ramdisk_size);
+-  kernel_free(linux_cmdline, params->cmdline_size + 1);
+-  kernel_free(kernel_mem, kernel_size);
+-  kernel_free(params, sizeof(*params));
++  kernel_free (context->initrd_mem, params->ramdisk_size);
++  kernel_free (context->cmdline, params->cmdline_size + 1);
++  kernel_free (context->kernel_mem, context->kernel_size);
++  kernel_free (params, sizeof(*params));
++  cmd_initrd->data = 0;
++  cmd_initrdefi->data = 0;
++  grub_free (context);
+ 
+   return GRUB_ERR_NONE;
+ }
+@@ -188,13 +201,14 @@ read(grub_file_t file, grub_uint8_t *bufp, grub_size_t len)
+ #define HIGH_U32(val) ((grub_uint32_t)(((grub_addr_t)(val) >> 32) & 0xffffffffull))
+ 
+ static grub_err_t
+-grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+-                 int argc, char *argv[])
++grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
+ {
+   grub_file_t *files = 0;
+   int i, nfiles = 0;
+   grub_size_t size = 0;
+   grub_uint8_t *ptr;
++  struct grub_linuxefi_context *context = (struct grub_linuxefi_context *) cmd->data;
++  struct linux_kernel_params *params;
+ 
+   if (argc == 0)
+     {
+@@ -202,12 +216,14 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+       goto fail;
+     }
+ 
+-  if (!loaded)
++  if (!context)
+     {
+       grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first"));
+       goto fail;
+     }
+ 
++  params = context->params;
++
+   files = grub_calloc (argc, sizeof (files[0]));
+   if (!files)
+     goto fail;
+@@ -226,19 +242,19 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+ 	}
+     }
+ 
+-  initrd_mem = kernel_alloc(size, N_("can't allocate initrd"));
+-  if (initrd_mem == NULL)
++  context->initrd_mem = kernel_alloc(size, N_("can't allocate initrd"));
++  if (context->initrd_mem == NULL)
+     goto fail;
+-  grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem);
++  grub_dprintf ("linux", "initrd_mem = %p\n", context->initrd_mem);
+ 
+   params->ramdisk_size = LOW_U32(size);
+-  params->ramdisk_image = LOW_U32(initrd_mem);
++  params->ramdisk_image = LOW_U32(context->initrd_mem);
+ #if defined(__x86_64__)
+   params->ext_ramdisk_size = HIGH_U32(size);
+-  params->ext_ramdisk_image = HIGH_U32(initrd_mem);
++  params->ext_ramdisk_image = HIGH_U32(context->initrd_mem);
+ #endif
+ 
+-  ptr = initrd_mem;
++  ptr = context->initrd_mem;
+ 
+   for (i = 0; i < nfiles; i++)
+     {
+@@ -264,8 +280,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+     grub_file_close (files[i]);
+   grub_free (files);
+ 
+-  if (initrd_mem && grub_errno)
+-    grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)initrd_mem,
++  if (context->initrd_mem && grub_errno)
++    grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)context->initrd_mem,
+ 			 BYTES_TO_PAGES(size));
+ 
+   return grub_errno;
+@@ -281,6 +297,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+   void *kernel = NULL;
+   int setup_header_end_offset;
+   int rc;
++  void *kernel_mem = 0;
++  grub_uint64_t kernel_size = 0;
++  grub_uint32_t handover_offset;
++  struct linux_kernel_params *params = 0;
++  char *cmdline = 0;
++  struct grub_linuxefi_context *context = 0;
+ 
+   grub_dl_ref (my_mod);
+ 
+@@ -407,27 +429,27 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+   grub_dprintf ("linux", "new lh is at %p\n", lh);
+ 
+   grub_dprintf ("linux", "setting up cmdline\n");
+-  linux_cmdline = kernel_alloc (lh->cmdline_size + 1, N_("can't allocate cmdline"));
+-  if (!linux_cmdline)
++  cmdline = kernel_alloc (lh->cmdline_size + 1, N_("can't allocate cmdline"));
++  if (!cmdline)
+     goto fail;
+-  grub_dprintf ("linux", "linux_cmdline = %p\n", linux_cmdline);
++  grub_dprintf ("linux", "cmdline = %p\n", cmdline);
+ 
+-  grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE));
++  grub_memcpy (cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE));
+   grub_create_loader_cmdline (argc, argv,
+-                              linux_cmdline + sizeof (LINUX_IMAGE) - 1,
++                              cmdline + sizeof (LINUX_IMAGE) - 1,
+ 			      lh->cmdline_size - (sizeof (LINUX_IMAGE) - 1),
+ 			      GRUB_VERIFY_KERNEL_CMDLINE);
+ 
+-  grub_dprintf ("linux", "cmdline:%s\n", linux_cmdline);
++  grub_dprintf ("linux", "cmdline:%s\n", cmdline);
+   grub_dprintf ("linux", "setting lh->cmd_line_ptr to 0x%08x\n",
+-		LOW_U32(linux_cmdline));
+-  lh->cmd_line_ptr = LOW_U32(linux_cmdline);
++		LOW_U32(cmdline));
++  lh->cmd_line_ptr = LOW_U32(cmdline);
+ #if defined(__x86_64__)
+-  if ((grub_efi_uintn_t)linux_cmdline > 0xffffffffull)
++  if ((grub_efi_uintn_t)cmdline > 0xffffffffull)
+     {
+       grub_dprintf ("linux", "setting params->ext_cmd_line_ptr to 0x%08x\n",
+-		    HIGH_U32(linux_cmdline));
+-      params->ext_cmd_line_ptr = HIGH_U32(linux_cmdline);
++		    HIGH_U32(cmdline));
++      params->ext_cmd_line_ptr = HIGH_U32(cmdline);
+     }
+ #endif
+ 
+@@ -452,16 +474,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+     }
+   max_addresses[1].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
+   max_addresses[2].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
+-  kernel_mem = kernel_alloc (lh->init_size, N_("can't allocate kernel"));
++  kernel_size = lh->init_size;
++  kernel_mem = kernel_alloc (kernel_size, N_("can't allocate kernel"));
+   restore_addresses();
+   if (!kernel_mem)
+     goto fail;
+   grub_dprintf("linux", "kernel_mem = %p\n", kernel_mem);
+ 
+-  grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0);
+-
+-  loaded = 1;
+-
+   grub_dprintf ("linux", "setting lh->code32_start to 0x%08x\n",
+ 		LOW_U32(kernel_mem));
+   lh->code32_start = LOW_U32(kernel_mem);
+@@ -478,33 +497,42 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+ 		"setting lh->ext_loader_{type,ver} = {0x%02x,0x%02x}\n",
+ 		params->ext_loader_type, params->ext_loader_ver);
+ 
++  context = grub_zalloc (sizeof (*context));
++  if (!context)
++    goto fail;
++  context->kernel_mem = kernel_mem;
++  context->kernel_size = kernel_size;
++  context->handover_offset = handover_offset;
++  context->params = params;
++  context->cmdline = cmdline;
++
++  grub_loader_set_ex (grub_linuxefi_boot, grub_linuxefi_unload, context, 0);
++
++  cmd_initrd->data = context;
++  cmd_initrdefi->data = context;
++
++  grub_file_close (file);
++  grub_free (kernel);
++  return 0;
++
+ fail:
+   if (file)
+     grub_file_close (file);
+ 
+-  if (grub_errno != GRUB_ERR_NONE)
+-    {
+-      grub_dl_unref (my_mod);
+-      loaded = 0;
+-    }
++  grub_dl_unref (my_mod);
+ 
+-  if (!loaded)
+-    {
+-      if (lh)
+-	kernel_free (linux_cmdline, lh->cmdline_size + 1);
++  if (lh)
++    kernel_free (cmdline, lh->cmdline_size + 1);
+ 
+-      kernel_free (kernel_mem, kernel_size);
+-      kernel_free (params, sizeof(*params));
+-    }
++  kernel_free (kernel_mem, kernel_size);
++  kernel_free (params, sizeof(*params));
+ 
++  grub_free (context);
+   grub_free (kernel);
+ 
+   return grub_errno;
+ }
+ 
+-static grub_command_t cmd_linux, cmd_initrd;
+-static grub_command_t cmd_linuxefi, cmd_initrdefi;
+-
+ GRUB_MOD_INIT(linux)
+ {
+   cmd_linux =
diff --git a/SOURCES/0511-video-readers-png-Drop-greyscale-support-to-fix-heap.patch b/SOURCES/0511-video-readers-png-Drop-greyscale-support-to-fix-heap.patch
deleted file mode 100644
index ba88782..0000000
--- a/SOURCES/0511-video-readers-png-Drop-greyscale-support-to-fix-heap.patch
+++ /dev/null
@@ -1,173 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Axtens <dja@axtens.net>
-Date: Tue, 6 Jul 2021 18:51:35 +1000
-Subject: [PATCH] video/readers/png: Drop greyscale support to fix heap
- out-of-bounds write
-
-A 16-bit greyscale PNG without alpha is processed in the following loop:
-
-      for (i = 0; i < (data->image_width * data->image_height);
-	   i++, d1 += 4, d2 += 2)
-	{
-	  d1[R3] = d2[1];
-	  d1[G3] = d2[1];
-	  d1[B3] = d2[1];
-	}
-
-The increment of d1 is wrong. d1 is incremented by 4 bytes per iteration,
-but there are only 3 bytes allocated for storage. This means that image
-data will overwrite somewhat-attacker-controlled parts of memory - 3 bytes
-out of every 4 following the end of the image.
-
-This has existed since greyscale support was added in 2013 in commit
-3ccf16dff98f (grub-core/video/readers/png.c: Support grayscale).
-
-Saving starfield.png as a 16-bit greyscale image without alpha in the gimp
-and attempting to load it causes grub-emu to crash - I don't think this code
-has ever worked.
-
-Delete all PNG greyscale support.
-
-Fixes: CVE-2021-3695
-
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit 0e1d163382669bd734439d8864ee969616d971d9)
-[rharwood: context conflict]
-Signed-off-by: Robbie Harwood <rharwood@redhat.com>
-(cherry picked from commit 4c631c8119206b3178912df2905434d967661c3d)
-(cherry picked from commit 6d5d5f51266b8113c6ba560835500e3c135f3722)
-(cherry picked from commit b20fc5589561a8c57a2071b2ae93fcdcf51a10d4)
----
- grub-core/video/readers/png.c | 85 +++----------------------------------------
- 1 file changed, 6 insertions(+), 79 deletions(-)
-
-diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
-index 8955b8ecfd..a3161e25b6 100644
---- a/grub-core/video/readers/png.c
-+++ b/grub-core/video/readers/png.c
-@@ -100,7 +100,7 @@ struct grub_png_data
- 
-   unsigned image_width, image_height;
-   int bpp, is_16bit;
--  int raw_bytes, is_gray, is_alpha, is_palette;
-+  int raw_bytes, is_alpha, is_palette;
-   int row_bytes, color_bits;
-   grub_uint8_t *image_data;
- 
-@@ -296,13 +296,13 @@ grub_png_decode_image_header (struct grub_png_data *data)
-     data->bpp = 3;
-   else
-     {
--      data->is_gray = 1;
--      data->bpp = 1;
-+      return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-+			 "png: color type not supported");
-     }
- 
-   if ((color_bits != 8) && (color_bits != 16)
-       && (color_bits != 4
--	  || !(data->is_gray || data->is_palette)))
-+	  || !data->is_palette))
-     return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                        "png: bit depth must be 8 or 16");
- 
-@@ -331,7 +331,7 @@ grub_png_decode_image_header (struct grub_png_data *data)
-     }
- 
- #ifndef GRUB_CPU_WORDS_BIGENDIAN
--  if (data->is_16bit || data->is_gray || data->is_palette)
-+  if (data->is_16bit || data->is_palette)
- #endif
-     {
-       data->image_data = grub_calloc (data->image_height, data->row_bytes);
-@@ -899,27 +899,8 @@ grub_png_convert_image (struct grub_png_data *data)
-       int shift;
-       int mask = (1 << data->color_bits) - 1;
-       unsigned j;
--      if (data->is_gray)
--	{
--	  /* Generic formula is
--	     (0xff * i) / ((1U << data->color_bits) - 1)
--	     but for allowed bit depth of 1, 2 and for it's
--	     equivalent to
--	     (0xff / ((1U << data->color_bits) - 1)) * i
--	     Precompute the multipliers to avoid division.
--	  */
- 
--	  const grub_uint8_t multipliers[5] = { 0xff, 0xff, 0x55, 0x24, 0x11 };
--	  for (i = 0; i < (1U << data->color_bits); i++)
--	    {
--	      grub_uint8_t col = multipliers[data->color_bits] * i;
--	      palette[i][0] = col;
--	      palette[i][1] = col;
--	      palette[i][2] = col;
--	    }
--	}
--      else
--	grub_memcpy (palette, data->palette, 3 << data->color_bits);
-+      grub_memcpy (palette, data->palette, 3 << data->color_bits);
-       d1c = d1;
-       d2c = d2;
-       for (j = 0; j < data->image_height; j++, d1c += data->image_width * 3,
-@@ -956,60 +937,6 @@ grub_png_convert_image (struct grub_png_data *data)
- 	}
-       return;
-     }
--  
--  if (data->is_gray)
--    {
--      switch (data->bpp)
--	{
--	case 4:
--	  /* 16-bit gray with alpha.  */
--	  for (i = 0; i < (data->image_width * data->image_height);
--	       i++, d1 += 4, d2 += 4)
--	    {
--	      d1[R4] = d2[3];
--	      d1[G4] = d2[3];
--	      d1[B4] = d2[3];
--	      d1[A4] = d2[1];
--	    }
--	  break;
--	case 2:
--	  if (data->is_16bit)
--	    /* 16-bit gray without alpha.  */
--	    {
--	      for (i = 0; i < (data->image_width * data->image_height);
--		   i++, d1 += 4, d2 += 2)
--		{
--		  d1[R3] = d2[1];
--		  d1[G3] = d2[1];
--		  d1[B3] = d2[1];
--		}
--	    }
--	  else
--	    /* 8-bit gray with alpha.  */
--	    {
--	      for (i = 0; i < (data->image_width * data->image_height);
--		   i++, d1 += 4, d2 += 2)
--		{
--		  d1[R4] = d2[1];
--		  d1[G4] = d2[1];
--		  d1[B4] = d2[1];
--		  d1[A4] = d2[0];
--		}
--	    }
--	  break;
--	  /* 8-bit gray without alpha.  */
--	case 1:
--	  for (i = 0; i < (data->image_width * data->image_height);
--	       i++, d1 += 3, d2++)
--	    {
--	      d1[R3] = d2[0];
--	      d1[G3] = d2[0];
--	      d1[B3] = d2[0];
--	    }
--	  break;
--	}
--      return;
--    }
- 
-     {
-   /* Only copy the upper 8 bit.  */
diff --git a/SOURCES/0512-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch b/SOURCES/0512-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch
new file mode 100644
index 0000000..1a8cae9
--- /dev/null
+++ b/SOURCES/0512-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch
@@ -0,0 +1,77 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Chris Coulson <chris.coulson@canonical.com>
+Date: Tue, 3 May 2022 09:47:35 +0200
+Subject: [PATCH] loader/i386/efi/linux: Fix a memory leak in the initrd
+ command
+
+Subsequent invocations of the initrd command result in the previous
+initrd being leaked, so fix that.
+
+Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
+(cherry picked from commit d98af31ce1e31bb22163960d53f5eb28c66582a0)
+(cherry picked from commit 62234d6a00e6d1dd8e017ff161d359feb5234082)
+(cherry picked from commit bda5a10716dc9676400dce1374232452f46d0bc4)
+---
+ grub-core/loader/i386/efi/linux.c | 21 ++++++++++++---------
+ 1 file changed, 12 insertions(+), 9 deletions(-)
+
+diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
+index 77a0734786..8337191921 100644
+--- a/grub-core/loader/i386/efi/linux.c
++++ b/grub-core/loader/i386/efi/linux.c
+@@ -209,6 +209,7 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
+   grub_uint8_t *ptr;
+   struct grub_linuxefi_context *context = (struct grub_linuxefi_context *) cmd->data;
+   struct linux_kernel_params *params;
++  void *initrd_mem = 0;
+ 
+   if (argc == 0)
+     {
+@@ -242,19 +243,19 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
+ 	}
+     }
+ 
+-  context->initrd_mem = kernel_alloc(size, N_("can't allocate initrd"));
+-  if (context->initrd_mem == NULL)
++  initrd_mem = kernel_alloc(size, N_("can't allocate initrd"));
++  if (initrd_mem == NULL)
+     goto fail;
+-  grub_dprintf ("linux", "initrd_mem = %p\n", context->initrd_mem);
++  grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem);
+ 
+   params->ramdisk_size = LOW_U32(size);
+-  params->ramdisk_image = LOW_U32(context->initrd_mem);
++  params->ramdisk_image = LOW_U32(initrd_mem);
+ #if defined(__x86_64__)
+   params->ext_ramdisk_size = HIGH_U32(size);
+-  params->ext_ramdisk_image = HIGH_U32(context->initrd_mem);
++  params->ext_ramdisk_image = HIGH_U32(initrd_mem);
+ #endif
+ 
+-  ptr = context->initrd_mem;
++  ptr = initrd_mem;
+ 
+   for (i = 0; i < nfiles; i++)
+     {
+@@ -273,6 +274,9 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
+       ptr += ALIGN_UP_OVERHEAD (cursize, 4);
+     }
+ 
++  kernel_free(context->initrd_mem, params->ramdisk_size);
++
++  context->initrd_mem = initrd_mem;
+   params->ramdisk_size = size;
+ 
+  fail:
+@@ -280,9 +284,8 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
+     grub_file_close (files[i]);
+   grub_free (files);
+ 
+-  if (context->initrd_mem && grub_errno)
+-    grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)context->initrd_mem,
+-			 BYTES_TO_PAGES(size));
++  if (initrd_mem && grub_errno)
++    kernel_free (initrd_mem, size);
+ 
+   return grub_errno;
+ }
diff --git a/SOURCES/0512-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch b/SOURCES/0512-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch
deleted file mode 100644
index a25685c..0000000
--- a/SOURCES/0512-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Axtens <dja@axtens.net>
-Date: Tue, 6 Jul 2021 23:25:07 +1000
-Subject: [PATCH] video/readers/png: Avoid heap OOB R/W inserting huff table
- items
-
-In fuzzing we observed crashes where a code would attempt to be inserted
-into a huffman table before the start, leading to a set of heap OOB reads
-and writes as table entries with negative indices were shifted around and
-the new code written in.
-
-Catch the case where we would underflow the array and bail.
-
-Fixes: CVE-2021-3696
-
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit 1ae9a91d42cb40da8a6f11fac65541858e340afa)
-(cherry picked from commit 132ccc681cf642ad748580f26b54c9259a7f43fd)
-(cherry picked from commit 3a70e1f6e69af6e0d3c3cf526faa44dc0c80ac19)
-(cherry picked from commit 809d25ffa6b89d390a66d2f3cf3090196f07e2aa)
----
- grub-core/video/readers/png.c | 7 +++++++
- 1 file changed, 7 insertions(+)
-
-diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
-index a3161e25b6..d7ed5aa6cf 100644
---- a/grub-core/video/readers/png.c
-+++ b/grub-core/video/readers/png.c
-@@ -438,6 +438,13 @@ grub_png_insert_huff_item (struct huff_table *ht, int code, int len)
-   for (i = len; i < ht->max_length; i++)
-     n += ht->maxval[i];
- 
-+  if (n > ht->num_values)
-+    {
-+      grub_error (GRUB_ERR_BAD_FILE_TYPE,
-+		  "png: out of range inserting huffman table item");
-+      return;
-+    }
-+
-   for (i = 0; i < n; i++)
-     ht->values[ht->num_values - i] = ht->values[ht->num_values - i - 1];
- 
diff --git a/SOURCES/0513-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch b/SOURCES/0513-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch
new file mode 100644
index 0000000..aff3231
--- /dev/null
+++ b/SOURCES/0513-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch
@@ -0,0 +1,41 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Fri, 25 Jun 2021 02:19:05 +1000
+Subject: [PATCH] kern/file: Do not leak device_name on error in
+ grub_file_open()
+
+If we have an error in grub_file_open() before we free device_name, we
+will leak it.
+
+Free device_name in the error path and null out the pointer in the good
+path once we free it there.
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit 1499a5068839fa37cb77ecef4b5bdacbd1ed12ea)
+(cherry picked from commit 2ec50b289d8b24922433439533113087f111f110)
+(cherry picked from commit 17c36ae88d7d6040cabc01cd4a21e71ff4731668)
+---
+ grub-core/kern/file.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c
+index 2efc31da94..f062fc21e7 100644
+--- a/grub-core/kern/file.c
++++ b/grub-core/kern/file.c
+@@ -81,6 +81,7 @@ grub_file_open (const char *name, enum grub_file_type type)
+ 
+   device = grub_device_open (device_name);
+   grub_free (device_name);
++  device_name = NULL;
+   if (! device)
+     goto fail;
+ 
+@@ -135,6 +136,7 @@ grub_file_open (const char *name, enum grub_file_type type)
+   return file;
+ 
+  fail:
++  grub_free (device_name);
+   if (device)
+     grub_device_close (device);
+ 
diff --git a/SOURCES/0513-video-readers-png-Sanity-check-some-huffman-codes.patch b/SOURCES/0513-video-readers-png-Sanity-check-some-huffman-codes.patch
deleted file mode 100644
index 4ba2e4d..0000000
--- a/SOURCES/0513-video-readers-png-Sanity-check-some-huffman-codes.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Axtens <dja@axtens.net>
-Date: Tue, 6 Jul 2021 19:19:11 +1000
-Subject: [PATCH] video/readers/png: Sanity check some huffman codes
-
-ASAN picked up two OOB global reads: we weren't checking if some code
-values fit within the cplens or cpdext arrays. Check and throw an error
-if not.
-
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit c3a8ab0cbd24153ec7b1f84a96ddfdd72ef8d117)
-(cherry picked from commit 5d09addf58086aa11d5f9a91af5632ff87c2d2ee)
-(cherry picked from commit ff12584f9376a472f37d4ec14213fd29bf3b233a)
-(cherry picked from commit ac8b5464a076d2e38ecf7f761be9cd1f5bbeb784)
----
- grub-core/video/readers/png.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
-index d7ed5aa6cf..7f2ba7849b 100644
---- a/grub-core/video/readers/png.c
-+++ b/grub-core/video/readers/png.c
-@@ -753,6 +753,9 @@ grub_png_read_dynamic_block (struct grub_png_data *data)
- 	  int len, dist, pos;
- 
- 	  n -= 257;
-+	  if (((unsigned int) n) >= ARRAY_SIZE (cplens))
-+	    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-+			       "png: invalid huff code");
- 	  len = cplens[n];
- 	  if (cplext[n])
- 	    len += grub_png_get_bits (data, cplext[n]);
-@@ -760,6 +763,9 @@ grub_png_read_dynamic_block (struct grub_png_data *data)
- 	    return grub_errno;
- 
- 	  n = grub_png_get_huff_code (data, &data->dist_table);
-+	  if (((unsigned int) n) >= ARRAY_SIZE (cpdist))
-+	    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-+			       "png: invalid huff code");
- 	  dist = cpdist[n];
- 	  if (cpdext[n])
- 	    dist += grub_png_get_bits (data, cpdext[n]);
diff --git a/SOURCES/0514-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch b/SOURCES/0514-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch
deleted file mode 100644
index b5c2ca9..0000000
--- a/SOURCES/0514-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch
+++ /dev/null
@@ -1,258 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Axtens <dja@axtens.net>
-Date: Mon, 28 Jun 2021 14:16:14 +1000
-Subject: [PATCH] video/readers/jpeg: Abort sooner if a read operation fails
-
-Fuzzing revealed some inputs that were taking a long time, potentially
-forever, because they did not bail quickly upon encountering an I/O error.
-
-Try to catch I/O errors sooner and bail out.
-
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit ab2e5d2e4bff488bbb557ed435a61ae102ef9f0c)
-(cherry picked from commit 1ff8df0d2dea8ec7c8575241d5e7d6622c204ec3)
-(cherry picked from commit b07767383b74a0ce7135c09ba8701510d4ad32f0)
-(cherry picked from commit 5f097165152d61d4aea02f26dc789d840147d50e)
----
- grub-core/video/readers/jpeg.c | 86 ++++++++++++++++++++++++++++++++++--------
- 1 file changed, 70 insertions(+), 16 deletions(-)
-
-diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
-index e31602f766..10225abd53 100644
---- a/grub-core/video/readers/jpeg.c
-+++ b/grub-core/video/readers/jpeg.c
-@@ -109,9 +109,17 @@ static grub_uint8_t
- grub_jpeg_get_byte (struct grub_jpeg_data *data)
- {
-   grub_uint8_t r;
-+  grub_ssize_t bytes_read;
- 
-   r = 0;
--  grub_file_read (data->file, &r, 1);
-+  bytes_read = grub_file_read (data->file, &r, 1);
-+
-+  if (bytes_read != 1)
-+    {
-+      grub_error (GRUB_ERR_BAD_FILE_TYPE,
-+		  "jpeg: unexpected end of data");
-+      return 0;
-+    }
- 
-   return r;
- }
-@@ -120,9 +128,17 @@ static grub_uint16_t
- grub_jpeg_get_word (struct grub_jpeg_data *data)
- {
-   grub_uint16_t r;
-+  grub_ssize_t bytes_read;
- 
-   r = 0;
--  grub_file_read (data->file, &r, sizeof (grub_uint16_t));
-+  bytes_read = grub_file_read (data->file, &r, sizeof (grub_uint16_t));
-+
-+  if (bytes_read != sizeof (grub_uint16_t))
-+    {
-+      grub_error (GRUB_ERR_BAD_FILE_TYPE,
-+		  "jpeg: unexpected end of data");
-+      return 0;
-+    }
- 
-   return grub_be_to_cpu16 (r);
- }
-@@ -135,6 +151,11 @@ grub_jpeg_get_bit (struct grub_jpeg_data *data)
-   if (data->bit_mask == 0)
-     {
-       data->bit_save = grub_jpeg_get_byte (data);
-+      if (grub_errno != GRUB_ERR_NONE) {
-+	grub_error (GRUB_ERR_BAD_FILE_TYPE,
-+		    "jpeg: file read error");
-+	return 0;
-+      }
-       if (data->bit_save == JPEG_ESC_CHAR)
- 	{
- 	  if (grub_jpeg_get_byte (data) != 0)
-@@ -143,6 +164,11 @@ grub_jpeg_get_bit (struct grub_jpeg_data *data)
- 			  "jpeg: invalid 0xFF in data stream");
- 	      return 0;
- 	    }
-+	  if (grub_errno != GRUB_ERR_NONE)
-+	    {
-+	      grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: file read error");
-+	      return 0;
-+	    }
- 	}
-       data->bit_mask = 0x80;
-     }
-@@ -161,7 +187,7 @@ grub_jpeg_get_number (struct grub_jpeg_data *data, int num)
-     return 0;
- 
-   msb = value = grub_jpeg_get_bit (data);
--  for (i = 1; i < num; i++)
-+  for (i = 1; i < num && grub_errno == GRUB_ERR_NONE; i++)
-     value = (value << 1) + (grub_jpeg_get_bit (data) != 0);
-   if (!msb)
-     value += 1 - (1 << num);
-@@ -202,6 +228,8 @@ grub_jpeg_decode_huff_table (struct grub_jpeg_data *data)
-   while (data->file->offset + sizeof (count) + 1 <= next_marker)
-     {
-       id = grub_jpeg_get_byte (data);
-+      if (grub_errno != GRUB_ERR_NONE)
-+	return grub_errno;
-       ac = (id >> 4) & 1;
-       id &= 0xF;
-       if (id > 1)
-@@ -252,6 +280,8 @@ grub_jpeg_decode_quan_table (struct grub_jpeg_data *data)
- 
-   next_marker = data->file->offset;
-   next_marker += grub_jpeg_get_word (data);
-+  if (grub_errno != GRUB_ERR_NONE)
-+    return grub_errno;
- 
-   if (next_marker > data->file->size)
-     {
-@@ -263,6 +293,8 @@ grub_jpeg_decode_quan_table (struct grub_jpeg_data *data)
- 	 <= next_marker)
-     {
-       id = grub_jpeg_get_byte (data);
-+      if (grub_errno != GRUB_ERR_NONE)
-+        return grub_errno;
-       if (id >= 0x10)		/* Upper 4-bit is precision.  */
- 	return grub_error (GRUB_ERR_BAD_FILE_TYPE,
- 			   "jpeg: only 8-bit precision is supported");
-@@ -294,6 +326,9 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data)
-   next_marker = data->file->offset;
-   next_marker += grub_jpeg_get_word (data);
- 
-+  if (grub_errno != GRUB_ERR_NONE)
-+    return grub_errno;
-+
-   if (grub_jpeg_get_byte (data) != 8)
-     return grub_error (GRUB_ERR_BAD_FILE_TYPE,
- 		       "jpeg: only 8-bit precision is supported");
-@@ -319,6 +354,8 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data)
- 	return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index");
- 
-       ss = grub_jpeg_get_byte (data);	/* Sampling factor.  */
-+      if (grub_errno != GRUB_ERR_NONE)
-+	return grub_errno;
-       if (!id)
- 	{
- 	  grub_uint8_t vs, hs;
-@@ -498,7 +535,7 @@ grub_jpeg_idct_transform (jpeg_data_unit_t du)
-     }
- }
- 
--static void
-+static grub_err_t
- grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du)
- {
-   int h1, h2, qt;
-@@ -513,6 +550,9 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du)
-   data->dc_value[id] +=
-     grub_jpeg_get_number (data, grub_jpeg_get_huff_code (data, h1));
- 
-+  if (grub_errno != GRUB_ERR_NONE)
-+    return grub_errno;
-+
-   du[0] = data->dc_value[id] * (int) data->quan_table[qt][0];
-   pos = 1;
-   while (pos < ARRAY_SIZE (data->quan_table[qt]))
-@@ -527,11 +567,13 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du)
-       num >>= 4;
-       pos += num;
- 
-+      if (grub_errno != GRUB_ERR_NONE)
-+        return grub_errno;
-+
-       if (pos >= ARRAY_SIZE (jpeg_zigzag_order))
- 	{
--	  grub_error (GRUB_ERR_BAD_FILE_TYPE,
--		      "jpeg: invalid position in zigzag order!?");
--	  return;
-+	  return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-+			     "jpeg: invalid position in zigzag order!?");
- 	}
- 
-       du[jpeg_zigzag_order[pos]] = val * (int) data->quan_table[qt][pos];
-@@ -539,6 +581,7 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du)
-     }
- 
-   grub_jpeg_idct_transform (du);
-+  return GRUB_ERR_NONE;
- }
- 
- static void
-@@ -597,7 +640,8 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data)
-   data_offset += grub_jpeg_get_word (data);
- 
-   cc = grub_jpeg_get_byte (data);
--
-+  if (grub_errno != GRUB_ERR_NONE)
-+    return grub_errno;
-   if (cc != 3 && cc != 1)
-     return grub_error (GRUB_ERR_BAD_FILE_TYPE,
- 		       "jpeg: component count must be 1 or 3");
-@@ -610,7 +654,8 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data)
-       id = grub_jpeg_get_byte (data) - 1;
-       if ((id < 0) || (id >= 3))
- 	return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index");
--
-+      if (grub_errno != GRUB_ERR_NONE)
-+	return grub_errno;
-       ht = grub_jpeg_get_byte (data);
-       data->comp_index[id][1] = (ht >> 4);
-       data->comp_index[id][2] = (ht & 0xF) + 2;
-@@ -618,11 +663,14 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data)
-       if ((data->comp_index[id][1] < 0) || (data->comp_index[id][1] > 3) ||
- 	  (data->comp_index[id][2] < 0) || (data->comp_index[id][2] > 3))
- 	return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid hufftable index");
-+      if (grub_errno != GRUB_ERR_NONE)
-+	return grub_errno;
-     }
- 
-   grub_jpeg_get_byte (data);	/* Skip 3 unused bytes.  */
-   grub_jpeg_get_word (data);
--
-+  if (grub_errno != GRUB_ERR_NONE)
-+    return grub_errno;
-   if (data->file->offset != data_offset)
-     return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sos");
- 
-@@ -640,6 +688,7 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data)
- {
-   unsigned c1, vb, hb, nr1, nc1;
-   int rst = data->dri;
-+  grub_err_t err = GRUB_ERR_NONE;
- 
-   vb = 8 << data->log_vs;
-   hb = 8 << data->log_hs;
-@@ -660,17 +709,22 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data)
- 
- 	for (r2 = 0; r2 < (1U << data->log_vs); r2++)
- 	  for (c2 = 0; c2 < (1U << data->log_hs); c2++)
--	    grub_jpeg_decode_du (data, 0, data->ydu[r2 * 2 + c2]);
-+            {
-+              err = grub_jpeg_decode_du (data, 0, data->ydu[r2 * 2 + c2]);
-+              if (err != GRUB_ERR_NONE)
-+                return err;
-+            }
- 
- 	if (data->color_components >= 3)
- 	  {
--	    grub_jpeg_decode_du (data, 1, data->cbdu);
--	    grub_jpeg_decode_du (data, 2, data->crdu);
-+	    err = grub_jpeg_decode_du (data, 1, data->cbdu);
-+	    if (err != GRUB_ERR_NONE)
-+	      return err;
-+	    err = grub_jpeg_decode_du (data, 2, data->crdu);
-+	    if (err != GRUB_ERR_NONE)
-+	      return err;
- 	  }
- 
--	if (grub_errno)
--	  return grub_errno;
--
- 	nr2 = (data->r1 == nr1 - 1) ? (data->image_height - data->r1 * vb) : vb;
- 	nc2 = (c1 == nc1 - 1) ? (data->image_width - c1 * hb) : hb;
- 
diff --git a/SOURCES/0514-video-readers-png-Abort-sooner-if-a-read-operation-f.patch b/SOURCES/0514-video-readers-png-Abort-sooner-if-a-read-operation-f.patch
new file mode 100644
index 0000000..12dba4d
--- /dev/null
+++ b/SOURCES/0514-video-readers-png-Abort-sooner-if-a-read-operation-f.patch
@@ -0,0 +1,200 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Tue, 6 Jul 2021 14:02:55 +1000
+Subject: [PATCH] video/readers/png: Abort sooner if a read operation fails
+
+Fuzzing revealed some inputs that were taking a long time, potentially
+forever, because they did not bail quickly upon encountering an I/O error.
+
+Try to catch I/O errors sooner and bail out.
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit 882be97d1df6449b9fd4d593f0cb70005fde3494)
+(cherry picked from commit 3f6fc3ebfd58fcdb3fe6c2f7a5a4fa05772ae786)
+(cherry picked from commit aac5b8257d4078c3f764216aeae3367bdc19043f)
+---
+ grub-core/video/readers/png.c | 55 ++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 47 insertions(+), 8 deletions(-)
+
+diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
+index 0157ff7420..e2a6b1cf3c 100644
+--- a/grub-core/video/readers/png.c
++++ b/grub-core/video/readers/png.c
+@@ -142,6 +142,7 @@ static grub_uint8_t
+ grub_png_get_byte (struct grub_png_data *data)
+ {
+   grub_uint8_t r;
++  grub_ssize_t bytes_read = 0;
+ 
+   if ((data->inside_idat) && (data->idat_remain == 0))
+     {
+@@ -175,7 +176,14 @@ grub_png_get_byte (struct grub_png_data *data)
+     }
+ 
+   r = 0;
+-  grub_file_read (data->file, &r, 1);
++  bytes_read = grub_file_read (data->file, &r, 1);
++
++  if (bytes_read != 1)
++    {
++      grub_error (GRUB_ERR_BAD_FILE_TYPE,
++		  "png: unexpected end of data");
++      return 0;
++    }
+ 
+   if (data->inside_idat)
+     data->idat_remain--;
+@@ -231,15 +239,16 @@ grub_png_decode_image_palette (struct grub_png_data *data,
+   if (len == 0)
+     return GRUB_ERR_NONE;
+ 
+-  for (i = 0; 3 * i < len && i < 256; i++)
++  grub_errno = GRUB_ERR_NONE;
++  for (i = 0; 3 * i < len && i < 256 && grub_errno == GRUB_ERR_NONE; i++)
+     for (j = 0; j < 3; j++)
+       data->palette[i][j] = grub_png_get_byte (data);
+-  for (i *= 3; i < len; i++)
++  for (i *= 3; i < len && grub_errno == GRUB_ERR_NONE; i++)
+     grub_png_get_byte (data);
+ 
+   grub_png_get_dword (data);
+ 
+-  return GRUB_ERR_NONE;
++  return grub_errno;
+ }
+ 
+ static grub_err_t
+@@ -256,9 +265,13 @@ grub_png_decode_image_header (struct grub_png_data *data)
+     return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: invalid image size");
+ 
+   color_bits = grub_png_get_byte (data);
++  if (grub_errno != GRUB_ERR_NONE)
++    return grub_errno;
+   data->is_16bit = (color_bits == 16);
+ 
+   color_type = grub_png_get_byte (data);
++  if (grub_errno != GRUB_ERR_NONE)
++    return grub_errno;
+ 
+   /* According to PNG spec, no other types are valid.  */
+   if ((color_type & ~(PNG_COLOR_MASK_ALPHA | PNG_COLOR_MASK_COLOR))
+@@ -340,14 +353,20 @@ grub_png_decode_image_header (struct grub_png_data *data)
+   if (grub_png_get_byte (data) != PNG_COMPRESSION_BASE)
+     return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ 		       "png: compression method not supported");
++  if (grub_errno != GRUB_ERR_NONE)
++    return grub_errno;
+ 
+   if (grub_png_get_byte (data) != PNG_FILTER_TYPE_BASE)
+     return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ 		       "png: filter method not supported");
++  if (grub_errno != GRUB_ERR_NONE)
++    return grub_errno;
+ 
+   if (grub_png_get_byte (data) != PNG_INTERLACE_NONE)
+     return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ 		       "png: interlace method not supported");
++  if (grub_errno != GRUB_ERR_NONE)
++    return grub_errno;
+ 
+   /* Skip crc checksum.  */
+   grub_png_get_dword (data);
+@@ -449,7 +468,7 @@ grub_png_get_huff_code (struct grub_png_data *data, struct huff_table *ht)
+   int code, i;
+ 
+   code = 0;
+-  for (i = 0; i < ht->max_length; i++)
++  for (i = 0; i < ht->max_length && grub_errno == GRUB_ERR_NONE; i++)
+     {
+       code = (code << 1) + grub_png_get_bits (data, 1);
+       if (code < ht->maxval[i])
+@@ -504,8 +523,14 @@ grub_png_init_dynamic_block (struct grub_png_data *data)
+   grub_uint8_t lens[DEFLATE_HCLEN_MAX];
+ 
+   nl = DEFLATE_HLIT_BASE + grub_png_get_bits (data, 5);
++  if (grub_errno != GRUB_ERR_NONE)
++    return grub_errno;
+   nd = DEFLATE_HDIST_BASE + grub_png_get_bits (data, 5);
++  if (grub_errno != GRUB_ERR_NONE)
++    return grub_errno;
+   nb = DEFLATE_HCLEN_BASE + grub_png_get_bits (data, 4);
++  if (grub_errno != GRUB_ERR_NONE)
++    return grub_errno;
+ 
+   if ((nl > DEFLATE_HLIT_MAX) || (nd > DEFLATE_HDIST_MAX) ||
+       (nb > DEFLATE_HCLEN_MAX))
+@@ -533,7 +558,7 @@ grub_png_init_dynamic_block (struct grub_png_data *data)
+ 			    data->dist_offset);
+ 
+   prev = 0;
+-  for (i = 0; i < nl + nd; i++)
++  for (i = 0; i < nl + nd && grub_errno == GRUB_ERR_NONE; i++)
+     {
+       int n, code;
+       struct huff_table *ht;
+@@ -721,17 +746,21 @@ grub_png_read_dynamic_block (struct grub_png_data *data)
+ 	  len = cplens[n];
+ 	  if (cplext[n])
+ 	    len += grub_png_get_bits (data, cplext[n]);
++	  if (grub_errno != GRUB_ERR_NONE)
++	    return grub_errno;
+ 
+ 	  n = grub_png_get_huff_code (data, &data->dist_table);
+ 	  dist = cpdist[n];
+ 	  if (cpdext[n])
+ 	    dist += grub_png_get_bits (data, cpdext[n]);
++	  if (grub_errno != GRUB_ERR_NONE)
++	    return grub_errno;
+ 
+ 	  pos = data->wp - dist;
+ 	  if (pos < 0)
+ 	    pos += WSIZE;
+ 
+-	  while (len > 0)
++	  while (len > 0 && grub_errno == GRUB_ERR_NONE)
+ 	    {
+ 	      data->slide[data->wp] = data->slide[pos];
+ 	      grub_png_output_byte (data, data->slide[data->wp]);
+@@ -759,7 +788,11 @@ grub_png_decode_image_data (struct grub_png_data *data)
+   int final;
+ 
+   cmf = grub_png_get_byte (data);
++  if (grub_errno != GRUB_ERR_NONE)
++    return grub_errno;
+   flg = grub_png_get_byte (data);
++  if (grub_errno != GRUB_ERR_NONE)
++    return grub_errno;
+ 
+   if ((cmf & 0xF) != Z_DEFLATED)
+     return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+@@ -774,7 +807,11 @@ grub_png_decode_image_data (struct grub_png_data *data)
+       int block_type;
+ 
+       final = grub_png_get_bits (data, 1);
++      if (grub_errno != GRUB_ERR_NONE)
++	return grub_errno;
+       block_type = grub_png_get_bits (data, 2);
++      if (grub_errno != GRUB_ERR_NONE)
++	return grub_errno;
+ 
+       switch (block_type)
+ 	{
+@@ -790,7 +827,7 @@ grub_png_decode_image_data (struct grub_png_data *data)
+ 	    grub_png_get_byte (data);
+ 	    grub_png_get_byte (data);
+ 
+-	    for (i = 0; i < len; i++)
++	    for (i = 0; i < len && grub_errno == GRUB_ERR_NONE; i++)
+ 	      grub_png_output_byte (data, grub_png_get_byte (data));
+ 
+ 	    break;
+@@ -1045,6 +1082,8 @@ grub_png_decode_png (struct grub_png_data *data)
+ 
+       len = grub_png_get_dword (data);
+       type = grub_png_get_dword (data);
++      if (grub_errno != GRUB_ERR_NONE)
++	break;
+       data->next_offset = data->file->offset + len + 4;
+ 
+       switch (type)
diff --git a/SOURCES/0515-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch b/SOURCES/0515-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch
deleted file mode 100644
index 7677c8d..0000000
--- a/SOURCES/0515-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Axtens <dja@axtens.net>
-Date: Mon, 28 Jun 2021 14:16:58 +1000
-Subject: [PATCH] video/readers/jpeg: Do not reallocate a given huff table
-
-Fix a memory leak where an invalid file could cause us to reallocate
-memory for a huffman table we had already allocated memory for.
-
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit bc06e12b4de55cc6f926af9f064170c82b1403e9)
-(cherry picked from commit 5298bf758ea39a90537f9a1c76541ff2f21b970b)
-(cherry picked from commit aae6bac7f26c6b848156ed7adcff83309b833664)
-(cherry picked from commit bc58c0da3aed59486042759a03fe61a9782e36ce)
----
- grub-core/video/readers/jpeg.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
-index 10225abd53..caa211f06d 100644
---- a/grub-core/video/readers/jpeg.c
-+++ b/grub-core/video/readers/jpeg.c
-@@ -245,6 +245,9 @@ grub_jpeg_decode_huff_table (struct grub_jpeg_data *data)
- 	n += count[i];
- 
-       id += ac * 2;
-+      if (data->huff_value[id] != NULL)
-+	return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-+			   "jpeg: attempt to reallocate huffman table");
-       data->huff_value[id] = grub_malloc (n);
-       if (grub_errno)
- 	return grub_errno;
diff --git a/SOURCES/0515-video-readers-png-Refuse-to-handle-multiple-image-he.patch b/SOURCES/0515-video-readers-png-Refuse-to-handle-multiple-image-he.patch
new file mode 100644
index 0000000..e6bad78
--- /dev/null
+++ b/SOURCES/0515-video-readers-png-Refuse-to-handle-multiple-image-he.patch
@@ -0,0 +1,30 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Tue, 6 Jul 2021 14:13:40 +1000
+Subject: [PATCH] video/readers/png: Refuse to handle multiple image headers
+
+This causes the bitmap to be leaked. Do not permit multiple image headers.
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit 8ce433557adeadbc46429aabb9f850b02ad2bdfb)
+(cherry picked from commit 6e10bba6a4cbfd6c7bf116f41fd4e037465e19d8)
+(cherry picked from commit 812272d919ecfd368c008f15b677d369616ada54)
+---
+ grub-core/video/readers/png.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
+index e2a6b1cf3c..8955b8ecfd 100644
+--- a/grub-core/video/readers/png.c
++++ b/grub-core/video/readers/png.c
+@@ -258,6 +258,9 @@ grub_png_decode_image_header (struct grub_png_data *data)
+   int color_bits;
+   enum grub_video_blit_format blt;
+ 
++  if (data->image_width || data->image_height)
++    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: two image headers found");
++
+   data->image_width = grub_png_get_dword (data);
+   data->image_height = grub_png_get_dword (data);
+ 
diff --git a/SOURCES/0516-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch b/SOURCES/0516-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch
deleted file mode 100644
index bc4ef25..0000000
--- a/SOURCES/0516-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Axtens <dja@axtens.net>
-Date: Mon, 28 Jun 2021 14:25:17 +1000
-Subject: [PATCH] video/readers/jpeg: Refuse to handle multiple start of
- streams
-
-An invalid file could contain multiple start of stream blocks, which
-would cause us to reallocate and leak our bitmap. Refuse to handle
-multiple start of streams.
-
-Additionally, fix a grub_error() call formatting.
-
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit f3a854def3e281b7ad4bbea730cd3046de1da52f)
-(cherry picked from commit db0154828989a0a52ee59a4dda8c3803752bc827)
-(cherry picked from commit 75afb375ef46bc99a7faf5879d0283934e34db97)
-(cherry picked from commit 82f8de94e19be775cdabd05528dc7acf0cb485a7)
----
- grub-core/video/readers/jpeg.c | 7 +++++--
- 1 file changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
-index caa211f06d..1df1171d78 100644
---- a/grub-core/video/readers/jpeg.c
-+++ b/grub-core/video/readers/jpeg.c
-@@ -677,6 +677,9 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data)
-   if (data->file->offset != data_offset)
-     return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sos");
- 
-+  if (*data->bitmap)
-+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: too many start of scan blocks");
-+
-   if (grub_video_bitmap_create (data->bitmap, data->image_width,
- 				data->image_height,
- 				GRUB_VIDEO_BLIT_FORMAT_RGB_888))
-@@ -699,8 +702,8 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data)
-   nc1 = (data->image_width + hb - 1)  >> (3 + data->log_hs);
- 
-   if (data->bitmap_ptr == NULL)
--    return grub_error(GRUB_ERR_BAD_FILE_TYPE,
--		      "jpeg: attempted to decode data before start of stream");
-+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-+		       "jpeg: attempted to decode data before start of stream");
- 
-   for (; data->r1 < nr1 && (!data->dri || rst);
-        data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3)
diff --git a/SOURCES/0516-video-readers-png-Drop-greyscale-support-to-fix-heap.patch b/SOURCES/0516-video-readers-png-Drop-greyscale-support-to-fix-heap.patch
new file mode 100644
index 0000000..5233539
--- /dev/null
+++ b/SOURCES/0516-video-readers-png-Drop-greyscale-support-to-fix-heap.patch
@@ -0,0 +1,172 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Tue, 6 Jul 2021 18:51:35 +1000
+Subject: [PATCH] video/readers/png: Drop greyscale support to fix heap
+ out-of-bounds write
+
+A 16-bit greyscale PNG without alpha is processed in the following loop:
+
+      for (i = 0; i < (data->image_width * data->image_height);
+	   i++, d1 += 4, d2 += 2)
+	{
+	  d1[R3] = d2[1];
+	  d1[G3] = d2[1];
+	  d1[B3] = d2[1];
+	}
+
+The increment of d1 is wrong. d1 is incremented by 4 bytes per iteration,
+but there are only 3 bytes allocated for storage. This means that image
+data will overwrite somewhat-attacker-controlled parts of memory - 3 bytes
+out of every 4 following the end of the image.
+
+This has existed since greyscale support was added in 2013 in commit
+3ccf16dff98f (grub-core/video/readers/png.c: Support grayscale).
+
+Saving starfield.png as a 16-bit greyscale image without alpha in the gimp
+and attempting to load it causes grub-emu to crash - I don't think this code
+has ever worked.
+
+Delete all PNG greyscale support.
+
+Fixes: CVE-2021-3695
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit 0e1d163382669bd734439d8864ee969616d971d9)
+[rharwood: context conflict]
+Signed-off-by: Robbie Harwood <rharwood@redhat.com>
+(cherry picked from commit 4c631c8119206b3178912df2905434d967661c3d)
+(cherry picked from commit 6d5d5f51266b8113c6ba560835500e3c135f3722)
+---
+ grub-core/video/readers/png.c | 85 +++----------------------------------------
+ 1 file changed, 6 insertions(+), 79 deletions(-)
+
+diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
+index 8955b8ecfd..a3161e25b6 100644
+--- a/grub-core/video/readers/png.c
++++ b/grub-core/video/readers/png.c
+@@ -100,7 +100,7 @@ struct grub_png_data
+ 
+   unsigned image_width, image_height;
+   int bpp, is_16bit;
+-  int raw_bytes, is_gray, is_alpha, is_palette;
++  int raw_bytes, is_alpha, is_palette;
+   int row_bytes, color_bits;
+   grub_uint8_t *image_data;
+ 
+@@ -296,13 +296,13 @@ grub_png_decode_image_header (struct grub_png_data *data)
+     data->bpp = 3;
+   else
+     {
+-      data->is_gray = 1;
+-      data->bpp = 1;
++      return grub_error (GRUB_ERR_BAD_FILE_TYPE,
++			 "png: color type not supported");
+     }
+ 
+   if ((color_bits != 8) && (color_bits != 16)
+       && (color_bits != 4
+-	  || !(data->is_gray || data->is_palette)))
++	  || !data->is_palette))
+     return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                        "png: bit depth must be 8 or 16");
+ 
+@@ -331,7 +331,7 @@ grub_png_decode_image_header (struct grub_png_data *data)
+     }
+ 
+ #ifndef GRUB_CPU_WORDS_BIGENDIAN
+-  if (data->is_16bit || data->is_gray || data->is_palette)
++  if (data->is_16bit || data->is_palette)
+ #endif
+     {
+       data->image_data = grub_calloc (data->image_height, data->row_bytes);
+@@ -899,27 +899,8 @@ grub_png_convert_image (struct grub_png_data *data)
+       int shift;
+       int mask = (1 << data->color_bits) - 1;
+       unsigned j;
+-      if (data->is_gray)
+-	{
+-	  /* Generic formula is
+-	     (0xff * i) / ((1U << data->color_bits) - 1)
+-	     but for allowed bit depth of 1, 2 and for it's
+-	     equivalent to
+-	     (0xff / ((1U << data->color_bits) - 1)) * i
+-	     Precompute the multipliers to avoid division.
+-	  */
+ 
+-	  const grub_uint8_t multipliers[5] = { 0xff, 0xff, 0x55, 0x24, 0x11 };
+-	  for (i = 0; i < (1U << data->color_bits); i++)
+-	    {
+-	      grub_uint8_t col = multipliers[data->color_bits] * i;
+-	      palette[i][0] = col;
+-	      palette[i][1] = col;
+-	      palette[i][2] = col;
+-	    }
+-	}
+-      else
+-	grub_memcpy (palette, data->palette, 3 << data->color_bits);
++      grub_memcpy (palette, data->palette, 3 << data->color_bits);
+       d1c = d1;
+       d2c = d2;
+       for (j = 0; j < data->image_height; j++, d1c += data->image_width * 3,
+@@ -956,60 +937,6 @@ grub_png_convert_image (struct grub_png_data *data)
+ 	}
+       return;
+     }
+-  
+-  if (data->is_gray)
+-    {
+-      switch (data->bpp)
+-	{
+-	case 4:
+-	  /* 16-bit gray with alpha.  */
+-	  for (i = 0; i < (data->image_width * data->image_height);
+-	       i++, d1 += 4, d2 += 4)
+-	    {
+-	      d1[R4] = d2[3];
+-	      d1[G4] = d2[3];
+-	      d1[B4] = d2[3];
+-	      d1[A4] = d2[1];
+-	    }
+-	  break;
+-	case 2:
+-	  if (data->is_16bit)
+-	    /* 16-bit gray without alpha.  */
+-	    {
+-	      for (i = 0; i < (data->image_width * data->image_height);
+-		   i++, d1 += 4, d2 += 2)
+-		{
+-		  d1[R3] = d2[1];
+-		  d1[G3] = d2[1];
+-		  d1[B3] = d2[1];
+-		}
+-	    }
+-	  else
+-	    /* 8-bit gray with alpha.  */
+-	    {
+-	      for (i = 0; i < (data->image_width * data->image_height);
+-		   i++, d1 += 4, d2 += 2)
+-		{
+-		  d1[R4] = d2[1];
+-		  d1[G4] = d2[1];
+-		  d1[B4] = d2[1];
+-		  d1[A4] = d2[0];
+-		}
+-	    }
+-	  break;
+-	  /* 8-bit gray without alpha.  */
+-	case 1:
+-	  for (i = 0; i < (data->image_width * data->image_height);
+-	       i++, d1 += 3, d2++)
+-	    {
+-	      d1[R3] = d2[0];
+-	      d1[G3] = d2[0];
+-	      d1[B3] = d2[0];
+-	    }
+-	  break;
+-	}
+-      return;
+-    }
+ 
+     {
+   /* Only copy the upper 8 bit.  */
diff --git a/SOURCES/0517-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch b/SOURCES/0517-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch
deleted file mode 100644
index 9434ba1..0000000
--- a/SOURCES/0517-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Axtens <dja@axtens.net>
-Date: Wed, 7 Jul 2021 15:38:19 +1000
-Subject: [PATCH] video/readers/jpeg: Block int underflow -> wild pointer write
-
-Certain 1 px wide images caused a wild pointer write in
-grub_jpeg_ycrcb_to_rgb(). This was caused because in grub_jpeg_decode_data(),
-we have the following loop:
-
-for (; data->r1 < nr1 && (!data->dri || rst);
-     data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3)
-
-We did not check if vb * width >= hb * nc1.
-
-On a 64-bit platform, if that turns out to be negative, it will underflow,
-be interpreted as unsigned 64-bit, then be added to the 64-bit pointer, so
-we see data->bitmap_ptr jump, e.g.:
-
-0x6180_0000_0480 to
-0x6181_0000_0498
-     ^
-     ~--- carry has occurred and this pointer is now far away from
-          any object.
-
-On a 32-bit platform, it will decrement the pointer, creating a pointer
-that won't crash but will overwrite random data.
-
-Catch the underflow and error out.
-
-Fixes: CVE-2021-3697
-
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit 41aeb2004db9924fecd9f2dd64bc2a5a5594a4b5)
-(cherry picked from commit 5f9582490792108306d047379fed2371bee286f8)
-(cherry picked from commit 7e4bf25d9bb5219fbf11c523296dc3bd78b80698)
-(cherry picked from commit 397ecffe404b892470c41f4d24340526d3d33666)
----
- grub-core/video/readers/jpeg.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
-index 1df1171d78..2da04094b3 100644
---- a/grub-core/video/readers/jpeg.c
-+++ b/grub-core/video/readers/jpeg.c
-@@ -705,6 +705,10 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data)
-     return grub_error (GRUB_ERR_BAD_FILE_TYPE,
- 		       "jpeg: attempted to decode data before start of stream");
- 
-+  if (vb * data->image_width <= hb * nc1)
-+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-+		       "jpeg: cannot decode image with these dimensions");
-+
-   for (; data->r1 < nr1 && (!data->dri || rst);
-        data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3)
-     for (c1 = 0;  c1 < nc1 && (!data->dri || rst);
diff --git a/SOURCES/0517-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch b/SOURCES/0517-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch
new file mode 100644
index 0000000..8c59310
--- /dev/null
+++ b/SOURCES/0517-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch
@@ -0,0 +1,42 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Tue, 6 Jul 2021 23:25:07 +1000
+Subject: [PATCH] video/readers/png: Avoid heap OOB R/W inserting huff table
+ items
+
+In fuzzing we observed crashes where a code would attempt to be inserted
+into a huffman table before the start, leading to a set of heap OOB reads
+and writes as table entries with negative indices were shifted around and
+the new code written in.
+
+Catch the case where we would underflow the array and bail.
+
+Fixes: CVE-2021-3696
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit 1ae9a91d42cb40da8a6f11fac65541858e340afa)
+(cherry picked from commit 132ccc681cf642ad748580f26b54c9259a7f43fd)
+(cherry picked from commit 3a70e1f6e69af6e0d3c3cf526faa44dc0c80ac19)
+---
+ grub-core/video/readers/png.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
+index a3161e25b6..d7ed5aa6cf 100644
+--- a/grub-core/video/readers/png.c
++++ b/grub-core/video/readers/png.c
+@@ -438,6 +438,13 @@ grub_png_insert_huff_item (struct huff_table *ht, int code, int len)
+   for (i = len; i < ht->max_length; i++)
+     n += ht->maxval[i];
+ 
++  if (n > ht->num_values)
++    {
++      grub_error (GRUB_ERR_BAD_FILE_TYPE,
++		  "png: out of range inserting huffman table item");
++      return;
++    }
++
+   for (i = 0; i < n; i++)
+     ht->values[ht->num_values - i] = ht->values[ht->num_values - i - 1];
+ 
diff --git a/SOURCES/0518-normal-charset-Fix-array-out-of-bounds-formatting-un.patch b/SOURCES/0518-normal-charset-Fix-array-out-of-bounds-formatting-un.patch
deleted file mode 100644
index 2043b05..0000000
--- a/SOURCES/0518-normal-charset-Fix-array-out-of-bounds-formatting-un.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Axtens <dja@axtens.net>
-Date: Tue, 13 Jul 2021 13:24:38 +1000
-Subject: [PATCH] normal/charset: Fix array out-of-bounds formatting unicode
- for display
-
-In some cases attempting to display arbitrary binary strings leads
-to ASAN splats reading the widthspec array out of bounds.
-
-Check the index. If it would be out of bounds, return a width of 1.
-I don't know if that's strictly correct, but we're not really expecting
-great display of arbitrary binary data, and it's certainly not worse than
-an OOB read.
-
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit fdf32abc7a3928852422c0f291d8cd1dd6b34a8d)
-(cherry picked from commit f2c10aaf335b88a69885375c4d68ffab2429df77)
-(cherry picked from commit 4c942e1ba8d1f1199a58d2eb139022ae22f75cb2)
-(cherry picked from commit 83efea59ad671d043b3a48fe0581f11beb63303c)
----
- grub-core/normal/charset.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c
-index f902b13b44..7b2de12001 100644
---- a/grub-core/normal/charset.c
-+++ b/grub-core/normal/charset.c
-@@ -395,6 +395,8 @@ grub_unicode_estimate_width (const struct grub_unicode_glyph *c)
- {
-   if (grub_unicode_get_comb_type (c->base))
-     return 0;
-+  if (((unsigned long) (c->base >> 3)) >= ARRAY_SIZE (widthspec))
-+    return 1;
-   if (widthspec[c->base >> 3] & (1 << (c->base & 7)))
-     return 2;
-   else
diff --git a/SOURCES/0518-video-readers-png-Sanity-check-some-huffman-codes.patch b/SOURCES/0518-video-readers-png-Sanity-check-some-huffman-codes.patch
new file mode 100644
index 0000000..ca2e209
--- /dev/null
+++ b/SOURCES/0518-video-readers-png-Sanity-check-some-huffman-codes.patch
@@ -0,0 +1,42 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Tue, 6 Jul 2021 19:19:11 +1000
+Subject: [PATCH] video/readers/png: Sanity check some huffman codes
+
+ASAN picked up two OOB global reads: we weren't checking if some code
+values fit within the cplens or cpdext arrays. Check and throw an error
+if not.
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit c3a8ab0cbd24153ec7b1f84a96ddfdd72ef8d117)
+(cherry picked from commit 5d09addf58086aa11d5f9a91af5632ff87c2d2ee)
+(cherry picked from commit ff12584f9376a472f37d4ec14213fd29bf3b233a)
+---
+ grub-core/video/readers/png.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
+index d7ed5aa6cf..7f2ba7849b 100644
+--- a/grub-core/video/readers/png.c
++++ b/grub-core/video/readers/png.c
+@@ -753,6 +753,9 @@ grub_png_read_dynamic_block (struct grub_png_data *data)
+ 	  int len, dist, pos;
+ 
+ 	  n -= 257;
++	  if (((unsigned int) n) >= ARRAY_SIZE (cplens))
++	    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
++			       "png: invalid huff code");
+ 	  len = cplens[n];
+ 	  if (cplext[n])
+ 	    len += grub_png_get_bits (data, cplext[n]);
+@@ -760,6 +763,9 @@ grub_png_read_dynamic_block (struct grub_png_data *data)
+ 	    return grub_errno;
+ 
+ 	  n = grub_png_get_huff_code (data, &data->dist_table);
++	  if (((unsigned int) n) >= ARRAY_SIZE (cpdist))
++	    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
++			       "png: invalid huff code");
+ 	  dist = cpdist[n];
+ 	  if (cpdext[n])
+ 	    dist += grub_png_get_bits (data, cpdext[n]);
diff --git a/SOURCES/0519-net-netbuff-Block-overly-large-netbuff-allocs.patch b/SOURCES/0519-net-netbuff-Block-overly-large-netbuff-allocs.patch
deleted file mode 100644
index 6d590ee..0000000
--- a/SOURCES/0519-net-netbuff-Block-overly-large-netbuff-allocs.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Axtens <dja@axtens.net>
-Date: Tue, 8 Mar 2022 23:47:46 +1100
-Subject: [PATCH] net/netbuff: Block overly large netbuff allocs
-
-A netbuff shouldn't be too huge. It's bounded by MTU and TCP segment
-reassembly.
-
-This helps avoid some bugs (and provides a spot to instrument to catch
-them at their source).
-
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit ee9591103004cd13b4efadda671536090ca7fd57)
-(cherry picked from commit acde668bb9d9fa862a1a63e3bbd5fa47fdfa9183)
-(cherry picked from commit e47ad2eb4fe38ef2bdcab52245286f31170e73e3)
-(cherry picked from commit 3517b6baf69ee77065f0216ff29190ad392a2c84)
----
- grub-core/net/netbuff.c | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
-diff --git a/grub-core/net/netbuff.c b/grub-core/net/netbuff.c
-index dbeeefe478..d5e9e9a0d7 100644
---- a/grub-core/net/netbuff.c
-+++ b/grub-core/net/netbuff.c
-@@ -79,10 +79,23 @@ grub_netbuff_alloc (grub_size_t len)
- 
-   COMPILE_TIME_ASSERT (NETBUFF_ALIGN % sizeof (grub_properly_aligned_t) == 0);
- 
-+  /*
-+   * The largest size of a TCP packet is 64 KiB, and everything else
-+   * should be a lot smaller - most MTUs are 1500 or less. Cap data
-+   * size at 64 KiB + a buffer.
-+   */
-+  if (len > 0xffffUL + 0x1000UL)
-+    {
-+      grub_error (GRUB_ERR_BUG,
-+                  "attempted to allocate a packet that is too big");
-+      return NULL;
-+    }
-+
-   if (len < NETBUFFMINLEN)
-     len = NETBUFFMINLEN;
- 
-   len = ALIGN_UP (len, NETBUFF_ALIGN);
-+
- #ifdef GRUB_MACHINE_EMU
-   data = grub_malloc (len + sizeof (*nb));
- #else
diff --git a/SOURCES/0519-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch b/SOURCES/0519-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch
new file mode 100644
index 0000000..5d71be6
--- /dev/null
+++ b/SOURCES/0519-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch
@@ -0,0 +1,257 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Mon, 28 Jun 2021 14:16:14 +1000
+Subject: [PATCH] video/readers/jpeg: Abort sooner if a read operation fails
+
+Fuzzing revealed some inputs that were taking a long time, potentially
+forever, because they did not bail quickly upon encountering an I/O error.
+
+Try to catch I/O errors sooner and bail out.
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit ab2e5d2e4bff488bbb557ed435a61ae102ef9f0c)
+(cherry picked from commit 1ff8df0d2dea8ec7c8575241d5e7d6622c204ec3)
+(cherry picked from commit b07767383b74a0ce7135c09ba8701510d4ad32f0)
+---
+ grub-core/video/readers/jpeg.c | 86 ++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 70 insertions(+), 16 deletions(-)
+
+diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
+index e31602f766..10225abd53 100644
+--- a/grub-core/video/readers/jpeg.c
++++ b/grub-core/video/readers/jpeg.c
+@@ -109,9 +109,17 @@ static grub_uint8_t
+ grub_jpeg_get_byte (struct grub_jpeg_data *data)
+ {
+   grub_uint8_t r;
++  grub_ssize_t bytes_read;
+ 
+   r = 0;
+-  grub_file_read (data->file, &r, 1);
++  bytes_read = grub_file_read (data->file, &r, 1);
++
++  if (bytes_read != 1)
++    {
++      grub_error (GRUB_ERR_BAD_FILE_TYPE,
++		  "jpeg: unexpected end of data");
++      return 0;
++    }
+ 
+   return r;
+ }
+@@ -120,9 +128,17 @@ static grub_uint16_t
+ grub_jpeg_get_word (struct grub_jpeg_data *data)
+ {
+   grub_uint16_t r;
++  grub_ssize_t bytes_read;
+ 
+   r = 0;
+-  grub_file_read (data->file, &r, sizeof (grub_uint16_t));
++  bytes_read = grub_file_read (data->file, &r, sizeof (grub_uint16_t));
++
++  if (bytes_read != sizeof (grub_uint16_t))
++    {
++      grub_error (GRUB_ERR_BAD_FILE_TYPE,
++		  "jpeg: unexpected end of data");
++      return 0;
++    }
+ 
+   return grub_be_to_cpu16 (r);
+ }
+@@ -135,6 +151,11 @@ grub_jpeg_get_bit (struct grub_jpeg_data *data)
+   if (data->bit_mask == 0)
+     {
+       data->bit_save = grub_jpeg_get_byte (data);
++      if (grub_errno != GRUB_ERR_NONE) {
++	grub_error (GRUB_ERR_BAD_FILE_TYPE,
++		    "jpeg: file read error");
++	return 0;
++      }
+       if (data->bit_save == JPEG_ESC_CHAR)
+ 	{
+ 	  if (grub_jpeg_get_byte (data) != 0)
+@@ -143,6 +164,11 @@ grub_jpeg_get_bit (struct grub_jpeg_data *data)
+ 			  "jpeg: invalid 0xFF in data stream");
+ 	      return 0;
+ 	    }
++	  if (grub_errno != GRUB_ERR_NONE)
++	    {
++	      grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: file read error");
++	      return 0;
++	    }
+ 	}
+       data->bit_mask = 0x80;
+     }
+@@ -161,7 +187,7 @@ grub_jpeg_get_number (struct grub_jpeg_data *data, int num)
+     return 0;
+ 
+   msb = value = grub_jpeg_get_bit (data);
+-  for (i = 1; i < num; i++)
++  for (i = 1; i < num && grub_errno == GRUB_ERR_NONE; i++)
+     value = (value << 1) + (grub_jpeg_get_bit (data) != 0);
+   if (!msb)
+     value += 1 - (1 << num);
+@@ -202,6 +228,8 @@ grub_jpeg_decode_huff_table (struct grub_jpeg_data *data)
+   while (data->file->offset + sizeof (count) + 1 <= next_marker)
+     {
+       id = grub_jpeg_get_byte (data);
++      if (grub_errno != GRUB_ERR_NONE)
++	return grub_errno;
+       ac = (id >> 4) & 1;
+       id &= 0xF;
+       if (id > 1)
+@@ -252,6 +280,8 @@ grub_jpeg_decode_quan_table (struct grub_jpeg_data *data)
+ 
+   next_marker = data->file->offset;
+   next_marker += grub_jpeg_get_word (data);
++  if (grub_errno != GRUB_ERR_NONE)
++    return grub_errno;
+ 
+   if (next_marker > data->file->size)
+     {
+@@ -263,6 +293,8 @@ grub_jpeg_decode_quan_table (struct grub_jpeg_data *data)
+ 	 <= next_marker)
+     {
+       id = grub_jpeg_get_byte (data);
++      if (grub_errno != GRUB_ERR_NONE)
++        return grub_errno;
+       if (id >= 0x10)		/* Upper 4-bit is precision.  */
+ 	return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ 			   "jpeg: only 8-bit precision is supported");
+@@ -294,6 +326,9 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data)
+   next_marker = data->file->offset;
+   next_marker += grub_jpeg_get_word (data);
+ 
++  if (grub_errno != GRUB_ERR_NONE)
++    return grub_errno;
++
+   if (grub_jpeg_get_byte (data) != 8)
+     return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ 		       "jpeg: only 8-bit precision is supported");
+@@ -319,6 +354,8 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data)
+ 	return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index");
+ 
+       ss = grub_jpeg_get_byte (data);	/* Sampling factor.  */
++      if (grub_errno != GRUB_ERR_NONE)
++	return grub_errno;
+       if (!id)
+ 	{
+ 	  grub_uint8_t vs, hs;
+@@ -498,7 +535,7 @@ grub_jpeg_idct_transform (jpeg_data_unit_t du)
+     }
+ }
+ 
+-static void
++static grub_err_t
+ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du)
+ {
+   int h1, h2, qt;
+@@ -513,6 +550,9 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du)
+   data->dc_value[id] +=
+     grub_jpeg_get_number (data, grub_jpeg_get_huff_code (data, h1));
+ 
++  if (grub_errno != GRUB_ERR_NONE)
++    return grub_errno;
++
+   du[0] = data->dc_value[id] * (int) data->quan_table[qt][0];
+   pos = 1;
+   while (pos < ARRAY_SIZE (data->quan_table[qt]))
+@@ -527,11 +567,13 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du)
+       num >>= 4;
+       pos += num;
+ 
++      if (grub_errno != GRUB_ERR_NONE)
++        return grub_errno;
++
+       if (pos >= ARRAY_SIZE (jpeg_zigzag_order))
+ 	{
+-	  grub_error (GRUB_ERR_BAD_FILE_TYPE,
+-		      "jpeg: invalid position in zigzag order!?");
+-	  return;
++	  return grub_error (GRUB_ERR_BAD_FILE_TYPE,
++			     "jpeg: invalid position in zigzag order!?");
+ 	}
+ 
+       du[jpeg_zigzag_order[pos]] = val * (int) data->quan_table[qt][pos];
+@@ -539,6 +581,7 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du)
+     }
+ 
+   grub_jpeg_idct_transform (du);
++  return GRUB_ERR_NONE;
+ }
+ 
+ static void
+@@ -597,7 +640,8 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data)
+   data_offset += grub_jpeg_get_word (data);
+ 
+   cc = grub_jpeg_get_byte (data);
+-
++  if (grub_errno != GRUB_ERR_NONE)
++    return grub_errno;
+   if (cc != 3 && cc != 1)
+     return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ 		       "jpeg: component count must be 1 or 3");
+@@ -610,7 +654,8 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data)
+       id = grub_jpeg_get_byte (data) - 1;
+       if ((id < 0) || (id >= 3))
+ 	return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index");
+-
++      if (grub_errno != GRUB_ERR_NONE)
++	return grub_errno;
+       ht = grub_jpeg_get_byte (data);
+       data->comp_index[id][1] = (ht >> 4);
+       data->comp_index[id][2] = (ht & 0xF) + 2;
+@@ -618,11 +663,14 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data)
+       if ((data->comp_index[id][1] < 0) || (data->comp_index[id][1] > 3) ||
+ 	  (data->comp_index[id][2] < 0) || (data->comp_index[id][2] > 3))
+ 	return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid hufftable index");
++      if (grub_errno != GRUB_ERR_NONE)
++	return grub_errno;
+     }
+ 
+   grub_jpeg_get_byte (data);	/* Skip 3 unused bytes.  */
+   grub_jpeg_get_word (data);
+-
++  if (grub_errno != GRUB_ERR_NONE)
++    return grub_errno;
+   if (data->file->offset != data_offset)
+     return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sos");
+ 
+@@ -640,6 +688,7 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data)
+ {
+   unsigned c1, vb, hb, nr1, nc1;
+   int rst = data->dri;
++  grub_err_t err = GRUB_ERR_NONE;
+ 
+   vb = 8 << data->log_vs;
+   hb = 8 << data->log_hs;
+@@ -660,17 +709,22 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data)
+ 
+ 	for (r2 = 0; r2 < (1U << data->log_vs); r2++)
+ 	  for (c2 = 0; c2 < (1U << data->log_hs); c2++)
+-	    grub_jpeg_decode_du (data, 0, data->ydu[r2 * 2 + c2]);
++            {
++              err = grub_jpeg_decode_du (data, 0, data->ydu[r2 * 2 + c2]);
++              if (err != GRUB_ERR_NONE)
++                return err;
++            }
+ 
+ 	if (data->color_components >= 3)
+ 	  {
+-	    grub_jpeg_decode_du (data, 1, data->cbdu);
+-	    grub_jpeg_decode_du (data, 2, data->crdu);
++	    err = grub_jpeg_decode_du (data, 1, data->cbdu);
++	    if (err != GRUB_ERR_NONE)
++	      return err;
++	    err = grub_jpeg_decode_du (data, 2, data->crdu);
++	    if (err != GRUB_ERR_NONE)
++	      return err;
+ 	  }
+ 
+-	if (grub_errno)
+-	  return grub_errno;
+-
+ 	nr2 = (data->r1 == nr1 - 1) ? (data->image_height - data->r1 * vb) : vb;
+ 	nc2 = (c1 == nc1 - 1) ? (data->image_width - c1 * hb) : hb;
+ 
diff --git a/SOURCES/0520-net-ip-Do-IP-fragment-maths-safely.patch b/SOURCES/0520-net-ip-Do-IP-fragment-maths-safely.patch
deleted file mode 100644
index 433d703..0000000
--- a/SOURCES/0520-net-ip-Do-IP-fragment-maths-safely.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Axtens <dja@axtens.net>
-Date: Mon, 20 Dec 2021 19:41:21 +1100
-Subject: [PATCH] net/ip: Do IP fragment maths safely
-
-This avoids an underflow and subsequent unpleasantness.
-
-Fixes: CVE-2022-28733
-
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit eb74e5743ca7e18a5e75c392fe0b21d1549a1936)
-(cherry picked from commit 552ad34583e788542e9ca08524a0d4bc8f98c297)
-(cherry picked from commit 2c8cb7e3b8b48b136a950e5692fa6251b76df90e)
-(cherry picked from commit 17bb2fe79e6b9688cf2008b840af9022804204ec)
----
- grub-core/net/ip.c | 10 +++++++++-
- 1 file changed, 9 insertions(+), 1 deletion(-)
-
-diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c
-index 9a4e589aa3..c766ac65f5 100644
---- a/grub-core/net/ip.c
-+++ b/grub-core/net/ip.c
-@@ -25,6 +25,7 @@
- #include <grub/net/netbuff.h>
- #include <grub/mm.h>
- #include <grub/priority_queue.h>
-+#include <grub/safemath.h>
- #include <grub/time.h>
- 
- struct iphdr {
-@@ -552,7 +553,14 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb,
-     {
-       rsm->total_len = (8 * (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK)
- 			+ (nb->tail - nb->data));
--      rsm->total_len -= ((iph->verhdrlen & 0xf) * sizeof (grub_uint32_t));
-+
-+      if (grub_sub (rsm->total_len, (iph->verhdrlen & 0xf) * sizeof (grub_uint32_t),
-+		    &rsm->total_len))
-+	{
-+	  grub_dprintf ("net", "IP reassembly size underflow\n");
-+	  return GRUB_ERR_NONE;
-+	}
-+
-       rsm->asm_netbuff = grub_netbuff_alloc (rsm->total_len);
-       if (!rsm->asm_netbuff)
- 	{
diff --git a/SOURCES/0520-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch b/SOURCES/0520-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch
new file mode 100644
index 0000000..fb89198
--- /dev/null
+++ b/SOURCES/0520-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch
@@ -0,0 +1,31 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Mon, 28 Jun 2021 14:16:58 +1000
+Subject: [PATCH] video/readers/jpeg: Do not reallocate a given huff table
+
+Fix a memory leak where an invalid file could cause us to reallocate
+memory for a huffman table we had already allocated memory for.
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit bc06e12b4de55cc6f926af9f064170c82b1403e9)
+(cherry picked from commit 5298bf758ea39a90537f9a1c76541ff2f21b970b)
+(cherry picked from commit aae6bac7f26c6b848156ed7adcff83309b833664)
+---
+ grub-core/video/readers/jpeg.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
+index 10225abd53..caa211f06d 100644
+--- a/grub-core/video/readers/jpeg.c
++++ b/grub-core/video/readers/jpeg.c
+@@ -245,6 +245,9 @@ grub_jpeg_decode_huff_table (struct grub_jpeg_data *data)
+ 	n += count[i];
+ 
+       id += ac * 2;
++      if (data->huff_value[id] != NULL)
++	return grub_error (GRUB_ERR_BAD_FILE_TYPE,
++			   "jpeg: attempt to reallocate huffman table");
+       data->huff_value[id] = grub_malloc (n);
+       if (grub_errno)
+ 	return grub_errno;
diff --git a/SOURCES/0521-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch b/SOURCES/0521-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch
deleted file mode 100644
index 1fa2c3e..0000000
--- a/SOURCES/0521-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Axtens <dja@axtens.net>
-Date: Thu, 16 Sep 2021 01:29:54 +1000
-Subject: [PATCH] net/dns: Fix double-free addresses on corrupt DNS response
-
-grub_net_dns_lookup() takes as inputs a pointer to an array of addresses
-("addresses") for the given name, and pointer to a number of addresses
-("naddresses"). grub_net_dns_lookup() is responsible for allocating
-"addresses", and the caller is responsible for freeing it if
-"naddresses" > 0.
-
-The DNS recv_hook will sometimes set and free the addresses array,
-for example if the packet is too short:
-
-      if (ptr + 10 >= nb->tail)
-	{
-	  if (!*data->naddresses)
-	    grub_free (*data->addresses);
-	  grub_netbuff_free (nb);
-	  return GRUB_ERR_NONE;
-	}
-
-Later on the nslookup command code unconditionally frees the "addresses"
-array. Normally this is fine: the array is either populated with valid
-data or is NULL. But in these sorts of error cases it is neither NULL
-nor valid and we get a double-free.
-
-Only free "addresses" if "naddresses" > 0.
-
-It looks like the other use of grub_net_dns_lookup() is not affected.
-
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit eb2e69fcf51307757e43f55ee8c9354d1ee42dd1)
-(cherry picked from commit d801a27e7acec6c1a83067fab0bb975877eaf704)
-(cherry picked from commit 4d8b6e36ddfda4084e370b3b08c432e8a462e9be)
-(cherry picked from commit ae133c18f304cb0a22c569c98abc62e15ccf56d0)
----
- grub-core/net/dns.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
-index 906ec7d678..135faac035 100644
---- a/grub-core/net/dns.c
-+++ b/grub-core/net/dns.c
-@@ -667,9 +667,11 @@ grub_cmd_nslookup (struct grub_command *cmd __attribute__ ((unused)),
-       grub_net_addr_to_str (&addresses[i], buf);
-       grub_printf ("%s\n", buf);
-     }
--  grub_free (addresses);
-   if (naddresses)
--    return GRUB_ERR_NONE;
-+    {
-+      grub_free (addresses);
-+      return GRUB_ERR_NONE;
-+    }
-   return grub_error (GRUB_ERR_NET_NO_DOMAIN, N_("no DNS record found"));
- }
- 
diff --git a/SOURCES/0521-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch b/SOURCES/0521-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch
new file mode 100644
index 0000000..b484648
--- /dev/null
+++ b/SOURCES/0521-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch
@@ -0,0 +1,46 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Mon, 28 Jun 2021 14:25:17 +1000
+Subject: [PATCH] video/readers/jpeg: Refuse to handle multiple start of
+ streams
+
+An invalid file could contain multiple start of stream blocks, which
+would cause us to reallocate and leak our bitmap. Refuse to handle
+multiple start of streams.
+
+Additionally, fix a grub_error() call formatting.
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit f3a854def3e281b7ad4bbea730cd3046de1da52f)
+(cherry picked from commit db0154828989a0a52ee59a4dda8c3803752bc827)
+(cherry picked from commit 75afb375ef46bc99a7faf5879d0283934e34db97)
+---
+ grub-core/video/readers/jpeg.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
+index caa211f06d..1df1171d78 100644
+--- a/grub-core/video/readers/jpeg.c
++++ b/grub-core/video/readers/jpeg.c
+@@ -677,6 +677,9 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data)
+   if (data->file->offset != data_offset)
+     return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sos");
+ 
++  if (*data->bitmap)
++    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: too many start of scan blocks");
++
+   if (grub_video_bitmap_create (data->bitmap, data->image_width,
+ 				data->image_height,
+ 				GRUB_VIDEO_BLIT_FORMAT_RGB_888))
+@@ -699,8 +702,8 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data)
+   nc1 = (data->image_width + hb - 1)  >> (3 + data->log_hs);
+ 
+   if (data->bitmap_ptr == NULL)
+-    return grub_error(GRUB_ERR_BAD_FILE_TYPE,
+-		      "jpeg: attempted to decode data before start of stream");
++    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
++		       "jpeg: attempted to decode data before start of stream");
+ 
+   for (; data->r1 < nr1 && (!data->dri || rst);
+        data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3)
diff --git a/SOURCES/0522-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch b/SOURCES/0522-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch
deleted file mode 100644
index bd7797a..0000000
--- a/SOURCES/0522-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Axtens <dja@axtens.net>
-Date: Mon, 20 Dec 2021 21:55:43 +1100
-Subject: [PATCH] net/dns: Don't read past the end of the string we're checking
- against
-
-I don't really understand what's going on here but fuzzing found
-a bug where we read past the end of check_with. That's a C string,
-so use grub_strlen() to make sure we don't overread it.
-
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit 6a97b3f4b1d5173aa516edc6dedbc63de7306d21)
-(cherry picked from commit e0589624e86bc96666cbdb62f6e55cafec2871b3)
-(cherry picked from commit 95ecbc0b9aacfd43ba96cccc50daaf39eccd9f7f)
-(cherry picked from commit 110eee925ecd9efeebb8d018b042fcf067a443c2)
----
- grub-core/net/dns.c | 19 ++++++++++++++++---
- 1 file changed, 16 insertions(+), 3 deletions(-)
-
-diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
-index 135faac035..17961a9f18 100644
---- a/grub-core/net/dns.c
-+++ b/grub-core/net/dns.c
-@@ -146,11 +146,18 @@ check_name_real (const grub_uint8_t *name_at, const grub_uint8_t *head,
- 		 int *length, char *set)
- {
-   const char *readable_ptr = check_with;
-+  int readable_len;
-   const grub_uint8_t *ptr;
-   char *optr = set;
-   int bytes_processed = 0;
-   if (length)
-     *length = 0;
-+
-+  if (readable_ptr != NULL)
-+    readable_len = grub_strlen (readable_ptr);
-+  else
-+    readable_len = 0;
-+
-   for (ptr = name_at; ptr < tail && bytes_processed < tail - head + 2; )
-     {
-       /* End marker.  */
-@@ -172,13 +179,16 @@ check_name_real (const grub_uint8_t *name_at, const grub_uint8_t *head,
- 	  ptr = head + (((ptr[0] & 0x3f) << 8) | ptr[1]);
- 	  continue;
- 	}
--      if (readable_ptr && grub_memcmp (ptr + 1, readable_ptr, *ptr) != 0)
-+      if (readable_ptr != NULL && (*ptr > readable_len || grub_memcmp (ptr + 1, readable_ptr, *ptr) != 0))
- 	return 0;
-       if (grub_memchr (ptr + 1, 0, *ptr) 
- 	  || grub_memchr (ptr + 1, '.', *ptr))
- 	return 0;
-       if (readable_ptr)
--	readable_ptr += *ptr;
-+	{
-+	  readable_ptr += *ptr;
-+	  readable_len -= *ptr;
-+	}
-       if (readable_ptr && *readable_ptr != '.' && *readable_ptr != 0)
- 	return 0;
-       bytes_processed += *ptr + 1;
-@@ -192,7 +202,10 @@ check_name_real (const grub_uint8_t *name_at, const grub_uint8_t *head,
-       if (optr)
- 	*optr++ = '.';
-       if (readable_ptr && *readable_ptr)
--	readable_ptr++;
-+	{
-+	  readable_ptr++;
-+	  readable_len--;
-+	}
-       ptr += *ptr + 1;
-     }
-   return 0;
diff --git a/SOURCES/0522-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch b/SOURCES/0522-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch
new file mode 100644
index 0000000..90decbc
--- /dev/null
+++ b/SOURCES/0522-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch
@@ -0,0 +1,55 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Wed, 7 Jul 2021 15:38:19 +1000
+Subject: [PATCH] video/readers/jpeg: Block int underflow -> wild pointer write
+
+Certain 1 px wide images caused a wild pointer write in
+grub_jpeg_ycrcb_to_rgb(). This was caused because in grub_jpeg_decode_data(),
+we have the following loop:
+
+for (; data->r1 < nr1 && (!data->dri || rst);
+     data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3)
+
+We did not check if vb * width >= hb * nc1.
+
+On a 64-bit platform, if that turns out to be negative, it will underflow,
+be interpreted as unsigned 64-bit, then be added to the 64-bit pointer, so
+we see data->bitmap_ptr jump, e.g.:
+
+0x6180_0000_0480 to
+0x6181_0000_0498
+     ^
+     ~--- carry has occurred and this pointer is now far away from
+          any object.
+
+On a 32-bit platform, it will decrement the pointer, creating a pointer
+that won't crash but will overwrite random data.
+
+Catch the underflow and error out.
+
+Fixes: CVE-2021-3697
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit 41aeb2004db9924fecd9f2dd64bc2a5a5594a4b5)
+(cherry picked from commit 5f9582490792108306d047379fed2371bee286f8)
+(cherry picked from commit 7e4bf25d9bb5219fbf11c523296dc3bd78b80698)
+---
+ grub-core/video/readers/jpeg.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
+index 1df1171d78..2da04094b3 100644
+--- a/grub-core/video/readers/jpeg.c
++++ b/grub-core/video/readers/jpeg.c
+@@ -705,6 +705,10 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data)
+     return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ 		       "jpeg: attempted to decode data before start of stream");
+ 
++  if (vb * data->image_width <= hb * nc1)
++    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
++		       "jpeg: cannot decode image with these dimensions");
++
+   for (; data->r1 < nr1 && (!data->dri || rst);
+        data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3)
+     for (c1 = 0;  c1 < nc1 && (!data->dri || rst);
diff --git a/SOURCES/0523-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch b/SOURCES/0523-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch
deleted file mode 100644
index 6df1527..0000000
--- a/SOURCES/0523-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch
+++ /dev/null
@@ -1,115 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Axtens <dja@axtens.net>
-Date: Mon, 20 Sep 2021 01:12:24 +1000
-Subject: [PATCH] net/tftp: Prevent a UAF and double-free from a failed seek
-
-A malicious tftp server can cause UAFs and a double free.
-
-An attempt to read from a network file is handled by grub_net_fs_read(). If
-the read is at an offset other than the current offset, grub_net_seek_real()
-is invoked.
-
-In grub_net_seek_real(), if a backwards seek cannot be satisfied from the
-currently received packets, and the underlying transport does not provide
-a seek method, then grub_net_seek_real() will close and reopen the network
-protocol layer.
-
-For tftp, the ->close() call goes to tftp_close() and frees the tftp_data_t
-file->data. The file->data pointer is not nulled out after the free.
-
-If the ->open() call fails, the file->data will not be reallocated and will
-continue point to a freed memory block. This could happen from a server
-refusing to send the requisite ack to the new tftp request, for example.
-
-The seek and the read will then fail, but the grub_file continues to exist:
-the failed seek does not necessarily cause the entire file to be thrown
-away (e.g. where the file is checked to see if it is gzipped/lzio/xz/etc.,
-a read failure is interpreted as a decompressor passing on the file, not as
-an invalidation of the entire grub_file_t structure).
-
-This means subsequent attempts to read or seek the file will use the old
-file->data after free. Eventually, the file will be close()d again and
-file->data will be freed again.
-
-Mark a net_fs file that doesn't reopen as broken. Do not permit read() or
-close() on a broken file (seek is not exposed directly to the file API -
-it is only called as part of read, so this blocks seeks as well).
-
-As an additional defence, null out the ->data pointer if tftp_open() fails.
-That would have lead to a simple null pointer dereference rather than
-a mess of UAFs.
-
-This may affect other protocols, I haven't checked.
-
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit dada1dda695439bb55b2848dddc2d89843552f81)
-(cherry picked from commit 352c5ae8a9fc715712e6ecbd7ccb6218122c748f)
-(cherry picked from commit 61a010085ab9f0ecf42677773a6fc212f1579b0a)
-(cherry picked from commit 277d38531a47be78ac5062894e449726db2baf65)
----
- grub-core/net/net.c  | 11 +++++++++--
- grub-core/net/tftp.c |  1 +
- include/grub/net.h   |  1 +
- 3 files changed, 11 insertions(+), 2 deletions(-)
-
-diff --git a/grub-core/net/net.c b/grub-core/net/net.c
-index a27c53eee1..b9e2a4d100 100644
---- a/grub-core/net/net.c
-+++ b/grub-core/net/net.c
-@@ -1625,7 +1625,8 @@ grub_net_fs_close (grub_file_t file)
-       grub_netbuff_free (file->device->net->packs.first->nb);
-       grub_net_remove_packet (file->device->net->packs.first);
-     }
--  file->device->net->protocol->close (file);
-+  if (!file->device->net->broken)
-+    file->device->net->protocol->close (file);
-   grub_free (file->device->net->name);
-   return GRUB_ERR_NONE;
- }
-@@ -1847,7 +1848,10 @@ grub_net_seek_real (struct grub_file *file, grub_off_t offset)
-     file->device->net->stall = 0;
-     err = file->device->net->protocol->open (file, file->device->net->name);
-     if (err)
--      return err;
-+      {
-+	file->device->net->broken = 1;
-+	return err;
-+      }
-     grub_net_fs_read_real (file, NULL, offset);
-     return grub_errno;
-   }
-@@ -1856,6 +1860,9 @@ grub_net_seek_real (struct grub_file *file, grub_off_t offset)
- static grub_ssize_t
- grub_net_fs_read (grub_file_t file, char *buf, grub_size_t len)
- {
-+  if (file->device->net->broken)
-+    return -1;
-+
-   if (file->offset != file->device->net->offset)
-     {
-       grub_err_t err;
-diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c
-index aa0424dcee..85be965470 100644
---- a/grub-core/net/tftp.c
-+++ b/grub-core/net/tftp.c
-@@ -402,6 +402,7 @@ tftp_open (struct grub_file *file, const char *filename)
-     {
-       grub_net_udp_close (data->sock);
-       grub_free (data);
-+      file->data = NULL;
-       return grub_errno;
-     }
- 
-diff --git a/include/grub/net.h b/include/grub/net.h
-index 9cf6da6897..0d31f00664 100644
---- a/include/grub/net.h
-+++ b/include/grub/net.h
-@@ -280,6 +280,7 @@ typedef struct grub_net
-   grub_fs_t fs;
-   int eof;
-   int stall;
-+  int broken;
- } *grub_net_t;
- 
- extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name);
diff --git a/SOURCES/0523-normal-charset-Fix-array-out-of-bounds-formatting-un.patch b/SOURCES/0523-normal-charset-Fix-array-out-of-bounds-formatting-un.patch
new file mode 100644
index 0000000..6cbd3a5
--- /dev/null
+++ b/SOURCES/0523-normal-charset-Fix-array-out-of-bounds-formatting-un.patch
@@ -0,0 +1,36 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Tue, 13 Jul 2021 13:24:38 +1000
+Subject: [PATCH] normal/charset: Fix array out-of-bounds formatting unicode
+ for display
+
+In some cases attempting to display arbitrary binary strings leads
+to ASAN splats reading the widthspec array out of bounds.
+
+Check the index. If it would be out of bounds, return a width of 1.
+I don't know if that's strictly correct, but we're not really expecting
+great display of arbitrary binary data, and it's certainly not worse than
+an OOB read.
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit fdf32abc7a3928852422c0f291d8cd1dd6b34a8d)
+(cherry picked from commit f2c10aaf335b88a69885375c4d68ffab2429df77)
+(cherry picked from commit 4c942e1ba8d1f1199a58d2eb139022ae22f75cb2)
+---
+ grub-core/normal/charset.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c
+index f902b13b44..7b2de12001 100644
+--- a/grub-core/normal/charset.c
++++ b/grub-core/normal/charset.c
+@@ -395,6 +395,8 @@ grub_unicode_estimate_width (const struct grub_unicode_glyph *c)
+ {
+   if (grub_unicode_get_comb_type (c->base))
+     return 0;
++  if (((unsigned long) (c->base >> 3)) >= ARRAY_SIZE (widthspec))
++    return 1;
+   if (widthspec[c->base >> 3] & (1 << (c->base & 7)))
+     return 2;
+   else
diff --git a/SOURCES/0524-misc-Format-string-for-grub_error-should-be-a-litera.patch b/SOURCES/0524-misc-Format-string-for-grub_error-should-be-a-litera.patch
deleted file mode 100644
index f4a4f32..0000000
--- a/SOURCES/0524-misc-Format-string-for-grub_error-should-be-a-litera.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Glenn Washburn <development@efficientek.com>
-Date: Thu, 4 Mar 2021 18:22:32 -0600
-Subject: [PATCH] misc: Format string for grub_error() should be a literal
-
-Signed-off-by: Glenn Washburn <development@efficientek.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry-picked from commit 60875f4e15d704b875969b415501802b531c4db3)
-(cherry-picked from commit 6353cbd63cb3615a2b7aece183e3b177250d9415)
----
- grub-core/loader/efi/chainloader.c | 2 +-
- grub-core/net/tftp.c               | 2 +-
- grub-core/script/lexer.c           | 2 +-
- 3 files changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
-index 720f6181e5..8e658f713e 100644
---- a/grub-core/loader/efi/chainloader.c
-+++ b/grub-core/loader/efi/chainloader.c
-@@ -79,7 +79,7 @@ grub_start_image (grub_efi_handle_t handle)
- 	      *grub_utf16_to_utf8 ((grub_uint8_t *) buf,
- 				   exit_data, exit_data_size) = 0;
- 
--	      grub_error (GRUB_ERR_BAD_OS, buf);
-+	      grub_error (GRUB_ERR_BAD_OS, "%s", buf);
- 	      grub_free (buf);
- 	    }
- 	}
-diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c
-index 85be965470..69a9ba6979 100644
---- a/grub-core/net/tftp.c
-+++ b/grub-core/net/tftp.c
-@@ -253,7 +253,7 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)),
-     case TFTP_ERROR:
-       data->have_oack = 1;
-       grub_netbuff_free (nb);
--      grub_error (GRUB_ERR_IO, (char *) tftph->u.err.errmsg);
-+      grub_error (GRUB_ERR_IO, "%s", tftph->u.err.errmsg);
-       grub_error_save (&data->save_err);
-       return GRUB_ERR_NONE;
-     default:
-diff --git a/grub-core/script/lexer.c b/grub-core/script/lexer.c
-index 5fb0cbd0bc..27daad791c 100644
---- a/grub-core/script/lexer.c
-+++ b/grub-core/script/lexer.c
-@@ -349,7 +349,7 @@ void
- grub_script_yyerror (struct grub_parser_param *state, char const *err)
- {
-   if (err)
--    grub_error (GRUB_ERR_INVALID_COMMAND, err);
-+    grub_error (GRUB_ERR_INVALID_COMMAND, "%s", err);
- 
-   grub_print_error ();
-   state->err++;
diff --git a/SOURCES/0524-net-netbuff-Block-overly-large-netbuff-allocs.patch b/SOURCES/0524-net-netbuff-Block-overly-large-netbuff-allocs.patch
new file mode 100644
index 0000000..5a59ff4
--- /dev/null
+++ b/SOURCES/0524-net-netbuff-Block-overly-large-netbuff-allocs.patch
@@ -0,0 +1,48 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Tue, 8 Mar 2022 23:47:46 +1100
+Subject: [PATCH] net/netbuff: Block overly large netbuff allocs
+
+A netbuff shouldn't be too huge. It's bounded by MTU and TCP segment
+reassembly.
+
+This helps avoid some bugs (and provides a spot to instrument to catch
+them at their source).
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit ee9591103004cd13b4efadda671536090ca7fd57)
+(cherry picked from commit acde668bb9d9fa862a1a63e3bbd5fa47fdfa9183)
+(cherry picked from commit e47ad2eb4fe38ef2bdcab52245286f31170e73e3)
+---
+ grub-core/net/netbuff.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/grub-core/net/netbuff.c b/grub-core/net/netbuff.c
+index dbeeefe478..d5e9e9a0d7 100644
+--- a/grub-core/net/netbuff.c
++++ b/grub-core/net/netbuff.c
+@@ -79,10 +79,23 @@ grub_netbuff_alloc (grub_size_t len)
+ 
+   COMPILE_TIME_ASSERT (NETBUFF_ALIGN % sizeof (grub_properly_aligned_t) == 0);
+ 
++  /*
++   * The largest size of a TCP packet is 64 KiB, and everything else
++   * should be a lot smaller - most MTUs are 1500 or less. Cap data
++   * size at 64 KiB + a buffer.
++   */
++  if (len > 0xffffUL + 0x1000UL)
++    {
++      grub_error (GRUB_ERR_BUG,
++                  "attempted to allocate a packet that is too big");
++      return NULL;
++    }
++
+   if (len < NETBUFFMINLEN)
+     len = NETBUFFMINLEN;
+ 
+   len = ALIGN_UP (len, NETBUFF_ALIGN);
++
+ #ifdef GRUB_MACHINE_EMU
+   data = grub_malloc (len + sizeof (*nb));
+ #else
diff --git a/SOURCES/0525-net-ip-Do-IP-fragment-maths-safely.patch b/SOURCES/0525-net-ip-Do-IP-fragment-maths-safely.patch
new file mode 100644
index 0000000..e4b8f45
--- /dev/null
+++ b/SOURCES/0525-net-ip-Do-IP-fragment-maths-safely.patch
@@ -0,0 +1,46 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Mon, 20 Dec 2021 19:41:21 +1100
+Subject: [PATCH] net/ip: Do IP fragment maths safely
+
+This avoids an underflow and subsequent unpleasantness.
+
+Fixes: CVE-2022-28733
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit eb74e5743ca7e18a5e75c392fe0b21d1549a1936)
+(cherry picked from commit 552ad34583e788542e9ca08524a0d4bc8f98c297)
+(cherry picked from commit 2c8cb7e3b8b48b136a950e5692fa6251b76df90e)
+---
+ grub-core/net/ip.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c
+index 9a4e589aa3..c766ac65f5 100644
+--- a/grub-core/net/ip.c
++++ b/grub-core/net/ip.c
+@@ -25,6 +25,7 @@
+ #include <grub/net/netbuff.h>
+ #include <grub/mm.h>
+ #include <grub/priority_queue.h>
++#include <grub/safemath.h>
+ #include <grub/time.h>
+ 
+ struct iphdr {
+@@ -552,7 +553,14 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb,
+     {
+       rsm->total_len = (8 * (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK)
+ 			+ (nb->tail - nb->data));
+-      rsm->total_len -= ((iph->verhdrlen & 0xf) * sizeof (grub_uint32_t));
++
++      if (grub_sub (rsm->total_len, (iph->verhdrlen & 0xf) * sizeof (grub_uint32_t),
++		    &rsm->total_len))
++	{
++	  grub_dprintf ("net", "IP reassembly size underflow\n");
++	  return GRUB_ERR_NONE;
++	}
++
+       rsm->asm_netbuff = grub_netbuff_alloc (rsm->total_len);
+       if (!rsm->asm_netbuff)
+ 	{
diff --git a/SOURCES/0525-net-tftp-Avoid-a-trivial-UAF.patch b/SOURCES/0525-net-tftp-Avoid-a-trivial-UAF.patch
deleted file mode 100644
index 8c44b1f..0000000
--- a/SOURCES/0525-net-tftp-Avoid-a-trivial-UAF.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Axtens <dja@axtens.net>
-Date: Tue, 18 Jan 2022 14:29:20 +1100
-Subject: [PATCH] net/tftp: Avoid a trivial UAF
-
-Under tftp errors, we print a tftp error message from the tftp header.
-However, the tftph pointer is a pointer inside nb, the netbuff. Previously,
-we were freeing the nb and then dereferencing it. Don't do that, use it
-and then free it later.
-
-This isn't really _bad_ per se, especially as we're single-threaded, but
-it trips up fuzzers.
-
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit 956f4329cec23e4375182030ca9b2be631a61ba5)
-(cherry picked from commit dbe9abcdee6ce796811111b67e3f24eefe2135d1)
-(cherry picked from commit 72ae9c5d389d2c0337c44edead6e00db0bb84039)
-(cherry picked from commit 6a367d5b45cee3b452319cbaba1052f045c68081)
----
- grub-core/net/tftp.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c
-index 69a9ba6979..09e1511ccf 100644
---- a/grub-core/net/tftp.c
-+++ b/grub-core/net/tftp.c
-@@ -252,9 +252,9 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)),
-       return GRUB_ERR_NONE;
-     case TFTP_ERROR:
-       data->have_oack = 1;
--      grub_netbuff_free (nb);
-       grub_error (GRUB_ERR_IO, "%s", tftph->u.err.errmsg);
-       grub_error_save (&data->save_err);
-+      grub_netbuff_free (nb);
-       return GRUB_ERR_NONE;
-     default:
-       grub_netbuff_free (nb);
diff --git a/SOURCES/0526-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch b/SOURCES/0526-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch
new file mode 100644
index 0000000..11f6cb6
--- /dev/null
+++ b/SOURCES/0526-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch
@@ -0,0 +1,58 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Thu, 16 Sep 2021 01:29:54 +1000
+Subject: [PATCH] net/dns: Fix double-free addresses on corrupt DNS response
+
+grub_net_dns_lookup() takes as inputs a pointer to an array of addresses
+("addresses") for the given name, and pointer to a number of addresses
+("naddresses"). grub_net_dns_lookup() is responsible for allocating
+"addresses", and the caller is responsible for freeing it if
+"naddresses" > 0.
+
+The DNS recv_hook will sometimes set and free the addresses array,
+for example if the packet is too short:
+
+      if (ptr + 10 >= nb->tail)
+	{
+	  if (!*data->naddresses)
+	    grub_free (*data->addresses);
+	  grub_netbuff_free (nb);
+	  return GRUB_ERR_NONE;
+	}
+
+Later on the nslookup command code unconditionally frees the "addresses"
+array. Normally this is fine: the array is either populated with valid
+data or is NULL. But in these sorts of error cases it is neither NULL
+nor valid and we get a double-free.
+
+Only free "addresses" if "naddresses" > 0.
+
+It looks like the other use of grub_net_dns_lookup() is not affected.
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit eb2e69fcf51307757e43f55ee8c9354d1ee42dd1)
+(cherry picked from commit d801a27e7acec6c1a83067fab0bb975877eaf704)
+(cherry picked from commit 4d8b6e36ddfda4084e370b3b08c432e8a462e9be)
+---
+ grub-core/net/dns.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
+index 906ec7d678..135faac035 100644
+--- a/grub-core/net/dns.c
++++ b/grub-core/net/dns.c
+@@ -667,9 +667,11 @@ grub_cmd_nslookup (struct grub_command *cmd __attribute__ ((unused)),
+       grub_net_addr_to_str (&addresses[i], buf);
+       grub_printf ("%s\n", buf);
+     }
+-  grub_free (addresses);
+   if (naddresses)
+-    return GRUB_ERR_NONE;
++    {
++      grub_free (addresses);
++      return GRUB_ERR_NONE;
++    }
+   return grub_error (GRUB_ERR_NET_NO_DOMAIN, N_("no DNS record found"));
+ }
+ 
diff --git a/SOURCES/0526-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch b/SOURCES/0526-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch
deleted file mode 100644
index 75082a8..0000000
--- a/SOURCES/0526-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Axtens <dja@axtens.net>
-Date: Tue, 1 Mar 2022 23:14:15 +1100
-Subject: [PATCH] net/http: Do not tear down socket if it's already been torn
- down
-
-It's possible for data->sock to get torn down in tcp error handling.
-If we unconditionally tear it down again we will end up doing writes
-to an offset of the NULL pointer when we go to tear it down again.
-
-Detect if it has been torn down and don't do it again.
-
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit ec233d3ecf995293304de443579aab5c46c49e85)
-(cherry picked from commit d39cf87ed701b9f0900daed7f672e07994d37ce8)
-(cherry picked from commit e0aa5c3acec70eac3489d6df1893a93726cbce3a)
-(cherry picked from commit d29000397693cae279291b75ff89e5b9a5e2ed97)
----
- grub-core/net/http.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/grub-core/net/http.c b/grub-core/net/http.c
-index b52b558d63..5223ca57a4 100644
---- a/grub-core/net/http.c
-+++ b/grub-core/net/http.c
-@@ -427,7 +427,7 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial)
-       return err;
-     }
- 
--  for (i = 0; !data->headers_recv && i < 100; i++)
-+  for (i = 0; data->sock && !data->headers_recv && i < 100; i++)
-     {
-       grub_net_tcp_retransmit ();
-       grub_net_poll_cards (300, &data->headers_recv);
-@@ -435,7 +435,8 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial)
- 
-   if (!data->headers_recv)
-     {
--      grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
-+      if (data->sock)
-+        grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
-       if (data->err)
- 	{
- 	  char *str = data->errmsg;
diff --git a/SOURCES/0527-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch b/SOURCES/0527-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch
new file mode 100644
index 0000000..d641a9e
--- /dev/null
+++ b/SOURCES/0527-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch
@@ -0,0 +1,73 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Mon, 20 Dec 2021 21:55:43 +1100
+Subject: [PATCH] net/dns: Don't read past the end of the string we're checking
+ against
+
+I don't really understand what's going on here but fuzzing found
+a bug where we read past the end of check_with. That's a C string,
+so use grub_strlen() to make sure we don't overread it.
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit 6a97b3f4b1d5173aa516edc6dedbc63de7306d21)
+(cherry picked from commit e0589624e86bc96666cbdb62f6e55cafec2871b3)
+(cherry picked from commit 95ecbc0b9aacfd43ba96cccc50daaf39eccd9f7f)
+---
+ grub-core/net/dns.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
+index 135faac035..17961a9f18 100644
+--- a/grub-core/net/dns.c
++++ b/grub-core/net/dns.c
+@@ -146,11 +146,18 @@ check_name_real (const grub_uint8_t *name_at, const grub_uint8_t *head,
+ 		 int *length, char *set)
+ {
+   const char *readable_ptr = check_with;
++  int readable_len;
+   const grub_uint8_t *ptr;
+   char *optr = set;
+   int bytes_processed = 0;
+   if (length)
+     *length = 0;
++
++  if (readable_ptr != NULL)
++    readable_len = grub_strlen (readable_ptr);
++  else
++    readable_len = 0;
++
+   for (ptr = name_at; ptr < tail && bytes_processed < tail - head + 2; )
+     {
+       /* End marker.  */
+@@ -172,13 +179,16 @@ check_name_real (const grub_uint8_t *name_at, const grub_uint8_t *head,
+ 	  ptr = head + (((ptr[0] & 0x3f) << 8) | ptr[1]);
+ 	  continue;
+ 	}
+-      if (readable_ptr && grub_memcmp (ptr + 1, readable_ptr, *ptr) != 0)
++      if (readable_ptr != NULL && (*ptr > readable_len || grub_memcmp (ptr + 1, readable_ptr, *ptr) != 0))
+ 	return 0;
+       if (grub_memchr (ptr + 1, 0, *ptr) 
+ 	  || grub_memchr (ptr + 1, '.', *ptr))
+ 	return 0;
+       if (readable_ptr)
+-	readable_ptr += *ptr;
++	{
++	  readable_ptr += *ptr;
++	  readable_len -= *ptr;
++	}
+       if (readable_ptr && *readable_ptr != '.' && *readable_ptr != 0)
+ 	return 0;
+       bytes_processed += *ptr + 1;
+@@ -192,7 +202,10 @@ check_name_real (const grub_uint8_t *name_at, const grub_uint8_t *head,
+       if (optr)
+ 	*optr++ = '.';
+       if (readable_ptr && *readable_ptr)
+-	readable_ptr++;
++	{
++	  readable_ptr++;
++	  readable_len--;
++	}
+       ptr += *ptr + 1;
+     }
+   return 0;
diff --git a/SOURCES/0527-net-http-Fix-OOB-write-for-split-http-headers.patch b/SOURCES/0527-net-http-Fix-OOB-write-for-split-http-headers.patch
deleted file mode 100644
index eea35d6..0000000
--- a/SOURCES/0527-net-http-Fix-OOB-write-for-split-http-headers.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Axtens <dja@axtens.net>
-Date: Tue, 8 Mar 2022 18:17:03 +1100
-Subject: [PATCH] net/http: Fix OOB write for split http headers
-
-GRUB has special code for handling an http header that is split
-across two packets.
-
-The code tracks the end of line by looking for a "\n" byte. The
-code for split headers has always advanced the pointer just past the
-end of the line, whereas the code that handles unsplit headers does
-not advance the pointer. This extra advance causes the length to be
-one greater, which breaks an assumption in parse_line(), leading to
-it writing a NUL byte one byte past the end of the buffer where we
-reconstruct the line from the two packets.
-
-It's conceivable that an attacker controlled set of packets could
-cause this to zero out the first byte of the "next" pointer of the
-grub_mm_region structure following the current_line buffer.
-
-Do not advance the pointer in the split header case.
-
-Fixes: CVE-2022-28734
-
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit e9fb459638811c12b0989dbf64e3e124974ef617)
-(cherry picked from commit b604916beb6c39e8ed27f72851eb16f3eaa293c5)
-(cherry picked from commit c3c6b1167a43275991efd6847160a46ce3839fae)
-(cherry picked from commit 9b4ef71ed4f6fce00e868e3223cdbfb734e840d6)
----
- grub-core/net/http.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
-diff --git a/grub-core/net/http.c b/grub-core/net/http.c
-index 5223ca57a4..7fa2dcaea7 100644
---- a/grub-core/net/http.c
-+++ b/grub-core/net/http.c
-@@ -193,9 +193,7 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)),
- 	  int have_line = 1;
- 	  char *t;
- 	  ptr = grub_memchr (nb->data, '\n', nb->tail - nb->data);
--	  if (ptr)
--	    ptr++;
--	  else
-+	  if (ptr == NULL)
- 	    {
- 	      have_line = 0;
- 	      ptr = (char *) nb->tail;
diff --git a/SOURCES/0528-net-http-Error-out-on-headers-with-LF-without-CR.patch b/SOURCES/0528-net-http-Error-out-on-headers-with-LF-without-CR.patch
deleted file mode 100644
index a50904e..0000000
--- a/SOURCES/0528-net-http-Error-out-on-headers-with-LF-without-CR.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Axtens <dja@axtens.net>
-Date: Tue, 8 Mar 2022 19:04:40 +1100
-Subject: [PATCH] net/http: Error out on headers with LF without CR
-
-In a similar vein to the previous patch, parse_line() would write
-a NUL byte past the end of the buffer if there was an HTTP header
-with a LF rather than a CRLF.
-
-RFC-2616 says:
-
-  Many HTTP/1.1 header field values consist of words separated by LWS
-  or special characters. These special characters MUST be in a quoted
-  string to be used within a parameter value (as defined in section 3.6).
-
-We don't support quoted sections or continuation lines, etc.
-
-If we see an LF that's not part of a CRLF, bail out.
-
-Fixes: CVE-2022-28734
-
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit d232ad41ac4979a9de4d746e5fdff9caf0e303de)
-(cherry picked from commit 8960e6d6137090a7e8c6592077da6e387a4ef972)
-(cherry picked from commit 9b6b9398c90dd76ce0b935d21c4ecb8954c4b2b7)
-(cherry picked from commit 3eef2cc845f7ed34a89d8d0a7042d7768e43eaad)
----
- grub-core/net/http.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/grub-core/net/http.c b/grub-core/net/http.c
-index 7fa2dcaea7..745f429b51 100644
---- a/grub-core/net/http.c
-+++ b/grub-core/net/http.c
-@@ -69,7 +69,15 @@ parse_line (grub_file_t file, http_data_t data, char *ptr, grub_size_t len)
-   char *end = ptr + len;
-   while (end > ptr && *(end - 1) == '\r')
-     end--;
-+
-+  /* LF without CR. */
-+  if (end == ptr + len)
-+    {
-+      data->errmsg = grub_strdup (_("invalid HTTP header - LF without CR"));
-+      return GRUB_ERR_NONE;
-+    }
-   *end = 0;
-+
-   /* Trailing CRLF.  */
-   if (data->in_chunk_len == 1)
-     {
diff --git a/SOURCES/0528-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch b/SOURCES/0528-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch
new file mode 100644
index 0000000..dc4aab2
--- /dev/null
+++ b/SOURCES/0528-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch
@@ -0,0 +1,114 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Mon, 20 Sep 2021 01:12:24 +1000
+Subject: [PATCH] net/tftp: Prevent a UAF and double-free from a failed seek
+
+A malicious tftp server can cause UAFs and a double free.
+
+An attempt to read from a network file is handled by grub_net_fs_read(). If
+the read is at an offset other than the current offset, grub_net_seek_real()
+is invoked.
+
+In grub_net_seek_real(), if a backwards seek cannot be satisfied from the
+currently received packets, and the underlying transport does not provide
+a seek method, then grub_net_seek_real() will close and reopen the network
+protocol layer.
+
+For tftp, the ->close() call goes to tftp_close() and frees the tftp_data_t
+file->data. The file->data pointer is not nulled out after the free.
+
+If the ->open() call fails, the file->data will not be reallocated and will
+continue point to a freed memory block. This could happen from a server
+refusing to send the requisite ack to the new tftp request, for example.
+
+The seek and the read will then fail, but the grub_file continues to exist:
+the failed seek does not necessarily cause the entire file to be thrown
+away (e.g. where the file is checked to see if it is gzipped/lzio/xz/etc.,
+a read failure is interpreted as a decompressor passing on the file, not as
+an invalidation of the entire grub_file_t structure).
+
+This means subsequent attempts to read or seek the file will use the old
+file->data after free. Eventually, the file will be close()d again and
+file->data will be freed again.
+
+Mark a net_fs file that doesn't reopen as broken. Do not permit read() or
+close() on a broken file (seek is not exposed directly to the file API -
+it is only called as part of read, so this blocks seeks as well).
+
+As an additional defence, null out the ->data pointer if tftp_open() fails.
+That would have lead to a simple null pointer dereference rather than
+a mess of UAFs.
+
+This may affect other protocols, I haven't checked.
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit dada1dda695439bb55b2848dddc2d89843552f81)
+(cherry picked from commit 352c5ae8a9fc715712e6ecbd7ccb6218122c748f)
+(cherry picked from commit 61a010085ab9f0ecf42677773a6fc212f1579b0a)
+---
+ grub-core/net/net.c  | 11 +++++++++--
+ grub-core/net/tftp.c |  1 +
+ include/grub/net.h   |  1 +
+ 3 files changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/grub-core/net/net.c b/grub-core/net/net.c
+index a27c53eee1..b9e2a4d100 100644
+--- a/grub-core/net/net.c
++++ b/grub-core/net/net.c
+@@ -1625,7 +1625,8 @@ grub_net_fs_close (grub_file_t file)
+       grub_netbuff_free (file->device->net->packs.first->nb);
+       grub_net_remove_packet (file->device->net->packs.first);
+     }
+-  file->device->net->protocol->close (file);
++  if (!file->device->net->broken)
++    file->device->net->protocol->close (file);
+   grub_free (file->device->net->name);
+   return GRUB_ERR_NONE;
+ }
+@@ -1847,7 +1848,10 @@ grub_net_seek_real (struct grub_file *file, grub_off_t offset)
+     file->device->net->stall = 0;
+     err = file->device->net->protocol->open (file, file->device->net->name);
+     if (err)
+-      return err;
++      {
++	file->device->net->broken = 1;
++	return err;
++      }
+     grub_net_fs_read_real (file, NULL, offset);
+     return grub_errno;
+   }
+@@ -1856,6 +1860,9 @@ grub_net_seek_real (struct grub_file *file, grub_off_t offset)
+ static grub_ssize_t
+ grub_net_fs_read (grub_file_t file, char *buf, grub_size_t len)
+ {
++  if (file->device->net->broken)
++    return -1;
++
+   if (file->offset != file->device->net->offset)
+     {
+       grub_err_t err;
+diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c
+index aa0424dcee..85be965470 100644
+--- a/grub-core/net/tftp.c
++++ b/grub-core/net/tftp.c
+@@ -402,6 +402,7 @@ tftp_open (struct grub_file *file, const char *filename)
+     {
+       grub_net_udp_close (data->sock);
+       grub_free (data);
++      file->data = NULL;
+       return grub_errno;
+     }
+ 
+diff --git a/include/grub/net.h b/include/grub/net.h
+index 9cf6da6897..0d31f00664 100644
+--- a/include/grub/net.h
++++ b/include/grub/net.h
+@@ -280,6 +280,7 @@ typedef struct grub_net
+   grub_fs_t fs;
+   int eof;
+   int stall;
++  int broken;
+ } *grub_net_t;
+ 
+ extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name);
diff --git a/SOURCES/0529-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch b/SOURCES/0529-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch
deleted file mode 100644
index 93637a4..0000000
--- a/SOURCES/0529-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
-Date: Wed, 6 Apr 2022 18:03:37 +0530
-Subject: [PATCH] fs/f2fs: Do not read past the end of nat journal entries
-
-A corrupt f2fs file system could specify a nat journal entry count
-that is beyond the maximum NAT_JOURNAL_ENTRIES.
-
-Check if the specified nat journal entry count before accessing the
-array, and throw an error if it is too large.
-
-Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit a3988cb3f0a108dd67ac127a79a4c8479d23334e)
-(cherry picked from commit 7125978aa7d6068812ef6da0ab38ce521ae7eba1)
-(cherry picked from commit e488538cbf9fc63796c7047550b0598e1ef95c03)
-(cherry picked from commit a2e520d7ced2ded854fb24f3718530e1e6d7dd5e)
----
- grub-core/fs/f2fs.c | 21 ++++++++++++++-------
- 1 file changed, 14 insertions(+), 7 deletions(-)
-
-diff --git a/grub-core/fs/f2fs.c b/grub-core/fs/f2fs.c
-index 1cad2615f3..09dc932420 100644
---- a/grub-core/fs/f2fs.c
-+++ b/grub-core/fs/f2fs.c
-@@ -632,23 +632,27 @@ get_nat_journal (struct grub_f2fs_data *data)
-   return err;
- }
- 
--static grub_uint32_t
--get_blkaddr_from_nat_journal (struct grub_f2fs_data *data, grub_uint32_t nid)
-+static grub_err_t
-+get_blkaddr_from_nat_journal (struct grub_f2fs_data *data, grub_uint32_t nid,
-+                              grub_uint32_t *blkaddr)
- {
-   grub_uint16_t n = grub_le_to_cpu16 (data->nat_j.n_nats);
--  grub_uint32_t blkaddr = 0;
-   grub_uint16_t i;
- 
-+  if (n >= NAT_JOURNAL_ENTRIES)
-+    return grub_error (GRUB_ERR_BAD_FS,
-+                       "invalid number of nat journal entries");
-+
-   for (i = 0; i < n; i++)
-     {
-       if (grub_le_to_cpu32 (data->nat_j.entries[i].nid) == nid)
-         {
--          blkaddr = grub_le_to_cpu32 (data->nat_j.entries[i].ne.block_addr);
-+          *blkaddr = grub_le_to_cpu32 (data->nat_j.entries[i].ne.block_addr);
-           break;
-         }
-     }
- 
--  return blkaddr;
-+  return GRUB_ERR_NONE;
- }
- 
- static grub_uint32_t
-@@ -656,10 +660,13 @@ get_node_blkaddr (struct grub_f2fs_data *data, grub_uint32_t nid)
- {
-   struct grub_f2fs_nat_block *nat_block;
-   grub_uint32_t seg_off, block_off, entry_off, block_addr;
--  grub_uint32_t blkaddr;
-+  grub_uint32_t blkaddr = 0;
-   grub_err_t err;
- 
--  blkaddr = get_blkaddr_from_nat_journal (data, nid);
-+  err = get_blkaddr_from_nat_journal (data, nid, &blkaddr);
-+  if (err != GRUB_ERR_NONE)
-+    return 0;
-+
-   if (blkaddr)
-     return blkaddr;
- 
diff --git a/SOURCES/0529-misc-Format-string-for-grub_error-should-be-a-litera.patch b/SOURCES/0529-misc-Format-string-for-grub_error-should-be-a-litera.patch
new file mode 100644
index 0000000..ae0ec53
--- /dev/null
+++ b/SOURCES/0529-misc-Format-string-for-grub_error-should-be-a-litera.patch
@@ -0,0 +1,53 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Glenn Washburn <development@efficientek.com>
+Date: Thu, 4 Mar 2021 18:22:32 -0600
+Subject: [PATCH] misc: Format string for grub_error() should be a literal
+
+Signed-off-by: Glenn Washburn <development@efficientek.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry-picked from commit 60875f4e15d704b875969b415501802b531c4db3)
+---
+ grub-core/loader/efi/chainloader.c | 2 +-
+ grub-core/net/tftp.c               | 2 +-
+ grub-core/script/lexer.c           | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
+index 720f6181e5..8e658f713e 100644
+--- a/grub-core/loader/efi/chainloader.c
++++ b/grub-core/loader/efi/chainloader.c
+@@ -79,7 +79,7 @@ grub_start_image (grub_efi_handle_t handle)
+ 	      *grub_utf16_to_utf8 ((grub_uint8_t *) buf,
+ 				   exit_data, exit_data_size) = 0;
+ 
+-	      grub_error (GRUB_ERR_BAD_OS, buf);
++	      grub_error (GRUB_ERR_BAD_OS, "%s", buf);
+ 	      grub_free (buf);
+ 	    }
+ 	}
+diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c
+index 85be965470..69a9ba6979 100644
+--- a/grub-core/net/tftp.c
++++ b/grub-core/net/tftp.c
+@@ -253,7 +253,7 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)),
+     case TFTP_ERROR:
+       data->have_oack = 1;
+       grub_netbuff_free (nb);
+-      grub_error (GRUB_ERR_IO, (char *) tftph->u.err.errmsg);
++      grub_error (GRUB_ERR_IO, "%s", tftph->u.err.errmsg);
+       grub_error_save (&data->save_err);
+       return GRUB_ERR_NONE;
+     default:
+diff --git a/grub-core/script/lexer.c b/grub-core/script/lexer.c
+index 5fb0cbd0bc..27daad791c 100644
+--- a/grub-core/script/lexer.c
++++ b/grub-core/script/lexer.c
+@@ -349,7 +349,7 @@ void
+ grub_script_yyerror (struct grub_parser_param *state, char const *err)
+ {
+   if (err)
+-    grub_error (GRUB_ERR_INVALID_COMMAND, err);
++    grub_error (GRUB_ERR_INVALID_COMMAND, "%s", err);
+ 
+   grub_print_error ();
+   state->err++;
diff --git a/SOURCES/0530-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch b/SOURCES/0530-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch
deleted file mode 100644
index 07de7cd..0000000
--- a/SOURCES/0530-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch
+++ /dev/null
@@ -1,135 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
-Date: Wed, 6 Apr 2022 18:49:09 +0530
-Subject: [PATCH] fs/f2fs: Do not read past the end of nat bitmap
-
-A corrupt f2fs filesystem could have a block offset or a bitmap
-offset that would cause us to read beyond the bounds of the nat
-bitmap.
-
-Introduce the nat_bitmap_size member in grub_f2fs_data which holds
-the size of nat bitmap.
-
-Set the size when loading the nat bitmap in nat_bitmap_ptr(), and
-catch when an invalid offset would create a pointer past the end of
-the allocated space.
-
-Check against the bitmap size in grub_f2fs_test_bit() test bit to avoid
-reading past the end of the nat bitmap.
-
-Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit 62d63d5e38c67a6e349148bf7cb87c560e935a7e)
-(cherry picked from commit 92219e6d379b5b4d30b05361830b72ab1d95d281)
-(cherry picked from commit c23d97e3b56594bf0f802d94062e14b221143115)
-(cherry picked from commit e9536dd7fbdc632efbe3506386dbfb3bfc0465c8)
----
- grub-core/fs/f2fs.c | 33 +++++++++++++++++++++++++++------
- 1 file changed, 27 insertions(+), 6 deletions(-)
-
-diff --git a/grub-core/fs/f2fs.c b/grub-core/fs/f2fs.c
-index 09dc932420..33e565b180 100644
---- a/grub-core/fs/f2fs.c
-+++ b/grub-core/fs/f2fs.c
-@@ -122,6 +122,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
- #define F2FS_INLINE_DOTS          0x10  /* File having implicit dot dentries. */
- 
- #define MAX_VOLUME_NAME           512
-+#define MAX_NAT_BITMAP_SIZE       3900
- 
- enum FILE_TYPE
- {
-@@ -183,7 +184,7 @@ struct grub_f2fs_checkpoint
-   grub_uint32_t                   checksum_offset;
-   grub_uint64_t                   elapsed_time;
-   grub_uint8_t                    alloc_type[MAX_ACTIVE_LOGS];
--  grub_uint8_t                    sit_nat_version_bitmap[3900];
-+  grub_uint8_t                    sit_nat_version_bitmap[MAX_NAT_BITMAP_SIZE];
-   grub_uint32_t                   checksum;
- } GRUB_PACKED;
- 
-@@ -302,6 +303,7 @@ struct grub_f2fs_data
- 
-   struct grub_f2fs_nat_journal    nat_j;
-   char                            *nat_bitmap;
-+  grub_uint32_t                   nat_bitmap_size;
- 
-   grub_disk_t                     disk;
-   struct grub_f2fs_node           *inode;
-@@ -377,15 +379,20 @@ sum_blk_addr (struct grub_f2fs_data *data, int base, int type)
- }
- 
- static void *
--nat_bitmap_ptr (struct grub_f2fs_data *data)
-+nat_bitmap_ptr (struct grub_f2fs_data *data, grub_uint32_t *nat_bitmap_size)
- {
-   struct grub_f2fs_checkpoint *ckpt = &data->ckpt;
-   grub_uint32_t offset;
-+  *nat_bitmap_size = MAX_NAT_BITMAP_SIZE;
- 
-   if (grub_le_to_cpu32 (data->sblock.cp_payload) > 0)
-     return ckpt->sit_nat_version_bitmap;
- 
-   offset = grub_le_to_cpu32 (ckpt->sit_ver_bitmap_bytesize);
-+  if (offset >= MAX_NAT_BITMAP_SIZE)
-+     return NULL;
-+
-+  *nat_bitmap_size = *nat_bitmap_size - offset;
- 
-   return ckpt->sit_nat_version_bitmap + offset;
- }
-@@ -438,11 +445,15 @@ grub_f2fs_crc_valid (grub_uint32_t blk_crc, void *buf, const grub_uint32_t len)
- }
- 
- static int
--grub_f2fs_test_bit (grub_uint32_t nr, const char *p)
-+grub_f2fs_test_bit (grub_uint32_t nr, const char *p, grub_uint32_t len)
- {
-   int mask;
-+  grub_uint32_t shifted_nr = (nr >> 3);
- 
--  p += (nr >> 3);
-+  if (shifted_nr >= len)
-+    return -1;
-+
-+  p += shifted_nr;
-   mask = 1 << (7 - (nr & 0x07));
- 
-   return mask & *p;
-@@ -662,6 +673,7 @@ get_node_blkaddr (struct grub_f2fs_data *data, grub_uint32_t nid)
-   grub_uint32_t seg_off, block_off, entry_off, block_addr;
-   grub_uint32_t blkaddr = 0;
-   grub_err_t err;
-+  int result_bit;
- 
-   err = get_blkaddr_from_nat_journal (data, nid, &blkaddr);
-   if (err != GRUB_ERR_NONE)
-@@ -682,8 +694,15 @@ get_node_blkaddr (struct grub_f2fs_data *data, grub_uint32_t nid)
-         ((seg_off * data->blocks_per_seg) << 1) +
-         (block_off & (data->blocks_per_seg - 1));
- 
--  if (grub_f2fs_test_bit (block_off, data->nat_bitmap))
-+  result_bit = grub_f2fs_test_bit (block_off, data->nat_bitmap,
-+                                   data->nat_bitmap_size);
-+  if (result_bit > 0)
-     block_addr += data->blocks_per_seg;
-+  else if (result_bit == -1)
-+    {
-+      grub_free (nat_block);
-+      return 0;
-+    }
- 
-   err = grub_f2fs_block_read (data, block_addr, nat_block);
-   if (err)
-@@ -832,7 +851,9 @@ grub_f2fs_mount (grub_disk_t disk)
-   if (err)
-     goto fail;
- 
--  data->nat_bitmap = nat_bitmap_ptr (data);
-+  data->nat_bitmap = nat_bitmap_ptr (data, &data->nat_bitmap_size);
-+  if (data->nat_bitmap == NULL)
-+    goto fail;
- 
-   err = get_nat_journal (data);
-   if (err)
diff --git a/SOURCES/0530-net-tftp-Avoid-a-trivial-UAF.patch b/SOURCES/0530-net-tftp-Avoid-a-trivial-UAF.patch
new file mode 100644
index 0000000..f6f77f3
--- /dev/null
+++ b/SOURCES/0530-net-tftp-Avoid-a-trivial-UAF.patch
@@ -0,0 +1,37 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Tue, 18 Jan 2022 14:29:20 +1100
+Subject: [PATCH] net/tftp: Avoid a trivial UAF
+
+Under tftp errors, we print a tftp error message from the tftp header.
+However, the tftph pointer is a pointer inside nb, the netbuff. Previously,
+we were freeing the nb and then dereferencing it. Don't do that, use it
+and then free it later.
+
+This isn't really _bad_ per se, especially as we're single-threaded, but
+it trips up fuzzers.
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit 956f4329cec23e4375182030ca9b2be631a61ba5)
+(cherry picked from commit dbe9abcdee6ce796811111b67e3f24eefe2135d1)
+(cherry picked from commit 72ae9c5d389d2c0337c44edead6e00db0bb84039)
+---
+ grub-core/net/tftp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c
+index 69a9ba6979..09e1511ccf 100644
+--- a/grub-core/net/tftp.c
++++ b/grub-core/net/tftp.c
+@@ -252,9 +252,9 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)),
+       return GRUB_ERR_NONE;
+     case TFTP_ERROR:
+       data->have_oack = 1;
+-      grub_netbuff_free (nb);
+       grub_error (GRUB_ERR_IO, "%s", tftph->u.err.errmsg);
+       grub_error_save (&data->save_err);
++      grub_netbuff_free (nb);
+       return GRUB_ERR_NONE;
+     default:
+       grub_netbuff_free (nb);
diff --git a/SOURCES/0531-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch b/SOURCES/0531-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch
deleted file mode 100644
index 3444e4f..0000000
--- a/SOURCES/0531-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
-Date: Wed, 6 Apr 2022 18:17:43 +0530
-Subject: [PATCH] fs/f2fs: Do not copy file names that are too long
-
-A corrupt f2fs file system might specify a name length which is greater
-than the maximum name length supported by the GRUB f2fs driver.
-
-We will allocate enough memory to store the overly long name, but there
-are only F2FS_NAME_LEN bytes in the source, so we would read past the end
-of the source.
-
-While checking directory entries, do not copy a file name with an invalid
-length.
-
-Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
-Signed-off-by: Daniel Axtens <dja@axtens.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit 9a891f638509e031d322c94e3cbcf38d36f3993a)
-(cherry picked from commit 13f9160ae0d2806baed459884999356817096cd7)
-(cherry picked from commit a48ba4d48b3c66431e6bbeb386078efc6602110c)
-(cherry picked from commit f0440b61cebbab807638b90eb2ae86265d6cf49f)
----
- grub-core/fs/f2fs.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/grub-core/fs/f2fs.c b/grub-core/fs/f2fs.c
-index 33e565b180..07ea34196c 100644
---- a/grub-core/fs/f2fs.c
-+++ b/grub-core/fs/f2fs.c
-@@ -998,6 +998,10 @@ grub_f2fs_check_dentries (struct grub_f2fs_dir_iter_ctx *ctx)
- 
-       ftype = ctx->dentry[i].file_type;
-       name_len = grub_le_to_cpu16 (ctx->dentry[i].name_len);
-+
-+      if (name_len >= F2FS_NAME_LEN)
-+        return 0;
-+
-       filename = grub_malloc (name_len + 1);
-       if (!filename)
-         return 0;
diff --git a/SOURCES/0531-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch b/SOURCES/0531-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch
new file mode 100644
index 0000000..6fcb3c6
--- /dev/null
+++ b/SOURCES/0531-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch
@@ -0,0 +1,44 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Tue, 1 Mar 2022 23:14:15 +1100
+Subject: [PATCH] net/http: Do not tear down socket if it's already been torn
+ down
+
+It's possible for data->sock to get torn down in tcp error handling.
+If we unconditionally tear it down again we will end up doing writes
+to an offset of the NULL pointer when we go to tear it down again.
+
+Detect if it has been torn down and don't do it again.
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit ec233d3ecf995293304de443579aab5c46c49e85)
+(cherry picked from commit d39cf87ed701b9f0900daed7f672e07994d37ce8)
+(cherry picked from commit e0aa5c3acec70eac3489d6df1893a93726cbce3a)
+---
+ grub-core/net/http.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/grub-core/net/http.c b/grub-core/net/http.c
+index b52b558d63..5223ca57a4 100644
+--- a/grub-core/net/http.c
++++ b/grub-core/net/http.c
+@@ -427,7 +427,7 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial)
+       return err;
+     }
+ 
+-  for (i = 0; !data->headers_recv && i < 100; i++)
++  for (i = 0; data->sock && !data->headers_recv && i < 100; i++)
+     {
+       grub_net_tcp_retransmit ();
+       grub_net_poll_cards (300, &data->headers_recv);
+@@ -435,7 +435,8 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial)
+ 
+   if (!data->headers_recv)
+     {
+-      grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
++      if (data->sock)
++        grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
+       if (data->err)
+ 	{
+ 	  char *str = data->errmsg;
diff --git a/SOURCES/0532-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch b/SOURCES/0532-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch
deleted file mode 100644
index 289f139..0000000
--- a/SOURCES/0532-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Darren Kenny <darren.kenny@oracle.com>
-Date: Tue, 29 Mar 2022 10:49:56 +0000
-Subject: [PATCH] fs/btrfs: Fix several fuzz issues with invalid dir item
- sizing
-
-According to the btrfs code in Linux, the structure of a directory item
-leaf should be of the form:
-
-  |struct btrfs_dir_item|name|data|
-
-in GRUB the name len and data len are in the grub_btrfs_dir_item
-structure's n and m fields respectively.
-
-The combined size of the structure, name and data should be less than
-the allocated memory, a difference to the Linux kernel's struct
-btrfs_dir_item is that the grub_btrfs_dir_item has an extra field for
-where the name is stored, so we adjust for that too.
-
-Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit 6d3f06c0b6a8992b9b1bb0e62af93ac5ff2781f0)
-[rharwood: we've an extra variable here]
-Signed-off-by: Robbie Harwood <rharwood@redhat.com>
-(cherry picked from commit e3e21b9a81aea09dd43368cf097c1029a8380d82)
-(cherry picked from commit ab14a39777edb60c99751d4fdf1cc254a4faebf5)
-(cherry picked from commit 90a9fbd5969325993e069ee5a04a802b59657920)
----
- grub-core/fs/btrfs.c | 26 ++++++++++++++++++++++++++
- 1 file changed, 26 insertions(+)
-
-diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
-index 3faf9056c7..9da2952f70 100644
---- a/grub-core/fs/btrfs.c
-+++ b/grub-core/fs/btrfs.c
-@@ -1834,6 +1834,7 @@ grub_btrfs_dir (grub_device_t device, const char *path,
-   grub_uint64_t tree;
-   grub_uint8_t type;
-   char *new_path = NULL;
-+  grub_size_t est_size = 0;
- 
-   if (!data)
-     return grub_errno;
-@@ -1900,6 +1901,18 @@ grub_btrfs_dir (grub_device_t device, const char *path,
- 	  break;
- 	}
- 
-+      if (direl == NULL ||
-+	  grub_add (grub_le_to_cpu16 (direl->n),
-+		    grub_le_to_cpu16 (direl->m), &est_size) ||
-+	  grub_add (est_size, sizeof (*direl), &est_size) ||
-+	  grub_sub (est_size, sizeof (direl->name), &est_size) ||
-+	  est_size > allocated)
-+       {
-+         grub_errno = GRUB_ERR_OUT_OF_RANGE;
-+         r = -grub_errno;
-+         goto out;
-+       }
-+
-       for (cdirel = direl;
- 	   (grub_uint8_t *) cdirel - (grub_uint8_t *) direl
- 	   < (grub_ssize_t) elemsize;
-@@ -1910,6 +1923,19 @@ grub_btrfs_dir (grub_device_t device, const char *path,
- 	  char c;
- 	  struct grub_btrfs_inode inode;
- 	  struct grub_dirhook_info info;
-+
-+	  if (cdirel == NULL ||
-+	      grub_add (grub_le_to_cpu16 (cdirel->n),
-+			grub_le_to_cpu16 (cdirel->m), &est_size) ||
-+	      grub_add (est_size, sizeof (*cdirel), &est_size) ||
-+	      grub_sub (est_size, sizeof (cdirel->name), &est_size) ||
-+	      est_size > allocated)
-+	   {
-+	     grub_errno = GRUB_ERR_OUT_OF_RANGE;
-+	     r = -grub_errno;
-+	     goto out;
-+	   }
-+
- 	  err = grub_btrfs_read_inode (data, &inode, cdirel->key.object_id,
- 				       tree);
- 	  grub_memset (&info, 0, sizeof (info));
diff --git a/SOURCES/0532-net-http-Fix-OOB-write-for-split-http-headers.patch b/SOURCES/0532-net-http-Fix-OOB-write-for-split-http-headers.patch
new file mode 100644
index 0000000..daabc9e
--- /dev/null
+++ b/SOURCES/0532-net-http-Fix-OOB-write-for-split-http-headers.patch
@@ -0,0 +1,48 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Tue, 8 Mar 2022 18:17:03 +1100
+Subject: [PATCH] net/http: Fix OOB write for split http headers
+
+GRUB has special code for handling an http header that is split
+across two packets.
+
+The code tracks the end of line by looking for a "\n" byte. The
+code for split headers has always advanced the pointer just past the
+end of the line, whereas the code that handles unsplit headers does
+not advance the pointer. This extra advance causes the length to be
+one greater, which breaks an assumption in parse_line(), leading to
+it writing a NUL byte one byte past the end of the buffer where we
+reconstruct the line from the two packets.
+
+It's conceivable that an attacker controlled set of packets could
+cause this to zero out the first byte of the "next" pointer of the
+grub_mm_region structure following the current_line buffer.
+
+Do not advance the pointer in the split header case.
+
+Fixes: CVE-2022-28734
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit e9fb459638811c12b0989dbf64e3e124974ef617)
+(cherry picked from commit b604916beb6c39e8ed27f72851eb16f3eaa293c5)
+(cherry picked from commit c3c6b1167a43275991efd6847160a46ce3839fae)
+---
+ grub-core/net/http.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/grub-core/net/http.c b/grub-core/net/http.c
+index 5223ca57a4..7fa2dcaea7 100644
+--- a/grub-core/net/http.c
++++ b/grub-core/net/http.c
+@@ -193,9 +193,7 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)),
+ 	  int have_line = 1;
+ 	  char *t;
+ 	  ptr = grub_memchr (nb->data, '\n', nb->tail - nb->data);
+-	  if (ptr)
+-	    ptr++;
+-	  else
++	  if (ptr == NULL)
+ 	    {
+ 	      have_line = 0;
+ 	      ptr = (char *) nb->tail;
diff --git a/SOURCES/0533-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch b/SOURCES/0533-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch
deleted file mode 100644
index 0bc744f..0000000
--- a/SOURCES/0533-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch
+++ /dev/null
@@ -1,144 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Kiper <daniel.kiper@oracle.com>
-Date: Thu, 3 Dec 2020 16:01:46 +0100
-Subject: [PATCH] efi: Return grub_efi_status_t from grub_efi_get_variable()
-
-This is needed to properly detect and report UEFI Secure Boot status
-to the x86 Linux kernel. The functionality will be added by subsequent
-patches.
-
-Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
-Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
-Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit 04ae030d0eea8668d4417702d88bf2cf04713d80)
-(cherry picked from commit ed33b47f00bc0d728197357b8ae632028f91599b)
----
- grub-core/commands/efi/efifwsetup.c |  8 ++++----
- grub-core/kern/efi/efi.c            | 16 +++++++++-------
- grub-core/video/efi_gop.c           |  2 +-
- include/grub/efi/efi.h              |  7 ++++---
- 4 files changed, 18 insertions(+), 15 deletions(-)
-
-diff --git a/grub-core/commands/efi/efifwsetup.c b/grub-core/commands/efi/efifwsetup.c
-index 7a137a72a2..eaca032838 100644
---- a/grub-core/commands/efi/efifwsetup.c
-+++ b/grub-core/commands/efi/efifwsetup.c
-@@ -38,8 +38,8 @@ grub_cmd_fwsetup (grub_command_t cmd __attribute__ ((unused)),
-   grub_size_t oi_size;
-   grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID;
- 
--  old_os_indications = grub_efi_get_variable ("OsIndications", &global,
--					      &oi_size);
-+  grub_efi_get_variable ("OsIndications", &global, &oi_size,
-+			 (void **) &old_os_indications);
- 
-   if (old_os_indications != NULL && oi_size == sizeof (os_indications))
-     os_indications |= *old_os_indications;
-@@ -63,8 +63,8 @@ efifwsetup_is_supported (void)
-   grub_size_t oi_size = 0;
-   grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID;
- 
--  os_indications_supported = grub_efi_get_variable ("OsIndicationsSupported",
--						    &global, &oi_size);
-+  grub_efi_get_variable ("OsIndicationsSupported", &global, &oi_size,
-+			 (void **) &os_indications_supported);
- 
-   if (!os_indications_supported)
-     return 0;
-diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
-index 2863956458..335033975d 100644
---- a/grub-core/kern/efi/efi.c
-+++ b/grub-core/kern/efi/efi.c
-@@ -241,9 +241,9 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid,
-   return grub_error (GRUB_ERR_IO, "could not set EFI variable `%s'", var);
- }
- 
--void *
-+grub_efi_status_t
- grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
--		       grub_size_t *datasize_out)
-+		       grub_size_t *datasize_out, void **data_out)
- {
-   grub_efi_status_t status;
-   grub_efi_uintn_t datasize = 0;
-@@ -252,13 +252,14 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
-   void *data;
-   grub_size_t len, len16;
- 
-+  *data_out = NULL;
-   *datasize_out = 0;
- 
-   len = grub_strlen (var);
-   len16 = len * GRUB_MAX_UTF16_PER_UTF8;
-   var16 = grub_calloc (len16 + 1, sizeof (var16[0]));
-   if (!var16)
--    return NULL;
-+    return GRUB_EFI_OUT_OF_RESOURCES;
-   len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL);
-   var16[len16] = 0;
- 
-@@ -269,14 +270,14 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
-   if (status != GRUB_EFI_BUFFER_TOO_SMALL || !datasize)
-     {
-       grub_free (var16);
--      return NULL;
-+      return status;
-     }
- 
-   data = grub_malloc (datasize);
-   if (!data)
-     {
-       grub_free (var16);
--      return NULL;
-+      return GRUB_EFI_OUT_OF_RESOURCES;
-     }
- 
-   status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, data);
-@@ -284,12 +285,13 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
- 
-   if (status == GRUB_EFI_SUCCESS)
-     {
-+      *data_out = data;
-       *datasize_out = datasize;
--      return data;
-+      return status;
-     }
- 
-   grub_free (data);
--  return NULL;
-+  return status;
- }
- 
- #pragma GCC diagnostic ignored "-Wcast-align"
-diff --git a/grub-core/video/efi_gop.c b/grub-core/video/efi_gop.c
-index 9fcc41ac03..ec217db70f 100644
---- a/grub-core/video/efi_gop.c
-+++ b/grub-core/video/efi_gop.c
-@@ -302,7 +302,7 @@ grub_video_gop_get_edid (struct grub_video_edid_info *edid_info)
-       char edidname[] = "agp-internal-edid";
-       grub_size_t datasize;
-       grub_uint8_t *data;
--      data = grub_efi_get_variable (edidname, &efi_var_guid, &datasize);
-+      grub_efi_get_variable (edidname, &efi_var_guid, &datasize, (void **) &data);
-       if (data && datasize > 16)
- 	{
- 	  copy_size = datasize - 16;
-diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
-index 4411ffa16b..90a85d7d9a 100644
---- a/include/grub/efi/efi.h
-+++ b/include/grub/efi/efi.h
-@@ -113,9 +113,10 @@ grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) (grub_efi_uintn_t memo
- 							   grub_efi_uintn_t descriptor_size,
- 							   grub_efi_uint32_t descriptor_version,
- 							   grub_efi_memory_descriptor_t *virtual_map);
--void *EXPORT_FUNC (grub_efi_get_variable) (const char *variable,
--					   const grub_efi_guid_t *guid,
--					   grub_size_t *datasize_out);
-+grub_efi_status_t EXPORT_FUNC (grub_efi_get_variable) (const char *variable,
-+						       const grub_efi_guid_t *guid,
-+						       grub_size_t *datasize_out,
-+						       void **data_out);
- grub_err_t
- EXPORT_FUNC (grub_efi_set_variable) (const char *var,
- 				     const grub_efi_guid_t *guid,
diff --git a/SOURCES/0533-net-http-Error-out-on-headers-with-LF-without-CR.patch b/SOURCES/0533-net-http-Error-out-on-headers-with-LF-without-CR.patch
new file mode 100644
index 0000000..86a3b28
--- /dev/null
+++ b/SOURCES/0533-net-http-Error-out-on-headers-with-LF-without-CR.patch
@@ -0,0 +1,50 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Tue, 8 Mar 2022 19:04:40 +1100
+Subject: [PATCH] net/http: Error out on headers with LF without CR
+
+In a similar vein to the previous patch, parse_line() would write
+a NUL byte past the end of the buffer if there was an HTTP header
+with a LF rather than a CRLF.
+
+RFC-2616 says:
+
+  Many HTTP/1.1 header field values consist of words separated by LWS
+  or special characters. These special characters MUST be in a quoted
+  string to be used within a parameter value (as defined in section 3.6).
+
+We don't support quoted sections or continuation lines, etc.
+
+If we see an LF that's not part of a CRLF, bail out.
+
+Fixes: CVE-2022-28734
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit d232ad41ac4979a9de4d746e5fdff9caf0e303de)
+(cherry picked from commit 8960e6d6137090a7e8c6592077da6e387a4ef972)
+(cherry picked from commit 9b6b9398c90dd76ce0b935d21c4ecb8954c4b2b7)
+---
+ grub-core/net/http.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/grub-core/net/http.c b/grub-core/net/http.c
+index 7fa2dcaea7..745f429b51 100644
+--- a/grub-core/net/http.c
++++ b/grub-core/net/http.c
+@@ -69,7 +69,15 @@ parse_line (grub_file_t file, http_data_t data, char *ptr, grub_size_t len)
+   char *end = ptr + len;
+   while (end > ptr && *(end - 1) == '\r')
+     end--;
++
++  /* LF without CR. */
++  if (end == ptr + len)
++    {
++      data->errmsg = grub_strdup (_("invalid HTTP header - LF without CR"));
++      return GRUB_ERR_NONE;
++    }
+   *end = 0;
++
+   /* Trailing CRLF.  */
+   if (data->in_chunk_len == 1)
+     {
diff --git a/SOURCES/0534-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch b/SOURCES/0534-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch
deleted file mode 100644
index 8bc2666..0000000
--- a/SOURCES/0534-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Kiper <daniel.kiper@oracle.com>
-Date: Thu, 3 Dec 2020 16:01:47 +0100
-Subject: [PATCH] efi: Add a function to read EFI variables with attributes
-
-It will be used to properly detect and report UEFI Secure Boot status to
-the x86 Linux kernel. The functionality will be added by subsequent patches.
-
-Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
-Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
-Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
-Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-(cherry picked from commit ac5c9367548750e75ed1e7fc4354a3d20186d733)
-(cherry picked from commit 51b11f8b3ab96c38efb1636d9c53b5a86503f1f2)
----
- grub-core/kern/efi/efi.c | 16 +++++++++++++---
- include/grub/efi/efi.h   |  5 +++++
- 2 files changed, 18 insertions(+), 3 deletions(-)
-
-diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
-index 335033975d..fccea20a01 100644
---- a/grub-core/kern/efi/efi.c
-+++ b/grub-core/kern/efi/efi.c
-@@ -242,8 +242,11 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid,
- }
- 
- grub_efi_status_t
--grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
--		       grub_size_t *datasize_out, void **data_out)
-+grub_efi_get_variable_with_attributes (const char *var,
-+				       const grub_efi_guid_t *guid,
-+				       grub_size_t *datasize_out,
-+				       void **data_out,
-+				       grub_efi_uint32_t *attributes)
- {
-   grub_efi_status_t status;
-   grub_efi_uintn_t datasize = 0;
-@@ -280,7 +283,7 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
-       return GRUB_EFI_OUT_OF_RESOURCES;
-     }
- 
--  status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, data);
-+  status = efi_call_5 (r->get_variable, var16, guid, attributes, &datasize, data);
-   grub_free (var16);
- 
-   if (status == GRUB_EFI_SUCCESS)
-@@ -294,6 +297,13 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
-   return status;
- }
- 
-+grub_efi_status_t
-+grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
-+		       grub_size_t *datasize_out, void **data_out)
-+{
-+  return grub_efi_get_variable_with_attributes (var, guid, datasize_out, data_out, NULL);
-+}
-+
- #pragma GCC diagnostic ignored "-Wcast-align"
- 
- /* Search the mods section from the PE32/PE32+ image. This code uses
-diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
-index 90a85d7d9a..7af979b184 100644
---- a/include/grub/efi/efi.h
-+++ b/include/grub/efi/efi.h
-@@ -113,6 +113,11 @@ grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) (grub_efi_uintn_t memo
- 							   grub_efi_uintn_t descriptor_size,
- 							   grub_efi_uint32_t descriptor_version,
- 							   grub_efi_memory_descriptor_t *virtual_map);
-+grub_efi_status_t EXPORT_FUNC (grub_efi_get_variable_with_attributes) (const char *variable,
-+								       const grub_efi_guid_t *guid,
-+								       grub_size_t *datasize_out,
-+								       void **data_out,
-+								       grub_efi_uint32_t *attributes);
- grub_efi_status_t EXPORT_FUNC (grub_efi_get_variable) (const char *variable,
- 						       const grub_efi_guid_t *guid,
- 						       grub_size_t *datasize_out,
diff --git a/SOURCES/0534-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch b/SOURCES/0534-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch
new file mode 100644
index 0000000..684fc75
--- /dev/null
+++ b/SOURCES/0534-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch
@@ -0,0 +1,74 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
+Date: Wed, 6 Apr 2022 18:03:37 +0530
+Subject: [PATCH] fs/f2fs: Do not read past the end of nat journal entries
+
+A corrupt f2fs file system could specify a nat journal entry count
+that is beyond the maximum NAT_JOURNAL_ENTRIES.
+
+Check if the specified nat journal entry count before accessing the
+array, and throw an error if it is too large.
+
+Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit a3988cb3f0a108dd67ac127a79a4c8479d23334e)
+(cherry picked from commit 7125978aa7d6068812ef6da0ab38ce521ae7eba1)
+(cherry picked from commit e488538cbf9fc63796c7047550b0598e1ef95c03)
+---
+ grub-core/fs/f2fs.c | 21 ++++++++++++++-------
+ 1 file changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/grub-core/fs/f2fs.c b/grub-core/fs/f2fs.c
+index 1cad2615f3..09dc932420 100644
+--- a/grub-core/fs/f2fs.c
++++ b/grub-core/fs/f2fs.c
+@@ -632,23 +632,27 @@ get_nat_journal (struct grub_f2fs_data *data)
+   return err;
+ }
+ 
+-static grub_uint32_t
+-get_blkaddr_from_nat_journal (struct grub_f2fs_data *data, grub_uint32_t nid)
++static grub_err_t
++get_blkaddr_from_nat_journal (struct grub_f2fs_data *data, grub_uint32_t nid,
++                              grub_uint32_t *blkaddr)
+ {
+   grub_uint16_t n = grub_le_to_cpu16 (data->nat_j.n_nats);
+-  grub_uint32_t blkaddr = 0;
+   grub_uint16_t i;
+ 
++  if (n >= NAT_JOURNAL_ENTRIES)
++    return grub_error (GRUB_ERR_BAD_FS,
++                       "invalid number of nat journal entries");
++
+   for (i = 0; i < n; i++)
+     {
+       if (grub_le_to_cpu32 (data->nat_j.entries[i].nid) == nid)
+         {
+-          blkaddr = grub_le_to_cpu32 (data->nat_j.entries[i].ne.block_addr);
++          *blkaddr = grub_le_to_cpu32 (data->nat_j.entries[i].ne.block_addr);
+           break;
+         }
+     }
+ 
+-  return blkaddr;
++  return GRUB_ERR_NONE;
+ }
+ 
+ static grub_uint32_t
+@@ -656,10 +660,13 @@ get_node_blkaddr (struct grub_f2fs_data *data, grub_uint32_t nid)
+ {
+   struct grub_f2fs_nat_block *nat_block;
+   grub_uint32_t seg_off, block_off, entry_off, block_addr;
+-  grub_uint32_t blkaddr;
++  grub_uint32_t blkaddr = 0;
+   grub_err_t err;
+ 
+-  blkaddr = get_blkaddr_from_nat_journal (data, nid);
++  err = get_blkaddr_from_nat_journal (data, nid, &blkaddr);
++  if (err != GRUB_ERR_NONE)
++    return 0;
++
+   if (blkaddr)
+     return blkaddr;
+ 
diff --git a/SOURCES/0535-Define-GRUB_EFI_SHIM_LOCK_GUID.patch b/SOURCES/0535-Define-GRUB_EFI_SHIM_LOCK_GUID.patch
deleted file mode 100644
index 6b00c5c..0000000
--- a/SOURCES/0535-Define-GRUB_EFI_SHIM_LOCK_GUID.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Robbie Harwood <rharwood@redhat.com>
-Date: Wed, 11 May 2022 16:20:52 -0400
-Subject: [PATCH] Define GRUB_EFI_SHIM_LOCK_GUID
-
-Added in f76a27996c34900f2c369a8a0d6ac72ae2faa988 ("efi: Make shim_lock
-GUID and protocol type public"), but that commit also manipulates the
-lock protocol definition and some other guids we don't care about right
-now.
-
-Signed-off-by: Robbie Harwood <rharwood@redhat.com>
-(cherry picked from commit e44d6f8e801fae4716dd2528d7194f759c52aa12)
----
- include/grub/efi/api.h | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
-index 37e7b16287..2a243fd290 100644
---- a/include/grub/efi/api.h
-+++ b/include/grub/efi/api.h
-@@ -349,6 +349,11 @@
-     { 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 } \
-   }
- 
-+#define GRUB_EFI_SHIM_LOCK_GUID \
-+  { 0x605dab50, 0xe046, 0x4300, \
-+    { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } \
-+   }
-+
- struct grub_efi_sal_system_table
- {
-   grub_uint32_t signature;
diff --git a/SOURCES/0535-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch b/SOURCES/0535-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch
new file mode 100644
index 0000000..30ea7c6
--- /dev/null
+++ b/SOURCES/0535-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch
@@ -0,0 +1,134 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
+Date: Wed, 6 Apr 2022 18:49:09 +0530
+Subject: [PATCH] fs/f2fs: Do not read past the end of nat bitmap
+
+A corrupt f2fs filesystem could have a block offset or a bitmap
+offset that would cause us to read beyond the bounds of the nat
+bitmap.
+
+Introduce the nat_bitmap_size member in grub_f2fs_data which holds
+the size of nat bitmap.
+
+Set the size when loading the nat bitmap in nat_bitmap_ptr(), and
+catch when an invalid offset would create a pointer past the end of
+the allocated space.
+
+Check against the bitmap size in grub_f2fs_test_bit() test bit to avoid
+reading past the end of the nat bitmap.
+
+Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit 62d63d5e38c67a6e349148bf7cb87c560e935a7e)
+(cherry picked from commit 92219e6d379b5b4d30b05361830b72ab1d95d281)
+(cherry picked from commit c23d97e3b56594bf0f802d94062e14b221143115)
+---
+ grub-core/fs/f2fs.c | 33 +++++++++++++++++++++++++++------
+ 1 file changed, 27 insertions(+), 6 deletions(-)
+
+diff --git a/grub-core/fs/f2fs.c b/grub-core/fs/f2fs.c
+index 09dc932420..33e565b180 100644
+--- a/grub-core/fs/f2fs.c
++++ b/grub-core/fs/f2fs.c
+@@ -122,6 +122,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
+ #define F2FS_INLINE_DOTS          0x10  /* File having implicit dot dentries. */
+ 
+ #define MAX_VOLUME_NAME           512
++#define MAX_NAT_BITMAP_SIZE       3900
+ 
+ enum FILE_TYPE
+ {
+@@ -183,7 +184,7 @@ struct grub_f2fs_checkpoint
+   grub_uint32_t                   checksum_offset;
+   grub_uint64_t                   elapsed_time;
+   grub_uint8_t                    alloc_type[MAX_ACTIVE_LOGS];
+-  grub_uint8_t                    sit_nat_version_bitmap[3900];
++  grub_uint8_t                    sit_nat_version_bitmap[MAX_NAT_BITMAP_SIZE];
+   grub_uint32_t                   checksum;
+ } GRUB_PACKED;
+ 
+@@ -302,6 +303,7 @@ struct grub_f2fs_data
+ 
+   struct grub_f2fs_nat_journal    nat_j;
+   char                            *nat_bitmap;
++  grub_uint32_t                   nat_bitmap_size;
+ 
+   grub_disk_t                     disk;
+   struct grub_f2fs_node           *inode;
+@@ -377,15 +379,20 @@ sum_blk_addr (struct grub_f2fs_data *data, int base, int type)
+ }
+ 
+ static void *
+-nat_bitmap_ptr (struct grub_f2fs_data *data)
++nat_bitmap_ptr (struct grub_f2fs_data *data, grub_uint32_t *nat_bitmap_size)
+ {
+   struct grub_f2fs_checkpoint *ckpt = &data->ckpt;
+   grub_uint32_t offset;
++  *nat_bitmap_size = MAX_NAT_BITMAP_SIZE;
+ 
+   if (grub_le_to_cpu32 (data->sblock.cp_payload) > 0)
+     return ckpt->sit_nat_version_bitmap;
+ 
+   offset = grub_le_to_cpu32 (ckpt->sit_ver_bitmap_bytesize);
++  if (offset >= MAX_NAT_BITMAP_SIZE)
++     return NULL;
++
++  *nat_bitmap_size = *nat_bitmap_size - offset;
+ 
+   return ckpt->sit_nat_version_bitmap + offset;
+ }
+@@ -438,11 +445,15 @@ grub_f2fs_crc_valid (grub_uint32_t blk_crc, void *buf, const grub_uint32_t len)
+ }
+ 
+ static int
+-grub_f2fs_test_bit (grub_uint32_t nr, const char *p)
++grub_f2fs_test_bit (grub_uint32_t nr, const char *p, grub_uint32_t len)
+ {
+   int mask;
++  grub_uint32_t shifted_nr = (nr >> 3);
+ 
+-  p += (nr >> 3);
++  if (shifted_nr >= len)
++    return -1;
++
++  p += shifted_nr;
+   mask = 1 << (7 - (nr & 0x07));
+ 
+   return mask & *p;
+@@ -662,6 +673,7 @@ get_node_blkaddr (struct grub_f2fs_data *data, grub_uint32_t nid)
+   grub_uint32_t seg_off, block_off, entry_off, block_addr;
+   grub_uint32_t blkaddr = 0;
+   grub_err_t err;
++  int result_bit;
+ 
+   err = get_blkaddr_from_nat_journal (data, nid, &blkaddr);
+   if (err != GRUB_ERR_NONE)
+@@ -682,8 +694,15 @@ get_node_blkaddr (struct grub_f2fs_data *data, grub_uint32_t nid)
+         ((seg_off * data->blocks_per_seg) << 1) +
+         (block_off & (data->blocks_per_seg - 1));
+ 
+-  if (grub_f2fs_test_bit (block_off, data->nat_bitmap))
++  result_bit = grub_f2fs_test_bit (block_off, data->nat_bitmap,
++                                   data->nat_bitmap_size);
++  if (result_bit > 0)
+     block_addr += data->blocks_per_seg;
++  else if (result_bit == -1)
++    {
++      grub_free (nat_block);
++      return 0;
++    }
+ 
+   err = grub_f2fs_block_read (data, block_addr, nat_block);
+   if (err)
+@@ -832,7 +851,9 @@ grub_f2fs_mount (grub_disk_t disk)
+   if (err)
+     goto fail;
+ 
+-  data->nat_bitmap = nat_bitmap_ptr (data);
++  data->nat_bitmap = nat_bitmap_ptr (data, &data->nat_bitmap_size);
++  if (data->nat_bitmap == NULL)
++    goto fail;
+ 
+   err = get_nat_journal (data);
+   if (err)
diff --git a/SOURCES/0536-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch b/SOURCES/0536-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch
new file mode 100644
index 0000000..5ab2414
--- /dev/null
+++ b/SOURCES/0536-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch
@@ -0,0 +1,40 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
+Date: Wed, 6 Apr 2022 18:17:43 +0530
+Subject: [PATCH] fs/f2fs: Do not copy file names that are too long
+
+A corrupt f2fs file system might specify a name length which is greater
+than the maximum name length supported by the GRUB f2fs driver.
+
+We will allocate enough memory to store the overly long name, but there
+are only F2FS_NAME_LEN bytes in the source, so we would read past the end
+of the source.
+
+While checking directory entries, do not copy a file name with an invalid
+length.
+
+Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit 9a891f638509e031d322c94e3cbcf38d36f3993a)
+(cherry picked from commit 13f9160ae0d2806baed459884999356817096cd7)
+(cherry picked from commit a48ba4d48b3c66431e6bbeb386078efc6602110c)
+---
+ grub-core/fs/f2fs.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/grub-core/fs/f2fs.c b/grub-core/fs/f2fs.c
+index 33e565b180..07ea34196c 100644
+--- a/grub-core/fs/f2fs.c
++++ b/grub-core/fs/f2fs.c
+@@ -998,6 +998,10 @@ grub_f2fs_check_dentries (struct grub_f2fs_dir_iter_ctx *ctx)
+ 
+       ftype = ctx->dentry[i].file_type;
+       name_len = grub_le_to_cpu16 (ctx->dentry[i].name_len);
++
++      if (name_len >= F2FS_NAME_LEN)
++        return 0;
++
+       filename = grub_malloc (name_len + 1);
+       if (!filename)
+         return 0;
diff --git a/SOURCES/0536-misc-Make-grub_min-and-grub_max-more-resilient.patch b/SOURCES/0536-misc-Make-grub_min-and-grub_max-more-resilient.patch
deleted file mode 100644
index 3cca336..0000000
--- a/SOURCES/0536-misc-Make-grub_min-and-grub_max-more-resilient.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Mon, 21 Mar 2022 16:06:10 -0400
-Subject: [PATCH] misc: Make grub_min() and grub_max() more resilient.
-
-grub_min(a,b) and grub_max(a,b) use a relatively naive implementation
-which leads to several problems:
-- they evaluate their parameters more than once
-- the naive way to address this, to declare temporary variables in a
-  statement-expression, isn't resilient against nested uses, because
-  MIN(a,MIN(b,c)) results in the temporary variables being declared in
-  two nested scopes, which may result in a build warning depending on
-  your build options.
-
-This patch changes our implementation to use a statement-expression
-inside a helper macro, and creates the symbols for the temporary
-variables with __COUNTER__ (A GNU C cpp extension) and token pasting to
-create uniquely named internal variables.
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
-(cherry picked from commit 2d6800450fa731d7b3ef9893986806e88e819eb6)
-(cherry picked from commit adaf6a5ae66fb8a23274e3030e9df2714d0fc396)
-(cherry picked from commit 5282d19d1942d9c3470337a84aa4a92562ba1575)
----
- grub-core/loader/multiboot_elfxx.c |  4 +---
- include/grub/misc.h                | 25 +++++++++++++++++++++++--
- 2 files changed, 24 insertions(+), 5 deletions(-)
-
-diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c
-index f2318e0d16..87f6e31aa6 100644
---- a/grub-core/loader/multiboot_elfxx.c
-+++ b/grub-core/loader/multiboot_elfxx.c
-@@ -35,9 +35,7 @@
- #endif
- 
- #include <grub/i386/relocator.h>
--
--#define CONCAT(a,b)	CONCAT_(a, b)
--#define CONCAT_(a,b)	a ## b
-+#include <grub/misc.h>
- 
- #pragma GCC diagnostic ignored "-Wcast-align"
- 
-diff --git a/include/grub/misc.h b/include/grub/misc.h
-index 6be6a88f65..7ef1a1a87e 100644
---- a/include/grub/misc.h
-+++ b/include/grub/misc.h
-@@ -35,6 +35,14 @@
- #define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0]))
- #define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; }
- 
-+#ifndef CONCAT_
-+#define CONCAT_(a, b) a ## b
-+#endif
-+
-+#ifndef CONCAT
-+#define CONCAT(a, b) CONCAT_(a, b)
-+#endif
-+
- #define grub_dprintf(condition, ...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, __VA_ARGS__)
- 
- void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n);
-@@ -524,7 +532,20 @@ void EXPORT_FUNC(grub_real_boot_time) (const char *file,
- #define grub_boot_time(...)
- #endif
- 
--#define grub_max(a, b) (((a) > (b)) ? (a) : (b))
--#define grub_min(a, b) (((a) < (b)) ? (a) : (b))
-+#define _grub_min(a, b, _a, _b)						      \
-+  ({ typeof (a) _a = (a);						      \
-+     typeof (b) _b = (b);						      \
-+     _a < _b ? _a : _b; })
-+#define grub_min(a, b) _grub_min(a, b,					      \
-+				 CONCAT(_a_,__COUNTER__),		      \
-+				 CONCAT(_b_,__COUNTER__))
-+
-+#define _grub_max(a, b, _a, _b)						      \
-+  ({ typeof (a) _a = (a);						      \
-+     typeof (b) _b = (b);						      \
-+     _a > _b ? _a : _b; })
-+#define grub_max(a, b) _grub_max(a, b,					      \
-+				 CONCAT(_a_,__COUNTER__),		      \
-+				 CONCAT(_b_,__COUNTER__))
- 
- #endif /* ! GRUB_MISC_HEADER */
diff --git a/SOURCES/0537-ReiserFS-switch-to-using-grub_min-grub_max.patch b/SOURCES/0537-ReiserFS-switch-to-using-grub_min-grub_max.patch
deleted file mode 100644
index c3baecf..0000000
--- a/SOURCES/0537-ReiserFS-switch-to-using-grub_min-grub_max.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Thu, 21 Apr 2022 16:31:17 -0400
-Subject: [PATCH] ReiserFS: switch to using grub_min()/grub_max()
-
-This is a minor cleanup patch to remove the bespoke MIN() and MAX()
-definitions from the reiserfs driver, and uses grub_min() / grub_max()
-instead.
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
-(cherry picked from commit 5fc601574fce99b32fe4dfb55bd8f3ab0175fd6a)
-(cherry picked from commit 31e581893c564582c729fd0c033d3ce021854be8)
-(cherry picked from commit 2c46aae48eabcf91d7ed34a7bed2b59aa80c2c03)
----
- grub-core/fs/reiserfs.c | 28 +++++++++-------------------
- 1 file changed, 9 insertions(+), 19 deletions(-)
-
-diff --git a/grub-core/fs/reiserfs.c b/grub-core/fs/reiserfs.c
-index 39736f63c6..9556c15ff0 100644
---- a/grub-core/fs/reiserfs.c
-+++ b/grub-core/fs/reiserfs.c
-@@ -42,16 +42,6 @@
- 
- GRUB_MOD_LICENSE ("GPLv3+");
- 
--#define MIN(a, b) \
--  ({ typeof (a) _a = (a); \
--     typeof (b) _b = (b); \
--     _a < _b ? _a : _b; })
--
--#define MAX(a, b) \
--  ({ typeof (a) _a = (a); \
--     typeof (b) _b = (b); \
--     _a > _b ? _a : _b; })
--
- #define REISERFS_SUPER_BLOCK_OFFSET 0x10000
- #define REISERFS_MAGIC_LEN 12
- #define REISERFS_MAGIC_STRING "ReIsEr"
-@@ -1076,7 +1066,7 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node,
-   grub_reiserfs_set_key_type (&key, GRUB_REISERFS_ANY, 2);
-   initial_position = off;
-   current_position = 0;
--  final_position = MIN (len + initial_position, node->size);
-+  final_position = grub_min (len + initial_position, node->size);
-   grub_dprintf ("reiserfs",
- 		"Reading from %lld to %lld (%lld instead of requested %ld)\n",
- 		(unsigned long long) initial_position,
-@@ -1115,8 +1105,8 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node,
-           grub_dprintf ("reiserfs_blocktype", "D: %u\n", (unsigned) block);
-           if (initial_position < current_position + item_size)
-             {
--              offset = MAX ((signed) (initial_position - current_position), 0);
--              length = (MIN (item_size, final_position - current_position)
-+              offset = grub_max ((signed) (initial_position - current_position), 0);
-+              length = (grub_min (item_size, final_position - current_position)
-                         - offset);
-               grub_dprintf ("reiserfs",
-                             "Reading direct block %u from %u to %u...\n",
-@@ -1161,9 +1151,9 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node,
-               grub_dprintf ("reiserfs_blocktype", "I: %u\n", (unsigned) block);
-               if (current_position + block_size >= initial_position)
-                 {
--                  offset = MAX ((signed) (initial_position - current_position),
--                                0);
--                  length = (MIN (block_size, final_position - current_position)
-+                  offset = grub_max ((signed) (initial_position - current_position),
-+				     0);
-+                  length = (grub_min (block_size, final_position - current_position)
-                             - offset);
-                   grub_dprintf ("reiserfs",
-                                 "Reading indirect block %u from %u to %u...\n",
-@@ -1205,7 +1195,7 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node,
-   switch (found.type)
-     {
-       case GRUB_REISERFS_DIRECT:
--        read_length = MIN (len, item_size - file->offset);
-+        read_length = grub_min (len, item_size - file->offset);
-         grub_disk_read (found.data->disk,
-                         (found.block_number * block_size) / GRUB_DISK_SECTOR_SIZE,
-                         grub_le_to_cpu16 (found.header.item_location) + file->offset,
-@@ -1224,12 +1214,12 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node,
-                         item_size, (char *) indirect_block_ptr);
-         if (grub_errno)
-           goto fail;
--        len = MIN (len, file->size - file->offset);
-+        len = grub_min (len, file->size - file->offset);
-         for (indirect_block = file->offset / block_size;
-              indirect_block < indirect_block_count && read_length < len;
-              indirect_block++)
-           {
--            read = MIN (block_size, len - read_length);
-+            read = grub_min (block_size, len - read_length);
-             grub_disk_read (found.data->disk,
-                             (grub_le_to_cpu32 (indirect_block_ptr[indirect_block]) * block_size) / GRUB_DISK_SECTOR_SIZE,
-                             file->offset % block_size, read,
diff --git a/SOURCES/0537-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch b/SOURCES/0537-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch
new file mode 100644
index 0000000..21e95cf
--- /dev/null
+++ b/SOURCES/0537-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch
@@ -0,0 +1,81 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Darren Kenny <darren.kenny@oracle.com>
+Date: Tue, 29 Mar 2022 10:49:56 +0000
+Subject: [PATCH] fs/btrfs: Fix several fuzz issues with invalid dir item
+ sizing
+
+According to the btrfs code in Linux, the structure of a directory item
+leaf should be of the form:
+
+  |struct btrfs_dir_item|name|data|
+
+in GRUB the name len and data len are in the grub_btrfs_dir_item
+structure's n and m fields respectively.
+
+The combined size of the structure, name and data should be less than
+the allocated memory, a difference to the Linux kernel's struct
+btrfs_dir_item is that the grub_btrfs_dir_item has an extra field for
+where the name is stored, so we adjust for that too.
+
+Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit 6d3f06c0b6a8992b9b1bb0e62af93ac5ff2781f0)
+[rharwood: we've an extra variable here]
+Signed-off-by: Robbie Harwood <rharwood@redhat.com>
+(cherry picked from commit e3e21b9a81aea09dd43368cf097c1029a8380d82)
+(cherry picked from commit ab14a39777edb60c99751d4fdf1cc254a4faebf5)
+---
+ grub-core/fs/btrfs.c | 26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
+index 3faf9056c7..9da2952f70 100644
+--- a/grub-core/fs/btrfs.c
++++ b/grub-core/fs/btrfs.c
+@@ -1834,6 +1834,7 @@ grub_btrfs_dir (grub_device_t device, const char *path,
+   grub_uint64_t tree;
+   grub_uint8_t type;
+   char *new_path = NULL;
++  grub_size_t est_size = 0;
+ 
+   if (!data)
+     return grub_errno;
+@@ -1900,6 +1901,18 @@ grub_btrfs_dir (grub_device_t device, const char *path,
+ 	  break;
+ 	}
+ 
++      if (direl == NULL ||
++	  grub_add (grub_le_to_cpu16 (direl->n),
++		    grub_le_to_cpu16 (direl->m), &est_size) ||
++	  grub_add (est_size, sizeof (*direl), &est_size) ||
++	  grub_sub (est_size, sizeof (direl->name), &est_size) ||
++	  est_size > allocated)
++       {
++         grub_errno = GRUB_ERR_OUT_OF_RANGE;
++         r = -grub_errno;
++         goto out;
++       }
++
+       for (cdirel = direl;
+ 	   (grub_uint8_t *) cdirel - (grub_uint8_t *) direl
+ 	   < (grub_ssize_t) elemsize;
+@@ -1910,6 +1923,19 @@ grub_btrfs_dir (grub_device_t device, const char *path,
+ 	  char c;
+ 	  struct grub_btrfs_inode inode;
+ 	  struct grub_dirhook_info info;
++
++	  if (cdirel == NULL ||
++	      grub_add (grub_le_to_cpu16 (cdirel->n),
++			grub_le_to_cpu16 (cdirel->m), &est_size) ||
++	      grub_add (est_size, sizeof (*cdirel), &est_size) ||
++	      grub_sub (est_size, sizeof (cdirel->name), &est_size) ||
++	      est_size > allocated)
++	   {
++	     grub_errno = GRUB_ERR_OUT_OF_RANGE;
++	     r = -grub_errno;
++	     goto out;
++	   }
++
+ 	  err = grub_btrfs_read_inode (data, &inode, cdirel->key.object_id,
+ 				       tree);
+ 	  grub_memset (&info, 0, sizeof (info));
diff --git a/SOURCES/0538-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch b/SOURCES/0538-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch
new file mode 100644
index 0000000..184165b
--- /dev/null
+++ b/SOURCES/0538-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch
@@ -0,0 +1,143 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Kiper <daniel.kiper@oracle.com>
+Date: Thu, 3 Dec 2020 16:01:46 +0100
+Subject: [PATCH] efi: Return grub_efi_status_t from grub_efi_get_variable()
+
+This is needed to properly detect and report UEFI Secure Boot status
+to the x86 Linux kernel. The functionality will be added by subsequent
+patches.
+
+Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
+Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
+Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit 04ae030d0eea8668d4417702d88bf2cf04713d80)
+---
+ grub-core/commands/efi/efifwsetup.c |  8 ++++----
+ grub-core/kern/efi/efi.c            | 16 +++++++++-------
+ grub-core/video/efi_gop.c           |  2 +-
+ include/grub/efi/efi.h              |  7 ++++---
+ 4 files changed, 18 insertions(+), 15 deletions(-)
+
+diff --git a/grub-core/commands/efi/efifwsetup.c b/grub-core/commands/efi/efifwsetup.c
+index 7a137a72a2..eaca032838 100644
+--- a/grub-core/commands/efi/efifwsetup.c
++++ b/grub-core/commands/efi/efifwsetup.c
+@@ -38,8 +38,8 @@ grub_cmd_fwsetup (grub_command_t cmd __attribute__ ((unused)),
+   grub_size_t oi_size;
+   grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID;
+ 
+-  old_os_indications = grub_efi_get_variable ("OsIndications", &global,
+-					      &oi_size);
++  grub_efi_get_variable ("OsIndications", &global, &oi_size,
++			 (void **) &old_os_indications);
+ 
+   if (old_os_indications != NULL && oi_size == sizeof (os_indications))
+     os_indications |= *old_os_indications;
+@@ -63,8 +63,8 @@ efifwsetup_is_supported (void)
+   grub_size_t oi_size = 0;
+   grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID;
+ 
+-  os_indications_supported = grub_efi_get_variable ("OsIndicationsSupported",
+-						    &global, &oi_size);
++  grub_efi_get_variable ("OsIndicationsSupported", &global, &oi_size,
++			 (void **) &os_indications_supported);
+ 
+   if (!os_indications_supported)
+     return 0;
+diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
+index 2863956458..335033975d 100644
+--- a/grub-core/kern/efi/efi.c
++++ b/grub-core/kern/efi/efi.c
+@@ -241,9 +241,9 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid,
+   return grub_error (GRUB_ERR_IO, "could not set EFI variable `%s'", var);
+ }
+ 
+-void *
++grub_efi_status_t
+ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
+-		       grub_size_t *datasize_out)
++		       grub_size_t *datasize_out, void **data_out)
+ {
+   grub_efi_status_t status;
+   grub_efi_uintn_t datasize = 0;
+@@ -252,13 +252,14 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
+   void *data;
+   grub_size_t len, len16;
+ 
++  *data_out = NULL;
+   *datasize_out = 0;
+ 
+   len = grub_strlen (var);
+   len16 = len * GRUB_MAX_UTF16_PER_UTF8;
+   var16 = grub_calloc (len16 + 1, sizeof (var16[0]));
+   if (!var16)
+-    return NULL;
++    return GRUB_EFI_OUT_OF_RESOURCES;
+   len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL);
+   var16[len16] = 0;
+ 
+@@ -269,14 +270,14 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
+   if (status != GRUB_EFI_BUFFER_TOO_SMALL || !datasize)
+     {
+       grub_free (var16);
+-      return NULL;
++      return status;
+     }
+ 
+   data = grub_malloc (datasize);
+   if (!data)
+     {
+       grub_free (var16);
+-      return NULL;
++      return GRUB_EFI_OUT_OF_RESOURCES;
+     }
+ 
+   status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, data);
+@@ -284,12 +285,13 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
+ 
+   if (status == GRUB_EFI_SUCCESS)
+     {
++      *data_out = data;
+       *datasize_out = datasize;
+-      return data;
++      return status;
+     }
+ 
+   grub_free (data);
+-  return NULL;
++  return status;
+ }
+ 
+ #pragma GCC diagnostic ignored "-Wcast-align"
+diff --git a/grub-core/video/efi_gop.c b/grub-core/video/efi_gop.c
+index 9fcc41ac03..ec217db70f 100644
+--- a/grub-core/video/efi_gop.c
++++ b/grub-core/video/efi_gop.c
+@@ -302,7 +302,7 @@ grub_video_gop_get_edid (struct grub_video_edid_info *edid_info)
+       char edidname[] = "agp-internal-edid";
+       grub_size_t datasize;
+       grub_uint8_t *data;
+-      data = grub_efi_get_variable (edidname, &efi_var_guid, &datasize);
++      grub_efi_get_variable (edidname, &efi_var_guid, &datasize, (void **) &data);
+       if (data && datasize > 16)
+ 	{
+ 	  copy_size = datasize - 16;
+diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
+index 4411ffa16b..90a85d7d9a 100644
+--- a/include/grub/efi/efi.h
++++ b/include/grub/efi/efi.h
+@@ -113,9 +113,10 @@ grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) (grub_efi_uintn_t memo
+ 							   grub_efi_uintn_t descriptor_size,
+ 							   grub_efi_uint32_t descriptor_version,
+ 							   grub_efi_memory_descriptor_t *virtual_map);
+-void *EXPORT_FUNC (grub_efi_get_variable) (const char *variable,
+-					   const grub_efi_guid_t *guid,
+-					   grub_size_t *datasize_out);
++grub_efi_status_t EXPORT_FUNC (grub_efi_get_variable) (const char *variable,
++						       const grub_efi_guid_t *guid,
++						       grub_size_t *datasize_out,
++						       void **data_out);
+ grub_err_t
+ EXPORT_FUNC (grub_efi_set_variable) (const char *var,
+ 				     const grub_efi_guid_t *guid,
diff --git a/SOURCES/0538-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch b/SOURCES/0538-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch
deleted file mode 100644
index 9455dd1..0000000
--- a/SOURCES/0538-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Thu, 24 Mar 2022 14:40:01 -0400
-Subject: [PATCH] misc: make grub_boot_time() also call
- grub_dprintf("boot",...)
-
-Currently grub_boot_time() includes valuable debugging messages, but if
-you build without BOOT_TIME_STATS enabled, they are silently and
-confusingly compiled away.
-
-This patch changes grub_boot_time() to also log when "boot" is enabled
-in DEBUG, regardless of BOOT_TIME_STATS.
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
-(cherry picked from commit 4fd282de00df05ce289467861deb7a0e186cfbd7)
-(cherry picked from commit cc7e60a9f3ad1fa74b9cd48a7e66b1976f9a554a)
-(cherry picked from commit 9e78e5749d5c99a01c96c9c0d9ec3e98633a4cbd)
----
- grub-core/kern/misc.c | 3 ++-
- include/grub/misc.h   | 2 +-
- 2 files changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
-index 859d71659a..b375e486a4 100644
---- a/grub-core/kern/misc.c
-+++ b/grub-core/kern/misc.c
-@@ -1336,7 +1336,8 @@ grub_real_boot_time (const char *file,
-   n->next = 0;
- 
-   va_start (args, fmt);
--  n->msg = grub_xvasprintf (fmt, args);    
-+  n->msg = grub_xvasprintf (fmt, args);
-+  grub_dprintf ("boot", "%s\n", n->msg);
-   va_end (args);
- 
-   *boot_time_last = n;
-diff --git a/include/grub/misc.h b/include/grub/misc.h
-index 7ef1a1a87e..1b722c8185 100644
---- a/include/grub/misc.h
-+++ b/include/grub/misc.h
-@@ -529,7 +529,7 @@ void EXPORT_FUNC(grub_real_boot_time) (const char *file,
- 				       const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 3, 4)));
- #define grub_boot_time(...) grub_real_boot_time(GRUB_FILE, __LINE__, __VA_ARGS__)
- #else
--#define grub_boot_time(...)
-+#define grub_boot_time(fmt, ...) grub_dprintf("boot", fmt "\n", ##__VA_ARGS__)
- #endif
- 
- #define _grub_min(a, b, _a, _b)						      \
diff --git a/SOURCES/0539-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch b/SOURCES/0539-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch
new file mode 100644
index 0000000..526a123
--- /dev/null
+++ b/SOURCES/0539-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch
@@ -0,0 +1,76 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Kiper <daniel.kiper@oracle.com>
+Date: Thu, 3 Dec 2020 16:01:47 +0100
+Subject: [PATCH] efi: Add a function to read EFI variables with attributes
+
+It will be used to properly detect and report UEFI Secure Boot status to
+the x86 Linux kernel. The functionality will be added by subsequent patches.
+
+Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
+Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
+Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
+Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+(cherry picked from commit ac5c9367548750e75ed1e7fc4354a3d20186d733)
+---
+ grub-core/kern/efi/efi.c | 16 +++++++++++++---
+ include/grub/efi/efi.h   |  5 +++++
+ 2 files changed, 18 insertions(+), 3 deletions(-)
+
+diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
+index 335033975d..fccea20a01 100644
+--- a/grub-core/kern/efi/efi.c
++++ b/grub-core/kern/efi/efi.c
+@@ -242,8 +242,11 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid,
+ }
+ 
+ grub_efi_status_t
+-grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
+-		       grub_size_t *datasize_out, void **data_out)
++grub_efi_get_variable_with_attributes (const char *var,
++				       const grub_efi_guid_t *guid,
++				       grub_size_t *datasize_out,
++				       void **data_out,
++				       grub_efi_uint32_t *attributes)
+ {
+   grub_efi_status_t status;
+   grub_efi_uintn_t datasize = 0;
+@@ -280,7 +283,7 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
+       return GRUB_EFI_OUT_OF_RESOURCES;
+     }
+ 
+-  status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, data);
++  status = efi_call_5 (r->get_variable, var16, guid, attributes, &datasize, data);
+   grub_free (var16);
+ 
+   if (status == GRUB_EFI_SUCCESS)
+@@ -294,6 +297,13 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
+   return status;
+ }
+ 
++grub_efi_status_t
++grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
++		       grub_size_t *datasize_out, void **data_out)
++{
++  return grub_efi_get_variable_with_attributes (var, guid, datasize_out, data_out, NULL);
++}
++
+ #pragma GCC diagnostic ignored "-Wcast-align"
+ 
+ /* Search the mods section from the PE32/PE32+ image. This code uses
+diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
+index 90a85d7d9a..7af979b184 100644
+--- a/include/grub/efi/efi.h
++++ b/include/grub/efi/efi.h
+@@ -113,6 +113,11 @@ grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) (grub_efi_uintn_t memo
+ 							   grub_efi_uintn_t descriptor_size,
+ 							   grub_efi_uint32_t descriptor_version,
+ 							   grub_efi_memory_descriptor_t *virtual_map);
++grub_efi_status_t EXPORT_FUNC (grub_efi_get_variable_with_attributes) (const char *variable,
++								       const grub_efi_guid_t *guid,
++								       grub_size_t *datasize_out,
++								       void **data_out,
++								       grub_efi_uint32_t *attributes);
+ grub_efi_status_t EXPORT_FUNC (grub_efi_get_variable) (const char *variable,
+ 						       const grub_efi_guid_t *guid,
+ 						       grub_size_t *datasize_out,
diff --git a/SOURCES/0539-modules-make-.module_license-read-only.patch b/SOURCES/0539-modules-make-.module_license-read-only.patch
deleted file mode 100644
index 94dc892..0000000
--- a/SOURCES/0539-modules-make-.module_license-read-only.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Thu, 24 Feb 2022 16:32:51 -0500
-Subject: [PATCH] modules: make .module_license read-only
-
-Currently .module_license is set writable (that is, the section has the
-SHF_WRITE flag set) in the module's ELF headers.  This probably never
-actually matters, but it can't possibly be correct.
-
-This patch sets that data as "const", which causes that flag not to be
-set.
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
-(cherry picked from commit 2eff3e2c9d9e6b75daa81b840c96f112ef7d5de6)
-(cherry picked from commit 3c3c1858d1c056eee660d67888be80e7eae498ca)
-(cherry picked from commit ebcce09e35ef6916a2d1ddbf0906e9f3f5c539ad)
----
- include/grub/dl.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/include/grub/dl.h b/include/grub/dl.h
-index 6a3e251b45..9ec6caf3f9 100644
---- a/include/grub/dl.h
-+++ b/include/grub/dl.h
-@@ -121,7 +121,7 @@ grub_mod_fini (void)
- #define ATTRIBUTE_USED __unused__
- #endif
- #define GRUB_MOD_LICENSE(license)	\
--  static char grub_module_license[] __attribute__ ((section (GRUB_MOD_SECTION (module_license)), ATTRIBUTE_USED)) = "LICENSE=" license;
-+  static const char grub_module_license[] __attribute__ ((section (GRUB_MOD_SECTION (module_license)), ATTRIBUTE_USED)) = "LICENSE=" license;
- #define GRUB_MOD_DEP(name)	\
- static const char grub_module_depend_##name[] \
-  __attribute__((section(GRUB_MOD_SECTION(moddeps)), ATTRIBUTE_USED)) = #name
diff --git a/SOURCES/0540-Define-GRUB_EFI_SHIM_LOCK_GUID.patch b/SOURCES/0540-Define-GRUB_EFI_SHIM_LOCK_GUID.patch
new file mode 100644
index 0000000..354ec29
--- /dev/null
+++ b/SOURCES/0540-Define-GRUB_EFI_SHIM_LOCK_GUID.patch
@@ -0,0 +1,31 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Wed, 11 May 2022 16:20:52 -0400
+Subject: [PATCH] Define GRUB_EFI_SHIM_LOCK_GUID
+
+Added in f76a27996c34900f2c369a8a0d6ac72ae2faa988 ("efi: Make shim_lock
+GUID and protocol type public"), but that commit also manipulates the
+lock protocol definition and some other guids we don't care about right
+now.
+
+Signed-off-by: Robbie Harwood <rharwood@redhat.com>
+---
+ include/grub/efi/api.h | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
+index 37e7b16287..2a243fd290 100644
+--- a/include/grub/efi/api.h
++++ b/include/grub/efi/api.h
+@@ -349,6 +349,11 @@
+     { 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 } \
+   }
+ 
++#define GRUB_EFI_SHIM_LOCK_GUID \
++  { 0x605dab50, 0xe046, 0x4300, \
++    { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } \
++   }
++
+ struct grub_efi_sal_system_table
+ {
+   grub_uint32_t signature;
diff --git a/SOURCES/0540-modules-strip-.llvm_addrsig-sections-and-similar.patch b/SOURCES/0540-modules-strip-.llvm_addrsig-sections-and-similar.patch
deleted file mode 100644
index 51aba29..0000000
--- a/SOURCES/0540-modules-strip-.llvm_addrsig-sections-and-similar.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Thu, 24 Feb 2022 16:40:11 -0500
-Subject: [PATCH] modules: strip .llvm_addrsig sections and similar.
-
-Currently grub modules built with clang or gcc have several sections
-which we don't actually need or support.
-
-We already have a list of section to skip in genmod.sh, and this patch
-adds the following sections to that list (as well as a few newlines):
-
-.note.gnu.property
-.llvm*
-
-Note that the glob there won't work without a new enough linker, but the
-failure is just reversion to the status quo, so that's not a big problem.
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
-(cherry picked from commit e85d1c4d795f8135ad0acfa36d64760d12d6fed1)
-(cherry picked from commit d3024204b2e2c69ecb91392eeb87c1e6835c3743)
-(cherry picked from commit f729241a34394b1019d83d75ffe6bfe0986ab274)
----
- grub-core/genmod.sh.in | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/grub-core/genmod.sh.in b/grub-core/genmod.sh.in
-index 1250589b3f..c2c5280d75 100644
---- a/grub-core/genmod.sh.in
-+++ b/grub-core/genmod.sh.in
-@@ -57,8 +57,11 @@ if test x@TARGET_APPLE_LINKER@ != x1; then
- 	    @TARGET_STRIP@ --strip-unneeded \
- 		-K grub_mod_init -K grub_mod_fini \
- 		-K _grub_mod_init -K _grub_mod_fini \
--		-R .note.gnu.gold-version -R .note.GNU-stack \
-+		-R .note.GNU-stack \
-+		-R .note.gnu.gold-version \
-+		-R .note.gnu.property \
- 		-R .gnu.build.attributes \
-+		-R '.llvm*' \
- 		-R .rel.gnu.build.attributes \
- 		-R .rela.gnu.build.attributes \
- 		-R .eh_frame -R .rela.eh_frame -R .rel.eh_frame \
diff --git a/SOURCES/0541-misc-Make-grub_min-and-grub_max-more-resilient.patch b/SOURCES/0541-misc-Make-grub_min-and-grub_max-more-resilient.patch
new file mode 100644
index 0000000..bf1741b
--- /dev/null
+++ b/SOURCES/0541-misc-Make-grub_min-and-grub_max-more-resilient.patch
@@ -0,0 +1,84 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Mon, 21 Mar 2022 16:06:10 -0400
+Subject: [PATCH] misc: Make grub_min() and grub_max() more resilient.
+
+grub_min(a,b) and grub_max(a,b) use a relatively naive implementation
+which leads to several problems:
+- they evaluate their parameters more than once
+- the naive way to address this, to declare temporary variables in a
+  statement-expression, isn't resilient against nested uses, because
+  MIN(a,MIN(b,c)) results in the temporary variables being declared in
+  two nested scopes, which may result in a build warning depending on
+  your build options.
+
+This patch changes our implementation to use a statement-expression
+inside a helper macro, and creates the symbols for the temporary
+variables with __COUNTER__ (A GNU C cpp extension) and token pasting to
+create uniquely named internal variables.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+(cherry picked from commit 2d6800450fa731d7b3ef9893986806e88e819eb6)
+(cherry picked from commit adaf6a5ae66fb8a23274e3030e9df2714d0fc396)
+---
+ grub-core/loader/multiboot_elfxx.c |  4 +---
+ include/grub/misc.h                | 25 +++++++++++++++++++++++--
+ 2 files changed, 24 insertions(+), 5 deletions(-)
+
+diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c
+index f2318e0d16..87f6e31aa6 100644
+--- a/grub-core/loader/multiboot_elfxx.c
++++ b/grub-core/loader/multiboot_elfxx.c
+@@ -35,9 +35,7 @@
+ #endif
+ 
+ #include <grub/i386/relocator.h>
+-
+-#define CONCAT(a,b)	CONCAT_(a, b)
+-#define CONCAT_(a,b)	a ## b
++#include <grub/misc.h>
+ 
+ #pragma GCC diagnostic ignored "-Wcast-align"
+ 
+diff --git a/include/grub/misc.h b/include/grub/misc.h
+index 6be6a88f65..7ef1a1a87e 100644
+--- a/include/grub/misc.h
++++ b/include/grub/misc.h
+@@ -35,6 +35,14 @@
+ #define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0]))
+ #define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; }
+ 
++#ifndef CONCAT_
++#define CONCAT_(a, b) a ## b
++#endif
++
++#ifndef CONCAT
++#define CONCAT(a, b) CONCAT_(a, b)
++#endif
++
+ #define grub_dprintf(condition, ...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, __VA_ARGS__)
+ 
+ void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n);
+@@ -524,7 +532,20 @@ void EXPORT_FUNC(grub_real_boot_time) (const char *file,
+ #define grub_boot_time(...)
+ #endif
+ 
+-#define grub_max(a, b) (((a) > (b)) ? (a) : (b))
+-#define grub_min(a, b) (((a) < (b)) ? (a) : (b))
++#define _grub_min(a, b, _a, _b)						      \
++  ({ typeof (a) _a = (a);						      \
++     typeof (b) _b = (b);						      \
++     _a < _b ? _a : _b; })
++#define grub_min(a, b) _grub_min(a, b,					      \
++				 CONCAT(_a_,__COUNTER__),		      \
++				 CONCAT(_b_,__COUNTER__))
++
++#define _grub_max(a, b, _a, _b)						      \
++  ({ typeof (a) _a = (a);						      \
++     typeof (b) _b = (b);						      \
++     _a > _b ? _a : _b; })
++#define grub_max(a, b) _grub_max(a, b,					      \
++				 CONCAT(_a_,__COUNTER__),		      \
++				 CONCAT(_b_,__COUNTER__))
+ 
+ #endif /* ! GRUB_MISC_HEADER */
diff --git a/SOURCES/0541-modules-Don-t-allocate-space-for-non-allocable-secti.patch b/SOURCES/0541-modules-Don-t-allocate-space-for-non-allocable-secti.patch
deleted file mode 100644
index 12c1a59..0000000
--- a/SOURCES/0541-modules-Don-t-allocate-space-for-non-allocable-secti.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Mon, 21 Mar 2022 16:56:10 -0400
-Subject: [PATCH] modules: Don't allocate space for non-allocable sections.
-
-Currently when loading grub modules, we allocate space for all sections,
-including those without SHF_ALLOC set.  We then copy the sections that
-/do/ have SHF_ALLOC set into the allocated memory, leaving some of our
-allocation untouched forever.  Additionally, on platforms with GOT
-fixups and trampolines, we currently compute alignment round-ups for the
-sections and sections with sh_size = 0.
-
-This patch removes the extra space from the allocation computation, and
-makes the allocation computation loop skip empty sections as the loading
-loop does.
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
-(cherry picked from commit 03215e342f552396ab08125ea769b1e166417ec1)
-(cherry picked from commit 91518751b9bcba078e3f4385f4b2f6c39cab49cd)
-(cherry picked from commit ee945970425488bd5b72d837706764a6a0fde46c)
----
- grub-core/kern/dl.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
-index 520126beab..ba1b33c20b 100644
---- a/grub-core/kern/dl.c
-+++ b/grub-core/kern/dl.c
-@@ -290,6 +290,9 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
-        i < e->e_shnum;
-        i++, s = (const Elf_Shdr *)((const char *) s + e->e_shentsize))
-     {
-+      if (s->sh_size == 0 || !(s->sh_flags & SHF_ALLOC))
-+	continue;
-+
-       tsize = ALIGN_UP (tsize, s->sh_addralign) + s->sh_size;
-       if (talign < s->sh_addralign)
- 	talign = s->sh_addralign;
diff --git a/SOURCES/0542-ReiserFS-switch-to-using-grub_min-grub_max.patch b/SOURCES/0542-ReiserFS-switch-to-using-grub_min-grub_max.patch
new file mode 100644
index 0000000..e8688dc
--- /dev/null
+++ b/SOURCES/0542-ReiserFS-switch-to-using-grub_min-grub_max.patch
@@ -0,0 +1,94 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Thu, 21 Apr 2022 16:31:17 -0400
+Subject: [PATCH] ReiserFS: switch to using grub_min()/grub_max()
+
+This is a minor cleanup patch to remove the bespoke MIN() and MAX()
+definitions from the reiserfs driver, and uses grub_min() / grub_max()
+instead.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+(cherry picked from commit 5fc601574fce99b32fe4dfb55bd8f3ab0175fd6a)
+(cherry picked from commit 31e581893c564582c729fd0c033d3ce021854be8)
+---
+ grub-core/fs/reiserfs.c | 28 +++++++++-------------------
+ 1 file changed, 9 insertions(+), 19 deletions(-)
+
+diff --git a/grub-core/fs/reiserfs.c b/grub-core/fs/reiserfs.c
+index 39736f63c6..9556c15ff0 100644
+--- a/grub-core/fs/reiserfs.c
++++ b/grub-core/fs/reiserfs.c
+@@ -42,16 +42,6 @@
+ 
+ GRUB_MOD_LICENSE ("GPLv3+");
+ 
+-#define MIN(a, b) \
+-  ({ typeof (a) _a = (a); \
+-     typeof (b) _b = (b); \
+-     _a < _b ? _a : _b; })
+-
+-#define MAX(a, b) \
+-  ({ typeof (a) _a = (a); \
+-     typeof (b) _b = (b); \
+-     _a > _b ? _a : _b; })
+-
+ #define REISERFS_SUPER_BLOCK_OFFSET 0x10000
+ #define REISERFS_MAGIC_LEN 12
+ #define REISERFS_MAGIC_STRING "ReIsEr"
+@@ -1076,7 +1066,7 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node,
+   grub_reiserfs_set_key_type (&key, GRUB_REISERFS_ANY, 2);
+   initial_position = off;
+   current_position = 0;
+-  final_position = MIN (len + initial_position, node->size);
++  final_position = grub_min (len + initial_position, node->size);
+   grub_dprintf ("reiserfs",
+ 		"Reading from %lld to %lld (%lld instead of requested %ld)\n",
+ 		(unsigned long long) initial_position,
+@@ -1115,8 +1105,8 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node,
+           grub_dprintf ("reiserfs_blocktype", "D: %u\n", (unsigned) block);
+           if (initial_position < current_position + item_size)
+             {
+-              offset = MAX ((signed) (initial_position - current_position), 0);
+-              length = (MIN (item_size, final_position - current_position)
++              offset = grub_max ((signed) (initial_position - current_position), 0);
++              length = (grub_min (item_size, final_position - current_position)
+                         - offset);
+               grub_dprintf ("reiserfs",
+                             "Reading direct block %u from %u to %u...\n",
+@@ -1161,9 +1151,9 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node,
+               grub_dprintf ("reiserfs_blocktype", "I: %u\n", (unsigned) block);
+               if (current_position + block_size >= initial_position)
+                 {
+-                  offset = MAX ((signed) (initial_position - current_position),
+-                                0);
+-                  length = (MIN (block_size, final_position - current_position)
++                  offset = grub_max ((signed) (initial_position - current_position),
++				     0);
++                  length = (grub_min (block_size, final_position - current_position)
+                             - offset);
+                   grub_dprintf ("reiserfs",
+                                 "Reading indirect block %u from %u to %u...\n",
+@@ -1205,7 +1195,7 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node,
+   switch (found.type)
+     {
+       case GRUB_REISERFS_DIRECT:
+-        read_length = MIN (len, item_size - file->offset);
++        read_length = grub_min (len, item_size - file->offset);
+         grub_disk_read (found.data->disk,
+                         (found.block_number * block_size) / GRUB_DISK_SECTOR_SIZE,
+                         grub_le_to_cpu16 (found.header.item_location) + file->offset,
+@@ -1224,12 +1214,12 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node,
+                         item_size, (char *) indirect_block_ptr);
+         if (grub_errno)
+           goto fail;
+-        len = MIN (len, file->size - file->offset);
++        len = grub_min (len, file->size - file->offset);
+         for (indirect_block = file->offset / block_size;
+              indirect_block < indirect_block_count && read_length < len;
+              indirect_block++)
+           {
+-            read = MIN (block_size, len - read_length);
++            read = grub_min (block_size, len - read_length);
+             grub_disk_read (found.data->disk,
+                             (grub_le_to_cpu32 (indirect_block_ptr[indirect_block]) * block_size) / GRUB_DISK_SECTOR_SIZE,
+                             file->offset % block_size, read,
diff --git a/SOURCES/0542-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch b/SOURCES/0542-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch
deleted file mode 100644
index 8cc3da5..0000000
--- a/SOURCES/0542-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Fri, 25 Mar 2022 15:40:12 -0400
-Subject: [PATCH] pe: add the DOS header struct and fix some bad naming.
-
-In order to properly validate a loaded kernel's support for being loaded
-without a writable stack or executable, we need to be able to properly
-parse arbitrary PE headers.
-
-Currently, pe32.h is written in such a way that the MS-DOS header that
-tells us where to find the PE header in the binary can't be accessed.
-Further, for some reason it calls the DOS MZ magic "GRUB_PE32_MAGIC".
-
-This patch adds the structure for the DOS header, renames the DOS magic
-define, and adds defines for the actual PE magic.
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
-(cherry picked from commit 955f47aa8300387eecf18b0866d21dde7720593d)
-(cherry picked from commit 662744c2e986cb770fe49e71e019aaf33a66272d)
-(cherry picked from commit 4b541b7e76b77d131ff534e537a622551e774a2b)
----
- grub-core/loader/arm64/linux.c |  2 +-
- include/grub/efi/pe32.h        | 28 ++++++++++++++++++++++++++--
- 2 files changed, 27 insertions(+), 3 deletions(-)
-
-diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
-index e1923cf725..24ab0f0074 100644
---- a/grub-core/loader/arm64/linux.c
-+++ b/grub-core/loader/arm64/linux.c
-@@ -57,7 +57,7 @@ grub_armxx_efi_linux_check_image (struct linux_armxx_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)
-+  if ((lh->code0 & 0xffff) != GRUB_DOS_MAGIC)
-     return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
- 		       N_("plain image kernel not supported - rebuild with CONFIG_(U)EFI_STUB enabled"));
- 
-diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
-index c03cc599f6..2241f6317b 100644
---- a/include/grub/efi/pe32.h
-+++ b/include/grub/efi/pe32.h
-@@ -45,7 +45,30 @@
- 
- #define GRUB_PE32_MSDOS_STUB_SIZE	0x80
- 
--#define GRUB_PE32_MAGIC			0x5a4d
-+#define GRUB_DOS_MAGIC			0x5a4d
-+
-+struct grub_dos_header
-+{
-+  grub_uint16_t magic;
-+  grub_uint16_t cblp;
-+  grub_uint16_t cp;
-+  grub_uint16_t crlc;
-+  grub_uint16_t cparhdr;
-+  grub_uint16_t minalloc;
-+  grub_uint16_t maxalloc;
-+  grub_uint16_t ss;
-+  grub_uint16_t sp;
-+  grub_uint16_t csum;
-+  grub_uint16_t ip;
-+  grub_uint16_t cs;
-+  grub_uint16_t lfarlc;
-+  grub_uint16_t ovno;
-+  grub_uint16_t res0[4];
-+  grub_uint16_t oemid;
-+  grub_uint16_t oeminfo;
-+  grub_uint16_t res1[10];
-+  grub_uint32_t lfanew;
-+};
- 
- /* According to the spec, the minimal alignment is 512 bytes...
-    But some examples (such as EFI drivers in the Intel
-@@ -271,7 +294,8 @@ struct grub_pe32_section_table
- 
- 
- 
--#define GRUB_PE32_SIGNATURE_SIZE 4
-+#define GRUB_PE32_SIGNATURE_SIZE		4
-+#define GRUB_PE32_SIGNATURE			"PE\0\0"
- 
- struct grub_pe32_header
- {
diff --git a/SOURCES/0543-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch b/SOURCES/0543-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch
deleted file mode 100644
index 7d7a44a..0000000
--- a/SOURCES/0543-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Wed, 9 Feb 2022 16:08:20 -0500
-Subject: [PATCH] EFI: allocate kernel in EFI_RUNTIME_SERVICES_CODE instead of
- EFI_LOADER_DATA.
-
-On some of the firmwares with more security mitigations, EFI_LOADER_DATA
-doesn't get you executable memory, and we take a fault and reboot when
-we enter kernel.
-
-This patch correctly allocates the kernel code as EFI_RUNTIME_SERVICES_CODE
-rather than EFI_LOADER_DATA.
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
-[rharwood: use kernel_size]
-Signed-off-by: Robbie Harwood <rharwood@redhat.com>
-(cherry picked from commit 8b31058a12d3e85f0f0180ac90b98d6465fccbb7)
-(cherry picked from commit 460df66aab9b3a57fc0d14a21a595cd467c4b13e)
-(cherry picked from commit 2380ad45c78ed12710f1186eda9f2ba38c20f6ba)
----
- grub-core/loader/i386/efi/linux.c | 19 +++++++++++++------
- 1 file changed, 13 insertions(+), 6 deletions(-)
-
-diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
-index 8337191921..3d4069e4c6 100644
---- a/grub-core/loader/i386/efi/linux.c
-+++ b/grub-core/loader/i386/efi/linux.c
-@@ -86,7 +86,9 @@ kernel_free(void *addr, grub_efi_uintn_t size)
- }
- 
- static void *
--kernel_alloc(grub_efi_uintn_t size, const char * const errmsg)
-+kernel_alloc(grub_efi_uintn_t size,
-+	     grub_efi_memory_type_t memtype,
-+	     const char * const errmsg)
- {
-   void *addr = 0;
-   unsigned int i;
-@@ -112,7 +114,7 @@ kernel_alloc(grub_efi_uintn_t size, const char * const errmsg)
-       prev_max = max;
-       addr = grub_efi_allocate_pages_real (max, pages,
- 					   max_addresses[i].alloc_type,
--					   GRUB_EFI_LOADER_DATA);
-+					   memtype);
-       if (addr)
- 	grub_dprintf ("linux", "Allocated at %p\n", addr);
-     }
-@@ -243,7 +245,8 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
- 	}
-     }
- 
--  initrd_mem = kernel_alloc(size, N_("can't allocate initrd"));
-+  initrd_mem = kernel_alloc(size, GRUB_EFI_RUNTIME_SERVICES_DATA,
-+			    N_("can't allocate initrd"));
-   if (initrd_mem == NULL)
-     goto fail;
-   grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem);
-@@ -411,7 +414,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-     }
- #endif
- 
--  params = kernel_alloc (sizeof(*params), "cannot allocate kernel parameters");
-+  params = kernel_alloc (sizeof(*params), GRUB_EFI_RUNTIME_SERVICES_DATA,
-+			 "cannot allocate kernel parameters");
-   if (!params)
-     goto fail;
-   grub_dprintf ("linux", "params = %p\n", params);
-@@ -432,7 +436,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-   grub_dprintf ("linux", "new lh is at %p\n", lh);
- 
-   grub_dprintf ("linux", "setting up cmdline\n");
--  cmdline = kernel_alloc (lh->cmdline_size + 1, N_("can't allocate cmdline"));
-+  cmdline = kernel_alloc (lh->cmdline_size + 1,
-+			  GRUB_EFI_RUNTIME_SERVICES_DATA,
-+			  N_("can't allocate cmdline"));
-   if (!cmdline)
-     goto fail;
-   grub_dprintf ("linux", "cmdline = %p\n", cmdline);
-@@ -478,7 +484,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-   max_addresses[1].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
-   max_addresses[2].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
-   kernel_size = lh->init_size;
--  kernel_mem = kernel_alloc (kernel_size, N_("can't allocate kernel"));
-+  kernel_mem = kernel_alloc (kernel_size, GRUB_EFI_RUNTIME_SERVICES_CODE,
-+			     N_("can't allocate kernel"));
-   restore_addresses();
-   if (!kernel_mem)
-     goto fail;
diff --git a/SOURCES/0543-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch b/SOURCES/0543-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch
new file mode 100644
index 0000000..37cb0a8
--- /dev/null
+++ b/SOURCES/0543-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch
@@ -0,0 +1,48 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Thu, 24 Mar 2022 14:40:01 -0400
+Subject: [PATCH] misc: make grub_boot_time() also call
+ grub_dprintf("boot",...)
+
+Currently grub_boot_time() includes valuable debugging messages, but if
+you build without BOOT_TIME_STATS enabled, they are silently and
+confusingly compiled away.
+
+This patch changes grub_boot_time() to also log when "boot" is enabled
+in DEBUG, regardless of BOOT_TIME_STATS.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+(cherry picked from commit 4fd282de00df05ce289467861deb7a0e186cfbd7)
+(cherry picked from commit cc7e60a9f3ad1fa74b9cd48a7e66b1976f9a554a)
+---
+ grub-core/kern/misc.c | 3 ++-
+ include/grub/misc.h   | 2 +-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
+index 859d71659a..b375e486a4 100644
+--- a/grub-core/kern/misc.c
++++ b/grub-core/kern/misc.c
+@@ -1336,7 +1336,8 @@ grub_real_boot_time (const char *file,
+   n->next = 0;
+ 
+   va_start (args, fmt);
+-  n->msg = grub_xvasprintf (fmt, args);    
++  n->msg = grub_xvasprintf (fmt, args);
++  grub_dprintf ("boot", "%s\n", n->msg);
+   va_end (args);
+ 
+   *boot_time_last = n;
+diff --git a/include/grub/misc.h b/include/grub/misc.h
+index 7ef1a1a87e..1b722c8185 100644
+--- a/include/grub/misc.h
++++ b/include/grub/misc.h
+@@ -529,7 +529,7 @@ void EXPORT_FUNC(grub_real_boot_time) (const char *file,
+ 				       const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 3, 4)));
+ #define grub_boot_time(...) grub_real_boot_time(GRUB_FILE, __LINE__, __VA_ARGS__)
+ #else
+-#define grub_boot_time(...)
++#define grub_boot_time(fmt, ...) grub_dprintf("boot", fmt "\n", ##__VA_ARGS__)
+ #endif
+ 
+ #define _grub_min(a, b, _a, _b)						      \
diff --git a/SOURCES/0544-modules-load-module-sections-at-page-aligned-address.patch b/SOURCES/0544-modules-load-module-sections-at-page-aligned-address.patch
deleted file mode 100644
index 5cc42b1..0000000
--- a/SOURCES/0544-modules-load-module-sections-at-page-aligned-address.patch
+++ /dev/null
@@ -1,361 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Mon, 21 Mar 2022 17:45:40 -0400
-Subject: [PATCH] modules: load module sections at page-aligned addresses
-
-Currently we load module sections at whatever alignment gcc+ld happened
-to dump into the ELF section header, which is often pretty useless.  For
-example, by default time.mod has these sections on a current x86_64
-build:
-
-$ eu-readelf -a grub-core/time.mod |& grep ^Section -A13
-Section Headers:
-[Nr] Name            Type         Addr  Off      Size     ES Flags Lk Inf Al
-[ 0]                 NULL         0     00000000 00000000  0        0   0  0
-[ 1] .text           PROGBITS     0     00000040 0000015e  0 AX     0   0  1
-[ 2] .rela.text      RELA         0     00000458 000001e0 24 I      8   1  8
-[ 3] .rodata.str1.1  PROGBITS     0     0000019e 000000a1  1 AMS    0   0  1
-[ 4] .module_license PROGBITS     0     00000240 0000000f  0 A      0   0  8
-[ 5] .data           PROGBITS     0     0000024f 00000000  0 WA     0   0  1
-[ 6] .bss            NOBITS       0     00000250 00000008  0 WA     0   0  8
-[ 7] .modname        PROGBITS     0     00000250 00000005  0        0   0  1
-[ 8] .symtab         SYMTAB       0     00000258 00000150 24        9   6  8
-[ 9] .strtab         STRTAB       0     000003a8 000000ab  0        0   0  1
-[10] .shstrtab       STRTAB       0     00000638 00000059  0        0   0  1
-
-With NX protections being page based, loading sections with either a 1
-or 8 *byte* alignment does absolutely nothing to help us out.
-
-This patch switches most EFI platforms to load module sections at 4kB
-page-aligned addresses.  To do so, it adds an new per-arch function,
-grub_arch_dl_min_alignment(), which returns the alignment needed for
-dynamically loaded sections (in bytes).  Currently it sets it to 4096
-when GRUB_MACHINE_EFI is true on x86_64, i386, arm, arm64, and emu, and
-1-byte alignment on everything else.
-
-It then changes the allocation size computation and the loader code in
-grub_dl_load_segments() to align the locations and sizes up to these
-boundaries, and fills any added padding with zeros.
-
-All of this happens before relocations are applied, so the relocations
-factor that in with no change.
-
-As an aside, initially Daniel Kiper and I thought that it might be a
-better idea to split the modules up into top-level sections as
-.text.modules, .rodata.modules, .data.modules, etc., so that their page
-permissions would get set by the loader that's loading grub itself.
-This turns out to have two significant downsides: 1) either in mkimage
-or in grub_dl_relocate_symbols(), you wind up having to dynamically
-process the relocations to accommodate the moved module sections, and 2)
-you then need to change the permissions on the modules and change them
-back while relocating them in grub_dl_relocate_symbols(), which means
-that any loader that /does/ honor the section flags but does /not/
-generally support NX with the memory attributes API will cause grub to
-fail.
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
-(cherry picked from commit 31d52500b281619d92b03b2c2d30fe15aedaf326)
-(cherry picked from commit 04f1df6b665493e38de66018aebe377fdac4ceec)
-[rharwood: not risc-v yet]
-Signed-off-by: Robbie Harwood <rharwood@redhat.com>
-(cherry picked from commit 62c48da3ef51fc4f98746fbc35791ec2beab0426)
----
- grub-core/kern/arm/dl.c     | 13 +++++++++++++
- grub-core/kern/arm64/dl.c   | 13 +++++++++++++
- grub-core/kern/dl.c         | 29 +++++++++++++++++++++--------
- grub-core/kern/emu/full.c   | 13 +++++++++++++
- grub-core/kern/i386/dl.c    | 13 +++++++++++++
- grub-core/kern/ia64/dl.c    |  9 +++++++++
- grub-core/kern/mips/dl.c    |  8 ++++++++
- grub-core/kern/powerpc/dl.c |  9 +++++++++
- grub-core/kern/sparc64/dl.c |  9 +++++++++
- grub-core/kern/x86_64/dl.c  | 13 +++++++++++++
- include/grub/dl.h           |  2 ++
- docs/grub-dev.texi          |  6 +++---
- 12 files changed, 126 insertions(+), 11 deletions(-)
-
-diff --git a/grub-core/kern/arm/dl.c b/grub-core/kern/arm/dl.c
-index eab9d17ff2..9260737936 100644
---- a/grub-core/kern/arm/dl.c
-+++ b/grub-core/kern/arm/dl.c
-@@ -278,3 +278,16 @@ grub_arch_dl_check_header (void *ehdr)
- 
-   return GRUB_ERR_NONE;
- }
-+
-+/*
-+ * Tell the loader what our minimum section alignment is.
-+ */
-+grub_size_t
-+grub_arch_dl_min_alignment (void)
-+{
-+#ifdef GRUB_MACHINE_EFI
-+  return 4096;
-+#else
-+  return 1;
-+#endif
-+}
-diff --git a/grub-core/kern/arm64/dl.c b/grub-core/kern/arm64/dl.c
-index fb03373190..826f8e721e 100644
---- a/grub-core/kern/arm64/dl.c
-+++ b/grub-core/kern/arm64/dl.c
-@@ -191,3 +191,16 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
- 
-   return GRUB_ERR_NONE;
- }
-+
-+/*
-+ * Tell the loader what our minimum section alignment is.
-+ */
-+grub_size_t
-+grub_arch_dl_min_alignment (void)
-+{
-+#ifdef GRUB_MACHINE_EFI
-+  return 4096;
-+#else
-+  return 1;
-+#endif
-+}
-diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
-index ba1b33c20b..5c2153acf9 100644
---- a/grub-core/kern/dl.c
-+++ b/grub-core/kern/dl.c
-@@ -278,7 +278,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
- {
-   unsigned i;
-   const Elf_Shdr *s;
--  grub_size_t tsize = 0, talign = 1;
-+  grub_size_t tsize = 0, talign = 1, arch_addralign = 1;
- #if !defined (__i386__) && !defined (__x86_64__)
-   grub_size_t tramp;
-   grub_size_t got;
-@@ -286,16 +286,24 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
- #endif
-   char *ptr;
- 
-+  arch_addralign = grub_arch_dl_min_alignment ();
-+
-   for (i = 0, s = (const Elf_Shdr *)((const char *) e + e->e_shoff);
-        i < e->e_shnum;
-        i++, s = (const Elf_Shdr *)((const char *) s + e->e_shentsize))
-     {
-+      grub_size_t sh_addralign;
-+      grub_size_t sh_size;
-+
-       if (s->sh_size == 0 || !(s->sh_flags & SHF_ALLOC))
- 	continue;
- 
--      tsize = ALIGN_UP (tsize, s->sh_addralign) + s->sh_size;
--      if (talign < s->sh_addralign)
--	talign = s->sh_addralign;
-+      sh_addralign = ALIGN_UP(s->sh_addralign, arch_addralign);
-+      sh_size = ALIGN_UP(s->sh_size, sh_addralign);
-+
-+      tsize = ALIGN_UP (tsize, sh_addralign) + sh_size;
-+      if (talign < sh_addralign)
-+	talign = sh_addralign;
-     }
- 
- #if !defined (__i386__) && !defined (__x86_64__)
-@@ -324,6 +332,9 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
-        i < e->e_shnum;
-        i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
-     {
-+      grub_size_t sh_addralign = ALIGN_UP(s->sh_addralign, arch_addralign);
-+      grub_size_t sh_size = ALIGN_UP(s->sh_size, sh_addralign);
-+
-       if (s->sh_flags & SHF_ALLOC)
- 	{
- 	  grub_dl_segment_t seg;
-@@ -336,17 +347,19 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
- 	    {
- 	      void *addr;
- 
--	      ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, s->sh_addralign);
-+	      ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, sh_addralign);
- 	      addr = ptr;
--	      ptr += s->sh_size;
-+	      ptr += sh_size;
- 
- 	      switch (s->sh_type)
- 		{
- 		case SHT_PROGBITS:
- 		  grub_memcpy (addr, (char *) e + s->sh_offset, s->sh_size);
-+		  grub_memset ((char *)addr + s->sh_size, 0,
-+			       sh_size - s->sh_size);
- 		  break;
- 		case SHT_NOBITS:
--		  grub_memset (addr, 0, s->sh_size);
-+		  grub_memset (addr, 0, sh_size);
- 		  break;
- 		}
- 
-@@ -355,7 +368,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
- 	  else
- 	    seg->addr = 0;
- 
--	  seg->size = s->sh_size;
-+	  seg->size = sh_size;
- 	  seg->section = i;
- 	  seg->next = mod->segment;
- 	  mod->segment = seg;
-diff --git a/grub-core/kern/emu/full.c b/grub-core/kern/emu/full.c
-index e8d63b1f5f..1de1c28eb0 100644
---- a/grub-core/kern/emu/full.c
-+++ b/grub-core/kern/emu/full.c
-@@ -67,3 +67,16 @@ grub_arch_dl_init_linker (void)
- }
- #endif
- 
-+
-+/*
-+ * Tell the loader what our minimum section alignment is.
-+ */
-+grub_size_t
-+grub_arch_dl_min_alignment (void)
-+{
-+#ifdef GRUB_MACHINE_EFI
-+  return 4096;
-+#else
-+  return 1;
-+#endif
-+}
-diff --git a/grub-core/kern/i386/dl.c b/grub-core/kern/i386/dl.c
-index 1346da5cc9..d6b4681fc9 100644
---- a/grub-core/kern/i386/dl.c
-+++ b/grub-core/kern/i386/dl.c
-@@ -79,3 +79,16 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
- 
-   return GRUB_ERR_NONE;
- }
-+
-+/*
-+ * Tell the loader what our minimum section alignment is.
-+ */
-+grub_size_t
-+grub_arch_dl_min_alignment (void)
-+{
-+#ifdef GRUB_MACHINE_EFI
-+  return 4096;
-+#else
-+  return 1;
-+#endif
-+}
-diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c
-index ebcf316298..3bb753a89b 100644
---- a/grub-core/kern/ia64/dl.c
-+++ b/grub-core/kern/ia64/dl.c
-@@ -143,3 +143,12 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
-     }
-   return GRUB_ERR_NONE;
- }
-+
-+/*
-+ * Tell the loader what our minimum section alignment is.
-+ */
-+grub_size_t
-+grub_arch_dl_min_alignment (void)
-+{
-+  return 1;
-+}
-diff --git a/grub-core/kern/mips/dl.c b/grub-core/kern/mips/dl.c
-index 5d7d299c74..6d83bd71e9 100644
---- a/grub-core/kern/mips/dl.c
-+++ b/grub-core/kern/mips/dl.c
-@@ -272,3 +272,11 @@ grub_arch_dl_init_linker (void)
-   grub_dl_register_symbol ("_gp_disp", &_gp_disp_dummy, 0, 0);
- }
- 
-+/*
-+ * Tell the loader what our minimum section alignment is.
-+ */
-+grub_size_t
-+grub_arch_dl_min_alignment (void)
-+{
-+  return 1;
-+}
-diff --git a/grub-core/kern/powerpc/dl.c b/grub-core/kern/powerpc/dl.c
-index 3a7fa3ed3d..577e27d871 100644
---- a/grub-core/kern/powerpc/dl.c
-+++ b/grub-core/kern/powerpc/dl.c
-@@ -165,3 +165,12 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
- 
-   return GRUB_ERR_NONE;
- }
-+
-+/*
-+ * Tell the loader what our minimum section alignment is.
-+ */
-+grub_size_t
-+grub_arch_dl_min_alignment (void)
-+{
-+  return 1;
-+}
-diff --git a/grub-core/kern/sparc64/dl.c b/grub-core/kern/sparc64/dl.c
-index 739be47174..c741c1782e 100644
---- a/grub-core/kern/sparc64/dl.c
-+++ b/grub-core/kern/sparc64/dl.c
-@@ -184,3 +184,12 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
- 
-   return GRUB_ERR_NONE;
- }
-+
-+/*
-+ * Tell the loader what our minimum section alignment is.
-+ */
-+grub_size_t
-+grub_arch_dl_min_alignment (void)
-+{
-+  return 1;
-+}
-diff --git a/grub-core/kern/x86_64/dl.c b/grub-core/kern/x86_64/dl.c
-index 3a73e6e6ce..6c20b7c367 100644
---- a/grub-core/kern/x86_64/dl.c
-+++ b/grub-core/kern/x86_64/dl.c
-@@ -114,3 +114,16 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
- 
-   return GRUB_ERR_NONE;
- }
-+
-+/*
-+ * Tell the loader what our minimum section alignment is.
-+ */
-+grub_size_t
-+grub_arch_dl_min_alignment (void)
-+{
-+#ifdef GRUB_MACHINE_EFI
-+  return 4096;
-+#else
-+  return 1;
-+#endif
-+}
-diff --git a/include/grub/dl.h b/include/grub/dl.h
-index 9ec6caf3f9..dd4c3e7ff4 100644
---- a/include/grub/dl.h
-+++ b/include/grub/dl.h
-@@ -280,6 +280,8 @@ grub_err_t grub_arch_dl_check_header (void *ehdr);
- grub_err_t
- grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
- 			       Elf_Shdr *s, grub_dl_segment_t seg);
-+grub_size_t
-+grub_arch_dl_min_alignment (void);
- #endif
- 
- #if defined (_mips)
-diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi
-index 03d53498c5..dbfb94bc06 100644
---- a/docs/grub-dev.texi
-+++ b/docs/grub-dev.texi
-@@ -638,9 +638,9 @@ declare startup asm file ($cpu_$platform_startup) as well as any other files
- (e.g. init.c and callwrap.S) (e.g. $cpu_$platform = kern/$cpu/$platform/init.c).
- At this stage you will also need to add dummy dl.c and cache.S with functions
- grub_err_t grub_arch_dl_check_header (void *ehdr), grub_err_t
--grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) (dl.c) and
--void grub_arch_sync_caches (void *address, grub_size_t len) (cache.S). They
--won't be used for now.
-+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) (dl.c), grub_uint32_t
-+grub_arch_dl_min_alignment (void), and void grub_arch_sync_caches (void
-+*address, grub_size_t len) (cache.S). They won't be used for now.
- 
- You will need to create directory include/$cpu/$platform and a file
- include/$cpu/types.h. The later folowing this template:
diff --git a/SOURCES/0544-modules-make-.module_license-read-only.patch b/SOURCES/0544-modules-make-.module_license-read-only.patch
new file mode 100644
index 0000000..e5af3e9
--- /dev/null
+++ b/SOURCES/0544-modules-make-.module_license-read-only.patch
@@ -0,0 +1,32 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Thu, 24 Feb 2022 16:32:51 -0500
+Subject: [PATCH] modules: make .module_license read-only
+
+Currently .module_license is set writable (that is, the section has the
+SHF_WRITE flag set) in the module's ELF headers.  This probably never
+actually matters, but it can't possibly be correct.
+
+This patch sets that data as "const", which causes that flag not to be
+set.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+(cherry picked from commit 2eff3e2c9d9e6b75daa81b840c96f112ef7d5de6)
+(cherry picked from commit 3c3c1858d1c056eee660d67888be80e7eae498ca)
+---
+ include/grub/dl.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/grub/dl.h b/include/grub/dl.h
+index 6a3e251b45..9ec6caf3f9 100644
+--- a/include/grub/dl.h
++++ b/include/grub/dl.h
+@@ -121,7 +121,7 @@ grub_mod_fini (void)
+ #define ATTRIBUTE_USED __unused__
+ #endif
+ #define GRUB_MOD_LICENSE(license)	\
+-  static char grub_module_license[] __attribute__ ((section (GRUB_MOD_SECTION (module_license)), ATTRIBUTE_USED)) = "LICENSE=" license;
++  static const char grub_module_license[] __attribute__ ((section (GRUB_MOD_SECTION (module_license)), ATTRIBUTE_USED)) = "LICENSE=" license;
+ #define GRUB_MOD_DEP(name)	\
+ static const char grub_module_depend_##name[] \
+  __attribute__((section(GRUB_MOD_SECTION(moddeps)), ATTRIBUTE_USED)) = #name
diff --git a/SOURCES/0545-modules-strip-.llvm_addrsig-sections-and-similar.patch b/SOURCES/0545-modules-strip-.llvm_addrsig-sections-and-similar.patch
new file mode 100644
index 0000000..c8a17de
--- /dev/null
+++ b/SOURCES/0545-modules-strip-.llvm_addrsig-sections-and-similar.patch
@@ -0,0 +1,41 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Thu, 24 Feb 2022 16:40:11 -0500
+Subject: [PATCH] modules: strip .llvm_addrsig sections and similar.
+
+Currently grub modules built with clang or gcc have several sections
+which we don't actually need or support.
+
+We already have a list of section to skip in genmod.sh, and this patch
+adds the following sections to that list (as well as a few newlines):
+
+.note.gnu.property
+.llvm*
+
+Note that the glob there won't work without a new enough linker, but the
+failure is just reversion to the status quo, so that's not a big problem.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+(cherry picked from commit e85d1c4d795f8135ad0acfa36d64760d12d6fed1)
+(cherry picked from commit d3024204b2e2c69ecb91392eeb87c1e6835c3743)
+---
+ grub-core/genmod.sh.in | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/grub-core/genmod.sh.in b/grub-core/genmod.sh.in
+index 1250589b3f..c2c5280d75 100644
+--- a/grub-core/genmod.sh.in
++++ b/grub-core/genmod.sh.in
+@@ -57,8 +57,11 @@ if test x@TARGET_APPLE_LINKER@ != x1; then
+ 	    @TARGET_STRIP@ --strip-unneeded \
+ 		-K grub_mod_init -K grub_mod_fini \
+ 		-K _grub_mod_init -K _grub_mod_fini \
+-		-R .note.gnu.gold-version -R .note.GNU-stack \
++		-R .note.GNU-stack \
++		-R .note.gnu.gold-version \
++		-R .note.gnu.property \
+ 		-R .gnu.build.attributes \
++		-R '.llvm*' \
+ 		-R .rel.gnu.build.attributes \
+ 		-R .rela.gnu.build.attributes \
+ 		-R .eh_frame -R .rela.eh_frame -R .rel.eh_frame \
diff --git a/SOURCES/0545-nx-add-memory-attribute-get-set-API.patch b/SOURCES/0545-nx-add-memory-attribute-get-set-API.patch
deleted file mode 100644
index eec3160..0000000
--- a/SOURCES/0545-nx-add-memory-attribute-get-set-API.patch
+++ /dev/null
@@ -1,321 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Tue, 22 Mar 2022 10:56:21 -0400
-Subject: [PATCH] nx: add memory attribute get/set API
-
-For NX, we need to set the page access permission attributes for write
-and execute permissions.
-
-This patch adds two new primitives, grub_set_mem_attrs() and
-grub_clear_mem_attrs(), and associated constant definitions, to be used
-for that purpose.
-
-For most platforms, it adds a dummy implementation that returns
-GRUB_ERR_NONE.  On EFI platforms, it adds a common helper function,
-grub_efi_status_to_err(), which translates EFI error codes to grub error
-codes, adds headers for the EFI Memory Attribute Protocol (still pending
-standardization), and an implementation of the grub nx primitives using
-it.
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
-[rharwood: add pjones's none/nyi fixup]
-(cherry picked from commit 35de78a8d32b9fad5291ec96fd3cbb9cf2f4a80b)
-(cherry picked from commit 46cb4f9557bdba1db0a17d012df705d94d81a9f6)
-[rharwood: context fuzz, guids]
-Signed-off-by: Robbie Harwood <rharwood@redhat.com>
-(cherry picked from commit 7d8eea48e82c4ef572cc0f9d3252487c1d7e5729)
----
- grub-core/kern/efi/efi.c |  36 +++++++++++++
- grub-core/kern/efi/mm.c  | 131 +++++++++++++++++++++++++++++++++++++++++++++++
- include/grub/efi/api.h   |  25 +++++++++
- include/grub/efi/efi.h   |   2 +
- include/grub/mm.h        |  32 ++++++++++++
- 5 files changed, 226 insertions(+)
-
-diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
-index fccea20a01..09468dc5d5 100644
---- a/grub-core/kern/efi/efi.c
-+++ b/grub-core/kern/efi/efi.c
-@@ -1093,3 +1093,39 @@ grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1,
- 
-   return 0;
- }
-+
-+grub_err_t
-+grub_efi_status_to_err (grub_efi_status_t status)
-+{
-+  grub_err_t err;
-+  switch (status)
-+    {
-+    case GRUB_EFI_SUCCESS:
-+      err = GRUB_ERR_NONE;
-+      break;
-+    case GRUB_EFI_INVALID_PARAMETER:
-+    default:
-+      err = GRUB_ERR_BAD_ARGUMENT;
-+      break;
-+    case GRUB_EFI_OUT_OF_RESOURCES:
-+      err = GRUB_ERR_OUT_OF_MEMORY;
-+      break;
-+    case GRUB_EFI_DEVICE_ERROR:
-+      err = GRUB_ERR_IO;
-+      break;
-+    case GRUB_EFI_WRITE_PROTECTED:
-+      err = GRUB_ERR_WRITE_ERROR;
-+      break;
-+    case GRUB_EFI_SECURITY_VIOLATION:
-+      err = GRUB_ERR_ACCESS_DENIED;
-+      break;
-+    case GRUB_EFI_NOT_FOUND:
-+      err = GRUB_ERR_FILE_NOT_FOUND;
-+      break;
-+    case GRUB_EFI_ABORTED:
-+      err = GRUB_ERR_WAIT;
-+      break;
-+    }
-+
-+  return err;
-+}
-diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
-index 9e76f23e5f..2cf4a4883a 100644
---- a/grub-core/kern/efi/mm.c
-+++ b/grub-core/kern/efi/mm.c
-@@ -730,3 +730,134 @@ grub_efi_get_ram_base(grub_addr_t *base_addr)
-   return GRUB_ERR_NONE;
- }
- #endif
-+
-+static inline grub_uint64_t
-+grub_mem_attrs_to_uefi_mem_attrs (grub_uint64_t attrs)
-+{
-+  grub_uint64_t ret = GRUB_EFI_MEMORY_RP |
-+		      GRUB_EFI_MEMORY_RO |
-+		      GRUB_EFI_MEMORY_XP;
-+
-+  if (attrs & GRUB_MEM_ATTR_R)
-+    ret &= ~GRUB_EFI_MEMORY_RP;
-+
-+  if (attrs & GRUB_MEM_ATTR_W)
-+    ret &= ~GRUB_EFI_MEMORY_RO;
-+
-+  if (attrs & GRUB_MEM_ATTR_X)
-+    ret &= ~GRUB_EFI_MEMORY_XP;
-+
-+  return ret;
-+}
-+
-+static inline grub_uint64_t
-+uefi_mem_attrs_to_grub_mem_attrs (grub_uint64_t attrs)
-+{
-+  grub_uint64_t ret = GRUB_MEM_ATTR_R |
-+		      GRUB_MEM_ATTR_W |
-+		      GRUB_MEM_ATTR_X;
-+
-+  if (attrs & GRUB_EFI_MEMORY_RP)
-+    ret &= ~GRUB_MEM_ATTR_R;
-+
-+  if (attrs & GRUB_EFI_MEMORY_RO)
-+    ret &= ~GRUB_MEM_ATTR_W;
-+
-+  if (attrs & GRUB_EFI_MEMORY_XP)
-+    ret &= ~GRUB_MEM_ATTR_X;
-+
-+  return ret;
-+}
-+
-+grub_err_t
-+grub_get_mem_attrs (grub_addr_t addr, grub_size_t size, grub_uint64_t *attrs)
-+{
-+  grub_efi_memory_attribute_protocol_t *proto;
-+  grub_efi_physical_address_t physaddr = addr;
-+  grub_efi_guid_t protocol_guid = GRUB_EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID;
-+  grub_efi_status_t efi_status;
-+
-+  proto = grub_efi_locate_protocol (&protocol_guid, 0);
-+  if (!proto)
-+    return GRUB_ERR_NOT_IMPLEMENTED_YET;
-+
-+  if (physaddr & 0xfff || size & 0xfff || size == 0 || attrs == NULL)
-+    {
-+      grub_dprintf ("nx", "%s called on 0x%"PRIxGRUB_ADDR"-0x%"PRIxGRUB_ADDR" and attrs %p\n",
-+		    __func__, physaddr, physaddr+size-1, attrs);
-+      return 0;
-+    }
-+
-+  efi_status = efi_call_4(proto->get_memory_attributes,
-+			  proto, physaddr, size, attrs);
-+  *attrs = uefi_mem_attrs_to_grub_mem_attrs (*attrs);
-+
-+  return grub_efi_status_to_err (efi_status);
-+}
-+
-+grub_err_t
-+grub_update_mem_attrs (grub_addr_t addr, grub_size_t size,
-+		       grub_uint64_t set_attrs, grub_uint64_t clear_attrs)
-+{
-+  grub_efi_memory_attribute_protocol_t *proto;
-+  grub_efi_physical_address_t physaddr = addr;
-+  grub_efi_guid_t protocol_guid = GRUB_EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID;
-+  grub_efi_status_t efi_status = GRUB_EFI_SUCCESS;
-+  grub_uint64_t before = 0, after = 0, uefi_set_attrs, uefi_clear_attrs;
-+  grub_err_t err;
-+
-+  proto = grub_efi_locate_protocol (&protocol_guid, 0);
-+  if (!proto)
-+    return GRUB_ERR_NONE;
-+
-+  err = grub_get_mem_attrs (addr, size, &before);
-+  if (err)
-+    grub_dprintf ("nx", "grub_get_mem_attrs(0x%"PRIxGRUB_ADDR", %"PRIuGRUB_SIZE", %p) -> 0x%x\n",
-+		  addr, size, &before, err);
-+
-+  if (physaddr & 0xfff || size & 0xfff || size == 0)
-+    {
-+      grub_dprintf ("nx", "%s called on 0x%"PRIxGRUB_ADDR"-0x%"PRIxGRUB_ADDR" +%s%s%s -%s%s%s\n",
-+		    __func__, physaddr, physaddr + size - 1,
-+		    (set_attrs & GRUB_MEM_ATTR_R) ? "r" : "",
-+		    (set_attrs & GRUB_MEM_ATTR_W) ? "w" : "",
-+		    (set_attrs & GRUB_MEM_ATTR_X) ? "x" : "",
-+		    (clear_attrs & GRUB_MEM_ATTR_R) ? "r" : "",
-+		    (clear_attrs & GRUB_MEM_ATTR_W) ? "w" : "",
-+		    (clear_attrs & GRUB_MEM_ATTR_X) ? "x" : "");
-+      return 0;
-+    }
-+
-+  uefi_set_attrs = grub_mem_attrs_to_uefi_mem_attrs (set_attrs);
-+  grub_dprintf ("nx", "translating set_attrs from 0x%lx to 0x%lx\n", set_attrs, uefi_set_attrs);
-+  uefi_clear_attrs = grub_mem_attrs_to_uefi_mem_attrs (clear_attrs);
-+  grub_dprintf ("nx", "translating clear_attrs from 0x%lx to 0x%lx\n", clear_attrs, uefi_clear_attrs);
-+  if (uefi_set_attrs)
-+    efi_status = efi_call_4(proto->set_memory_attributes,
-+			    proto, physaddr, size, uefi_set_attrs);
-+  if (efi_status == GRUB_EFI_SUCCESS && uefi_clear_attrs)
-+    efi_status = efi_call_4(proto->clear_memory_attributes,
-+			    proto, physaddr, size, uefi_clear_attrs);
-+
-+  err = grub_get_mem_attrs (addr, size, &after);
-+  if (err)
-+    grub_dprintf ("nx", "grub_get_mem_attrs(0x%"PRIxGRUB_ADDR", %"PRIuGRUB_SIZE", %p) -> 0x%x\n",
-+		  addr, size, &after, err);
-+
-+  grub_dprintf ("nx", "set +%s%s%s -%s%s%s on 0x%"PRIxGRUB_ADDR"-0x%"PRIxGRUB_ADDR" before:%c%c%c after:%c%c%c\n",
-+		(set_attrs & GRUB_MEM_ATTR_R) ? "r" : "",
-+		(set_attrs & GRUB_MEM_ATTR_W) ? "w" : "",
-+		(set_attrs & GRUB_MEM_ATTR_X) ? "x" : "",
-+		(clear_attrs & GRUB_MEM_ATTR_R) ? "r" : "",
-+		(clear_attrs & GRUB_MEM_ATTR_W) ? "w" : "",
-+		(clear_attrs & GRUB_MEM_ATTR_X) ? "x" : "",
-+		addr, addr + size - 1,
-+		(before & GRUB_MEM_ATTR_R) ? 'r' : '-',
-+		(before & GRUB_MEM_ATTR_W) ? 'w' : '-',
-+		(before & GRUB_MEM_ATTR_X) ? 'x' : '-',
-+		(after & GRUB_MEM_ATTR_R) ? 'r' : '-',
-+		(after & GRUB_MEM_ATTR_W) ? 'w' : '-',
-+		(after & GRUB_MEM_ATTR_X) ? 'x' : '-');
-+
-+  return grub_efi_status_to_err (efi_status);
-+}
-diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
-index 2a243fd290..510a4030f5 100644
---- a/include/grub/efi/api.h
-+++ b/include/grub/efi/api.h
-@@ -354,6 +354,11 @@
-     { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } \
-    }
- 
-+#define GRUB_EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID \
-+  { 0xf4560cf6, 0x40ec, 0x4b4a, \
-+    { 0xa1, 0x92, 0xbf, 0x1d, 0x57, 0xd0, 0xb1, 0x89 } \
-+  }
-+
- struct grub_efi_sal_system_table
- {
-   grub_uint32_t signature;
-@@ -2091,6 +2096,26 @@ struct grub_efi_rng_protocol
- };
- typedef struct grub_efi_rng_protocol grub_efi_rng_protocol_t;
- 
-+struct grub_efi_memory_attribute_protocol
-+{
-+  grub_efi_status_t (*get_memory_attributes) (
-+			    struct grub_efi_memory_attribute_protocol *this,
-+			    grub_efi_physical_address_t base_address,
-+			    grub_efi_uint64_t length,
-+			    grub_efi_uint64_t *attributes);
-+  grub_efi_status_t (*set_memory_attributes) (
-+			    struct grub_efi_memory_attribute_protocol *this,
-+			    grub_efi_physical_address_t base_address,
-+			    grub_efi_uint64_t length,
-+			    grub_efi_uint64_t attributes);
-+  grub_efi_status_t (*clear_memory_attributes) (
-+			    struct grub_efi_memory_attribute_protocol *this,
-+			    grub_efi_physical_address_t base_address,
-+			    grub_efi_uint64_t length,
-+			    grub_efi_uint64_t attributes);
-+};
-+typedef struct grub_efi_memory_attribute_protocol grub_efi_memory_attribute_protocol_t;
-+
- #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \
-   || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__)
- 
-diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
-index 7af979b184..a635bcb0a9 100644
---- a/include/grub/efi/efi.h
-+++ b/include/grub/efi/efi.h
-@@ -159,4 +159,6 @@ struct grub_net_card;
- grub_efi_handle_t
- grub_efinet_get_device_handle (struct grub_net_card *card);
- 
-+grub_err_t EXPORT_FUNC(grub_efi_status_to_err) (grub_efi_status_t status);
-+
- #endif /* ! GRUB_EFI_EFI_HEADER */
-diff --git a/include/grub/mm.h b/include/grub/mm.h
-index 9c38dd3ca5..d81623d226 100644
---- a/include/grub/mm.h
-+++ b/include/grub/mm.h
-@@ -22,6 +22,7 @@
- 
- #include <grub/types.h>
- #include <grub/symbol.h>
-+#include <grub/err.h>
- #include <config.h>
- 
- #ifndef NULL
-@@ -38,6 +39,37 @@ void *EXPORT_FUNC(grub_realloc) (void *ptr, grub_size_t size);
- void *EXPORT_FUNC(grub_memalign) (grub_size_t align, grub_size_t size);
- #endif
- 
-+#define GRUB_MEM_ATTR_R	0x0000000000000004LLU
-+#define GRUB_MEM_ATTR_W	0x0000000000000002LLU
-+#define GRUB_MEM_ATTR_X	0x0000000000000001LLU
-+
-+#ifdef GRUB_MACHINE_EFI
-+grub_err_t EXPORT_FUNC(grub_get_mem_attrs) (grub_addr_t addr,
-+					    grub_size_t size,
-+					    grub_uint64_t *attrs);
-+grub_err_t EXPORT_FUNC(grub_update_mem_attrs) (grub_addr_t addr,
-+					       grub_size_t size,
-+					       grub_uint64_t set_attrs,
-+					       grub_uint64_t clear_attrs);
-+#else /* !GRUB_MACHINE_EFI */
-+static inline grub_err_t
-+grub_get_mem_attrs (grub_addr_t addr __attribute__((__unused__)),
-+		    grub_size_t size __attribute__((__unused__)),
-+		    grub_uint64_t *attrs __attribute__((__unused__)))
-+{
-+  return GRUB_ERR_NONE;
-+}
-+
-+static inline grub_err_t
-+grub_update_mem_attrs (grub_addr_t addr __attribute__((__unused__)),
-+		       grub_size_t size __attribute__((__unused__)),
-+		       grub_uint64_t set_attrs __attribute__((__unused__)),
-+		       grub_uint64_t clear_attrs __attribute__((__unused__)))
-+{
-+  return GRUB_ERR_NONE;
-+}
-+#endif /* GRUB_MACHINE_EFI */
-+
- void grub_mm_check_real (const char *file, int line);
- #define grub_mm_check() grub_mm_check_real (GRUB_FILE, __LINE__);
- 
diff --git a/SOURCES/0546-modules-Don-t-allocate-space-for-non-allocable-secti.patch b/SOURCES/0546-modules-Don-t-allocate-space-for-non-allocable-secti.patch
new file mode 100644
index 0000000..2f3bc0c
--- /dev/null
+++ b/SOURCES/0546-modules-Don-t-allocate-space-for-non-allocable-secti.patch
@@ -0,0 +1,37 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Mon, 21 Mar 2022 16:56:10 -0400
+Subject: [PATCH] modules: Don't allocate space for non-allocable sections.
+
+Currently when loading grub modules, we allocate space for all sections,
+including those without SHF_ALLOC set.  We then copy the sections that
+/do/ have SHF_ALLOC set into the allocated memory, leaving some of our
+allocation untouched forever.  Additionally, on platforms with GOT
+fixups and trampolines, we currently compute alignment round-ups for the
+sections and sections with sh_size = 0.
+
+This patch removes the extra space from the allocation computation, and
+makes the allocation computation loop skip empty sections as the loading
+loop does.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+(cherry picked from commit 03215e342f552396ab08125ea769b1e166417ec1)
+(cherry picked from commit 91518751b9bcba078e3f4385f4b2f6c39cab49cd)
+---
+ grub-core/kern/dl.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
+index 520126beab..ba1b33c20b 100644
+--- a/grub-core/kern/dl.c
++++ b/grub-core/kern/dl.c
+@@ -290,6 +290,9 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
+        i < e->e_shnum;
+        i++, s = (const Elf_Shdr *)((const char *) s + e->e_shentsize))
+     {
++      if (s->sh_size == 0 || !(s->sh_flags & SHF_ALLOC))
++	continue;
++
+       tsize = ALIGN_UP (tsize, s->sh_addralign) + s->sh_size;
+       if (talign < s->sh_addralign)
+ 	talign = s->sh_addralign;
diff --git a/SOURCES/0546-nx-set-page-permissions-for-loaded-modules.patch b/SOURCES/0546-nx-set-page-permissions-for-loaded-modules.patch
deleted file mode 100644
index 0d40b91..0000000
--- a/SOURCES/0546-nx-set-page-permissions-for-loaded-modules.patch
+++ /dev/null
@@ -1,266 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Mon, 21 Mar 2022 17:46:35 -0400
-Subject: [PATCH] nx: set page permissions for loaded modules.
-
-For NX, we need to set write and executable permissions on the sections
-of grub modules when we load them.
-
-On sections with SHF_ALLOC set, which is typically everything except
-.modname and the symbol and string tables, this patch clears the Read
-Only flag on sections that have the ELF flag SHF_WRITE set, and clears
-the No eXecute flag on sections with SHF_EXECINSTR set.  In all other
-cases it sets both flags.
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
-[rharwood: arm tgptr -> tgaddr]
-Signed-off-by: Robbie Harwood <rharwood@redhat.com>
-(cherry-picked from commit ca74904ede0406b594cbedc52ce8e38a6633d2ae)
-(cherry picked from commit 2e2e72026f41cf7cffeb46a6a47f3c67d0b3be45)
-(cherry picked from commit 736e5ccd9175d31ebea848f3b627f3e99988bb0a)
----
- grub-core/kern/dl.c | 120 +++++++++++++++++++++++++++++++++++++++-------------
- include/grub/dl.h   |  44 +++++++++++++++++++
- 2 files changed, 134 insertions(+), 30 deletions(-)
-
-diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
-index 5c2153acf9..68d3177f5e 100644
---- a/grub-core/kern/dl.c
-+++ b/grub-core/kern/dl.c
-@@ -286,6 +286,8 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
- #endif
-   char *ptr;
- 
-+  grub_dprintf ("modules", "loading segments for \"%s\"\n", mod->name);
-+
-   arch_addralign = grub_arch_dl_min_alignment ();
- 
-   for (i = 0, s = (const Elf_Shdr *)((const char *) e + e->e_shoff);
-@@ -385,6 +387,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
-   ptr += got;
- #endif
- 
-+  grub_dprintf ("modules", "done loading segments for \"%s\"\n", mod->name);
-   return GRUB_ERR_NONE;
- }
- 
-@@ -518,23 +521,6 @@ grub_dl_find_section (Elf_Ehdr *e, const char *name)
-       return s;
-   return NULL;
- }
--static long
--grub_dl_find_section_index (Elf_Ehdr *e, const char *name)
--{
--  Elf_Shdr *s;
--  const char *str;
--  unsigned i;
--
--  s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize);
--  str = (char *) e + s->sh_offset;
--
--  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
--       i < e->e_shnum;
--       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
--    if (grub_strcmp (str + s->sh_name, name) == 0)
--      return (long)i;
--  return -1;
--}
- 
- /* Me, Vladimir Serbinenko, hereby I add this module check as per new
-    GNU module policy. Note that this license check is informative only.
-@@ -661,6 +647,7 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
-   Elf_Shdr *s;
-   unsigned i;
- 
-+  grub_dprintf ("modules", "relocating symbols for \"%s\"\n", mod->name);
-   for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
-        i < e->e_shnum;
-        i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
-@@ -669,24 +656,95 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
- 	grub_dl_segment_t seg;
- 	grub_err_t err;
- 
--	/* Find the target segment.  */
--	for (seg = mod->segment; seg; seg = seg->next)
--	  if (seg->section == s->sh_info)
--	    break;
-+	seg = grub_dl_find_segment(mod, s->sh_info);
-+        if (!seg)
-+	  continue;
- 
--	if (seg)
--	  {
--	    if (!mod->symtab)
--	      return grub_error (GRUB_ERR_BAD_MODULE, "relocation without symbol table");
-+	if (!mod->symtab)
-+	  return grub_error (GRUB_ERR_BAD_MODULE, "relocation without symbol table");
- 
--	    err = grub_arch_dl_relocate_symbols (mod, ehdr, s, seg);
--	    if (err)
--	      return err;
--	  }
-+	err = grub_arch_dl_relocate_symbols (mod, ehdr, s, seg);
-+	if (err)
-+	  return err;
-       }
- 
-+  grub_dprintf ("modules", "done relocating symbols for \"%s\"\n", mod->name);
-   return GRUB_ERR_NONE;
- }
-+
-+static grub_err_t
-+grub_dl_set_mem_attrs (grub_dl_t mod, void *ehdr)
-+{
-+  unsigned i;
-+  const Elf_Shdr *s;
-+  const Elf_Ehdr *e = ehdr;
-+#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv)
-+  grub_size_t arch_addralign = grub_arch_dl_min_alignment ();
-+  grub_addr_t tgaddr;
-+  grub_uint64_t tgsz;
-+#endif
-+
-+  grub_dprintf ("modules", "updating memory attributes for \"%s\"\n",
-+		mod->name);
-+  for (i = 0, s = (const Elf_Shdr *)((const char *) e + e->e_shoff);
-+       i < e->e_shnum;
-+       i++, s = (const Elf_Shdr *)((const char *) s + e->e_shentsize))
-+    {
-+      grub_dl_segment_t seg;
-+      grub_uint64_t set_attrs = GRUB_MEM_ATTR_R;
-+      grub_uint64_t clear_attrs = GRUB_MEM_ATTR_W|GRUB_MEM_ATTR_X;
-+
-+      seg = grub_dl_find_segment(mod, i);
-+      if (!seg)
-+	continue;
-+
-+      if (seg->size == 0 || !(s->sh_flags & SHF_ALLOC))
-+	continue;
-+
-+      if (s->sh_flags & SHF_WRITE)
-+	{
-+	  set_attrs |= GRUB_MEM_ATTR_W;
-+	  clear_attrs &= ~GRUB_MEM_ATTR_W;
-+	}
-+
-+      if (s->sh_flags & SHF_EXECINSTR)
-+	{
-+	  set_attrs |= GRUB_MEM_ATTR_X;
-+	  clear_attrs &= ~GRUB_MEM_ATTR_X;
-+	}
-+
-+      grub_dprintf ("modules", "setting memory attrs for section \"%s\" to -%s%s%s+%s%s%s\n",
-+		    grub_dl_get_section_name(e, s),
-+		    (clear_attrs & GRUB_MEM_ATTR_R) ? "r" : "",
-+		    (clear_attrs & GRUB_MEM_ATTR_W) ? "w" : "",
-+		    (clear_attrs & GRUB_MEM_ATTR_X) ? "x" : "",
-+		    (set_attrs & GRUB_MEM_ATTR_R) ? "r" : "",
-+		    (set_attrs & GRUB_MEM_ATTR_W) ? "w" : "",
-+		    (set_attrs & GRUB_MEM_ATTR_X) ? "x" : "");
-+      grub_update_mem_attrs ((grub_addr_t)(seg->addr), seg->size, set_attrs, clear_attrs);
-+    }
-+
-+#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv)
-+  tgaddr = grub_min((grub_addr_t)mod->tramp, (grub_addr_t)mod->got);
-+  tgsz = grub_max((grub_addr_t)mod->trampptr, (grub_addr_t)mod->gotptr) - tgaddr;
-+
-+  if (tgsz)
-+    {
-+      tgsz = ALIGN_UP(tgsz, arch_addralign);
-+
-+      grub_dprintf ("modules", "updating attributes for GOT and trampolines\n",
-+		    mod->name);
-+      grub_update_mem_attrs (tgaddr, tgsz, GRUB_MEM_ATTR_R|GRUB_MEM_ATTR_X,
-+			     GRUB_MEM_ATTR_W);
-+    }
-+#endif
-+
-+  grub_dprintf ("modules", "done updating module memory attributes for \"%s\"\n",
-+		mod->name);
-+
-+  return GRUB_ERR_NONE;
-+}
-+
- static void
- grub_dl_print_gdb_info (grub_dl_t mod, Elf_Ehdr *e)
- {
-@@ -752,6 +810,7 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size)
-   mod->ref_count = 1;
- 
-   grub_dprintf ("modules", "relocating to %p\n", mod);
-+
-   /* Me, Vladimir Serbinenko, hereby I add this module check as per new
-      GNU module policy. Note that this license check is informative only.
-      Modules have to be licensed under GPLv3 or GPLv3+ (optionally
-@@ -765,7 +824,8 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size)
-       || grub_dl_resolve_dependencies (mod, e)
-       || grub_dl_load_segments (mod, e)
-       || grub_dl_resolve_symbols (mod, e)
--      || grub_dl_relocate_symbols (mod, e))
-+      || grub_dl_relocate_symbols (mod, e)
-+      || grub_dl_set_mem_attrs (mod, e))
-     {
-       mod->fini = 0;
-       grub_dl_unload (mod);
-diff --git a/include/grub/dl.h b/include/grub/dl.h
-index dd4c3e7ff4..6f46b7e86f 100644
---- a/include/grub/dl.h
-+++ b/include/grub/dl.h
-@@ -27,6 +27,7 @@
- #include <grub/elf.h>
- #include <grub/list.h>
- #include <grub/misc.h>
-+#include <grub/mm.h>
- #endif
- 
- /*
-@@ -268,6 +269,49 @@ grub_dl_is_persistent (grub_dl_t mod)
-   return mod->persistent;
- }
- 
-+static inline const char *
-+grub_dl_get_section_name (const Elf_Ehdr *e, const Elf_Shdr *s)
-+{
-+  Elf_Shdr *str_s;
-+  const char *str;
-+
-+  str_s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize);
-+  str = (char *) e + str_s->sh_offset;
-+
-+  return str + s->sh_name;
-+}
-+
-+static inline long
-+grub_dl_find_section_index (Elf_Ehdr *e, const char *name)
-+{
-+  Elf_Shdr *s;
-+  const char *str;
-+  unsigned i;
-+
-+  s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize);
-+  str = (char *) e + s->sh_offset;
-+
-+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
-+       i < e->e_shnum;
-+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
-+    if (grub_strcmp (str + s->sh_name, name) == 0)
-+      return (long)i;
-+  return -1;
-+}
-+
-+/* Return the segment for a section of index N */
-+static inline grub_dl_segment_t
-+grub_dl_find_segment (grub_dl_t mod, unsigned n)
-+{
-+  grub_dl_segment_t seg;
-+
-+  for (seg = mod->segment; seg; seg = seg->next)
-+    if (seg->section == n)
-+      return seg;
-+
-+  return NULL;
-+}
-+
- #endif
- 
- void * EXPORT_FUNC(grub_resolve_symbol) (const char *name);
diff --git a/SOURCES/0547-nx-set-attrs-in-our-kernel-loaders.patch b/SOURCES/0547-nx-set-attrs-in-our-kernel-loaders.patch
deleted file mode 100644
index 3fddaae..0000000
--- a/SOURCES/0547-nx-set-attrs-in-our-kernel-loaders.patch
+++ /dev/null
@@ -1,572 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Tue, 22 Mar 2022 10:57:07 -0400
-Subject: [PATCH] nx: set attrs in our kernel loaders
-
-For NX, our kernel loaders need to set write and execute page
-permissions on allocated pages and the stack.
-
-This patch adds those calls.
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
-[rharwood: fix aarch64 callsites]
-(cherry-picked from commit a9f79a997f01a83b36cdfa89ef2e72ac2a17c06c)
-[rharwood: double verification]
-(cherry picked from commit daba852bd3e4d7b7784b19cf7acf107dc3c0dce4)
-[rharwood: stack_attrs initialization, no risc-v, arm renames, arm age]
-Signed-off-by: Robbie Harwood <rharwood@redhat.com>
-(cherry picked from commit 3a402a2e54b3468b20eae182d98913600a6b68dd)
----
- grub-core/kern/efi/mm.c            |  78 ++++++++++++++++++
- grub-core/loader/arm64/linux.c     |  16 +++-
- grub-core/loader/arm64/xen_boot.c  |   4 +-
- grub-core/loader/efi/chainloader.c |  11 +++
- grub-core/loader/efi/linux.c       | 162 ++++++++++++++++++++++++++++++++++++-
- grub-core/loader/i386/efi/linux.c  |  26 +++++-
- grub-core/loader/i386/linux.c      |   5 ++
- include/grub/efi/efi.h             |   6 +-
- include/grub/efi/linux.h           |  17 +++-
- include/grub/efi/pe32.h            |   2 +
- 10 files changed, 312 insertions(+), 15 deletions(-)
-
-diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
-index 2cf4a4883a..8a896144df 100644
---- a/grub-core/kern/efi/mm.c
-+++ b/grub-core/kern/efi/mm.c
-@@ -602,6 +602,82 @@ print_memory_map (grub_efi_memory_descriptor_t *memory_map,
- }
- #endif
- 
-+grub_addr_t grub_stack_addr = (grub_addr_t)-1ll;
-+grub_size_t grub_stack_size = 0;
-+
-+static void
-+grub_nx_init (void)
-+{
-+  grub_uint64_t attrs, stack_attrs;
-+  grub_err_t err;
-+  grub_addr_t stack_current, stack_end;
-+  const grub_uint64_t page_size = 4096;
-+  const grub_uint64_t page_mask = ~(page_size - 1);
-+
-+  /*
-+   * These are to confirm that the flags are working as expected when
-+   * debugging.
-+   */
-+  attrs = 0;
-+  stack_current = (grub_addr_t)grub_nx_init & page_mask;
-+  err = grub_get_mem_attrs (stack_current, page_size, &attrs);
-+  if (err)
-+    {
-+      grub_dprintf ("nx",
-+		    "grub_get_mem_attrs(0x%"PRIxGRUB_UINT64_T", ...) -> 0x%x\n",
-+		    stack_current, err);
-+      grub_error_pop ();
-+    }
-+  else
-+    grub_dprintf ("nx", "page attrs for grub_nx_init (%p) are %c%c%c\n",
-+		  grub_dl_load_core,
-+		  (attrs & GRUB_MEM_ATTR_R) ? 'r' : '-',
-+		  (attrs & GRUB_MEM_ATTR_R) ? 'w' : '-',
-+		  (attrs & GRUB_MEM_ATTR_R) ? 'x' : '-');
-+
-+  stack_current = (grub_addr_t)&stack_current & page_mask;
-+  err = grub_get_mem_attrs (stack_current, page_size, &stack_attrs);
-+  if (err)
-+    {
-+      grub_dprintf ("nx",
-+		    "grub_get_mem_attrs(0x%"PRIxGRUB_UINT64_T", ...) -> 0x%x\n",
-+		    stack_current, err);
-+      grub_error_pop ();
-+    }
-+  else
-+    {
-+      attrs = stack_attrs;
-+      grub_dprintf ("nx", "page attrs for stack (%p) are %c%c%c\n",
-+                    &attrs,
-+                    (attrs & GRUB_MEM_ATTR_R) ? 'r' : '-',
-+                    (attrs & GRUB_MEM_ATTR_R) ? 'w' : '-',
-+                    (attrs & GRUB_MEM_ATTR_R) ? 'x' : '-');
-+    }
-+
-+  for (stack_end = stack_current + page_size ;
-+       !(attrs & GRUB_MEM_ATTR_R);
-+       stack_end += page_size)
-+    {
-+      err = grub_get_mem_attrs (stack_current, page_size, &attrs);
-+      if (err)
-+	{
-+	  grub_dprintf ("nx",
-+			"grub_get_mem_attrs(0x%"PRIxGRUB_UINT64_T", ...) -> 0x%x\n",
-+			stack_current, err);
-+	  grub_error_pop ();
-+	  break;
-+	}
-+    }
-+  if (stack_end > stack_current)
-+    {
-+      grub_stack_addr = stack_current;
-+      grub_stack_size = stack_end - stack_current;
-+      grub_dprintf ("nx",
-+		    "detected stack from 0x%"PRIxGRUB_ADDR" to 0x%"PRIxGRUB_ADDR"\n",
-+		    grub_stack_addr, grub_stack_addr + grub_stack_size - 1);
-+    }
-+}
-+
- void
- grub_efi_mm_init (void)
- {
-@@ -615,6 +691,8 @@ grub_efi_mm_init (void)
-   grub_efi_uint64_t required_pages;
-   int mm_status;
- 
-+  grub_nx_init ();
-+
-   /* Prepare a memory region to store two memory maps.  */
-   memory_map = grub_efi_allocate_any_pages (2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
-   if (! memory_map)
-diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
-index 24ab0f0074..37f5d0c7eb 100644
---- a/grub-core/loader/arm64/linux.c
-+++ b/grub-core/loader/arm64/linux.c
-@@ -191,7 +191,8 @@ free_params (void)
- }
- 
- grub_err_t
--grub_armxx_efi_linux_boot_image (grub_addr_t addr, char *args)
-+grub_armxx_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args,
-+				int nx_supported)
- {
-   grub_err_t retval;
- 
-@@ -201,7 +202,8 @@ grub_armxx_efi_linux_boot_image (grub_addr_t addr, char *args)
- 
-   grub_dprintf ("linux", "linux command line: '%s'\n", args);
- 
--  retval = grub_efi_linux_boot ((char *)addr, handover_offset, (void *)addr);
-+  retval = grub_efi_linux_boot (addr, size, handover_offset,
-+				(void *)addr, nx_supported);
- 
-   /* Never reached... */
-   free_params();
-@@ -211,7 +213,10 @@ grub_armxx_efi_linux_boot_image (grub_addr_t addr, char *args)
- static grub_err_t
- grub_linux_boot (void)
- {
--  return grub_armxx_efi_linux_boot_image((grub_addr_t)kernel_addr, linux_args);
-+  return grub_armxx_efi_linux_boot_image((grub_addr_t)kernel_addr,
-+					(grub_size_t)kernel_size,
-+					linux_args,
-+					0);
- }
- 
- static grub_err_t
-@@ -340,6 +345,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-   struct grub_armxx_linux_pe_header *pe;
-   int rc;
-   grub_err_t err;
-+  int nx_supported = 1;
- 
-   grub_dl_ref (my_mod);
- 
-@@ -395,6 +401,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- 	}
-     }
- 
-+  err = grub_efi_check_nx_image_support((grub_addr_t) kernel_addr, kernel_size, &nx_supported);
-+  if (err != GRUB_ERR_NONE)
-+    goto fail;
-+
-   pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
-   handover_offset = pe->opt.entry_addr;
- 
-diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c
-index 1a337866f0..1fd1bbb4bd 100644
---- a/grub-core/loader/arm64/xen_boot.c
-+++ b/grub-core/loader/arm64/xen_boot.c
-@@ -266,7 +266,9 @@ xen_boot (void)
-     return err;
- 
-   return grub_armxx_efi_linux_boot_image (xen_hypervisor->start,
--					  xen_hypervisor->cmdline);
-+                                         xen_hypervisor->size,
-+                                         xen_hypervisor->cmdline,
-+                                         0);
- }
- 
- static void
-diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
-index 8e658f713e..b72e6bd5e3 100644
---- a/grub-core/loader/efi/chainloader.c
-+++ b/grub-core/loader/efi/chainloader.c
-@@ -1055,6 +1055,17 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
-       goto fail;
-     }
- 
-+  /*
-+   * The OS kernel is going to set its own permissions when it takes over
-+   * paging a few million instructions from now, and load_image() will set up
-+   * anything that's needed based on the section headers, so there's no point
-+   * in doing anything but clearing the protection bits here.
-+   */
-+  grub_dprintf("nx", "setting attributes for %p (%lu bytes) to %llx\n",
-+	       (void *)(grub_addr_t)address, fsize, 0llu);
-+  grub_update_mem_attrs (address, fsize,
-+			 GRUB_MEM_ATTR_R|GRUB_MEM_ATTR_W|GRUB_MEM_ATTR_X, 0);
-+
- #if defined (__i386__) || defined (__x86_64__)
-   if (fsize >= (grub_ssize_t) sizeof (struct grub_macho_fat_header))
-     {
-diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
-index 927d89a90d..421502bd25 100644
---- a/grub-core/loader/efi/linux.c
-+++ b/grub-core/loader/efi/linux.c
-@@ -66,16 +66,125 @@ grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
- 
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wcast-align"
-+#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
-+
-+grub_err_t
-+grub_efi_check_nx_image_support (grub_addr_t kernel_addr,
-+				 grub_size_t kernel_size,
-+				 int *nx_supported)
-+{
-+  struct grub_dos_header *doshdr;
-+  grub_size_t sz = sizeof (*doshdr);
-+
-+  struct grub_pe32_header_32 *pe32;
-+  struct grub_pe32_header_64 *pe64;
-+
-+  int image_is_compatible = 0;
-+  int is_64_bit;
-+
-+  if (kernel_size < sz)
-+    return grub_error (GRUB_ERR_BAD_OS, N_("kernel is too small"));
-+
-+  doshdr = (void *)kernel_addr;
-+
-+  if ((doshdr->magic & 0xffff) != GRUB_DOS_MAGIC)
-+    return grub_error (GRUB_ERR_BAD_OS, N_("kernel DOS magic is invalid"));
-+
-+  sz = doshdr->lfanew + sizeof (*pe32);
-+  if (kernel_size < sz)
-+    return grub_error (GRUB_ERR_BAD_OS, N_("kernel is too small"));
-+
-+  pe32 = (struct grub_pe32_header_32 *)(kernel_addr + doshdr->lfanew);
-+  pe64 = (struct grub_pe32_header_64 *)pe32;
-+
-+  if (grub_memcmp (pe32->signature, GRUB_PE32_SIGNATURE,
-+		   GRUB_PE32_SIGNATURE_SIZE) != 0)
-+    return grub_error (GRUB_ERR_BAD_OS, N_("kernel PE magic is invalid"));
-+
-+  switch (pe32->coff_header.machine)
-+    {
-+    case GRUB_PE32_MACHINE_ARMTHUMB_MIXED:
-+    case GRUB_PE32_MACHINE_I386:
-+      is_64_bit = 0;
-+      break;
-+    case GRUB_PE32_MACHINE_ARM64:
-+    case GRUB_PE32_MACHINE_IA64:
-+    case GRUB_PE32_MACHINE_X86_64:
-+      is_64_bit = 1;
-+      break;
-+    default:
-+      return grub_error (GRUB_ERR_BAD_OS, N_("PE machine type 0x%04hx unknown"),
-+			 pe32->coff_header.machine);
-+    }
-+
-+  if (is_64_bit)
-+    {
-+      sz = doshdr->lfanew + sizeof (*pe64);
-+      if (kernel_size < sz)
-+	return grub_error (GRUB_ERR_BAD_OS, N_("kernel is too small"));
-+
-+      if (pe64->optional_header.dll_characteristics & GRUB_PE32_NX_COMPAT)
-+	image_is_compatible = 1;
-+    }
-+  else
-+    {
-+      if (pe32->optional_header.dll_characteristics & GRUB_PE32_NX_COMPAT)
-+	image_is_compatible = 1;
-+    }
-+
-+  *nx_supported = image_is_compatible;
-+  return GRUB_ERR_NONE;
-+}
-+
-+grub_err_t
-+grub_efi_check_nx_required (int *nx_required)
-+{
-+  grub_efi_status_t status;
-+  grub_efi_guid_t guid = GRUB_EFI_SHIM_LOCK_GUID;
-+  grub_size_t mok_policy_sz = 0;
-+  char *mok_policy = NULL;
-+  grub_uint32_t mok_policy_attrs = 0;
-+
-+  status = grub_efi_get_variable_with_attributes ("MokPolicy", &guid,
-+						  &mok_policy_sz,
-+						  (void **)&mok_policy,
-+						  &mok_policy_attrs);
-+  if (status == GRUB_EFI_NOT_FOUND ||
-+      mok_policy_sz == 0 ||
-+      mok_policy == NULL)
-+    {
-+      *nx_required = 0;
-+      return GRUB_ERR_NONE;
-+    }
-+
-+  *nx_required = 0;
-+  if (mok_policy_sz < 1 ||
-+      mok_policy_attrs != (GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
-+			   GRUB_EFI_VARIABLE_RUNTIME_ACCESS) ||
-+      (mok_policy[mok_policy_sz-1] & GRUB_MOK_POLICY_NX_REQUIRED))
-+    *nx_required = 1;
-+
-+  return GRUB_ERR_NONE;
-+}
- 
- typedef void (*handover_func) (void *, grub_efi_system_table_t *, void *);
- 
- grub_err_t
--grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset,
--		     void *kernel_params)
-+grub_efi_linux_boot (grub_addr_t kernel_addr, grub_size_t kernel_size,
-+		     grub_off_t handover_offset, void *kernel_params,
-+		     int nx_supported)
- {
-   grub_efi_loaded_image_t *loaded_image = NULL;
-   handover_func hf;
-   int offset = 0;
-+  grub_uint64_t stack_set_attrs = GRUB_MEM_ATTR_R |
-+				  GRUB_MEM_ATTR_W |
-+				  GRUB_MEM_ATTR_X;
-+  grub_uint64_t stack_clear_attrs = 0;
-+  grub_uint64_t kernel_set_attrs = stack_set_attrs;
-+  grub_uint64_t kernel_clear_attrs = stack_clear_attrs;
-+  grub_uint64_t attrs;
-+  int nx_required = 0;
- 
- #ifdef __x86_64__
-   offset = 512;
-@@ -88,12 +197,57 @@ grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset,
-    */
-   loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
-   if (loaded_image)
--    loaded_image->image_base = kernel_addr;
-+    loaded_image->image_base = (void *)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_addr, (void *)(grub_efi_uintn_t)handover_offset, kernel_params);
-+		(void *)kernel_addr, (void *)handover_offset, kernel_params);
-+
-+
-+  if (nx_required && !nx_supported)
-+    return grub_error (GRUB_ERR_BAD_OS, N_("kernel does not support NX loading required by policy"));
-+
-+  if (nx_supported)
-+    {
-+      kernel_set_attrs &= ~GRUB_MEM_ATTR_W;
-+      kernel_clear_attrs |= GRUB_MEM_ATTR_W;
-+      stack_set_attrs &= ~GRUB_MEM_ATTR_X;
-+      stack_clear_attrs |= GRUB_MEM_ATTR_X;
-+    }
-+
-+  grub_dprintf ("nx", "Setting attributes for 0x%"PRIxGRUB_ADDR"-0x%"PRIxGRUB_ADDR" to r%cx\n",
-+		    kernel_addr, kernel_addr + kernel_size - 1,
-+		    (kernel_set_attrs & GRUB_MEM_ATTR_W) ? 'w' : '-');
-+  grub_update_mem_attrs (kernel_addr, kernel_size,
-+			 kernel_set_attrs, kernel_clear_attrs);
-+
-+  grub_get_mem_attrs (kernel_addr, 4096, &attrs);
-+  grub_dprintf ("nx", "permissions for 0x%"PRIxGRUB_ADDR" are %s%s%s\n",
-+		(grub_addr_t)kernel_addr,
-+		(attrs & GRUB_MEM_ATTR_R) ? "r" : "-",
-+		(attrs & GRUB_MEM_ATTR_W) ? "w" : "-",
-+		(attrs & GRUB_MEM_ATTR_X) ? "x" : "-");
-+  if (grub_stack_addr != (grub_addr_t)-1ll)
-+    {
-+      grub_dprintf ("nx", "Setting attributes for stack at 0x%"PRIxGRUB_ADDR"-0x%"PRIxGRUB_ADDR" to rw%c\n",
-+		    grub_stack_addr, grub_stack_addr + grub_stack_size - 1,
-+		    (stack_set_attrs & GRUB_MEM_ATTR_X) ? 'x' : '-');
-+      grub_update_mem_attrs (grub_stack_addr, grub_stack_size,
-+			     stack_set_attrs, stack_clear_attrs);
-+
-+      grub_get_mem_attrs (grub_stack_addr, 4096, &attrs);
-+      grub_dprintf ("nx", "permissions for 0x%"PRIxGRUB_ADDR" are %s%s%s\n",
-+		    grub_stack_addr,
-+		    (attrs & GRUB_MEM_ATTR_R) ? "r" : "-",
-+		    (attrs & GRUB_MEM_ATTR_W) ? "w" : "-",
-+		    (attrs & GRUB_MEM_ATTR_X) ? "x" : "-");
-+    }
-+
-+#if defined(__i386__) || defined(__x86_64__)
-+  asm volatile ("cli");
-+#endif
-+
-   hf = (handover_func)((char *)kernel_addr + handover_offset + offset);
-   grub_dprintf ("linux", "handover_func() = %p\n", hf);
-   hf (grub_efi_image_handle, grub_efi_system_table, kernel_params);
-diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
-index 3d4069e4c6..d80d6ec312 100644
---- a/grub-core/loader/i386/efi/linux.c
-+++ b/grub-core/loader/i386/efi/linux.c
-@@ -44,7 +44,7 @@ struct grub_linuxefi_context {
-   grub_uint32_t handover_offset;
-   struct linux_kernel_params *params;
-   char *cmdline;
--
-+  int nx_supported;
-   void *initrd_mem;
- };
- 
-@@ -110,13 +110,19 @@ kernel_alloc(grub_efi_uintn_t size,
-       pages = BYTES_TO_PAGES(size);
-       grub_dprintf ("linux", "Trying to allocate %lu pages from %p\n",
- 		    pages, (void *)max);
-+      size = pages * GRUB_EFI_PAGE_SIZE;
- 
-       prev_max = max;
-       addr = grub_efi_allocate_pages_real (max, pages,
- 					   max_addresses[i].alloc_type,
- 					   memtype);
-       if (addr)
--	grub_dprintf ("linux", "Allocated at %p\n", addr);
-+	{
-+	  grub_dprintf ("linux", "Allocated at %p\n", addr);
-+	  grub_update_mem_attrs ((grub_addr_t)addr, size,
-+				 GRUB_MEM_ATTR_R|GRUB_MEM_ATTR_W,
-+				 GRUB_MEM_ATTR_X);
-+	}
-     }
- 
-   while (grub_error_pop ())
-@@ -137,9 +143,11 @@ grub_linuxefi_boot (void *data)
- 
-   asm volatile ("cli");
- 
--  return grub_efi_linux_boot ((char *)context->kernel_mem,
-+  return grub_efi_linux_boot ((grub_addr_t)context->kernel_mem,
-+			      context->kernel_size,
- 			      context->handover_offset,
--			      context->params);
-+			      context->params,
-+			      context->nx_supported);
- }
- 
- static grub_err_t
-@@ -308,7 +316,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-   grub_uint32_t handover_offset;
-   struct linux_kernel_params *params = 0;
-   char *cmdline = 0;
-+  int nx_supported = 1;
-   struct grub_linuxefi_context *context = 0;
-+  grub_err_t err;
- 
-   grub_dl_ref (my_mod);
- 
-@@ -352,6 +362,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- 	}
-     }
- 
-+  err = grub_efi_check_nx_image_support ((grub_addr_t)kernel, filelen,
-+					 &nx_supported);
-+  if (err != GRUB_ERR_NONE)
-+    return err;
-+  grub_dprintf ("linux", "nx is%s supported by this kernel\n",
-+		nx_supported ? "" : " not");
-+
-   lh = (struct linux_i386_kernel_header *)kernel;
-   grub_dprintf ("linux", "original lh is at %p\n", kernel);
- 
-@@ -515,6 +532,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-   context->handover_offset = handover_offset;
-   context->params = params;
-   context->cmdline = cmdline;
-+  context->nx_supported = nx_supported;
- 
-   grub_loader_set_ex (grub_linuxefi_boot, grub_linuxefi_unload, context, 0);
- 
-diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
-index ef8fcb9e1b..c160ddb0ea 100644
---- a/grub-core/loader/i386/linux.c
-+++ b/grub-core/loader/i386/linux.c
-@@ -831,6 +831,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-   grub_memset (&linux_params, 0, sizeof (linux_params));
-   grub_memcpy (&linux_params.setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1);
- 
-+  grub_dprintf("efi", "setting attributes for %p (%zu bytes) to +rw-x\n",
-+	       &linux_params, sizeof (lh) + len);
-+  grub_update_mem_attrs ((grub_addr_t)&linux_params, sizeof (lh) + len,
-+			 GRUB_MEM_ATTR_R|GRUB_MEM_ATTR_W, GRUB_MEM_ATTR_X);
-+
-   linux_params.code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR;
-   linux_params.kernel_alignment = (1 << align);
-   linux_params.ps_mouse = linux_params.padding10 =  0;
-diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
-index a635bcb0a9..8ca8c38f9a 100644
---- a/include/grub/efi/efi.h
-+++ b/include/grub/efi/efi.h
-@@ -135,12 +135,16 @@ extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd,
- 						char **device,
- 						char **path);
- 
-+extern grub_addr_t EXPORT_VAR(grub_stack_addr);
-+extern grub_size_t EXPORT_VAR(grub_stack_size);
-+
- #if defined(__arm__) || defined(__aarch64__)
- void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void);
- grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *);
- #include <grub/cpu/linux.h>
- grub_err_t grub_armxx_efi_linux_check_image(struct linux_armxx_kernel_header *lh);
--grub_err_t grub_armxx_efi_linux_boot_image(grub_addr_t addr, char *args);
-+grub_err_t grub_armxx_efi_linux_boot_image(grub_addr_t addr, grub_size_t size,
-+					  char *args, int nx_enabled);
- #endif
- 
- grub_addr_t grub_efi_section_addr (const char *section);
-diff --git a/include/grub/efi/linux.h b/include/grub/efi/linux.h
-index 0033d9305a..8130b19590 100644
---- a/include/grub/efi/linux.h
-+++ b/include/grub/efi/linux.h
-@@ -22,10 +22,23 @@
- #include <grub/err.h>
- #include <grub/symbol.h>
- 
-+#define GRUB_MOK_POLICY_NX_REQUIRED   0x1
-+
- int
- EXPORT_FUNC(grub_linuxefi_secure_validate) (void *data, grub_uint32_t size);
-+
- grub_err_t
--EXPORT_FUNC(grub_efi_linux_boot) (void *kernel_address, grub_off_t offset,
--				  void *kernel_param);
-+EXPORT_FUNC(grub_efi_linux_boot) (grub_addr_t kernel_address,
-+				  grub_size_t kernel_size,
-+				  grub_off_t handover_offset,
-+				  void *kernel_param, int nx_enabled);
-+
-+grub_err_t
-+EXPORT_FUNC(grub_efi_check_nx_image_support) (grub_addr_t kernel_addr,
-+					      grub_size_t kernel_size,
-+					      int *nx_supported);
-+
-+grub_err_t
-+EXPORT_FUNC(grub_efi_check_nx_required) (int *nx_required);
- 
- #endif /* ! GRUB_EFI_LINUX_HEADER */
-diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
-index 2241f6317b..45c9f8b756 100644
---- a/include/grub/efi/pe32.h
-+++ b/include/grub/efi/pe32.h
-@@ -172,6 +172,8 @@ struct grub_pe32_optional_header
-   struct grub_pe32_data_directory reserved_entry;
- };
- 
-+#define GRUB_PE32_NX_COMPAT 0x0100
-+
- struct grub_pe64_optional_header
- {
-   grub_uint16_t magic;
diff --git a/SOURCES/0547-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch b/SOURCES/0547-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch
new file mode 100644
index 0000000..f9c2234
--- /dev/null
+++ b/SOURCES/0547-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch
@@ -0,0 +1,83 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Fri, 25 Mar 2022 15:40:12 -0400
+Subject: [PATCH] pe: add the DOS header struct and fix some bad naming.
+
+In order to properly validate a loaded kernel's support for being loaded
+without a writable stack or executable, we need to be able to properly
+parse arbitrary PE headers.
+
+Currently, pe32.h is written in such a way that the MS-DOS header that
+tells us where to find the PE header in the binary can't be accessed.
+Further, for some reason it calls the DOS MZ magic "GRUB_PE32_MAGIC".
+
+This patch adds the structure for the DOS header, renames the DOS magic
+define, and adds defines for the actual PE magic.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+(cherry picked from commit 955f47aa8300387eecf18b0866d21dde7720593d)
+(cherry picked from commit 662744c2e986cb770fe49e71e019aaf33a66272d)
+---
+ grub-core/loader/arm64/linux.c |  2 +-
+ include/grub/efi/pe32.h        | 28 ++++++++++++++++++++++++++--
+ 2 files changed, 27 insertions(+), 3 deletions(-)
+
+diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
+index e1923cf725..24ab0f0074 100644
+--- a/grub-core/loader/arm64/linux.c
++++ b/grub-core/loader/arm64/linux.c
+@@ -57,7 +57,7 @@ grub_armxx_efi_linux_check_image (struct linux_armxx_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)
++  if ((lh->code0 & 0xffff) != GRUB_DOS_MAGIC)
+     return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+ 		       N_("plain image kernel not supported - rebuild with CONFIG_(U)EFI_STUB enabled"));
+ 
+diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
+index c03cc599f6..2241f6317b 100644
+--- a/include/grub/efi/pe32.h
++++ b/include/grub/efi/pe32.h
+@@ -45,7 +45,30 @@
+ 
+ #define GRUB_PE32_MSDOS_STUB_SIZE	0x80
+ 
+-#define GRUB_PE32_MAGIC			0x5a4d
++#define GRUB_DOS_MAGIC			0x5a4d
++
++struct grub_dos_header
++{
++  grub_uint16_t magic;
++  grub_uint16_t cblp;
++  grub_uint16_t cp;
++  grub_uint16_t crlc;
++  grub_uint16_t cparhdr;
++  grub_uint16_t minalloc;
++  grub_uint16_t maxalloc;
++  grub_uint16_t ss;
++  grub_uint16_t sp;
++  grub_uint16_t csum;
++  grub_uint16_t ip;
++  grub_uint16_t cs;
++  grub_uint16_t lfarlc;
++  grub_uint16_t ovno;
++  grub_uint16_t res0[4];
++  grub_uint16_t oemid;
++  grub_uint16_t oeminfo;
++  grub_uint16_t res1[10];
++  grub_uint32_t lfanew;
++};
+ 
+ /* According to the spec, the minimal alignment is 512 bytes...
+    But some examples (such as EFI drivers in the Intel
+@@ -271,7 +294,8 @@ struct grub_pe32_section_table
+ 
+ 
+ 
+-#define GRUB_PE32_SIGNATURE_SIZE 4
++#define GRUB_PE32_SIGNATURE_SIZE		4
++#define GRUB_PE32_SIGNATURE			"PE\0\0"
+ 
+ struct grub_pe32_header
+ {
diff --git a/SOURCES/0548-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch b/SOURCES/0548-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch
new file mode 100644
index 0000000..8644e51
--- /dev/null
+++ b/SOURCES/0548-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch
@@ -0,0 +1,87 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Wed, 9 Feb 2022 16:08:20 -0500
+Subject: [PATCH] EFI: allocate kernel in EFI_RUNTIME_SERVICES_CODE instead of
+ EFI_LOADER_DATA.
+
+On some of the firmwares with more security mitigations, EFI_LOADER_DATA
+doesn't get you executable memory, and we take a fault and reboot when
+we enter kernel.
+
+This patch correctly allocates the kernel code as EFI_RUNTIME_SERVICES_CODE
+rather than EFI_LOADER_DATA.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+[rharwood: use kernel_size]
+Signed-off-by: Robbie Harwood <rharwood@redhat.com>
+(cherry picked from commit 8b31058a12d3e85f0f0180ac90b98d6465fccbb7)
+(cherry picked from commit 460df66aab9b3a57fc0d14a21a595cd467c4b13e)
+---
+ grub-core/loader/i386/efi/linux.c | 19 +++++++++++++------
+ 1 file changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
+index 8337191921..3d4069e4c6 100644
+--- a/grub-core/loader/i386/efi/linux.c
++++ b/grub-core/loader/i386/efi/linux.c
+@@ -86,7 +86,9 @@ kernel_free(void *addr, grub_efi_uintn_t size)
+ }
+ 
+ static void *
+-kernel_alloc(grub_efi_uintn_t size, const char * const errmsg)
++kernel_alloc(grub_efi_uintn_t size,
++	     grub_efi_memory_type_t memtype,
++	     const char * const errmsg)
+ {
+   void *addr = 0;
+   unsigned int i;
+@@ -112,7 +114,7 @@ kernel_alloc(grub_efi_uintn_t size, const char * const errmsg)
+       prev_max = max;
+       addr = grub_efi_allocate_pages_real (max, pages,
+ 					   max_addresses[i].alloc_type,
+-					   GRUB_EFI_LOADER_DATA);
++					   memtype);
+       if (addr)
+ 	grub_dprintf ("linux", "Allocated at %p\n", addr);
+     }
+@@ -243,7 +245,8 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
+ 	}
+     }
+ 
+-  initrd_mem = kernel_alloc(size, N_("can't allocate initrd"));
++  initrd_mem = kernel_alloc(size, GRUB_EFI_RUNTIME_SERVICES_DATA,
++			    N_("can't allocate initrd"));
+   if (initrd_mem == NULL)
+     goto fail;
+   grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem);
+@@ -411,7 +414,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+     }
+ #endif
+ 
+-  params = kernel_alloc (sizeof(*params), "cannot allocate kernel parameters");
++  params = kernel_alloc (sizeof(*params), GRUB_EFI_RUNTIME_SERVICES_DATA,
++			 "cannot allocate kernel parameters");
+   if (!params)
+     goto fail;
+   grub_dprintf ("linux", "params = %p\n", params);
+@@ -432,7 +436,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+   grub_dprintf ("linux", "new lh is at %p\n", lh);
+ 
+   grub_dprintf ("linux", "setting up cmdline\n");
+-  cmdline = kernel_alloc (lh->cmdline_size + 1, N_("can't allocate cmdline"));
++  cmdline = kernel_alloc (lh->cmdline_size + 1,
++			  GRUB_EFI_RUNTIME_SERVICES_DATA,
++			  N_("can't allocate cmdline"));
+   if (!cmdline)
+     goto fail;
+   grub_dprintf ("linux", "cmdline = %p\n", cmdline);
+@@ -478,7 +484,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+   max_addresses[1].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
+   max_addresses[2].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
+   kernel_size = lh->init_size;
+-  kernel_mem = kernel_alloc (kernel_size, N_("can't allocate kernel"));
++  kernel_mem = kernel_alloc (kernel_size, GRUB_EFI_RUNTIME_SERVICES_CODE,
++			     N_("can't allocate kernel"));
+   restore_addresses();
+   if (!kernel_mem)
+     goto fail;
diff --git a/SOURCES/0548-nx-set-the-nx-compatible-flag-in-EFI-grub-images.patch b/SOURCES/0548-nx-set-the-nx-compatible-flag-in-EFI-grub-images.patch
deleted file mode 100644
index 801efca..0000000
--- a/SOURCES/0548-nx-set-the-nx-compatible-flag-in-EFI-grub-images.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Tue, 22 Mar 2022 10:57:20 -0400
-Subject: [PATCH] nx: set the nx compatible flag in EFI grub images
-
-For NX, we need the grub binary to announce that it is compatible with
-the NX feature.  This implies that when loading the executable grub
-image, several attributes are true:
-
-- the binary doesn't need an executable stack
-- the binary doesn't need sections to be both executable and writable
-- the binary knows how to use the EFI Memory Attributes protocol on code
-  it is loading.
-
-This patch adds a definition for the PE DLL Characteristics flag
-GRUB_PE32_NX_COMPAT, and changes grub-mkimage to set that flag.
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
-(cherry picked from commit 0c7f1aed5a87f75051b421903a900ccb4bbd795a)
-(cherry picked from commit 2f9446d488da96de963f4ffe03b0a1c60a4664f5)
-(cherry picked from commit f56671343622b0e0216340cd07e77dfc4e88a97a)
----
- util/mkimage.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/util/mkimage.c b/util/mkimage.c
-index 16418e245d..c77025904c 100644
---- a/util/mkimage.c
-+++ b/util/mkimage.c
-@@ -1358,6 +1358,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
- 	    section = (struct grub_pe32_section_table *)(o64 + 1);
- 	  }
- 
-+	PE_OHDR (o32, o64, dll_characteristics) = grub_host_to_target16 (GRUB_PE32_NX_COMPAT);
- 	PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size);
- 	PE_OHDR (o32, o64, entry_addr) = grub_host_to_target32 (layout.start_address);
- 	PE_OHDR (o32, o64, image_base) = 0;
diff --git a/SOURCES/0549-Fixup-grub_efi_get_variable-type-in-our-loaders.patch b/SOURCES/0549-Fixup-grub_efi_get_variable-type-in-our-loaders.patch
deleted file mode 100644
index 8ec08c8..0000000
--- a/SOURCES/0549-Fixup-grub_efi_get_variable-type-in-our-loaders.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Robbie Harwood <rharwood@redhat.com>
-Date: Wed, 11 May 2022 16:37:14 -0400
-Subject: [PATCH] Fixup grub_efi_get_variable() type in our loaders
-
-Has a new type now that we have 04ae030d0eea8668d4417702d88bf2cf04713d80
-("efi: Return grub_efi_status_t from grub_efi_get_variable()").
-
-Signed-off-by: Robbie Harwood <rharwood@redhat.com>
-(cherry picked from commit d27cee05d31a9612f0b877d2de727b22cc3ec51a)
----
- grub-core/kern/efi/init.c | 4 ++--
- grub-core/kern/efi/sb.c   | 4 ++--
- 2 files changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
-index 501608f743..565ce541f5 100644
---- a/grub-core/kern/efi/init.c
-+++ b/grub-core/kern/efi/init.c
-@@ -104,8 +104,8 @@ grub_efi_env_init (void)
-   struct grub_envblk envblk_s = { NULL, 0 };
-   grub_envblk_t envblk = &envblk_s;
- 
--  envblk_s.buf = grub_efi_get_variable ("GRUB_ENV", &efi_grub_guid,
--					&envblk_s.size);
-+  grub_efi_get_variable ("GRUB_ENV", &efi_grub_guid, &envblk_s.size,
-+                         &envblk_s.buf);
-   if (!envblk_s.buf || envblk_s.size < 1)
-     return;
- 
-diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c
-index d74778b0ca..f84d7d3080 100644
---- a/grub-core/kern/efi/sb.c
-+++ b/grub-core/kern/efi/sb.c
-@@ -35,7 +35,7 @@ grub_efi_secure_boot (void)
-   char *setup_mode = NULL;
-   grub_efi_boolean_t ret = 0;
- 
--  secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize);
-+  grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize, &secure_boot);
-   if (datasize != 1 || !secure_boot)
-     {
-       grub_dprintf ("secureboot", "No SecureBoot variable\n");
-@@ -43,7 +43,7 @@ grub_efi_secure_boot (void)
-     }
-   grub_dprintf ("secureboot", "SecureBoot: %d\n", *secure_boot);
- 
--  setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize);
-+  grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize, &setup_mode);
-   if (datasize != 1 || !setup_mode)
-     {
-       grub_dprintf ("secureboot", "No SetupMode variable\n");
diff --git a/SOURCES/0549-modules-load-module-sections-at-page-aligned-address.patch b/SOURCES/0549-modules-load-module-sections-at-page-aligned-address.patch
new file mode 100644
index 0000000..44ecd2b
--- /dev/null
+++ b/SOURCES/0549-modules-load-module-sections-at-page-aligned-address.patch
@@ -0,0 +1,360 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Mon, 21 Mar 2022 17:45:40 -0400
+Subject: [PATCH] modules: load module sections at page-aligned addresses
+
+Currently we load module sections at whatever alignment gcc+ld happened
+to dump into the ELF section header, which is often pretty useless.  For
+example, by default time.mod has these sections on a current x86_64
+build:
+
+$ eu-readelf -a grub-core/time.mod |& grep ^Section -A13
+Section Headers:
+[Nr] Name            Type         Addr  Off      Size     ES Flags Lk Inf Al
+[ 0]                 NULL         0     00000000 00000000  0        0   0  0
+[ 1] .text           PROGBITS     0     00000040 0000015e  0 AX     0   0  1
+[ 2] .rela.text      RELA         0     00000458 000001e0 24 I      8   1  8
+[ 3] .rodata.str1.1  PROGBITS     0     0000019e 000000a1  1 AMS    0   0  1
+[ 4] .module_license PROGBITS     0     00000240 0000000f  0 A      0   0  8
+[ 5] .data           PROGBITS     0     0000024f 00000000  0 WA     0   0  1
+[ 6] .bss            NOBITS       0     00000250 00000008  0 WA     0   0  8
+[ 7] .modname        PROGBITS     0     00000250 00000005  0        0   0  1
+[ 8] .symtab         SYMTAB       0     00000258 00000150 24        9   6  8
+[ 9] .strtab         STRTAB       0     000003a8 000000ab  0        0   0  1
+[10] .shstrtab       STRTAB       0     00000638 00000059  0        0   0  1
+
+With NX protections being page based, loading sections with either a 1
+or 8 *byte* alignment does absolutely nothing to help us out.
+
+This patch switches most EFI platforms to load module sections at 4kB
+page-aligned addresses.  To do so, it adds an new per-arch function,
+grub_arch_dl_min_alignment(), which returns the alignment needed for
+dynamically loaded sections (in bytes).  Currently it sets it to 4096
+when GRUB_MACHINE_EFI is true on x86_64, i386, arm, arm64, and emu, and
+1-byte alignment on everything else.
+
+It then changes the allocation size computation and the loader code in
+grub_dl_load_segments() to align the locations and sizes up to these
+boundaries, and fills any added padding with zeros.
+
+All of this happens before relocations are applied, so the relocations
+factor that in with no change.
+
+As an aside, initially Daniel Kiper and I thought that it might be a
+better idea to split the modules up into top-level sections as
+.text.modules, .rodata.modules, .data.modules, etc., so that their page
+permissions would get set by the loader that's loading grub itself.
+This turns out to have two significant downsides: 1) either in mkimage
+or in grub_dl_relocate_symbols(), you wind up having to dynamically
+process the relocations to accommodate the moved module sections, and 2)
+you then need to change the permissions on the modules and change them
+back while relocating them in grub_dl_relocate_symbols(), which means
+that any loader that /does/ honor the section flags but does /not/
+generally support NX with the memory attributes API will cause grub to
+fail.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+(cherry picked from commit 31d52500b281619d92b03b2c2d30fe15aedaf326)
+(cherry picked from commit 04f1df6b665493e38de66018aebe377fdac4ceec)
+[rharwood: not risc-v yet]
+Signed-off-by: Robbie Harwood <rharwood@redhat.com>
+---
+ grub-core/kern/arm/dl.c     | 13 +++++++++++++
+ grub-core/kern/arm64/dl.c   | 13 +++++++++++++
+ grub-core/kern/dl.c         | 29 +++++++++++++++++++++--------
+ grub-core/kern/emu/full.c   | 13 +++++++++++++
+ grub-core/kern/i386/dl.c    | 13 +++++++++++++
+ grub-core/kern/ia64/dl.c    |  9 +++++++++
+ grub-core/kern/mips/dl.c    |  8 ++++++++
+ grub-core/kern/powerpc/dl.c |  9 +++++++++
+ grub-core/kern/sparc64/dl.c |  9 +++++++++
+ grub-core/kern/x86_64/dl.c  | 13 +++++++++++++
+ include/grub/dl.h           |  2 ++
+ docs/grub-dev.texi          |  6 +++---
+ 12 files changed, 126 insertions(+), 11 deletions(-)
+
+diff --git a/grub-core/kern/arm/dl.c b/grub-core/kern/arm/dl.c
+index eab9d17ff2..9260737936 100644
+--- a/grub-core/kern/arm/dl.c
++++ b/grub-core/kern/arm/dl.c
+@@ -278,3 +278,16 @@ grub_arch_dl_check_header (void *ehdr)
+ 
+   return GRUB_ERR_NONE;
+ }
++
++/*
++ * Tell the loader what our minimum section alignment is.
++ */
++grub_size_t
++grub_arch_dl_min_alignment (void)
++{
++#ifdef GRUB_MACHINE_EFI
++  return 4096;
++#else
++  return 1;
++#endif
++}
+diff --git a/grub-core/kern/arm64/dl.c b/grub-core/kern/arm64/dl.c
+index fb03373190..826f8e721e 100644
+--- a/grub-core/kern/arm64/dl.c
++++ b/grub-core/kern/arm64/dl.c
+@@ -191,3 +191,16 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
+ 
+   return GRUB_ERR_NONE;
+ }
++
++/*
++ * Tell the loader what our minimum section alignment is.
++ */
++grub_size_t
++grub_arch_dl_min_alignment (void)
++{
++#ifdef GRUB_MACHINE_EFI
++  return 4096;
++#else
++  return 1;
++#endif
++}
+diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
+index ba1b33c20b..5c2153acf9 100644
+--- a/grub-core/kern/dl.c
++++ b/grub-core/kern/dl.c
+@@ -278,7 +278,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
+ {
+   unsigned i;
+   const Elf_Shdr *s;
+-  grub_size_t tsize = 0, talign = 1;
++  grub_size_t tsize = 0, talign = 1, arch_addralign = 1;
+ #if !defined (__i386__) && !defined (__x86_64__)
+   grub_size_t tramp;
+   grub_size_t got;
+@@ -286,16 +286,24 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
+ #endif
+   char *ptr;
+ 
++  arch_addralign = grub_arch_dl_min_alignment ();
++
+   for (i = 0, s = (const Elf_Shdr *)((const char *) e + e->e_shoff);
+        i < e->e_shnum;
+        i++, s = (const Elf_Shdr *)((const char *) s + e->e_shentsize))
+     {
++      grub_size_t sh_addralign;
++      grub_size_t sh_size;
++
+       if (s->sh_size == 0 || !(s->sh_flags & SHF_ALLOC))
+ 	continue;
+ 
+-      tsize = ALIGN_UP (tsize, s->sh_addralign) + s->sh_size;
+-      if (talign < s->sh_addralign)
+-	talign = s->sh_addralign;
++      sh_addralign = ALIGN_UP(s->sh_addralign, arch_addralign);
++      sh_size = ALIGN_UP(s->sh_size, sh_addralign);
++
++      tsize = ALIGN_UP (tsize, sh_addralign) + sh_size;
++      if (talign < sh_addralign)
++	talign = sh_addralign;
+     }
+ 
+ #if !defined (__i386__) && !defined (__x86_64__)
+@@ -324,6 +332,9 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
+        i < e->e_shnum;
+        i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
+     {
++      grub_size_t sh_addralign = ALIGN_UP(s->sh_addralign, arch_addralign);
++      grub_size_t sh_size = ALIGN_UP(s->sh_size, sh_addralign);
++
+       if (s->sh_flags & SHF_ALLOC)
+ 	{
+ 	  grub_dl_segment_t seg;
+@@ -336,17 +347,19 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
+ 	    {
+ 	      void *addr;
+ 
+-	      ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, s->sh_addralign);
++	      ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, sh_addralign);
+ 	      addr = ptr;
+-	      ptr += s->sh_size;
++	      ptr += sh_size;
+ 
+ 	      switch (s->sh_type)
+ 		{
+ 		case SHT_PROGBITS:
+ 		  grub_memcpy (addr, (char *) e + s->sh_offset, s->sh_size);
++		  grub_memset ((char *)addr + s->sh_size, 0,
++			       sh_size - s->sh_size);
+ 		  break;
+ 		case SHT_NOBITS:
+-		  grub_memset (addr, 0, s->sh_size);
++		  grub_memset (addr, 0, sh_size);
+ 		  break;
+ 		}
+ 
+@@ -355,7 +368,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
+ 	  else
+ 	    seg->addr = 0;
+ 
+-	  seg->size = s->sh_size;
++	  seg->size = sh_size;
+ 	  seg->section = i;
+ 	  seg->next = mod->segment;
+ 	  mod->segment = seg;
+diff --git a/grub-core/kern/emu/full.c b/grub-core/kern/emu/full.c
+index e8d63b1f5f..1de1c28eb0 100644
+--- a/grub-core/kern/emu/full.c
++++ b/grub-core/kern/emu/full.c
+@@ -67,3 +67,16 @@ grub_arch_dl_init_linker (void)
+ }
+ #endif
+ 
++
++/*
++ * Tell the loader what our minimum section alignment is.
++ */
++grub_size_t
++grub_arch_dl_min_alignment (void)
++{
++#ifdef GRUB_MACHINE_EFI
++  return 4096;
++#else
++  return 1;
++#endif
++}
+diff --git a/grub-core/kern/i386/dl.c b/grub-core/kern/i386/dl.c
+index 1346da5cc9..d6b4681fc9 100644
+--- a/grub-core/kern/i386/dl.c
++++ b/grub-core/kern/i386/dl.c
+@@ -79,3 +79,16 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
+ 
+   return GRUB_ERR_NONE;
+ }
++
++/*
++ * Tell the loader what our minimum section alignment is.
++ */
++grub_size_t
++grub_arch_dl_min_alignment (void)
++{
++#ifdef GRUB_MACHINE_EFI
++  return 4096;
++#else
++  return 1;
++#endif
++}
+diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c
+index ebcf316298..3bb753a89b 100644
+--- a/grub-core/kern/ia64/dl.c
++++ b/grub-core/kern/ia64/dl.c
+@@ -143,3 +143,12 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
+     }
+   return GRUB_ERR_NONE;
+ }
++
++/*
++ * Tell the loader what our minimum section alignment is.
++ */
++grub_size_t
++grub_arch_dl_min_alignment (void)
++{
++  return 1;
++}
+diff --git a/grub-core/kern/mips/dl.c b/grub-core/kern/mips/dl.c
+index 5d7d299c74..6d83bd71e9 100644
+--- a/grub-core/kern/mips/dl.c
++++ b/grub-core/kern/mips/dl.c
+@@ -272,3 +272,11 @@ grub_arch_dl_init_linker (void)
+   grub_dl_register_symbol ("_gp_disp", &_gp_disp_dummy, 0, 0);
+ }
+ 
++/*
++ * Tell the loader what our minimum section alignment is.
++ */
++grub_size_t
++grub_arch_dl_min_alignment (void)
++{
++  return 1;
++}
+diff --git a/grub-core/kern/powerpc/dl.c b/grub-core/kern/powerpc/dl.c
+index 3a7fa3ed3d..577e27d871 100644
+--- a/grub-core/kern/powerpc/dl.c
++++ b/grub-core/kern/powerpc/dl.c
+@@ -165,3 +165,12 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
+ 
+   return GRUB_ERR_NONE;
+ }
++
++/*
++ * Tell the loader what our minimum section alignment is.
++ */
++grub_size_t
++grub_arch_dl_min_alignment (void)
++{
++  return 1;
++}
+diff --git a/grub-core/kern/sparc64/dl.c b/grub-core/kern/sparc64/dl.c
+index 739be47174..c741c1782e 100644
+--- a/grub-core/kern/sparc64/dl.c
++++ b/grub-core/kern/sparc64/dl.c
+@@ -184,3 +184,12 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
+ 
+   return GRUB_ERR_NONE;
+ }
++
++/*
++ * Tell the loader what our minimum section alignment is.
++ */
++grub_size_t
++grub_arch_dl_min_alignment (void)
++{
++  return 1;
++}
+diff --git a/grub-core/kern/x86_64/dl.c b/grub-core/kern/x86_64/dl.c
+index 3a73e6e6ce..6c20b7c367 100644
+--- a/grub-core/kern/x86_64/dl.c
++++ b/grub-core/kern/x86_64/dl.c
+@@ -114,3 +114,16 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
+ 
+   return GRUB_ERR_NONE;
+ }
++
++/*
++ * Tell the loader what our minimum section alignment is.
++ */
++grub_size_t
++grub_arch_dl_min_alignment (void)
++{
++#ifdef GRUB_MACHINE_EFI
++  return 4096;
++#else
++  return 1;
++#endif
++}
+diff --git a/include/grub/dl.h b/include/grub/dl.h
+index 9ec6caf3f9..dd4c3e7ff4 100644
+--- a/include/grub/dl.h
++++ b/include/grub/dl.h
+@@ -280,6 +280,8 @@ grub_err_t grub_arch_dl_check_header (void *ehdr);
+ grub_err_t
+ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
+ 			       Elf_Shdr *s, grub_dl_segment_t seg);
++grub_size_t
++grub_arch_dl_min_alignment (void);
+ #endif
+ 
+ #if defined (_mips)
+diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi
+index 03d53498c5..dbfb94bc06 100644
+--- a/docs/grub-dev.texi
++++ b/docs/grub-dev.texi
+@@ -638,9 +638,9 @@ declare startup asm file ($cpu_$platform_startup) as well as any other files
+ (e.g. init.c and callwrap.S) (e.g. $cpu_$platform = kern/$cpu/$platform/init.c).
+ At this stage you will also need to add dummy dl.c and cache.S with functions
+ grub_err_t grub_arch_dl_check_header (void *ehdr), grub_err_t
+-grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) (dl.c) and
+-void grub_arch_sync_caches (void *address, grub_size_t len) (cache.S). They
+-won't be used for now.
++grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) (dl.c), grub_uint32_t
++grub_arch_dl_min_alignment (void), and void grub_arch_sync_caches (void
++*address, grub_size_t len) (cache.S). They won't be used for now.
+ 
+ You will need to create directory include/$cpu/$platform and a file
+ include/$cpu/types.h. The later folowing this template:
diff --git a/SOURCES/0550-nx-add-memory-attribute-get-set-API.patch b/SOURCES/0550-nx-add-memory-attribute-get-set-API.patch
new file mode 100644
index 0000000..41ae1d0
--- /dev/null
+++ b/SOURCES/0550-nx-add-memory-attribute-get-set-API.patch
@@ -0,0 +1,320 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Tue, 22 Mar 2022 10:56:21 -0400
+Subject: [PATCH] nx: add memory attribute get/set API
+
+For NX, we need to set the page access permission attributes for write
+and execute permissions.
+
+This patch adds two new primitives, grub_set_mem_attrs() and
+grub_clear_mem_attrs(), and associated constant definitions, to be used
+for that purpose.
+
+For most platforms, it adds a dummy implementation that returns
+GRUB_ERR_NONE.  On EFI platforms, it adds a common helper function,
+grub_efi_status_to_err(), which translates EFI error codes to grub error
+codes, adds headers for the EFI Memory Attribute Protocol (still pending
+standardization), and an implementation of the grub nx primitives using
+it.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+[rharwood: add pjones's none/nyi fixup]
+(cherry picked from commit 35de78a8d32b9fad5291ec96fd3cbb9cf2f4a80b)
+(cherry picked from commit 46cb4f9557bdba1db0a17d012df705d94d81a9f6)
+[rharwood: context fuzz, guids]
+Signed-off-by: Robbie Harwood <rharwood@redhat.com>
+---
+ grub-core/kern/efi/efi.c |  36 +++++++++++++
+ grub-core/kern/efi/mm.c  | 131 +++++++++++++++++++++++++++++++++++++++++++++++
+ include/grub/efi/api.h   |  25 +++++++++
+ include/grub/efi/efi.h   |   2 +
+ include/grub/mm.h        |  32 ++++++++++++
+ 5 files changed, 226 insertions(+)
+
+diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
+index fccea20a01..09468dc5d5 100644
+--- a/grub-core/kern/efi/efi.c
++++ b/grub-core/kern/efi/efi.c
+@@ -1093,3 +1093,39 @@ grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1,
+ 
+   return 0;
+ }
++
++grub_err_t
++grub_efi_status_to_err (grub_efi_status_t status)
++{
++  grub_err_t err;
++  switch (status)
++    {
++    case GRUB_EFI_SUCCESS:
++      err = GRUB_ERR_NONE;
++      break;
++    case GRUB_EFI_INVALID_PARAMETER:
++    default:
++      err = GRUB_ERR_BAD_ARGUMENT;
++      break;
++    case GRUB_EFI_OUT_OF_RESOURCES:
++      err = GRUB_ERR_OUT_OF_MEMORY;
++      break;
++    case GRUB_EFI_DEVICE_ERROR:
++      err = GRUB_ERR_IO;
++      break;
++    case GRUB_EFI_WRITE_PROTECTED:
++      err = GRUB_ERR_WRITE_ERROR;
++      break;
++    case GRUB_EFI_SECURITY_VIOLATION:
++      err = GRUB_ERR_ACCESS_DENIED;
++      break;
++    case GRUB_EFI_NOT_FOUND:
++      err = GRUB_ERR_FILE_NOT_FOUND;
++      break;
++    case GRUB_EFI_ABORTED:
++      err = GRUB_ERR_WAIT;
++      break;
++    }
++
++  return err;
++}
+diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
+index 9e76f23e5f..2cf4a4883a 100644
+--- a/grub-core/kern/efi/mm.c
++++ b/grub-core/kern/efi/mm.c
+@@ -730,3 +730,134 @@ grub_efi_get_ram_base(grub_addr_t *base_addr)
+   return GRUB_ERR_NONE;
+ }
+ #endif
++
++static inline grub_uint64_t
++grub_mem_attrs_to_uefi_mem_attrs (grub_uint64_t attrs)
++{
++  grub_uint64_t ret = GRUB_EFI_MEMORY_RP |
++		      GRUB_EFI_MEMORY_RO |
++		      GRUB_EFI_MEMORY_XP;
++
++  if (attrs & GRUB_MEM_ATTR_R)
++    ret &= ~GRUB_EFI_MEMORY_RP;
++
++  if (attrs & GRUB_MEM_ATTR_W)
++    ret &= ~GRUB_EFI_MEMORY_RO;
++
++  if (attrs & GRUB_MEM_ATTR_X)
++    ret &= ~GRUB_EFI_MEMORY_XP;
++
++  return ret;
++}
++
++static inline grub_uint64_t
++uefi_mem_attrs_to_grub_mem_attrs (grub_uint64_t attrs)
++{
++  grub_uint64_t ret = GRUB_MEM_ATTR_R |
++		      GRUB_MEM_ATTR_W |
++		      GRUB_MEM_ATTR_X;
++
++  if (attrs & GRUB_EFI_MEMORY_RP)
++    ret &= ~GRUB_MEM_ATTR_R;
++
++  if (attrs & GRUB_EFI_MEMORY_RO)
++    ret &= ~GRUB_MEM_ATTR_W;
++
++  if (attrs & GRUB_EFI_MEMORY_XP)
++    ret &= ~GRUB_MEM_ATTR_X;
++
++  return ret;
++}
++
++grub_err_t
++grub_get_mem_attrs (grub_addr_t addr, grub_size_t size, grub_uint64_t *attrs)
++{
++  grub_efi_memory_attribute_protocol_t *proto;
++  grub_efi_physical_address_t physaddr = addr;
++  grub_efi_guid_t protocol_guid = GRUB_EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID;
++  grub_efi_status_t efi_status;
++
++  proto = grub_efi_locate_protocol (&protocol_guid, 0);
++  if (!proto)
++    return GRUB_ERR_NOT_IMPLEMENTED_YET;
++
++  if (physaddr & 0xfff || size & 0xfff || size == 0 || attrs == NULL)
++    {
++      grub_dprintf ("nx", "%s called on 0x%"PRIxGRUB_ADDR"-0x%"PRIxGRUB_ADDR" and attrs %p\n",
++		    __func__, physaddr, physaddr+size-1, attrs);
++      return 0;
++    }
++
++  efi_status = efi_call_4(proto->get_memory_attributes,
++			  proto, physaddr, size, attrs);
++  *attrs = uefi_mem_attrs_to_grub_mem_attrs (*attrs);
++
++  return grub_efi_status_to_err (efi_status);
++}
++
++grub_err_t
++grub_update_mem_attrs (grub_addr_t addr, grub_size_t size,
++		       grub_uint64_t set_attrs, grub_uint64_t clear_attrs)
++{
++  grub_efi_memory_attribute_protocol_t *proto;
++  grub_efi_physical_address_t physaddr = addr;
++  grub_efi_guid_t protocol_guid = GRUB_EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID;
++  grub_efi_status_t efi_status = GRUB_EFI_SUCCESS;
++  grub_uint64_t before = 0, after = 0, uefi_set_attrs, uefi_clear_attrs;
++  grub_err_t err;
++
++  proto = grub_efi_locate_protocol (&protocol_guid, 0);
++  if (!proto)
++    return GRUB_ERR_NONE;
++
++  err = grub_get_mem_attrs (addr, size, &before);
++  if (err)
++    grub_dprintf ("nx", "grub_get_mem_attrs(0x%"PRIxGRUB_ADDR", %"PRIuGRUB_SIZE", %p) -> 0x%x\n",
++		  addr, size, &before, err);
++
++  if (physaddr & 0xfff || size & 0xfff || size == 0)
++    {
++      grub_dprintf ("nx", "%s called on 0x%"PRIxGRUB_ADDR"-0x%"PRIxGRUB_ADDR" +%s%s%s -%s%s%s\n",
++		    __func__, physaddr, physaddr + size - 1,
++		    (set_attrs & GRUB_MEM_ATTR_R) ? "r" : "",
++		    (set_attrs & GRUB_MEM_ATTR_W) ? "w" : "",
++		    (set_attrs & GRUB_MEM_ATTR_X) ? "x" : "",
++		    (clear_attrs & GRUB_MEM_ATTR_R) ? "r" : "",
++		    (clear_attrs & GRUB_MEM_ATTR_W) ? "w" : "",
++		    (clear_attrs & GRUB_MEM_ATTR_X) ? "x" : "");
++      return 0;
++    }
++
++  uefi_set_attrs = grub_mem_attrs_to_uefi_mem_attrs (set_attrs);
++  grub_dprintf ("nx", "translating set_attrs from 0x%lx to 0x%lx\n", set_attrs, uefi_set_attrs);
++  uefi_clear_attrs = grub_mem_attrs_to_uefi_mem_attrs (clear_attrs);
++  grub_dprintf ("nx", "translating clear_attrs from 0x%lx to 0x%lx\n", clear_attrs, uefi_clear_attrs);
++  if (uefi_set_attrs)
++    efi_status = efi_call_4(proto->set_memory_attributes,
++			    proto, physaddr, size, uefi_set_attrs);
++  if (efi_status == GRUB_EFI_SUCCESS && uefi_clear_attrs)
++    efi_status = efi_call_4(proto->clear_memory_attributes,
++			    proto, physaddr, size, uefi_clear_attrs);
++
++  err = grub_get_mem_attrs (addr, size, &after);
++  if (err)
++    grub_dprintf ("nx", "grub_get_mem_attrs(0x%"PRIxGRUB_ADDR", %"PRIuGRUB_SIZE", %p) -> 0x%x\n",
++		  addr, size, &after, err);
++
++  grub_dprintf ("nx", "set +%s%s%s -%s%s%s on 0x%"PRIxGRUB_ADDR"-0x%"PRIxGRUB_ADDR" before:%c%c%c after:%c%c%c\n",
++		(set_attrs & GRUB_MEM_ATTR_R) ? "r" : "",
++		(set_attrs & GRUB_MEM_ATTR_W) ? "w" : "",
++		(set_attrs & GRUB_MEM_ATTR_X) ? "x" : "",
++		(clear_attrs & GRUB_MEM_ATTR_R) ? "r" : "",
++		(clear_attrs & GRUB_MEM_ATTR_W) ? "w" : "",
++		(clear_attrs & GRUB_MEM_ATTR_X) ? "x" : "",
++		addr, addr + size - 1,
++		(before & GRUB_MEM_ATTR_R) ? 'r' : '-',
++		(before & GRUB_MEM_ATTR_W) ? 'w' : '-',
++		(before & GRUB_MEM_ATTR_X) ? 'x' : '-',
++		(after & GRUB_MEM_ATTR_R) ? 'r' : '-',
++		(after & GRUB_MEM_ATTR_W) ? 'w' : '-',
++		(after & GRUB_MEM_ATTR_X) ? 'x' : '-');
++
++  return grub_efi_status_to_err (efi_status);
++}
+diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
+index 2a243fd290..510a4030f5 100644
+--- a/include/grub/efi/api.h
++++ b/include/grub/efi/api.h
+@@ -354,6 +354,11 @@
+     { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } \
+    }
+ 
++#define GRUB_EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID \
++  { 0xf4560cf6, 0x40ec, 0x4b4a, \
++    { 0xa1, 0x92, 0xbf, 0x1d, 0x57, 0xd0, 0xb1, 0x89 } \
++  }
++
+ struct grub_efi_sal_system_table
+ {
+   grub_uint32_t signature;
+@@ -2091,6 +2096,26 @@ struct grub_efi_rng_protocol
+ };
+ typedef struct grub_efi_rng_protocol grub_efi_rng_protocol_t;
+ 
++struct grub_efi_memory_attribute_protocol
++{
++  grub_efi_status_t (*get_memory_attributes) (
++			    struct grub_efi_memory_attribute_protocol *this,
++			    grub_efi_physical_address_t base_address,
++			    grub_efi_uint64_t length,
++			    grub_efi_uint64_t *attributes);
++  grub_efi_status_t (*set_memory_attributes) (
++			    struct grub_efi_memory_attribute_protocol *this,
++			    grub_efi_physical_address_t base_address,
++			    grub_efi_uint64_t length,
++			    grub_efi_uint64_t attributes);
++  grub_efi_status_t (*clear_memory_attributes) (
++			    struct grub_efi_memory_attribute_protocol *this,
++			    grub_efi_physical_address_t base_address,
++			    grub_efi_uint64_t length,
++			    grub_efi_uint64_t attributes);
++};
++typedef struct grub_efi_memory_attribute_protocol grub_efi_memory_attribute_protocol_t;
++
+ #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \
+   || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__)
+ 
+diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
+index 7af979b184..a635bcb0a9 100644
+--- a/include/grub/efi/efi.h
++++ b/include/grub/efi/efi.h
+@@ -159,4 +159,6 @@ struct grub_net_card;
+ grub_efi_handle_t
+ grub_efinet_get_device_handle (struct grub_net_card *card);
+ 
++grub_err_t EXPORT_FUNC(grub_efi_status_to_err) (grub_efi_status_t status);
++
+ #endif /* ! GRUB_EFI_EFI_HEADER */
+diff --git a/include/grub/mm.h b/include/grub/mm.h
+index 9c38dd3ca5..d81623d226 100644
+--- a/include/grub/mm.h
++++ b/include/grub/mm.h
+@@ -22,6 +22,7 @@
+ 
+ #include <grub/types.h>
+ #include <grub/symbol.h>
++#include <grub/err.h>
+ #include <config.h>
+ 
+ #ifndef NULL
+@@ -38,6 +39,37 @@ void *EXPORT_FUNC(grub_realloc) (void *ptr, grub_size_t size);
+ void *EXPORT_FUNC(grub_memalign) (grub_size_t align, grub_size_t size);
+ #endif
+ 
++#define GRUB_MEM_ATTR_R	0x0000000000000004LLU
++#define GRUB_MEM_ATTR_W	0x0000000000000002LLU
++#define GRUB_MEM_ATTR_X	0x0000000000000001LLU
++
++#ifdef GRUB_MACHINE_EFI
++grub_err_t EXPORT_FUNC(grub_get_mem_attrs) (grub_addr_t addr,
++					    grub_size_t size,
++					    grub_uint64_t *attrs);
++grub_err_t EXPORT_FUNC(grub_update_mem_attrs) (grub_addr_t addr,
++					       grub_size_t size,
++					       grub_uint64_t set_attrs,
++					       grub_uint64_t clear_attrs);
++#else /* !GRUB_MACHINE_EFI */
++static inline grub_err_t
++grub_get_mem_attrs (grub_addr_t addr __attribute__((__unused__)),
++		    grub_size_t size __attribute__((__unused__)),
++		    grub_uint64_t *attrs __attribute__((__unused__)))
++{
++  return GRUB_ERR_NONE;
++}
++
++static inline grub_err_t
++grub_update_mem_attrs (grub_addr_t addr __attribute__((__unused__)),
++		       grub_size_t size __attribute__((__unused__)),
++		       grub_uint64_t set_attrs __attribute__((__unused__)),
++		       grub_uint64_t clear_attrs __attribute__((__unused__)))
++{
++  return GRUB_ERR_NONE;
++}
++#endif /* GRUB_MACHINE_EFI */
++
+ void grub_mm_check_real (const char *file, int line);
+ #define grub_mm_check() grub_mm_check_real (GRUB_FILE, __LINE__);
+ 
diff --git a/SOURCES/0551-nx-set-page-permissions-for-loaded-modules.patch b/SOURCES/0551-nx-set-page-permissions-for-loaded-modules.patch
new file mode 100644
index 0000000..1032ea6
--- /dev/null
+++ b/SOURCES/0551-nx-set-page-permissions-for-loaded-modules.patch
@@ -0,0 +1,265 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Mon, 21 Mar 2022 17:46:35 -0400
+Subject: [PATCH] nx: set page permissions for loaded modules.
+
+For NX, we need to set write and executable permissions on the sections
+of grub modules when we load them.
+
+On sections with SHF_ALLOC set, which is typically everything except
+.modname and the symbol and string tables, this patch clears the Read
+Only flag on sections that have the ELF flag SHF_WRITE set, and clears
+the No eXecute flag on sections with SHF_EXECINSTR set.  In all other
+cases it sets both flags.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+[rharwood: arm tgptr -> tgaddr]
+Signed-off-by: Robbie Harwood <rharwood@redhat.com>
+(cherry-picked from commit ca74904ede0406b594cbedc52ce8e38a6633d2ae)
+(cherry picked from commit 2e2e72026f41cf7cffeb46a6a47f3c67d0b3be45)
+---
+ grub-core/kern/dl.c | 120 +++++++++++++++++++++++++++++++++++++++-------------
+ include/grub/dl.h   |  44 +++++++++++++++++++
+ 2 files changed, 134 insertions(+), 30 deletions(-)
+
+diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
+index 5c2153acf9..68d3177f5e 100644
+--- a/grub-core/kern/dl.c
++++ b/grub-core/kern/dl.c
+@@ -286,6 +286,8 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
+ #endif
+   char *ptr;
+ 
++  grub_dprintf ("modules", "loading segments for \"%s\"\n", mod->name);
++
+   arch_addralign = grub_arch_dl_min_alignment ();
+ 
+   for (i = 0, s = (const Elf_Shdr *)((const char *) e + e->e_shoff);
+@@ -385,6 +387,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
+   ptr += got;
+ #endif
+ 
++  grub_dprintf ("modules", "done loading segments for \"%s\"\n", mod->name);
+   return GRUB_ERR_NONE;
+ }
+ 
+@@ -518,23 +521,6 @@ grub_dl_find_section (Elf_Ehdr *e, const char *name)
+       return s;
+   return NULL;
+ }
+-static long
+-grub_dl_find_section_index (Elf_Ehdr *e, const char *name)
+-{
+-  Elf_Shdr *s;
+-  const char *str;
+-  unsigned i;
+-
+-  s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize);
+-  str = (char *) e + s->sh_offset;
+-
+-  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+-       i < e->e_shnum;
+-       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+-    if (grub_strcmp (str + s->sh_name, name) == 0)
+-      return (long)i;
+-  return -1;
+-}
+ 
+ /* Me, Vladimir Serbinenko, hereby I add this module check as per new
+    GNU module policy. Note that this license check is informative only.
+@@ -661,6 +647,7 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
+   Elf_Shdr *s;
+   unsigned i;
+ 
++  grub_dprintf ("modules", "relocating symbols for \"%s\"\n", mod->name);
+   for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+        i < e->e_shnum;
+        i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+@@ -669,24 +656,95 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
+ 	grub_dl_segment_t seg;
+ 	grub_err_t err;
+ 
+-	/* Find the target segment.  */
+-	for (seg = mod->segment; seg; seg = seg->next)
+-	  if (seg->section == s->sh_info)
+-	    break;
++	seg = grub_dl_find_segment(mod, s->sh_info);
++        if (!seg)
++	  continue;
+ 
+-	if (seg)
+-	  {
+-	    if (!mod->symtab)
+-	      return grub_error (GRUB_ERR_BAD_MODULE, "relocation without symbol table");
++	if (!mod->symtab)
++	  return grub_error (GRUB_ERR_BAD_MODULE, "relocation without symbol table");
+ 
+-	    err = grub_arch_dl_relocate_symbols (mod, ehdr, s, seg);
+-	    if (err)
+-	      return err;
+-	  }
++	err = grub_arch_dl_relocate_symbols (mod, ehdr, s, seg);
++	if (err)
++	  return err;
+       }
+ 
++  grub_dprintf ("modules", "done relocating symbols for \"%s\"\n", mod->name);
+   return GRUB_ERR_NONE;
+ }
++
++static grub_err_t
++grub_dl_set_mem_attrs (grub_dl_t mod, void *ehdr)
++{
++  unsigned i;
++  const Elf_Shdr *s;
++  const Elf_Ehdr *e = ehdr;
++#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv)
++  grub_size_t arch_addralign = grub_arch_dl_min_alignment ();
++  grub_addr_t tgaddr;
++  grub_uint64_t tgsz;
++#endif
++
++  grub_dprintf ("modules", "updating memory attributes for \"%s\"\n",
++		mod->name);
++  for (i = 0, s = (const Elf_Shdr *)((const char *) e + e->e_shoff);
++       i < e->e_shnum;
++       i++, s = (const Elf_Shdr *)((const char *) s + e->e_shentsize))
++    {
++      grub_dl_segment_t seg;
++      grub_uint64_t set_attrs = GRUB_MEM_ATTR_R;
++      grub_uint64_t clear_attrs = GRUB_MEM_ATTR_W|GRUB_MEM_ATTR_X;
++
++      seg = grub_dl_find_segment(mod, i);
++      if (!seg)
++	continue;
++
++      if (seg->size == 0 || !(s->sh_flags & SHF_ALLOC))
++	continue;
++
++      if (s->sh_flags & SHF_WRITE)
++	{
++	  set_attrs |= GRUB_MEM_ATTR_W;
++	  clear_attrs &= ~GRUB_MEM_ATTR_W;
++	}
++
++      if (s->sh_flags & SHF_EXECINSTR)
++	{
++	  set_attrs |= GRUB_MEM_ATTR_X;
++	  clear_attrs &= ~GRUB_MEM_ATTR_X;
++	}
++
++      grub_dprintf ("modules", "setting memory attrs for section \"%s\" to -%s%s%s+%s%s%s\n",
++		    grub_dl_get_section_name(e, s),
++		    (clear_attrs & GRUB_MEM_ATTR_R) ? "r" : "",
++		    (clear_attrs & GRUB_MEM_ATTR_W) ? "w" : "",
++		    (clear_attrs & GRUB_MEM_ATTR_X) ? "x" : "",
++		    (set_attrs & GRUB_MEM_ATTR_R) ? "r" : "",
++		    (set_attrs & GRUB_MEM_ATTR_W) ? "w" : "",
++		    (set_attrs & GRUB_MEM_ATTR_X) ? "x" : "");
++      grub_update_mem_attrs ((grub_addr_t)(seg->addr), seg->size, set_attrs, clear_attrs);
++    }
++
++#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv)
++  tgaddr = grub_min((grub_addr_t)mod->tramp, (grub_addr_t)mod->got);
++  tgsz = grub_max((grub_addr_t)mod->trampptr, (grub_addr_t)mod->gotptr) - tgaddr;
++
++  if (tgsz)
++    {
++      tgsz = ALIGN_UP(tgsz, arch_addralign);
++
++      grub_dprintf ("modules", "updating attributes for GOT and trampolines\n",
++		    mod->name);
++      grub_update_mem_attrs (tgaddr, tgsz, GRUB_MEM_ATTR_R|GRUB_MEM_ATTR_X,
++			     GRUB_MEM_ATTR_W);
++    }
++#endif
++
++  grub_dprintf ("modules", "done updating module memory attributes for \"%s\"\n",
++		mod->name);
++
++  return GRUB_ERR_NONE;
++}
++
+ static void
+ grub_dl_print_gdb_info (grub_dl_t mod, Elf_Ehdr *e)
+ {
+@@ -752,6 +810,7 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size)
+   mod->ref_count = 1;
+ 
+   grub_dprintf ("modules", "relocating to %p\n", mod);
++
+   /* Me, Vladimir Serbinenko, hereby I add this module check as per new
+      GNU module policy. Note that this license check is informative only.
+      Modules have to be licensed under GPLv3 or GPLv3+ (optionally
+@@ -765,7 +824,8 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size)
+       || grub_dl_resolve_dependencies (mod, e)
+       || grub_dl_load_segments (mod, e)
+       || grub_dl_resolve_symbols (mod, e)
+-      || grub_dl_relocate_symbols (mod, e))
++      || grub_dl_relocate_symbols (mod, e)
++      || grub_dl_set_mem_attrs (mod, e))
+     {
+       mod->fini = 0;
+       grub_dl_unload (mod);
+diff --git a/include/grub/dl.h b/include/grub/dl.h
+index dd4c3e7ff4..6f46b7e86f 100644
+--- a/include/grub/dl.h
++++ b/include/grub/dl.h
+@@ -27,6 +27,7 @@
+ #include <grub/elf.h>
+ #include <grub/list.h>
+ #include <grub/misc.h>
++#include <grub/mm.h>
+ #endif
+ 
+ /*
+@@ -268,6 +269,49 @@ grub_dl_is_persistent (grub_dl_t mod)
+   return mod->persistent;
+ }
+ 
++static inline const char *
++grub_dl_get_section_name (const Elf_Ehdr *e, const Elf_Shdr *s)
++{
++  Elf_Shdr *str_s;
++  const char *str;
++
++  str_s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize);
++  str = (char *) e + str_s->sh_offset;
++
++  return str + s->sh_name;
++}
++
++static inline long
++grub_dl_find_section_index (Elf_Ehdr *e, const char *name)
++{
++  Elf_Shdr *s;
++  const char *str;
++  unsigned i;
++
++  s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize);
++  str = (char *) e + s->sh_offset;
++
++  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
++       i < e->e_shnum;
++       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
++    if (grub_strcmp (str + s->sh_name, name) == 0)
++      return (long)i;
++  return -1;
++}
++
++/* Return the segment for a section of index N */
++static inline grub_dl_segment_t
++grub_dl_find_segment (grub_dl_t mod, unsigned n)
++{
++  grub_dl_segment_t seg;
++
++  for (seg = mod->segment; seg; seg = seg->next)
++    if (seg->section == n)
++      return seg;
++
++  return NULL;
++}
++
+ #endif
+ 
+ void * EXPORT_FUNC(grub_resolve_symbol) (const char *name);
diff --git a/SOURCES/0552-nx-set-attrs-in-our-kernel-loaders.patch b/SOURCES/0552-nx-set-attrs-in-our-kernel-loaders.patch
new file mode 100644
index 0000000..e4c4c3e
--- /dev/null
+++ b/SOURCES/0552-nx-set-attrs-in-our-kernel-loaders.patch
@@ -0,0 +1,571 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Tue, 22 Mar 2022 10:57:07 -0400
+Subject: [PATCH] nx: set attrs in our kernel loaders
+
+For NX, our kernel loaders need to set write and execute page
+permissions on allocated pages and the stack.
+
+This patch adds those calls.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+[rharwood: fix aarch64 callsites]
+(cherry-picked from commit a9f79a997f01a83b36cdfa89ef2e72ac2a17c06c)
+[rharwood: double verification]
+(cherry picked from commit daba852bd3e4d7b7784b19cf7acf107dc3c0dce4)
+[rharwood: stack_attrs initialization, no risc-v, arm renames, arm age]
+Signed-off-by: Robbie Harwood <rharwood@redhat.com>
+---
+ grub-core/kern/efi/mm.c            |  78 ++++++++++++++++++
+ grub-core/loader/arm64/linux.c     |  16 +++-
+ grub-core/loader/arm64/xen_boot.c  |   4 +-
+ grub-core/loader/efi/chainloader.c |  11 +++
+ grub-core/loader/efi/linux.c       | 162 ++++++++++++++++++++++++++++++++++++-
+ grub-core/loader/i386/efi/linux.c  |  26 +++++-
+ grub-core/loader/i386/linux.c      |   5 ++
+ include/grub/efi/efi.h             |   6 +-
+ include/grub/efi/linux.h           |  17 +++-
+ include/grub/efi/pe32.h            |   2 +
+ 10 files changed, 312 insertions(+), 15 deletions(-)
+
+diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
+index 2cf4a4883a..8a896144df 100644
+--- a/grub-core/kern/efi/mm.c
++++ b/grub-core/kern/efi/mm.c
+@@ -602,6 +602,82 @@ print_memory_map (grub_efi_memory_descriptor_t *memory_map,
+ }
+ #endif
+ 
++grub_addr_t grub_stack_addr = (grub_addr_t)-1ll;
++grub_size_t grub_stack_size = 0;
++
++static void
++grub_nx_init (void)
++{
++  grub_uint64_t attrs, stack_attrs;
++  grub_err_t err;
++  grub_addr_t stack_current, stack_end;
++  const grub_uint64_t page_size = 4096;
++  const grub_uint64_t page_mask = ~(page_size - 1);
++
++  /*
++   * These are to confirm that the flags are working as expected when
++   * debugging.
++   */
++  attrs = 0;
++  stack_current = (grub_addr_t)grub_nx_init & page_mask;
++  err = grub_get_mem_attrs (stack_current, page_size, &attrs);
++  if (err)
++    {
++      grub_dprintf ("nx",
++		    "grub_get_mem_attrs(0x%"PRIxGRUB_UINT64_T", ...) -> 0x%x\n",
++		    stack_current, err);
++      grub_error_pop ();
++    }
++  else
++    grub_dprintf ("nx", "page attrs for grub_nx_init (%p) are %c%c%c\n",
++		  grub_dl_load_core,
++		  (attrs & GRUB_MEM_ATTR_R) ? 'r' : '-',
++		  (attrs & GRUB_MEM_ATTR_R) ? 'w' : '-',
++		  (attrs & GRUB_MEM_ATTR_R) ? 'x' : '-');
++
++  stack_current = (grub_addr_t)&stack_current & page_mask;
++  err = grub_get_mem_attrs (stack_current, page_size, &stack_attrs);
++  if (err)
++    {
++      grub_dprintf ("nx",
++		    "grub_get_mem_attrs(0x%"PRIxGRUB_UINT64_T", ...) -> 0x%x\n",
++		    stack_current, err);
++      grub_error_pop ();
++    }
++  else
++    {
++      attrs = stack_attrs;
++      grub_dprintf ("nx", "page attrs for stack (%p) are %c%c%c\n",
++                    &attrs,
++                    (attrs & GRUB_MEM_ATTR_R) ? 'r' : '-',
++                    (attrs & GRUB_MEM_ATTR_R) ? 'w' : '-',
++                    (attrs & GRUB_MEM_ATTR_R) ? 'x' : '-');
++    }
++
++  for (stack_end = stack_current + page_size ;
++       !(attrs & GRUB_MEM_ATTR_R);
++       stack_end += page_size)
++    {
++      err = grub_get_mem_attrs (stack_current, page_size, &attrs);
++      if (err)
++	{
++	  grub_dprintf ("nx",
++			"grub_get_mem_attrs(0x%"PRIxGRUB_UINT64_T", ...) -> 0x%x\n",
++			stack_current, err);
++	  grub_error_pop ();
++	  break;
++	}
++    }
++  if (stack_end > stack_current)
++    {
++      grub_stack_addr = stack_current;
++      grub_stack_size = stack_end - stack_current;
++      grub_dprintf ("nx",
++		    "detected stack from 0x%"PRIxGRUB_ADDR" to 0x%"PRIxGRUB_ADDR"\n",
++		    grub_stack_addr, grub_stack_addr + grub_stack_size - 1);
++    }
++}
++
+ void
+ grub_efi_mm_init (void)
+ {
+@@ -615,6 +691,8 @@ grub_efi_mm_init (void)
+   grub_efi_uint64_t required_pages;
+   int mm_status;
+ 
++  grub_nx_init ();
++
+   /* Prepare a memory region to store two memory maps.  */
+   memory_map = grub_efi_allocate_any_pages (2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
+   if (! memory_map)
+diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
+index 24ab0f0074..37f5d0c7eb 100644
+--- a/grub-core/loader/arm64/linux.c
++++ b/grub-core/loader/arm64/linux.c
+@@ -191,7 +191,8 @@ free_params (void)
+ }
+ 
+ grub_err_t
+-grub_armxx_efi_linux_boot_image (grub_addr_t addr, char *args)
++grub_armxx_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args,
++				int nx_supported)
+ {
+   grub_err_t retval;
+ 
+@@ -201,7 +202,8 @@ grub_armxx_efi_linux_boot_image (grub_addr_t addr, char *args)
+ 
+   grub_dprintf ("linux", "linux command line: '%s'\n", args);
+ 
+-  retval = grub_efi_linux_boot ((char *)addr, handover_offset, (void *)addr);
++  retval = grub_efi_linux_boot (addr, size, handover_offset,
++				(void *)addr, nx_supported);
+ 
+   /* Never reached... */
+   free_params();
+@@ -211,7 +213,10 @@ grub_armxx_efi_linux_boot_image (grub_addr_t addr, char *args)
+ static grub_err_t
+ grub_linux_boot (void)
+ {
+-  return grub_armxx_efi_linux_boot_image((grub_addr_t)kernel_addr, linux_args);
++  return grub_armxx_efi_linux_boot_image((grub_addr_t)kernel_addr,
++					(grub_size_t)kernel_size,
++					linux_args,
++					0);
+ }
+ 
+ static grub_err_t
+@@ -340,6 +345,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+   struct grub_armxx_linux_pe_header *pe;
+   int rc;
+   grub_err_t err;
++  int nx_supported = 1;
+ 
+   grub_dl_ref (my_mod);
+ 
+@@ -395,6 +401,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+ 	}
+     }
+ 
++  err = grub_efi_check_nx_image_support((grub_addr_t) kernel_addr, kernel_size, &nx_supported);
++  if (err != GRUB_ERR_NONE)
++    goto fail;
++
+   pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
+   handover_offset = pe->opt.entry_addr;
+ 
+diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c
+index 1a337866f0..1fd1bbb4bd 100644
+--- a/grub-core/loader/arm64/xen_boot.c
++++ b/grub-core/loader/arm64/xen_boot.c
+@@ -266,7 +266,9 @@ xen_boot (void)
+     return err;
+ 
+   return grub_armxx_efi_linux_boot_image (xen_hypervisor->start,
+-					  xen_hypervisor->cmdline);
++                                         xen_hypervisor->size,
++                                         xen_hypervisor->cmdline,
++                                         0);
+ }
+ 
+ static void
+diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
+index 8e658f713e..b72e6bd5e3 100644
+--- a/grub-core/loader/efi/chainloader.c
++++ b/grub-core/loader/efi/chainloader.c
+@@ -1055,6 +1055,17 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
+       goto fail;
+     }
+ 
++  /*
++   * The OS kernel is going to set its own permissions when it takes over
++   * paging a few million instructions from now, and load_image() will set up
++   * anything that's needed based on the section headers, so there's no point
++   * in doing anything but clearing the protection bits here.
++   */
++  grub_dprintf("nx", "setting attributes for %p (%lu bytes) to %llx\n",
++	       (void *)(grub_addr_t)address, fsize, 0llu);
++  grub_update_mem_attrs (address, fsize,
++			 GRUB_MEM_ATTR_R|GRUB_MEM_ATTR_W|GRUB_MEM_ATTR_X, 0);
++
+ #if defined (__i386__) || defined (__x86_64__)
+   if (fsize >= (grub_ssize_t) sizeof (struct grub_macho_fat_header))
+     {
+diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
+index 927d89a90d..421502bd25 100644
+--- a/grub-core/loader/efi/linux.c
++++ b/grub-core/loader/efi/linux.c
+@@ -66,16 +66,125 @@ grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
+ 
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wcast-align"
++#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
++
++grub_err_t
++grub_efi_check_nx_image_support (grub_addr_t kernel_addr,
++				 grub_size_t kernel_size,
++				 int *nx_supported)
++{
++  struct grub_dos_header *doshdr;
++  grub_size_t sz = sizeof (*doshdr);
++
++  struct grub_pe32_header_32 *pe32;
++  struct grub_pe32_header_64 *pe64;
++
++  int image_is_compatible = 0;
++  int is_64_bit;
++
++  if (kernel_size < sz)
++    return grub_error (GRUB_ERR_BAD_OS, N_("kernel is too small"));
++
++  doshdr = (void *)kernel_addr;
++
++  if ((doshdr->magic & 0xffff) != GRUB_DOS_MAGIC)
++    return grub_error (GRUB_ERR_BAD_OS, N_("kernel DOS magic is invalid"));
++
++  sz = doshdr->lfanew + sizeof (*pe32);
++  if (kernel_size < sz)
++    return grub_error (GRUB_ERR_BAD_OS, N_("kernel is too small"));
++
++  pe32 = (struct grub_pe32_header_32 *)(kernel_addr + doshdr->lfanew);
++  pe64 = (struct grub_pe32_header_64 *)pe32;
++
++  if (grub_memcmp (pe32->signature, GRUB_PE32_SIGNATURE,
++		   GRUB_PE32_SIGNATURE_SIZE) != 0)
++    return grub_error (GRUB_ERR_BAD_OS, N_("kernel PE magic is invalid"));
++
++  switch (pe32->coff_header.machine)
++    {
++    case GRUB_PE32_MACHINE_ARMTHUMB_MIXED:
++    case GRUB_PE32_MACHINE_I386:
++      is_64_bit = 0;
++      break;
++    case GRUB_PE32_MACHINE_ARM64:
++    case GRUB_PE32_MACHINE_IA64:
++    case GRUB_PE32_MACHINE_X86_64:
++      is_64_bit = 1;
++      break;
++    default:
++      return grub_error (GRUB_ERR_BAD_OS, N_("PE machine type 0x%04hx unknown"),
++			 pe32->coff_header.machine);
++    }
++
++  if (is_64_bit)
++    {
++      sz = doshdr->lfanew + sizeof (*pe64);
++      if (kernel_size < sz)
++	return grub_error (GRUB_ERR_BAD_OS, N_("kernel is too small"));
++
++      if (pe64->optional_header.dll_characteristics & GRUB_PE32_NX_COMPAT)
++	image_is_compatible = 1;
++    }
++  else
++    {
++      if (pe32->optional_header.dll_characteristics & GRUB_PE32_NX_COMPAT)
++	image_is_compatible = 1;
++    }
++
++  *nx_supported = image_is_compatible;
++  return GRUB_ERR_NONE;
++}
++
++grub_err_t
++grub_efi_check_nx_required (int *nx_required)
++{
++  grub_efi_status_t status;
++  grub_efi_guid_t guid = GRUB_EFI_SHIM_LOCK_GUID;
++  grub_size_t mok_policy_sz = 0;
++  char *mok_policy = NULL;
++  grub_uint32_t mok_policy_attrs = 0;
++
++  status = grub_efi_get_variable_with_attributes ("MokPolicy", &guid,
++						  &mok_policy_sz,
++						  (void **)&mok_policy,
++						  &mok_policy_attrs);
++  if (status == GRUB_EFI_NOT_FOUND ||
++      mok_policy_sz == 0 ||
++      mok_policy == NULL)
++    {
++      *nx_required = 0;
++      return GRUB_ERR_NONE;
++    }
++
++  *nx_required = 0;
++  if (mok_policy_sz < 1 ||
++      mok_policy_attrs != (GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
++			   GRUB_EFI_VARIABLE_RUNTIME_ACCESS) ||
++      (mok_policy[mok_policy_sz-1] & GRUB_MOK_POLICY_NX_REQUIRED))
++    *nx_required = 1;
++
++  return GRUB_ERR_NONE;
++}
+ 
+ typedef void (*handover_func) (void *, grub_efi_system_table_t *, void *);
+ 
+ grub_err_t
+-grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset,
+-		     void *kernel_params)
++grub_efi_linux_boot (grub_addr_t kernel_addr, grub_size_t kernel_size,
++		     grub_off_t handover_offset, void *kernel_params,
++		     int nx_supported)
+ {
+   grub_efi_loaded_image_t *loaded_image = NULL;
+   handover_func hf;
+   int offset = 0;
++  grub_uint64_t stack_set_attrs = GRUB_MEM_ATTR_R |
++				  GRUB_MEM_ATTR_W |
++				  GRUB_MEM_ATTR_X;
++  grub_uint64_t stack_clear_attrs = 0;
++  grub_uint64_t kernel_set_attrs = stack_set_attrs;
++  grub_uint64_t kernel_clear_attrs = stack_clear_attrs;
++  grub_uint64_t attrs;
++  int nx_required = 0;
+ 
+ #ifdef __x86_64__
+   offset = 512;
+@@ -88,12 +197,57 @@ grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset,
+    */
+   loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
+   if (loaded_image)
+-    loaded_image->image_base = kernel_addr;
++    loaded_image->image_base = (void *)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_addr, (void *)(grub_efi_uintn_t)handover_offset, kernel_params);
++		(void *)kernel_addr, (void *)handover_offset, kernel_params);
++
++
++  if (nx_required && !nx_supported)
++    return grub_error (GRUB_ERR_BAD_OS, N_("kernel does not support NX loading required by policy"));
++
++  if (nx_supported)
++    {
++      kernel_set_attrs &= ~GRUB_MEM_ATTR_W;
++      kernel_clear_attrs |= GRUB_MEM_ATTR_W;
++      stack_set_attrs &= ~GRUB_MEM_ATTR_X;
++      stack_clear_attrs |= GRUB_MEM_ATTR_X;
++    }
++
++  grub_dprintf ("nx", "Setting attributes for 0x%"PRIxGRUB_ADDR"-0x%"PRIxGRUB_ADDR" to r%cx\n",
++		    kernel_addr, kernel_addr + kernel_size - 1,
++		    (kernel_set_attrs & GRUB_MEM_ATTR_W) ? 'w' : '-');
++  grub_update_mem_attrs (kernel_addr, kernel_size,
++			 kernel_set_attrs, kernel_clear_attrs);
++
++  grub_get_mem_attrs (kernel_addr, 4096, &attrs);
++  grub_dprintf ("nx", "permissions for 0x%"PRIxGRUB_ADDR" are %s%s%s\n",
++		(grub_addr_t)kernel_addr,
++		(attrs & GRUB_MEM_ATTR_R) ? "r" : "-",
++		(attrs & GRUB_MEM_ATTR_W) ? "w" : "-",
++		(attrs & GRUB_MEM_ATTR_X) ? "x" : "-");
++  if (grub_stack_addr != (grub_addr_t)-1ll)
++    {
++      grub_dprintf ("nx", "Setting attributes for stack at 0x%"PRIxGRUB_ADDR"-0x%"PRIxGRUB_ADDR" to rw%c\n",
++		    grub_stack_addr, grub_stack_addr + grub_stack_size - 1,
++		    (stack_set_attrs & GRUB_MEM_ATTR_X) ? 'x' : '-');
++      grub_update_mem_attrs (grub_stack_addr, grub_stack_size,
++			     stack_set_attrs, stack_clear_attrs);
++
++      grub_get_mem_attrs (grub_stack_addr, 4096, &attrs);
++      grub_dprintf ("nx", "permissions for 0x%"PRIxGRUB_ADDR" are %s%s%s\n",
++		    grub_stack_addr,
++		    (attrs & GRUB_MEM_ATTR_R) ? "r" : "-",
++		    (attrs & GRUB_MEM_ATTR_W) ? "w" : "-",
++		    (attrs & GRUB_MEM_ATTR_X) ? "x" : "-");
++    }
++
++#if defined(__i386__) || defined(__x86_64__)
++  asm volatile ("cli");
++#endif
++
+   hf = (handover_func)((char *)kernel_addr + handover_offset + offset);
+   grub_dprintf ("linux", "handover_func() = %p\n", hf);
+   hf (grub_efi_image_handle, grub_efi_system_table, kernel_params);
+diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
+index 3d4069e4c6..d80d6ec312 100644
+--- a/grub-core/loader/i386/efi/linux.c
++++ b/grub-core/loader/i386/efi/linux.c
+@@ -44,7 +44,7 @@ struct grub_linuxefi_context {
+   grub_uint32_t handover_offset;
+   struct linux_kernel_params *params;
+   char *cmdline;
+-
++  int nx_supported;
+   void *initrd_mem;
+ };
+ 
+@@ -110,13 +110,19 @@ kernel_alloc(grub_efi_uintn_t size,
+       pages = BYTES_TO_PAGES(size);
+       grub_dprintf ("linux", "Trying to allocate %lu pages from %p\n",
+ 		    pages, (void *)max);
++      size = pages * GRUB_EFI_PAGE_SIZE;
+ 
+       prev_max = max;
+       addr = grub_efi_allocate_pages_real (max, pages,
+ 					   max_addresses[i].alloc_type,
+ 					   memtype);
+       if (addr)
+-	grub_dprintf ("linux", "Allocated at %p\n", addr);
++	{
++	  grub_dprintf ("linux", "Allocated at %p\n", addr);
++	  grub_update_mem_attrs ((grub_addr_t)addr, size,
++				 GRUB_MEM_ATTR_R|GRUB_MEM_ATTR_W,
++				 GRUB_MEM_ATTR_X);
++	}
+     }
+ 
+   while (grub_error_pop ())
+@@ -137,9 +143,11 @@ grub_linuxefi_boot (void *data)
+ 
+   asm volatile ("cli");
+ 
+-  return grub_efi_linux_boot ((char *)context->kernel_mem,
++  return grub_efi_linux_boot ((grub_addr_t)context->kernel_mem,
++			      context->kernel_size,
+ 			      context->handover_offset,
+-			      context->params);
++			      context->params,
++			      context->nx_supported);
+ }
+ 
+ static grub_err_t
+@@ -308,7 +316,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+   grub_uint32_t handover_offset;
+   struct linux_kernel_params *params = 0;
+   char *cmdline = 0;
++  int nx_supported = 1;
+   struct grub_linuxefi_context *context = 0;
++  grub_err_t err;
+ 
+   grub_dl_ref (my_mod);
+ 
+@@ -352,6 +362,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+ 	}
+     }
+ 
++  err = grub_efi_check_nx_image_support ((grub_addr_t)kernel, filelen,
++					 &nx_supported);
++  if (err != GRUB_ERR_NONE)
++    return err;
++  grub_dprintf ("linux", "nx is%s supported by this kernel\n",
++		nx_supported ? "" : " not");
++
+   lh = (struct linux_i386_kernel_header *)kernel;
+   grub_dprintf ("linux", "original lh is at %p\n", kernel);
+ 
+@@ -515,6 +532,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+   context->handover_offset = handover_offset;
+   context->params = params;
+   context->cmdline = cmdline;
++  context->nx_supported = nx_supported;
+ 
+   grub_loader_set_ex (grub_linuxefi_boot, grub_linuxefi_unload, context, 0);
+ 
+diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
+index ef8fcb9e1b..c160ddb0ea 100644
+--- a/grub-core/loader/i386/linux.c
++++ b/grub-core/loader/i386/linux.c
+@@ -831,6 +831,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+   grub_memset (&linux_params, 0, sizeof (linux_params));
+   grub_memcpy (&linux_params.setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1);
+ 
++  grub_dprintf("efi", "setting attributes for %p (%zu bytes) to +rw-x\n",
++	       &linux_params, sizeof (lh) + len);
++  grub_update_mem_attrs ((grub_addr_t)&linux_params, sizeof (lh) + len,
++			 GRUB_MEM_ATTR_R|GRUB_MEM_ATTR_W, GRUB_MEM_ATTR_X);
++
+   linux_params.code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR;
+   linux_params.kernel_alignment = (1 << align);
+   linux_params.ps_mouse = linux_params.padding10 =  0;
+diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
+index a635bcb0a9..8ca8c38f9a 100644
+--- a/include/grub/efi/efi.h
++++ b/include/grub/efi/efi.h
+@@ -135,12 +135,16 @@ extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd,
+ 						char **device,
+ 						char **path);
+ 
++extern grub_addr_t EXPORT_VAR(grub_stack_addr);
++extern grub_size_t EXPORT_VAR(grub_stack_size);
++
+ #if defined(__arm__) || defined(__aarch64__)
+ void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void);
+ grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *);
+ #include <grub/cpu/linux.h>
+ grub_err_t grub_armxx_efi_linux_check_image(struct linux_armxx_kernel_header *lh);
+-grub_err_t grub_armxx_efi_linux_boot_image(grub_addr_t addr, char *args);
++grub_err_t grub_armxx_efi_linux_boot_image(grub_addr_t addr, grub_size_t size,
++					  char *args, int nx_enabled);
+ #endif
+ 
+ grub_addr_t grub_efi_section_addr (const char *section);
+diff --git a/include/grub/efi/linux.h b/include/grub/efi/linux.h
+index 0033d9305a..8130b19590 100644
+--- a/include/grub/efi/linux.h
++++ b/include/grub/efi/linux.h
+@@ -22,10 +22,23 @@
+ #include <grub/err.h>
+ #include <grub/symbol.h>
+ 
++#define GRUB_MOK_POLICY_NX_REQUIRED   0x1
++
+ int
+ EXPORT_FUNC(grub_linuxefi_secure_validate) (void *data, grub_uint32_t size);
++
+ grub_err_t
+-EXPORT_FUNC(grub_efi_linux_boot) (void *kernel_address, grub_off_t offset,
+-				  void *kernel_param);
++EXPORT_FUNC(grub_efi_linux_boot) (grub_addr_t kernel_address,
++				  grub_size_t kernel_size,
++				  grub_off_t handover_offset,
++				  void *kernel_param, int nx_enabled);
++
++grub_err_t
++EXPORT_FUNC(grub_efi_check_nx_image_support) (grub_addr_t kernel_addr,
++					      grub_size_t kernel_size,
++					      int *nx_supported);
++
++grub_err_t
++EXPORT_FUNC(grub_efi_check_nx_required) (int *nx_required);
+ 
+ #endif /* ! GRUB_EFI_LINUX_HEADER */
+diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
+index 2241f6317b..45c9f8b756 100644
+--- a/include/grub/efi/pe32.h
++++ b/include/grub/efi/pe32.h
+@@ -172,6 +172,8 @@ struct grub_pe32_optional_header
+   struct grub_pe32_data_directory reserved_entry;
+ };
+ 
++#define GRUB_PE32_NX_COMPAT 0x0100
++
+ struct grub_pe64_optional_header
+ {
+   grub_uint16_t magic;
diff --git a/SOURCES/0553-nx-set-the-nx-compatible-flag-in-EFI-grub-images.patch b/SOURCES/0553-nx-set-the-nx-compatible-flag-in-EFI-grub-images.patch
new file mode 100644
index 0000000..662de5d
--- /dev/null
+++ b/SOURCES/0553-nx-set-the-nx-compatible-flag-in-EFI-grub-images.patch
@@ -0,0 +1,38 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Tue, 22 Mar 2022 10:57:20 -0400
+Subject: [PATCH] nx: set the nx compatible flag in EFI grub images
+
+For NX, we need the grub binary to announce that it is compatible with
+the NX feature.  This implies that when loading the executable grub
+image, several attributes are true:
+
+- the binary doesn't need an executable stack
+- the binary doesn't need sections to be both executable and writable
+- the binary knows how to use the EFI Memory Attributes protocol on code
+  it is loading.
+
+This patch adds a definition for the PE DLL Characteristics flag
+GRUB_PE32_NX_COMPAT, and changes grub-mkimage to set that flag.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+(cherry picked from commit 0c7f1aed5a87f75051b421903a900ccb4bbd795a)
+(cherry picked from commit 2f9446d488da96de963f4ffe03b0a1c60a4664f5)
+[rharwood: fix uninitialized use of stack_attrs]
+Signed-off-by: Robbie Harwood <rharwood@redhat.com>
+---
+ util/mkimage.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/util/mkimage.c b/util/mkimage.c
+index 16418e245d..c77025904c 100644
+--- a/util/mkimage.c
++++ b/util/mkimage.c
+@@ -1358,6 +1358,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
+ 	    section = (struct grub_pe32_section_table *)(o64 + 1);
+ 	  }
+ 
++	PE_OHDR (o32, o64, dll_characteristics) = grub_host_to_target16 (GRUB_PE32_NX_COMPAT);
+ 	PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size);
+ 	PE_OHDR (o32, o64, entry_addr) = grub_host_to_target32 (layout.start_address);
+ 	PE_OHDR (o32, o64, image_base) = 0;
diff --git a/SOURCES/0554-Fixup-grub_efi_get_variable-type-in-our-loaders.patch b/SOURCES/0554-Fixup-grub_efi_get_variable-type-in-our-loaders.patch
new file mode 100644
index 0000000..7d0ca72
--- /dev/null
+++ b/SOURCES/0554-Fixup-grub_efi_get_variable-type-in-our-loaders.patch
@@ -0,0 +1,51 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Wed, 11 May 2022 16:37:14 -0400
+Subject: [PATCH] Fixup grub_efi_get_variable() type in our loaders
+
+Has a new type now that we have 04ae030d0eea8668d4417702d88bf2cf04713d80
+("efi: Return grub_efi_status_t from grub_efi_get_variable()").
+
+Signed-off-by: Robbie Harwood <rharwood@redhat.com>
+---
+ grub-core/kern/efi/init.c | 4 ++--
+ grub-core/kern/efi/sb.c   | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
+index 501608f743..565ce541f5 100644
+--- a/grub-core/kern/efi/init.c
++++ b/grub-core/kern/efi/init.c
+@@ -104,8 +104,8 @@ grub_efi_env_init (void)
+   struct grub_envblk envblk_s = { NULL, 0 };
+   grub_envblk_t envblk = &envblk_s;
+ 
+-  envblk_s.buf = grub_efi_get_variable ("GRUB_ENV", &efi_grub_guid,
+-					&envblk_s.size);
++  grub_efi_get_variable ("GRUB_ENV", &efi_grub_guid, &envblk_s.size,
++                         &envblk_s.buf);
+   if (!envblk_s.buf || envblk_s.size < 1)
+     return;
+ 
+diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c
+index d74778b0ca..f84d7d3080 100644
+--- a/grub-core/kern/efi/sb.c
++++ b/grub-core/kern/efi/sb.c
+@@ -35,7 +35,7 @@ grub_efi_secure_boot (void)
+   char *setup_mode = NULL;
+   grub_efi_boolean_t ret = 0;
+ 
+-  secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize);
++  grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize, &secure_boot);
+   if (datasize != 1 || !secure_boot)
+     {
+       grub_dprintf ("secureboot", "No SecureBoot variable\n");
+@@ -43,7 +43,7 @@ grub_efi_secure_boot (void)
+     }
+   grub_dprintf ("secureboot", "SecureBoot: %d\n", *secure_boot);
+ 
+-  setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize);
++  grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize, &setup_mode);
+   if (datasize != 1 || !setup_mode)
+     {
+       grub_dprintf ("secureboot", "No SetupMode variable\n");
diff --git a/SOURCES/0555-Make-debug-file-show-which-file-filters-get-run.patch b/SOURCES/0555-Make-debug-file-show-which-file-filters-get-run.patch
new file mode 100644
index 0000000..b614ef3
--- /dev/null
+++ b/SOURCES/0555-Make-debug-file-show-which-file-filters-get-run.patch
@@ -0,0 +1,47 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Fri, 29 Jul 2022 15:56:00 -0400
+Subject: [PATCH] Make debug=file show which file filters get run.
+
+If one of the file filters breaks things, it's hard to figure out where
+it has happened.
+
+This makes grub log which filter is being run, which makes it easier to
+figure out where you are in the sequence of events.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+(cherry picked from commit d3d6518a13b5440a3be6c66b0ae47447182f2891)
+(cherry picked from commit d197e70761b1383827e9008e21ee41c6c7015776)
+---
+ grub-core/kern/file.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c
+index f062fc21e7..5e1f29d0dd 100644
+--- a/grub-core/kern/file.c
++++ b/grub-core/kern/file.c
+@@ -30,6 +30,14 @@ void (*EXPORT_VAR (grub_grubnet_fini)) (void);
+ 
+ grub_file_filter_t grub_file_filters[GRUB_FILE_FILTER_MAX];
+ 
++static char *filter_names[] = {
++    [GRUB_FILE_FILTER_VERIFY] = "GRUB_FILE_FILTER_VERIFY",
++    [GRUB_FILE_FILTER_GZIO] = "GRUB_FILE_FILTER_GZIO",
++    [GRUB_FILE_FILTER_XZIO] = "GRUB_FILE_FILTER_XZIO",
++    [GRUB_FILE_FILTER_LZOPIO] = "GRUB_FILE_FILTER_LZOPIO",
++    [GRUB_FILE_FILTER_MAX] = "GRUB_FILE_FILTER_MAX"
++};
++
+ /* Get the device part of the filename NAME. It is enclosed by parentheses.  */
+ char *
+ grub_file_get_device_name (const char *name)
+@@ -121,6 +129,9 @@ grub_file_open (const char *name, enum grub_file_type type)
+     if (grub_file_filters[filter])
+       {
+ 	last_file = file;
++	if (filter < GRUB_FILE_FILTER_MAX)
++	  grub_dprintf ("file", "Running %s file filter\n",
++			filter_names[filter]);
+ 	file = grub_file_filters[filter] (file, type);
+ 	if (file && file != last_file)
+ 	  {
diff --git a/SOURCES/0556-efi-use-enumerated-array-positions-for-our-allocatio.patch b/SOURCES/0556-efi-use-enumerated-array-positions-for-our-allocatio.patch
new file mode 100644
index 0000000..6f1bfc7
--- /dev/null
+++ b/SOURCES/0556-efi-use-enumerated-array-positions-for-our-allocatio.patch
@@ -0,0 +1,83 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Mon, 1 Aug 2022 14:06:30 -0400
+Subject: [PATCH] efi: use enumerated array positions for our allocation
+ choices
+
+In our kernel allocator on EFI systems, we currently have a growing
+amount of code that references the various allocation policies by
+position in the array, and of course maintenance of this code scales
+very poorly.
+
+This patch changes them to be enumerated, so they're easier to refer to
+farther along in the code without confusion.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+(cherry picked from commit 6768026270cca015d7fef0ecc8a4119e9b3d3923)
+(cherry picked from commit 50b2ca3274b6950393a4ffc7edde04a1a3de594e)
+---
+ grub-core/loader/i386/efi/linux.c | 31 ++++++++++++++++++++-----------
+ 1 file changed, 20 insertions(+), 11 deletions(-)
+
+diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
+index d80d6ec312..23b27f6507 100644
+--- a/grub-core/loader/i386/efi/linux.c
++++ b/grub-core/loader/i386/efi/linux.c
+@@ -60,17 +60,26 @@ struct allocation_choice {
+     grub_efi_allocate_type_t alloc_type;
+ };
+ 
+-static struct allocation_choice max_addresses[4] =
++enum {
++    KERNEL_PREF_ADDRESS,
++    KERNEL_4G_LIMIT,
++    KERNEL_NO_LIMIT,
++};
++
++static struct allocation_choice max_addresses[] =
+   {
+     /* the kernel overrides this one with pref_address and
+      * GRUB_EFI_ALLOCATE_ADDRESS */
+-    { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
++    [KERNEL_PREF_ADDRESS] =
++      { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
++    /* If the flag in params is set, this one gets changed to be above 4GB. */
++    [KERNEL_4G_LIMIT] =
++      { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
+     /* this one is always below 4GB, which we still *prefer* even if the flag
+      * is set. */
+-    { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
+-    /* If the flag in params is set, this one gets changed to be above 4GB. */
+-    { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
+-    { 0, 0 }
++    [KERNEL_NO_LIMIT] =
++      { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
++    { NO_MEM, 0, 0 }
+   };
+ static struct allocation_choice saved_addresses[4];
+ 
+@@ -423,7 +432,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+   if (lh->xloadflags & LINUX_XLF_CAN_BE_LOADED_ABOVE_4G)
+     {
+       grub_dprintf ("linux", "Loading kernel above 4GB is supported; enabling.\n");
+-      max_addresses[2].addr = GRUB_EFI_MAX_USABLE_ADDRESS;
++      max_addresses[KERNEL_NO_LIMIT].addr = GRUB_EFI_MAX_USABLE_ADDRESS;
+     }
+   else
+     {
+@@ -495,11 +504,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+   grub_dprintf ("linux", "lh->pref_address: %p\n", (void *)(grub_addr_t)lh->pref_address);
+   if (lh->pref_address < (grub_uint64_t)GRUB_EFI_MAX_ALLOCATION_ADDRESS)
+     {
+-      max_addresses[0].addr = lh->pref_address;
+-      max_addresses[0].alloc_type = GRUB_EFI_ALLOCATE_ADDRESS;
++      max_addresses[KERNEL_PREF_ADDRESS].addr = lh->pref_address;
++      max_addresses[KERNEL_PREF_ADDRESS].alloc_type = GRUB_EFI_ALLOCATE_ADDRESS;
+     }
+-  max_addresses[1].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
+-  max_addresses[2].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
++  max_addresses[KERNEL_4G_LIMIT].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
++  max_addresses[KERNEL_NO_LIMIT].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
+   kernel_size = lh->init_size;
+   kernel_mem = kernel_alloc (kernel_size, GRUB_EFI_RUNTIME_SERVICES_CODE,
+ 			     N_("can't allocate kernel"));
diff --git a/SOURCES/0557-efi-split-allocation-policy-for-kernel-vs-initrd-mem.patch b/SOURCES/0557-efi-split-allocation-policy-for-kernel-vs-initrd-mem.patch
new file mode 100644
index 0000000..08d2765
--- /dev/null
+++ b/SOURCES/0557-efi-split-allocation-policy-for-kernel-vs-initrd-mem.patch
@@ -0,0 +1,129 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Mon, 1 Aug 2022 14:24:39 -0400
+Subject: [PATCH] efi: split allocation policy for kernel vs initrd memories.
+
+Currently in our kernel allocator, we use the same set of choices for
+all of our various kernel and initramfs allocations, though they do not
+have exactly the same constraints.
+
+This patch adds the concept of an allocation purpose, which currently
+can be KERNEL_MEM or INITRD_MEM, and updates kernel_alloc() calls
+appropriately, but does not change any current policy decision.  It
+also adds a few debug prints.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+(cherry picked from commit 36307bed28cd838116fc4af26a30719660d62d4c)
+(cherry picked from commit dc1196350b0cbe89582832f44df0fce67e0c9fb2)
+---
+ grub-core/loader/i386/efi/linux.c | 35 +++++++++++++++++++++++++++--------
+ 1 file changed, 27 insertions(+), 8 deletions(-)
+
+diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
+index 23b27f6507..09e7596064 100644
+--- a/grub-core/loader/i386/efi/linux.c
++++ b/grub-core/loader/i386/efi/linux.c
+@@ -55,7 +55,14 @@ struct grub_linuxefi_context {
+ 
+ #define BYTES_TO_PAGES(bytes)   (((bytes) + 0xfff) >> 12)
+ 
++typedef enum {
++    NO_MEM,
++    KERNEL_MEM,
++    INITRD_MEM,
++} kernel_alloc_purpose_t;
++
+ struct allocation_choice {
++    kernel_alloc_purpose_t purpose;
+     grub_efi_physical_address_t addr;
+     grub_efi_allocate_type_t alloc_type;
+ };
+@@ -64,6 +71,7 @@ enum {
+     KERNEL_PREF_ADDRESS,
+     KERNEL_4G_LIMIT,
+     KERNEL_NO_LIMIT,
++    INITRD_MAX_ADDRESS,
+ };
+ 
+ static struct allocation_choice max_addresses[] =
+@@ -71,14 +79,17 @@ static struct allocation_choice max_addresses[] =
+     /* the kernel overrides this one with pref_address and
+      * GRUB_EFI_ALLOCATE_ADDRESS */
+     [KERNEL_PREF_ADDRESS] =
+-      { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
++      { KERNEL_MEM, GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
+     /* If the flag in params is set, this one gets changed to be above 4GB. */
+     [KERNEL_4G_LIMIT] =
+-      { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
++      { KERNEL_MEM, GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
+     /* this one is always below 4GB, which we still *prefer* even if the flag
+      * is set. */
+     [KERNEL_NO_LIMIT] =
+-      { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
++      { KERNEL_MEM, GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
++    /* this is for the initrd */
++    [INITRD_MAX_ADDRESS] =
++      { INITRD_MEM, GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
+     { NO_MEM, 0, 0 }
+   };
+ static struct allocation_choice saved_addresses[4];
+@@ -95,7 +106,8 @@ kernel_free(void *addr, grub_efi_uintn_t size)
+ }
+ 
+ static void *
+-kernel_alloc(grub_efi_uintn_t size,
++kernel_alloc(kernel_alloc_purpose_t purpose,
++	     grub_efi_uintn_t size,
+ 	     grub_efi_memory_type_t memtype,
+ 	     const char * const errmsg)
+ {
+@@ -108,6 +120,9 @@ kernel_alloc(grub_efi_uintn_t size,
+       grub_uint64_t max = max_addresses[i].addr;
+       grub_efi_uintn_t pages;
+ 
++      if (purpose != max_addresses[i].purpose)
++	continue;
++
+       /*
+        * When we're *not* loading the kernel, or >4GB allocations aren't
+        * supported, these entries are basically all the same, so don't re-try
+@@ -262,7 +277,8 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
+ 	}
+     }
+ 
+-  initrd_mem = kernel_alloc(size, GRUB_EFI_RUNTIME_SERVICES_DATA,
++  grub_dprintf ("linux", "Trying to allocate initrd mem\n");
++  initrd_mem = kernel_alloc(INITRD_MEM, size, GRUB_EFI_RUNTIME_SERVICES_DATA,
+ 			    N_("can't allocate initrd"));
+   if (initrd_mem == NULL)
+     goto fail;
+@@ -440,7 +456,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+     }
+ #endif
+ 
+-  params = kernel_alloc (sizeof(*params), GRUB_EFI_RUNTIME_SERVICES_DATA,
++  params = kernel_alloc (KERNEL_MEM, sizeof(*params),
++			 GRUB_EFI_RUNTIME_SERVICES_DATA,
+ 			 "cannot allocate kernel parameters");
+   if (!params)
+     goto fail;
+@@ -462,7 +479,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+   grub_dprintf ("linux", "new lh is at %p\n", lh);
+ 
+   grub_dprintf ("linux", "setting up cmdline\n");
+-  cmdline = kernel_alloc (lh->cmdline_size + 1,
++  cmdline = kernel_alloc (KERNEL_MEM, lh->cmdline_size + 1,
+ 			  GRUB_EFI_RUNTIME_SERVICES_DATA,
+ 			  N_("can't allocate cmdline"));
+   if (!cmdline)
+@@ -510,7 +527,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+   max_addresses[KERNEL_4G_LIMIT].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
+   max_addresses[KERNEL_NO_LIMIT].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
+   kernel_size = lh->init_size;
+-  kernel_mem = kernel_alloc (kernel_size, GRUB_EFI_RUNTIME_SERVICES_CODE,
++  grub_dprintf ("linux", "Trying to allocate kernel mem\n");
++  kernel_mem = kernel_alloc (KERNEL_MEM, kernel_size,
++			     GRUB_EFI_RUNTIME_SERVICES_CODE,
+ 			     N_("can't allocate kernel"));
+   restore_addresses();
+   if (!kernel_mem)
diff --git a/SOURCES/0558-efi-use-EFI_LOADER_-CODE-DATA-for-kernel-and-initrd-.patch b/SOURCES/0558-efi-use-EFI_LOADER_-CODE-DATA-for-kernel-and-initrd-.patch
new file mode 100644
index 0000000..28f603e
--- /dev/null
+++ b/SOURCES/0558-efi-use-EFI_LOADER_-CODE-DATA-for-kernel-and-initrd-.patch
@@ -0,0 +1,63 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Mon, 1 Aug 2022 13:04:43 -0400
+Subject: [PATCH] efi: use EFI_LOADER_(CODE|DATA) for kernel and initrd
+ allocations
+
+At some point due to an erroneous kernel warning, we switched kernel and
+initramfs to being loaded in EFI_RUNTIME_SERVICES_CODE and
+EFI_RUNTIME_SERVICES_DATA memory pools.  This doesn't appear to be
+correct according to the spec, and that kernel warning has gone away.
+
+This patch puts them back in EFI_LOADER_CODE and EFI_LOADER_DATA
+allocations, respectively.
+
+Resolves: rhbz#2108456
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+(cherry picked from commit 35b5d5fa47bc394c76022e6595b173e68f53225e)
+(cherry picked from commit 66e1c922b40957fca488435e06a2f875a219844b)
+---
+ grub-core/loader/i386/efi/linux.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
+index 09e7596064..4d39023792 100644
+--- a/grub-core/loader/i386/efi/linux.c
++++ b/grub-core/loader/i386/efi/linux.c
+@@ -278,7 +278,7 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
+     }
+ 
+   grub_dprintf ("linux", "Trying to allocate initrd mem\n");
+-  initrd_mem = kernel_alloc(INITRD_MEM, size, GRUB_EFI_RUNTIME_SERVICES_DATA,
++  initrd_mem = kernel_alloc(INITRD_MEM, size, GRUB_EFI_LOADER_DATA,
+ 			    N_("can't allocate initrd"));
+   if (initrd_mem == NULL)
+     goto fail;
+@@ -457,7 +457,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+ #endif
+ 
+   params = kernel_alloc (KERNEL_MEM, sizeof(*params),
+-			 GRUB_EFI_RUNTIME_SERVICES_DATA,
++			 GRUB_EFI_LOADER_DATA,
+ 			 "cannot allocate kernel parameters");
+   if (!params)
+     goto fail;
+@@ -480,7 +480,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+ 
+   grub_dprintf ("linux", "setting up cmdline\n");
+   cmdline = kernel_alloc (KERNEL_MEM, lh->cmdline_size + 1,
+-			  GRUB_EFI_RUNTIME_SERVICES_DATA,
++			  GRUB_EFI_LOADER_DATA,
+ 			  N_("can't allocate cmdline"));
+   if (!cmdline)
+     goto fail;
+@@ -529,7 +529,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+   kernel_size = lh->init_size;
+   grub_dprintf ("linux", "Trying to allocate kernel mem\n");
+   kernel_mem = kernel_alloc (KERNEL_MEM, kernel_size,
+-			     GRUB_EFI_RUNTIME_SERVICES_CODE,
++			     GRUB_EFI_LOADER_CODE,
+ 			     N_("can't allocate kernel"));
+   restore_addresses();
+   if (!kernel_mem)
diff --git a/SOURCES/0559-ieee1275-implement-vec5-for-cas-negotiation.patch b/SOURCES/0559-ieee1275-implement-vec5-for-cas-negotiation.patch
new file mode 100644
index 0000000..ff614f8
--- /dev/null
+++ b/SOURCES/0559-ieee1275-implement-vec5-for-cas-negotiation.patch
@@ -0,0 +1,72 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Diego Domingos <diegodo@linux.vnet.ibm.com>
+Date: Thu, 25 Aug 2022 11:37:56 -0400
+Subject: [PATCH] ieee1275: implement vec5 for cas negotiation
+
+As a legacy support, if the vector 5 is not implemented, Power
+Hypervisor will consider the max CPUs as 64 instead 256 currently
+supported during client-architecture-support negotiation.
+
+This patch implements the vector 5 and set the MAX CPUs to 256 while
+setting the others values to 0 (default).
+
+Signed-off-by: Diego Domingos <diegodo@linux.vnet.ibm.com>
+Signed-off-by: Robbie Harwood <rharwood@redhat.com>
+(cherry picked from commit f735c65b6da8a9d4251242b37774e1a517511253)
+(cherry picked from commit 1639f43b2db4ac405ac2a92e50ed4cff351c3baa)
+---
+ grub-core/kern/ieee1275/init.c | 20 +++++++++++++++++++-
+ 1 file changed, 19 insertions(+), 1 deletion(-)
+
+diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
+index 1414695cc6..37f3098c39 100644
+--- a/grub-core/kern/ieee1275/init.c
++++ b/grub-core/kern/ieee1275/init.c
+@@ -307,6 +307,18 @@ struct option_vector2 {
+   grub_uint8_t max_pft_size;
+ } __attribute__((packed));
+ 
++struct option_vector5 {
++        grub_uint8_t byte1;
++        grub_uint8_t byte2;
++        grub_uint8_t byte3;
++        grub_uint8_t cmo;
++        grub_uint8_t associativity;
++        grub_uint8_t bin_opts;
++        grub_uint8_t micro_checkpoint;
++        grub_uint8_t reserved0;
++        grub_uint32_t max_cpus;
++} __attribute__((packed));
++
+ struct pvr_entry {
+   grub_uint32_t mask;
+   grub_uint32_t entry;
+@@ -325,6 +337,8 @@ struct cas_vector {
+   grub_uint16_t vec3;
+   grub_uint8_t vec4_size;
+   grub_uint16_t vec4;
++  grub_uint8_t vec5_size;
++  struct option_vector5 vec5;
+ } __attribute__((packed));
+ 
+ /* Call ibm,client-architecture-support to try to get more RMA.
+@@ -345,7 +359,7 @@ grub_ieee1275_ibm_cas (void)
+   } args;
+   struct cas_vector vector = {
+     .pvr_list = { { 0x00000000, 0xffffffff } }, /* any processor */
+-    .num_vecs = 4 - 1,
++    .num_vecs = 5 - 1,
+     .vec1_size = 0,
+     .vec1 = 0x80, /* ignore */
+     .vec2_size = 1 + sizeof(struct option_vector2) - 2,
+@@ -356,6 +370,10 @@ grub_ieee1275_ibm_cas (void)
+     .vec3 = 0x00e0, // ask for FP + VMX + DFP but don't halt if unsatisfied
+     .vec4_size = 2 - 1,
+     .vec4 = 0x0001, // set required minimum capacity % to the lowest value
++    .vec5_size = 1 + sizeof(struct option_vector5) - 2,
++    .vec5 = {
++	0, 0, 0, 0, 0, 0, 0, 0, 256
++    }
+   };
+ 
+   INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2);
diff --git a/SOURCES/grub.macros b/SOURCES/grub.macros
index 783cb57..c9ed442 100644
--- a/SOURCES/grub.macros
+++ b/SOURCES/grub.macros
@@ -379,11 +379,11 @@ for x in grub-mkimage ; do					\\\
 done								\
 %{nil}
 
-%global grub_modules " all_video boot blscfg 			\\\
+%global grub_modules " all_video boot blscfg			\\\
 		cat configfile cryptodisk echo ext2		\\\
 		fat font gcry_rijndael gcry_rsa gcry_serpent	\\\
 		gcry_sha256 gcry_twofish gcry_whirlpool		\\\
-		gfxmenu gfxterm gzio halt  http			\\\
+		gfxmenu gfxterm gzio halt http			\\\
 		increment iso9660 jpeg loadenv loopback linux	\\\
 		lvm luks mdraid09 mdraid1x minicmd net		\\\
 		normal part_apple part_msdos part_gpt		\\\
@@ -596,7 +596,7 @@ touch ${RPM_BUILD_ROOT}/boot/%{name}/grub.cfg			\
 %{expand:%%files %{1}}						\
 %defattr(-,root,root,-)						\
 %config(noreplace) %{_sysconfdir}/%{name}.cfg			\
-%ghost %config(noreplace) /boot/%{name}/grub.cfg		\
+%ghost %config(noreplace) %attr(0700,root,root)/boot/%{name}/grub.cfg	\
 %dir %attr(0700,root,root)/boot/loader/entries			\
 %ifarch ppc64le						\
 %dir %{_libdir}/grub/%{2}/					\
diff --git a/SOURCES/grub.patches b/SOURCES/grub.patches
index 54b52a2..9cd36c8 100644
--- a/SOURCES/grub.patches
+++ b/SOURCES/grub.patches
@@ -498,52 +498,62 @@ Patch0497: 0497-x86-efi-Re-arrange-grub_cmd_linux-a-little-bit.patch
 Patch0498: 0498-x86-efi-Make-our-own-allocator-for-kernel-stuff.patch
 Patch0499: 0499-x86-efi-Allow-initrd-params-cmdline-allocations-abov.patch
 Patch0500: 0500-x86-efi-Reduce-maximum-bounce-buffer-size-to-16-MiB.patch
-Patch0501: 0501-loader-efi-chainloader-grub_load_and_start_image-doe.patch
-Patch0502: 0502-loader-efi-chainloader-simplify-the-loader-state.patch
-Patch0503: 0503-commands-boot-Add-API-to-pass-context-to-loader.patch
-Patch0504: 0504-loader-efi-chainloader-Use-grub_loader_set_ex.patch
-Patch0505: 0505-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch
-Patch0506: 0506-loader-i386-efi-linux-Use-grub_loader_set_ex.patch
-Patch0507: 0507-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch
-Patch0508: 0508-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch
-Patch0509: 0509-video-readers-png-Abort-sooner-if-a-read-operation-f.patch
-Patch0510: 0510-video-readers-png-Refuse-to-handle-multiple-image-he.patch
-Patch0511: 0511-video-readers-png-Drop-greyscale-support-to-fix-heap.patch
-Patch0512: 0512-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch
-Patch0513: 0513-video-readers-png-Sanity-check-some-huffman-codes.patch
-Patch0514: 0514-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch
-Patch0515: 0515-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch
-Patch0516: 0516-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch
-Patch0517: 0517-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch
-Patch0518: 0518-normal-charset-Fix-array-out-of-bounds-formatting-un.patch
-Patch0519: 0519-net-netbuff-Block-overly-large-netbuff-allocs.patch
-Patch0520: 0520-net-ip-Do-IP-fragment-maths-safely.patch
-Patch0521: 0521-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch
-Patch0522: 0522-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch
-Patch0523: 0523-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch
-Patch0524: 0524-misc-Format-string-for-grub_error-should-be-a-litera.patch
-Patch0525: 0525-net-tftp-Avoid-a-trivial-UAF.patch
-Patch0526: 0526-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch
-Patch0527: 0527-net-http-Fix-OOB-write-for-split-http-headers.patch
-Patch0528: 0528-net-http-Error-out-on-headers-with-LF-without-CR.patch
-Patch0529: 0529-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch
-Patch0530: 0530-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch
-Patch0531: 0531-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch
-Patch0532: 0532-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch
-Patch0533: 0533-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch
-Patch0534: 0534-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch
-Patch0535: 0535-Define-GRUB_EFI_SHIM_LOCK_GUID.patch
-Patch0536: 0536-misc-Make-grub_min-and-grub_max-more-resilient.patch
-Patch0537: 0537-ReiserFS-switch-to-using-grub_min-grub_max.patch
-Patch0538: 0538-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch
-Patch0539: 0539-modules-make-.module_license-read-only.patch
-Patch0540: 0540-modules-strip-.llvm_addrsig-sections-and-similar.patch
-Patch0541: 0541-modules-Don-t-allocate-space-for-non-allocable-secti.patch
-Patch0542: 0542-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch
-Patch0543: 0543-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch
-Patch0544: 0544-modules-load-module-sections-at-page-aligned-address.patch
-Patch0545: 0545-nx-add-memory-attribute-get-set-API.patch
-Patch0546: 0546-nx-set-page-permissions-for-loaded-modules.patch
-Patch0547: 0547-nx-set-attrs-in-our-kernel-loaders.patch
-Patch0548: 0548-nx-set-the-nx-compatible-flag-in-EFI-grub-images.patch
-Patch0549: 0549-Fixup-grub_efi_get_variable-type-in-our-loaders.patch
+Patch0501: 0501-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch
+Patch0502: 0502-ibmvtpm-Backport-ibmvtpm-support-to-grub-2.02.patch
+Patch0503: 0503-powerpc-do-CAS-in-a-more-compatible-way.patch
+Patch0504: 0504-powerpc-prefix-detection-support-device-names-with-c.patch
+Patch0505: 0505-make-ofdisk_retries-optional.patch
+Patch0506: 0506-loader-efi-chainloader-grub_load_and_start_image-doe.patch
+Patch0507: 0507-loader-efi-chainloader-simplify-the-loader-state.patch
+Patch0508: 0508-commands-boot-Add-API-to-pass-context-to-loader.patch
+Patch0509: 0509-loader-efi-chainloader-Use-grub_loader_set_ex.patch
+Patch0510: 0510-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch
+Patch0511: 0511-loader-i386-efi-linux-Use-grub_loader_set_ex.patch
+Patch0512: 0512-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch
+Patch0513: 0513-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch
+Patch0514: 0514-video-readers-png-Abort-sooner-if-a-read-operation-f.patch
+Patch0515: 0515-video-readers-png-Refuse-to-handle-multiple-image-he.patch
+Patch0516: 0516-video-readers-png-Drop-greyscale-support-to-fix-heap.patch
+Patch0517: 0517-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch
+Patch0518: 0518-video-readers-png-Sanity-check-some-huffman-codes.patch
+Patch0519: 0519-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch
+Patch0520: 0520-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch
+Patch0521: 0521-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch
+Patch0522: 0522-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch
+Patch0523: 0523-normal-charset-Fix-array-out-of-bounds-formatting-un.patch
+Patch0524: 0524-net-netbuff-Block-overly-large-netbuff-allocs.patch
+Patch0525: 0525-net-ip-Do-IP-fragment-maths-safely.patch
+Patch0526: 0526-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch
+Patch0527: 0527-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch
+Patch0528: 0528-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch
+Patch0529: 0529-misc-Format-string-for-grub_error-should-be-a-litera.patch
+Patch0530: 0530-net-tftp-Avoid-a-trivial-UAF.patch
+Patch0531: 0531-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch
+Patch0532: 0532-net-http-Fix-OOB-write-for-split-http-headers.patch
+Patch0533: 0533-net-http-Error-out-on-headers-with-LF-without-CR.patch
+Patch0534: 0534-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch
+Patch0535: 0535-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch
+Patch0536: 0536-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch
+Patch0537: 0537-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch
+Patch0538: 0538-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch
+Patch0539: 0539-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch
+Patch0540: 0540-Define-GRUB_EFI_SHIM_LOCK_GUID.patch
+Patch0541: 0541-misc-Make-grub_min-and-grub_max-more-resilient.patch
+Patch0542: 0542-ReiserFS-switch-to-using-grub_min-grub_max.patch
+Patch0543: 0543-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch
+Patch0544: 0544-modules-make-.module_license-read-only.patch
+Patch0545: 0545-modules-strip-.llvm_addrsig-sections-and-similar.patch
+Patch0546: 0546-modules-Don-t-allocate-space-for-non-allocable-secti.patch
+Patch0547: 0547-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch
+Patch0548: 0548-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch
+Patch0549: 0549-modules-load-module-sections-at-page-aligned-address.patch
+Patch0550: 0550-nx-add-memory-attribute-get-set-API.patch
+Patch0551: 0551-nx-set-page-permissions-for-loaded-modules.patch
+Patch0552: 0552-nx-set-attrs-in-our-kernel-loaders.patch
+Patch0553: 0553-nx-set-the-nx-compatible-flag-in-EFI-grub-images.patch
+Patch0554: 0554-Fixup-grub_efi_get_variable-type-in-our-loaders.patch
+Patch0555: 0555-Make-debug-file-show-which-file-filters-get-run.patch
+Patch0556: 0556-efi-use-enumerated-array-positions-for-our-allocatio.patch
+Patch0557: 0557-efi-split-allocation-policy-for-kernel-vs-initrd-mem.patch
+Patch0558: 0558-efi-use-EFI_LOADER_-CODE-DATA-for-kernel-and-initrd-.patch
+Patch0559: 0559-ieee1275-implement-vec5-for-cas-negotiation.patch
diff --git a/SOURCES/redhatsecureboot303.cer b/SOURCES/redhatsecureboot303.cer
deleted file mode 100644
index 2c0087d..0000000
Binary files a/SOURCES/redhatsecureboot303.cer and /dev/null differ
diff --git a/SOURCES/redhatsecureboot701.cer b/SOURCES/redhatsecureboot701.cer
new file mode 100644
index 0000000..25e3743
Binary files /dev/null and b/SOURCES/redhatsecureboot701.cer differ
diff --git a/SPECS/grub2.spec b/SPECS/grub2.spec
index f140679..a5c909f 100644
--- a/SPECS/grub2.spec
+++ b/SPECS/grub2.spec
@@ -7,7 +7,7 @@
 Name:		grub2
 Epoch:		1
 Version:	2.02
-Release:	123%{?dist}.8
+Release:	142%{?dist}
 Summary:	Bootloader with support for Linux, Multiboot and more
 Group:		System Environment/Base
 License:	GPLv3+
@@ -28,8 +28,8 @@ Source13:	redhatsecurebootca3.cer
 Source14:	redhatsecureboot301.cer
 Source15:	redhatsecurebootca5.cer
 Source16:	redhatsecureboot502.cer
-Source17:	redhatsecureboot303.cer
-Source18:	redhatsecureboot601.cer
+Source17:	redhatsecureboot601.cer
+Source18:	redhatsecureboot701.cer
 Source19:	sbat.csv.in
 
 %include %{SOURCE1}
@@ -46,7 +46,7 @@ Source19:	sbat.csv.in
 %ifarch ppc64le
 %define old_sb_cer	%{SOURCE17}
 %define sb_cer		%{SOURCE18}
-%define sb_key		redhatsecureboot602
+%define sb_key		redhatsecureboot702
 %endif
 
 # generate with do-rebase
@@ -510,26 +510,58 @@ fi
 %endif
 
 %changelog
-* Thu Jun 16 2022 CentOS Sources <bugs@centos.org> - 2.02-123.el8.centos.8
-- Apply debranding changes
+* Thu Sep 08 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-142
+- Drop the arena size changes
+- Resolves: #2118896
 
-* Fri Jun 03 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-123.el8_6.8
+* Thu Aug 25 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-141
+- Implement vec5 for cas negotiation
+- Resolves: #2117914
+
+* Wed Aug 24 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-140
+- Or two, because I forgot the debug patch
+- Resolves: #2118896
+
+* Thu Aug 18 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-139
+- Kernel allocator fixups (in one pass)
+- Resolves: #2118896
+
+* Wed Jul 20 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-138
+- Rotate signing keys on ppc64le
+- Resolves: #2074762
+
+* Fri Jun 03 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-137
 - CVE fixes for 2022-06-07
 - CVE-2022-28736 CVE-2022-28735 CVE-2022-28734 CVE-2022-28733
 - CVE-2021-3697 CVE-2021-3696 CVE-2021-3695
-- Resolves: #2031899
+- Resolves: #2070687
+
+* Mon May 16 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-129
+- ppc64le: Slow boot after LPM
+- Resolves: #2070347
+
+* Wed May 04 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-127
+- ppc64le: CAS improvements, prefix detection, and vTPM support
+- Resolves: #2076795
+- Resolves: #2026568
+- Resolves: #2051331
+
+* Wed May 04 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-126
+- Fix rpm verification error on grub.cfg permissions
+- Resolves: #2071643
+
+* Wed Apr 20 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-125
+- RHEL 8.6.0 import; no code changes
+- Resolves: #2062892
 
 * Mon Mar 28 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-123
 - Bump for signing
-- Resolves: #2061252
 
 * Wed Mar 09 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-122
 - Fix initialization on efidisk patch
-- Resolves: #2061252
 
 * Tue Mar 08 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-121
 - Backport support for loading initrd above 4GB
-- Resolves: #2048433
 
 * Mon Feb 28 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-120
 - Bump signing