8e6824ec91
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
169 lines
4.8 KiB
Diff
169 lines
4.8 KiB
Diff
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
|
|
|