grub2/grub-efi: fix CVE-2022-28736

We add patches to fix CVEs for grub instead of upgrading because
grub2/grub-efi is ported from yocto for secure boot bringing up.

The patches for CVE-2022-28736 have conflicts with the patches for
secure boot. So refer to below link to fix this CVE:
(1) https://patchwork.yoctoproject.org/project/oe-core/patch/
20221207034254.58292-1-xiangyu.chen@eng.windriver.com/
(2)https://github.com/jiazhang0/meta-secure-core/pull/257

The special patches for grub-efi are from layers meta-lat and
meta-secure-core of yocto upstream, which are based on the patches
for grub-efi in oe-core layer (including CVE patches). We used to mix
all the patches together. Now we will move the patches from meta-lat
and meta-secure-core to the end of sequence for applying patches,
so that we can keep align with yocto upstream and make it easier
to maintain the grub here.
Since there are many patches involved here, we don't change the number
in patches' name in case confusion is caused if we rename many files.

Below commits are added for the CVE:
<loader/efi/chainloader: Simplify the loader state>
<commands/boot: Add API to pass context to loader>
<loader/efi/chainloader: Use grub_loader_set_ex()>

Below patches for secure boot are adapted for conflicts with above:
secure-core/0009 <efi: chainloader: port shim to grub>
secure-core/0010 <efi: chainloader: use shim to load and verify an image>
secure-core/0012 <efi: chainloader: take care of unload undershim>

All of them are aligned with upstream and no changes here.

Test plan:
 - PASS: build grub2/grub-efi.
 - PASS: build-image and install and boot up on lab/qemu.
 - PASS: check that the "stx.N" version number is right for both
         bios(grub2 ver) and uefi(grub-efi ver) boot.
 - PASS: the tests are done on lab with secure boot disabled and
         enabled.

Closes-Bug: #2034119

Signed-off-by: Li Zhou <li.zhou@windriver.com>
Change-Id: I9a37cd8b804b238407f8ac6528f087a2eb0cf2de
This commit is contained in:
Li Zhou 2023-09-05 14:55:38 +08:00
parent 44f318a38d
commit 8e6824ec91
26 changed files with 848 additions and 78 deletions

View File

@ -1,43 +0,0 @@
From 416eaf86565248e11bfb4ef56b6d5a5e21a4541f Mon Sep 17 00:00:00 2001
From: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Date: Fri, 27 Mar 2015 08:31:27 -0700
Subject: [PATCH] efi: chainloader: take care of unload undershim
Upstream-Status: Inappropriate [embedded specific]
Under shim, we use a custom buffer to put the relocated image, make
sure we free that memory when unloading.
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
---
grub-core/loader/efi/chainloader.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index adaf3c9..285271d 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -590,8 +590,18 @@ 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);
- efi_call_2 (b->free_pages, address, pages);
+ if (!shim_used)
+ {
+ efi_call_1 (b->unload_image, image_handle);
+ efi_call_2 (b->free_pages, address, pages);
+ }
+ else
+ {
+ if (shim_buffer)
+ {
+ efi_call_2 (b->free_pages, shim_buffer, shim_pages);
+ }
+ }
grub_free (file_path);
grub_free (cmdline);
--
2.17.1

View File

@ -0,0 +1,129 @@
From 1469983ebb9674753ad333d37087fb8cb20e1dce Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Tue, 5 Apr 2022 10:02:04 +0100
Subject: [PATCH] loader/efi/chainloader: Simplify the loader state
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.
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-Status: Backport
Reference to upstream patch:
https://git.savannah.gnu.org/cgit/grub.git/commit/?id=1469983ebb9674753ad333d37087fb8cb20e1dce
Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
---
grub-core/loader/efi/chainloader.c | 38 +++++++++++++++++-------------
1 file changed, 21 insertions(+), 17 deletions(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 2bd80f4db..d1602c89b 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -44,25 +44,20 @@ 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_efi_device_path_t *file_path;
static grub_efi_handle_t image_handle;
-static grub_efi_char16_t *cmdline;
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);
- efi_call_2 (b->free_pages, address, pages);
-
- grub_free (file_path);
- grub_free (cmdline);
- cmdline = 0;
- file_path = 0;
grub_dl_unref (my_mod);
return GRUB_ERR_NONE;
@@ -140,7 +135,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)
@@ -222,11 +217,14 @@ 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 = NULL, *file_path = NULL;
grub_efi_loaded_image_t *loaded_image;
char *filename;
void *boot_image = 0;
grub_efi_handle_t dev_handle = 0;
+ grub_efi_physical_address_t address = 0;
+ grub_efi_uintn_t pages = 0;
+ grub_efi_char16_t *cmdline = NULL;
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@@ -234,11 +232,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;
-
b = grub_efi_system_table->boot_services;
file = grub_file_open (filename, GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE);
@@ -408,6 +401,10 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
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;
@@ -419,11 +416,18 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
if (file)
grub_file_close (file);
+ grub_free (cmdline);
grub_free (file_path);
if (address)
efi_call_2 (b->free_pages, address, pages);
+ if (image_handle != NULL)
+ {
+ efi_call_1 (b->unload_image, image_handle);
+ image_handle = NULL;
+ }
+
grub_dl_unref (my_mod);
return grub_errno;
--
2.34.1

View File

@ -0,0 +1,168 @@
From 14ceb3b3ff6db664649138442b6562c114dcf56e Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Tue, 5 Apr 2022 10:58:28 +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>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-Status: Backport
Reference to upstream patch:
https://git.savannah.gnu.org/cgit/grub.git/commit/?id=14ceb3b3ff6db664649138442b6562c114dcf56e
Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
---
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 bbca81e94..61514788e 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 *context);
+static grub_err_t (*grub_loader_unload_func) (void *context);
+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 *context),
+ grub_err_t (*unload) (void *context),
+ 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 b20864282..97f231054 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 *context),
+ grub_err_t (*unload) (void *context),
+ void *context,
+ int flags);
+
/* Unset current loader, if any. */
void EXPORT_FUNC (grub_loader_unset) (void);
--
2.34.1

View File

@ -0,0 +1,86 @@
From 04c86e0bb7b58fc2f913f798cdb18934933e532d Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Tue, 5 Apr 2022 11:48:58 +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.
Fixes: CVE-2022-28736
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-Status: Backport
CVE: CVE-2022-28736
Reference to upstream patch:
https://git.savannah.gnu.org/cgit/grub.git/commit/?id=04c86e0bb7b58fc2f913f798cdb18934933e532d
Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
---
grub-core/loader/efi/chainloader.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index d1602c89b..7557eb269 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -44,11 +44,10 @@ GRUB_MOD_LICENSE ("GPLv3+");
static grub_dl_t my_mod;
-static grub_efi_handle_t image_handle;
-
static grub_err_t
-grub_chainloader_unload (void)
+grub_chainloader_unload (void *context)
{
+ grub_efi_handle_t image_handle = (grub_efi_handle_t) context;
grub_efi_loaded_image_t *loaded_image;
grub_efi_boot_services_t *b;
@@ -64,8 +63,9 @@ grub_chainloader_unload (void)
}
static grub_err_t
-grub_chainloader_boot (void)
+grub_chainloader_boot (void *context)
{
+ grub_efi_handle_t image_handle = (grub_efi_handle_t) context;
grub_efi_boot_services_t *b;
grub_efi_status_t status;
grub_efi_uintn_t exit_data_size;
@@ -225,6 +225,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
grub_efi_physical_address_t address = 0;
grub_efi_uintn_t pages = 0;
grub_efi_char16_t *cmdline = NULL;
+ grub_efi_handle_t image_handle = NULL;
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@@ -405,7 +406,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;
fail:
@@ -423,10 +424,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
efi_call_2 (b->free_pages, address, pages);
if (image_handle != NULL)
- {
- efi_call_1 (b->unload_image, image_handle);
- image_handle = NULL;
- }
+ efi_call_1 (b->unload_image, image_handle);
grub_dl_unref (my_mod);
--
2.34.1

View File

@ -1,7 +1,7 @@
From cb88b18b2648c89bccedb7bda25e398618110cbc Mon Sep 17 00:00:00 2001
From 061a1200d52bdfc6160cfad5fbe1cef125f8d3a2 Mon Sep 17 00:00:00 2001
From: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Date: Fri, 27 Mar 2015 08:19:21 -0700
Subject: [PATCH] efi: chainloader: port shim to grub
Subject: [PATCH 4/7] efi: chainloader: port shim to grub
Upstream-Status: Inappropriate [embedded specific]
@ -26,7 +26,7 @@ Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
1 file changed, 534 insertions(+)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 2bd80f4..d192e2d 100644
index 7557eb2..74c84a7 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -32,6 +32,7 @@
@ -37,10 +37,10 @@ index 2bd80f4..d192e2d 100644
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/net.h>
@@ -49,6 +50,539 @@ static grub_efi_uintn_t pages;
static grub_efi_device_path_t *file_path;
static grub_efi_handle_t image_handle;
static grub_efi_char16_t *cmdline;
@@ -43,6 +44,539 @@
GRUB_MOD_LICENSE ("GPLv3+");
static grub_dl_t my_mod;
+static grub_int32_t shim_used;
+static grub_efi_physical_address_t shim_buffer;
+static grub_efi_uintn_t shim_pages;
@ -576,7 +576,7 @@ index 2bd80f4..d192e2d 100644
+}
static grub_err_t
grub_chainloader_unload (void)
grub_chainloader_unload (void *context)
--
2.17.1
2.25.1

View File

@ -1,7 +1,7 @@
From 5d5f5231b008fa5e6299a76f9ae92a6da035c4f0 Mon Sep 17 00:00:00 2001
From a99c7ea281b02f14abd0911886cabbea9fc81649 Mon Sep 17 00:00:00 2001
From: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Date: Fri, 27 Mar 2015 08:26:08 -0700
Subject: [PATCH] efi: chainloader: use shim to load and verify an image
Subject: [PATCH 5/7] efi: chainloader: use shim to load and verify an image
Upstream-Status: Inappropriate [embedded specific]
@ -19,18 +19,18 @@ Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
1 file changed, 40 insertions(+), 9 deletions(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index d192e2d..121af25 100644
index 74c84a7..667b4c3 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -761,6 +761,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
char *filename;
void *boot_image = 0;
grub_efi_handle_t dev_handle = 0;
@@ -760,6 +760,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
grub_efi_uintn_t pages = 0;
grub_efi_char16_t *cmdline = NULL;
grub_efi_handle_t image_handle = NULL;
+ struct grub_shim_pe_coff_loader_image_context context;
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@@ -892,23 +893,53 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
@@ -886,23 +887,53 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
if (status != GRUB_EFI_SUCCESS)
{
if (status == GRUB_EFI_OUT_OF_RESOURCES)
@ -94,5 +94,5 @@ index d192e2d..121af25 100644
if (argc > 1)
{
--
2.17.1
2.25.1

View File

@ -0,0 +1,41 @@
From c2b23e972b657cdb5e0794c93d342f167fffb3e3 Mon Sep 17 00:00:00 2001
From: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Date: Fri, 27 Mar 2015 08:31:27 -0700
Subject: [PATCH 7/7] efi: chainloader: take care of unload undershim
Upstream-Status: Inappropriate [embedded specific]
Under shim, we use a custom buffer to put the relocated image, make
sure we free that memory when unloading.
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
---
grub-core/loader/efi/chainloader.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index baa85be..7b733a7 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -590,7 +590,17 @@ grub_chainloader_unload (void *context)
grub_free (loaded_image->load_options);
b = grub_efi_system_table->boot_services;
- efi_call_1 (b->unload_image, image_handle);
+ if (!shim_used)
+ {
+ efi_call_1 (b->unload_image, image_handle);
+ }
+ else
+ {
+ if (shim_buffer)
+ {
+ efi_call_2 (b->free_pages, shim_buffer, shim_pages);
+ }
+ }
grub_dl_unref (my_mod);
return GRUB_ERR_NONE;
--
2.25.1

View File

@ -1,22 +1,5 @@
0001-grub2-add-tboot.patch
0002-grub2-checking-if-loop-devices-are-available.patch
0003-Make-UEFI-watchdog-behaviour-configurable.patch
0004-correct-grub_errno.patch
0005-grub-verify-Add-skip_check_cfg-variable.patch
0006-pe32.h-add-header-structures-for-TE-and-DOS-executab.patch
0007-shim-add-needed-data-structures.patch
0008-efi-chainloader-implement-an-UEFI-Exit-service.patch
0009-efi-chainloader-port-shim-to-grub.patch
0010-efi-chainloader-use-shim-to-load-and-verify-an-image.patch
0011-efi-chainloader-boot-the-image-using-shim.patch
0012-efi-chainloader-take-care-of-unload-undershim.patch
0013-chainloader-handle-the-unauthenticated-image-by-shim.patch
0014-chainloader-Don-t-check-empty-section-in-file-like-..patch
0015-chainloader-find-the-relocations-correctly.patch
0016-Add-a-module-for-reading-EFI-global-variables.patch
0017-grub-shim-verify-Report-that-the-loaded-object-is-ve.patch
0018-grub-verify-Add-strict_security-variable.patch
0019-Disable-inside-lockdown-and-shim_lock-verifiers.patch
0020-kern-efi-sb-Reject-non-kernel-files-in-the-shim_lock.patch
0021-video-readers-Add-artificial-limit-to-image-dimensio.patch
0022-font-Reject-glyphs-exceeds-font-max_glyph_width-or-f.patch
@ -38,3 +21,23 @@
0038-net-ip-Do-IP-fragment-maths-safely.patch
0039-net-http-Fix-OOB-write-for-split-http-headers.patch
0040-net-http-Error-out-on-headers-with-LF-without-CR.patch
0041-loader-efi-chainloader-Simplify-the-loader-state.patch
0042-commands-boot-Add-API-to-pass-context-to-loader.patch
0043-loader-efi-chainloader-Use-grub_loader_set_ex.patch
lat/0003-Make-UEFI-watchdog-behaviour-configurable.patch
lat/0004-correct-grub_errno.patch
lat/0005-grub-verify-Add-skip_check_cfg-variable.patch
secure-core/0006-pe32.h-add-header-structures-for-TE-and-DOS-executab.patch
secure-core/0007-shim-add-needed-data-structures.patch
secure-core/0008-efi-chainloader-implement-an-UEFI-Exit-service.patch
secure-core/0009-efi-chainloader-port-shim-to-grub.patch
secure-core/0010-efi-chainloader-use-shim-to-load-and-verify-an-image.patch
secure-core/0011-efi-chainloader-boot-the-image-using-shim.patch
secure-core/0012-efi-chainloader-take-care-of-unload-undershim.patch
secure-core/0013-chainloader-handle-the-unauthenticated-image-by-shim.patch
secure-core/0014-chainloader-Don-t-check-empty-section-in-file-like-..patch
secure-core/0015-chainloader-find-the-relocations-correctly.patch
secure-core/0016-Add-a-module-for-reading-EFI-global-variables.patch
secure-core/0017-grub-shim-verify-Report-that-the-loaded-object-is-ve.patch
secure-core/0018-grub-verify-Add-strict_security-variable.patch
secure-core/0019-Disable-inside-lockdown-and-shim_lock-verifiers.patch

View File

@ -0,0 +1,129 @@
From 1469983ebb9674753ad333d37087fb8cb20e1dce Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Tue, 5 Apr 2022 10:02:04 +0100
Subject: [PATCH] loader/efi/chainloader: Simplify the loader state
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.
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-Status: Backport
Reference to upstream patch:
https://git.savannah.gnu.org/cgit/grub.git/commit/?id=1469983ebb9674753ad333d37087fb8cb20e1dce
Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
---
grub-core/loader/efi/chainloader.c | 38 +++++++++++++++++-------------
1 file changed, 21 insertions(+), 17 deletions(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 2bd80f4db..d1602c89b 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -44,25 +44,20 @@ 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_efi_device_path_t *file_path;
static grub_efi_handle_t image_handle;
-static grub_efi_char16_t *cmdline;
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);
- efi_call_2 (b->free_pages, address, pages);
-
- grub_free (file_path);
- grub_free (cmdline);
- cmdline = 0;
- file_path = 0;
grub_dl_unref (my_mod);
return GRUB_ERR_NONE;
@@ -140,7 +135,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)
@@ -222,11 +217,14 @@ 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 = NULL, *file_path = NULL;
grub_efi_loaded_image_t *loaded_image;
char *filename;
void *boot_image = 0;
grub_efi_handle_t dev_handle = 0;
+ grub_efi_physical_address_t address = 0;
+ grub_efi_uintn_t pages = 0;
+ grub_efi_char16_t *cmdline = NULL;
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@@ -234,11 +232,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;
-
b = grub_efi_system_table->boot_services;
file = grub_file_open (filename, GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE);
@@ -408,6 +401,10 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
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;
@@ -419,11 +416,18 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
if (file)
grub_file_close (file);
+ grub_free (cmdline);
grub_free (file_path);
if (address)
efi_call_2 (b->free_pages, address, pages);
+ if (image_handle != NULL)
+ {
+ efi_call_1 (b->unload_image, image_handle);
+ image_handle = NULL;
+ }
+
grub_dl_unref (my_mod);
return grub_errno;
--
2.34.1

View File

@ -0,0 +1,168 @@
From 14ceb3b3ff6db664649138442b6562c114dcf56e Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Tue, 5 Apr 2022 10:58:28 +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>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-Status: Backport
Reference to upstream patch:
https://git.savannah.gnu.org/cgit/grub.git/commit/?id=14ceb3b3ff6db664649138442b6562c114dcf56e
Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
---
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 bbca81e94..61514788e 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 *context);
+static grub_err_t (*grub_loader_unload_func) (void *context);
+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 *context),
+ grub_err_t (*unload) (void *context),
+ 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 b20864282..97f231054 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 *context),
+ grub_err_t (*unload) (void *context),
+ void *context,
+ int flags);
+
/* Unset current loader, if any. */
void EXPORT_FUNC (grub_loader_unset) (void);
--
2.34.1

View File

@ -0,0 +1,86 @@
From 04c86e0bb7b58fc2f913f798cdb18934933e532d Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Tue, 5 Apr 2022 11:48:58 +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.
Fixes: CVE-2022-28736
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-Status: Backport
CVE: CVE-2022-28736
Reference to upstream patch:
https://git.savannah.gnu.org/cgit/grub.git/commit/?id=04c86e0bb7b58fc2f913f798cdb18934933e532d
Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
---
grub-core/loader/efi/chainloader.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index d1602c89b..7557eb269 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -44,11 +44,10 @@ GRUB_MOD_LICENSE ("GPLv3+");
static grub_dl_t my_mod;
-static grub_efi_handle_t image_handle;
-
static grub_err_t
-grub_chainloader_unload (void)
+grub_chainloader_unload (void *context)
{
+ grub_efi_handle_t image_handle = (grub_efi_handle_t) context;
grub_efi_loaded_image_t *loaded_image;
grub_efi_boot_services_t *b;
@@ -64,8 +63,9 @@ grub_chainloader_unload (void)
}
static grub_err_t
-grub_chainloader_boot (void)
+grub_chainloader_boot (void *context)
{
+ grub_efi_handle_t image_handle = (grub_efi_handle_t) context;
grub_efi_boot_services_t *b;
grub_efi_status_t status;
grub_efi_uintn_t exit_data_size;
@@ -225,6 +225,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
grub_efi_physical_address_t address = 0;
grub_efi_uintn_t pages = 0;
grub_efi_char16_t *cmdline = NULL;
+ grub_efi_handle_t image_handle = NULL;
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@@ -405,7 +406,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;
fail:
@@ -423,10 +424,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
efi_call_2 (b->free_pages, address, pages);
if (image_handle != NULL)
- {
- efi_call_1 (b->unload_image, image_handle);
- image_handle = NULL;
- }
+ efi_call_1 (b->unload_image, image_handle);
grub_dl_unref (my_mod);
--
2.34.1

View File

@ -21,3 +21,6 @@
0021-net-ip-Do-IP-fragment-maths-safely.patch
0022-net-http-Fix-OOB-write-for-split-http-headers.patch
0023-net-http-Error-out-on-headers-with-LF-without-CR.patch
0024-loader-efi-chainloader-Simplify-the-loader-state.patch
0025-commands-boot-Add-API-to-pass-context-to-loader.patch
0026-loader-efi-chainloader-Use-grub_loader_set_ex.patch