From 8e6824ec91dec186f9c4a761dc7c191a4e8191ef Mon Sep 17 00:00:00 2001 From: Li Zhou Date: Tue, 5 Sep 2023 14:55:38 +0800 Subject: [PATCH] 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: Below patches for secure boot are adapted for conflicts with above: secure-core/0009 secure-core/0010 secure-core/0012 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 Change-Id: I9a37cd8b804b238407f8ac6528f087a2eb0cf2de --- ...loader-take-care-of-unload-undershim.patch | 43 ----- ...hainloader-Simplify-the-loader-state.patch | 129 ++++++++++++++ ...ot-Add-API-to-pass-context-to-loader.patch | 168 ++++++++++++++++++ ...i-chainloader-Use-grub_loader_set_ex.patch | 86 +++++++++ ...UEFI-watchdog-behaviour-configurable.patch | 0 .../{ => lat}/0004-correct-grub_errno.patch | 0 ...b-verify-Add-skip_check_cfg-variable.patch | 0 ...r-structures-for-TE-and-DOS-executab.patch | 0 ...0007-shim-add-needed-data-structures.patch | 0 ...oader-implement-an-UEFI-Exit-service.patch | 0 ...09-efi-chainloader-port-shim-to-grub.patch | 18 +- ...use-shim-to-load-and-verify-an-image.patch | 18 +- ...hainloader-boot-the-image-using-shim.patch | 0 ...loader-take-care-of-unload-undershim.patch | 41 +++++ ...le-the-unauthenticated-image-by-shim.patch | 0 ...t-check-empty-section-in-file-like-..patch | 0 ...oader-find-the-relocations-correctly.patch | 0 ...ule-for-reading-EFI-global-variables.patch | 0 ...-Report-that-the-loaded-object-is-ve.patch | 0 ...-verify-Add-strict_security-variable.patch | 0 ...ide-lockdown-and-shim_lock-verifiers.patch | 0 grub/grub-efi/debian/patches/series | 37 ++-- ...hainloader-Simplify-the-loader-state.patch | 129 ++++++++++++++ ...ot-Add-API-to-pass-context-to-loader.patch | 168 ++++++++++++++++++ ...i-chainloader-Use-grub_loader_set_ex.patch | 86 +++++++++ grub/grub2/debian/patches/series | 3 + 26 files changed, 848 insertions(+), 78 deletions(-) delete mode 100644 grub/grub-efi/debian/patches/0012-efi-chainloader-take-care-of-unload-undershim.patch create mode 100644 grub/grub-efi/debian/patches/0041-loader-efi-chainloader-Simplify-the-loader-state.patch create mode 100644 grub/grub-efi/debian/patches/0042-commands-boot-Add-API-to-pass-context-to-loader.patch create mode 100644 grub/grub-efi/debian/patches/0043-loader-efi-chainloader-Use-grub_loader_set_ex.patch rename grub/grub-efi/debian/patches/{ => lat}/0003-Make-UEFI-watchdog-behaviour-configurable.patch (100%) rename grub/grub-efi/debian/patches/{ => lat}/0004-correct-grub_errno.patch (100%) rename grub/grub-efi/debian/patches/{ => lat}/0005-grub-verify-Add-skip_check_cfg-variable.patch (100%) rename grub/grub-efi/debian/patches/{ => secure-core}/0006-pe32.h-add-header-structures-for-TE-and-DOS-executab.patch (100%) rename grub/grub-efi/debian/patches/{ => secure-core}/0007-shim-add-needed-data-structures.patch (100%) rename grub/grub-efi/debian/patches/{ => secure-core}/0008-efi-chainloader-implement-an-UEFI-Exit-service.patch (100%) rename grub/grub-efi/debian/patches/{ => secure-core}/0009-efi-chainloader-port-shim-to-grub.patch (98%) rename grub/grub-efi/debian/patches/{ => secure-core}/0010-efi-chainloader-use-shim-to-load-and-verify-an-image.patch (88%) rename grub/grub-efi/debian/patches/{ => secure-core}/0011-efi-chainloader-boot-the-image-using-shim.patch (100%) create mode 100644 grub/grub-efi/debian/patches/secure-core/0012-efi-chainloader-take-care-of-unload-undershim.patch rename grub/grub-efi/debian/patches/{ => secure-core}/0013-chainloader-handle-the-unauthenticated-image-by-shim.patch (100%) rename grub/grub-efi/debian/patches/{ => secure-core}/0014-chainloader-Don-t-check-empty-section-in-file-like-..patch (100%) rename grub/grub-efi/debian/patches/{ => secure-core}/0015-chainloader-find-the-relocations-correctly.patch (100%) rename grub/grub-efi/debian/patches/{ => secure-core}/0016-Add-a-module-for-reading-EFI-global-variables.patch (100%) rename grub/grub-efi/debian/patches/{ => secure-core}/0017-grub-shim-verify-Report-that-the-loaded-object-is-ve.patch (100%) rename grub/grub-efi/debian/patches/{ => secure-core}/0018-grub-verify-Add-strict_security-variable.patch (100%) rename grub/grub-efi/debian/patches/{ => secure-core}/0019-Disable-inside-lockdown-and-shim_lock-verifiers.patch (100%) create mode 100644 grub/grub2/debian/patches/0024-loader-efi-chainloader-Simplify-the-loader-state.patch create mode 100644 grub/grub2/debian/patches/0025-commands-boot-Add-API-to-pass-context-to-loader.patch create mode 100644 grub/grub2/debian/patches/0026-loader-efi-chainloader-Use-grub_loader_set_ex.patch diff --git a/grub/grub-efi/debian/patches/0012-efi-chainloader-take-care-of-unload-undershim.patch b/grub/grub-efi/debian/patches/0012-efi-chainloader-take-care-of-unload-undershim.patch deleted file mode 100644 index 6eec11a64..000000000 --- a/grub/grub-efi/debian/patches/0012-efi-chainloader-take-care-of-unload-undershim.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 416eaf86565248e11bfb4ef56b6d5a5e21a4541f Mon Sep 17 00:00:00 2001 -From: Ricardo Neri -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 ---- - 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 - diff --git a/grub/grub-efi/debian/patches/0041-loader-efi-chainloader-Simplify-the-loader-state.patch b/grub/grub-efi/debian/patches/0041-loader-efi-chainloader-Simplify-the-loader-state.patch new file mode 100644 index 000000000..a43025d42 --- /dev/null +++ b/grub/grub-efi/debian/patches/0041-loader-efi-chainloader-Simplify-the-loader-state.patch @@ -0,0 +1,129 @@ +From 1469983ebb9674753ad333d37087fb8cb20e1dce Mon Sep 17 00:00:00 2001 +From: Chris Coulson +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 +Reviewed-by: Daniel Kiper + +Upstream-Status: Backport + +Reference to upstream patch: +https://git.savannah.gnu.org/cgit/grub.git/commit/?id=1469983ebb9674753ad333d37087fb8cb20e1dce + +Signed-off-by: Xiangyu Chen +--- + 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 + diff --git a/grub/grub-efi/debian/patches/0042-commands-boot-Add-API-to-pass-context-to-loader.patch b/grub/grub-efi/debian/patches/0042-commands-boot-Add-API-to-pass-context-to-loader.patch new file mode 100644 index 000000000..a2c0530f0 --- /dev/null +++ b/grub/grub-efi/debian/patches/0042-commands-boot-Add-API-to-pass-context-to-loader.patch @@ -0,0 +1,168 @@ +From 14ceb3b3ff6db664649138442b6562c114dcf56e Mon Sep 17 00:00:00 2001 +From: Chris Coulson +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 +Reviewed-by: Daniel Kiper + +Upstream-Status: Backport + +Reference to upstream patch: +https://git.savannah.gnu.org/cgit/grub.git/commit/?id=14ceb3b3ff6db664649138442b6562c114dcf56e + +Signed-off-by: Xiangyu Chen +--- + 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 + diff --git a/grub/grub-efi/debian/patches/0043-loader-efi-chainloader-Use-grub_loader_set_ex.patch b/grub/grub-efi/debian/patches/0043-loader-efi-chainloader-Use-grub_loader_set_ex.patch new file mode 100644 index 000000000..5741e53f4 --- /dev/null +++ b/grub/grub-efi/debian/patches/0043-loader-efi-chainloader-Use-grub_loader_set_ex.patch @@ -0,0 +1,86 @@ +From 04c86e0bb7b58fc2f913f798cdb18934933e532d Mon Sep 17 00:00:00 2001 +From: Chris Coulson +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 +Reviewed-by: Daniel Kiper + +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 +--- + 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 + diff --git a/grub/grub-efi/debian/patches/0003-Make-UEFI-watchdog-behaviour-configurable.patch b/grub/grub-efi/debian/patches/lat/0003-Make-UEFI-watchdog-behaviour-configurable.patch similarity index 100% rename from grub/grub-efi/debian/patches/0003-Make-UEFI-watchdog-behaviour-configurable.patch rename to grub/grub-efi/debian/patches/lat/0003-Make-UEFI-watchdog-behaviour-configurable.patch diff --git a/grub/grub-efi/debian/patches/0004-correct-grub_errno.patch b/grub/grub-efi/debian/patches/lat/0004-correct-grub_errno.patch similarity index 100% rename from grub/grub-efi/debian/patches/0004-correct-grub_errno.patch rename to grub/grub-efi/debian/patches/lat/0004-correct-grub_errno.patch diff --git a/grub/grub-efi/debian/patches/0005-grub-verify-Add-skip_check_cfg-variable.patch b/grub/grub-efi/debian/patches/lat/0005-grub-verify-Add-skip_check_cfg-variable.patch similarity index 100% rename from grub/grub-efi/debian/patches/0005-grub-verify-Add-skip_check_cfg-variable.patch rename to grub/grub-efi/debian/patches/lat/0005-grub-verify-Add-skip_check_cfg-variable.patch diff --git a/grub/grub-efi/debian/patches/0006-pe32.h-add-header-structures-for-TE-and-DOS-executab.patch b/grub/grub-efi/debian/patches/secure-core/0006-pe32.h-add-header-structures-for-TE-and-DOS-executab.patch similarity index 100% rename from grub/grub-efi/debian/patches/0006-pe32.h-add-header-structures-for-TE-and-DOS-executab.patch rename to grub/grub-efi/debian/patches/secure-core/0006-pe32.h-add-header-structures-for-TE-and-DOS-executab.patch diff --git a/grub/grub-efi/debian/patches/0007-shim-add-needed-data-structures.patch b/grub/grub-efi/debian/patches/secure-core/0007-shim-add-needed-data-structures.patch similarity index 100% rename from grub/grub-efi/debian/patches/0007-shim-add-needed-data-structures.patch rename to grub/grub-efi/debian/patches/secure-core/0007-shim-add-needed-data-structures.patch diff --git a/grub/grub-efi/debian/patches/0008-efi-chainloader-implement-an-UEFI-Exit-service.patch b/grub/grub-efi/debian/patches/secure-core/0008-efi-chainloader-implement-an-UEFI-Exit-service.patch similarity index 100% rename from grub/grub-efi/debian/patches/0008-efi-chainloader-implement-an-UEFI-Exit-service.patch rename to grub/grub-efi/debian/patches/secure-core/0008-efi-chainloader-implement-an-UEFI-Exit-service.patch diff --git a/grub/grub-efi/debian/patches/0009-efi-chainloader-port-shim-to-grub.patch b/grub/grub-efi/debian/patches/secure-core/0009-efi-chainloader-port-shim-to-grub.patch similarity index 98% rename from grub/grub-efi/debian/patches/0009-efi-chainloader-port-shim-to-grub.patch rename to grub/grub-efi/debian/patches/secure-core/0009-efi-chainloader-port-shim-to-grub.patch index 23f8f1b5c..21a8fce3d 100644 --- a/grub/grub-efi/debian/patches/0009-efi-chainloader-port-shim-to-grub.patch +++ b/grub/grub-efi/debian/patches/secure-core/0009-efi-chainloader-port-shim-to-grub.patch @@ -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 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 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 #include #include -@@ -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 diff --git a/grub/grub-efi/debian/patches/0010-efi-chainloader-use-shim-to-load-and-verify-an-image.patch b/grub/grub-efi/debian/patches/secure-core/0010-efi-chainloader-use-shim-to-load-and-verify-an-image.patch similarity index 88% rename from grub/grub-efi/debian/patches/0010-efi-chainloader-use-shim-to-load-and-verify-an-image.patch rename to grub/grub-efi/debian/patches/secure-core/0010-efi-chainloader-use-shim-to-load-and-verify-an-image.patch index 560a6d91a..9f3a198c4 100644 --- a/grub/grub-efi/debian/patches/0010-efi-chainloader-use-shim-to-load-and-verify-an-image.patch +++ b/grub/grub-efi/debian/patches/secure-core/0010-efi-chainloader-use-shim-to-load-and-verify-an-image.patch @@ -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 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 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 diff --git a/grub/grub-efi/debian/patches/0011-efi-chainloader-boot-the-image-using-shim.patch b/grub/grub-efi/debian/patches/secure-core/0011-efi-chainloader-boot-the-image-using-shim.patch similarity index 100% rename from grub/grub-efi/debian/patches/0011-efi-chainloader-boot-the-image-using-shim.patch rename to grub/grub-efi/debian/patches/secure-core/0011-efi-chainloader-boot-the-image-using-shim.patch diff --git a/grub/grub-efi/debian/patches/secure-core/0012-efi-chainloader-take-care-of-unload-undershim.patch b/grub/grub-efi/debian/patches/secure-core/0012-efi-chainloader-take-care-of-unload-undershim.patch new file mode 100644 index 000000000..dab87afc4 --- /dev/null +++ b/grub/grub-efi/debian/patches/secure-core/0012-efi-chainloader-take-care-of-unload-undershim.patch @@ -0,0 +1,41 @@ +From c2b23e972b657cdb5e0794c93d342f167fffb3e3 Mon Sep 17 00:00:00 2001 +From: Ricardo Neri +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 +--- + 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 + diff --git a/grub/grub-efi/debian/patches/0013-chainloader-handle-the-unauthenticated-image-by-shim.patch b/grub/grub-efi/debian/patches/secure-core/0013-chainloader-handle-the-unauthenticated-image-by-shim.patch similarity index 100% rename from grub/grub-efi/debian/patches/0013-chainloader-handle-the-unauthenticated-image-by-shim.patch rename to grub/grub-efi/debian/patches/secure-core/0013-chainloader-handle-the-unauthenticated-image-by-shim.patch diff --git a/grub/grub-efi/debian/patches/0014-chainloader-Don-t-check-empty-section-in-file-like-..patch b/grub/grub-efi/debian/patches/secure-core/0014-chainloader-Don-t-check-empty-section-in-file-like-..patch similarity index 100% rename from grub/grub-efi/debian/patches/0014-chainloader-Don-t-check-empty-section-in-file-like-..patch rename to grub/grub-efi/debian/patches/secure-core/0014-chainloader-Don-t-check-empty-section-in-file-like-..patch diff --git a/grub/grub-efi/debian/patches/0015-chainloader-find-the-relocations-correctly.patch b/grub/grub-efi/debian/patches/secure-core/0015-chainloader-find-the-relocations-correctly.patch similarity index 100% rename from grub/grub-efi/debian/patches/0015-chainloader-find-the-relocations-correctly.patch rename to grub/grub-efi/debian/patches/secure-core/0015-chainloader-find-the-relocations-correctly.patch diff --git a/grub/grub-efi/debian/patches/0016-Add-a-module-for-reading-EFI-global-variables.patch b/grub/grub-efi/debian/patches/secure-core/0016-Add-a-module-for-reading-EFI-global-variables.patch similarity index 100% rename from grub/grub-efi/debian/patches/0016-Add-a-module-for-reading-EFI-global-variables.patch rename to grub/grub-efi/debian/patches/secure-core/0016-Add-a-module-for-reading-EFI-global-variables.patch diff --git a/grub/grub-efi/debian/patches/0017-grub-shim-verify-Report-that-the-loaded-object-is-ve.patch b/grub/grub-efi/debian/patches/secure-core/0017-grub-shim-verify-Report-that-the-loaded-object-is-ve.patch similarity index 100% rename from grub/grub-efi/debian/patches/0017-grub-shim-verify-Report-that-the-loaded-object-is-ve.patch rename to grub/grub-efi/debian/patches/secure-core/0017-grub-shim-verify-Report-that-the-loaded-object-is-ve.patch diff --git a/grub/grub-efi/debian/patches/0018-grub-verify-Add-strict_security-variable.patch b/grub/grub-efi/debian/patches/secure-core/0018-grub-verify-Add-strict_security-variable.patch similarity index 100% rename from grub/grub-efi/debian/patches/0018-grub-verify-Add-strict_security-variable.patch rename to grub/grub-efi/debian/patches/secure-core/0018-grub-verify-Add-strict_security-variable.patch diff --git a/grub/grub-efi/debian/patches/0019-Disable-inside-lockdown-and-shim_lock-verifiers.patch b/grub/grub-efi/debian/patches/secure-core/0019-Disable-inside-lockdown-and-shim_lock-verifiers.patch similarity index 100% rename from grub/grub-efi/debian/patches/0019-Disable-inside-lockdown-and-shim_lock-verifiers.patch rename to grub/grub-efi/debian/patches/secure-core/0019-Disable-inside-lockdown-and-shim_lock-verifiers.patch diff --git a/grub/grub-efi/debian/patches/series b/grub/grub-efi/debian/patches/series index 9b41090ec..a08485380 100644 --- a/grub/grub-efi/debian/patches/series +++ b/grub/grub-efi/debian/patches/series @@ -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 diff --git a/grub/grub2/debian/patches/0024-loader-efi-chainloader-Simplify-the-loader-state.patch b/grub/grub2/debian/patches/0024-loader-efi-chainloader-Simplify-the-loader-state.patch new file mode 100644 index 000000000..a43025d42 --- /dev/null +++ b/grub/grub2/debian/patches/0024-loader-efi-chainloader-Simplify-the-loader-state.patch @@ -0,0 +1,129 @@ +From 1469983ebb9674753ad333d37087fb8cb20e1dce Mon Sep 17 00:00:00 2001 +From: Chris Coulson +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 +Reviewed-by: Daniel Kiper + +Upstream-Status: Backport + +Reference to upstream patch: +https://git.savannah.gnu.org/cgit/grub.git/commit/?id=1469983ebb9674753ad333d37087fb8cb20e1dce + +Signed-off-by: Xiangyu Chen +--- + 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 + diff --git a/grub/grub2/debian/patches/0025-commands-boot-Add-API-to-pass-context-to-loader.patch b/grub/grub2/debian/patches/0025-commands-boot-Add-API-to-pass-context-to-loader.patch new file mode 100644 index 000000000..a2c0530f0 --- /dev/null +++ b/grub/grub2/debian/patches/0025-commands-boot-Add-API-to-pass-context-to-loader.patch @@ -0,0 +1,168 @@ +From 14ceb3b3ff6db664649138442b6562c114dcf56e Mon Sep 17 00:00:00 2001 +From: Chris Coulson +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 +Reviewed-by: Daniel Kiper + +Upstream-Status: Backport + +Reference to upstream patch: +https://git.savannah.gnu.org/cgit/grub.git/commit/?id=14ceb3b3ff6db664649138442b6562c114dcf56e + +Signed-off-by: Xiangyu Chen +--- + 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 + diff --git a/grub/grub2/debian/patches/0026-loader-efi-chainloader-Use-grub_loader_set_ex.patch b/grub/grub2/debian/patches/0026-loader-efi-chainloader-Use-grub_loader_set_ex.patch new file mode 100644 index 000000000..5741e53f4 --- /dev/null +++ b/grub/grub2/debian/patches/0026-loader-efi-chainloader-Use-grub_loader_set_ex.patch @@ -0,0 +1,86 @@ +From 04c86e0bb7b58fc2f913f798cdb18934933e532d Mon Sep 17 00:00:00 2001 +From: Chris Coulson +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 +Reviewed-by: Daniel Kiper + +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 +--- + 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 + diff --git a/grub/grub2/debian/patches/series b/grub/grub2/debian/patches/series index 3c311b847..def434d83 100644 --- a/grub/grub2/debian/patches/series +++ b/grub/grub2/debian/patches/series @@ -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