Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame^] | 1 | From 04c86e0bb7b58fc2f913f798cdb18934933e532d Mon Sep 17 00:00:00 2001 |
| 2 | From: Chris Coulson <chris.coulson@canonical.com> |
| 3 | Date: Tue, 5 Apr 2022 11:48:58 +0100 |
| 4 | Subject: [PATCH] loader/efi/chainloader: Use grub_loader_set_ex() |
| 5 | |
| 6 | This ports the EFI chainloader to use grub_loader_set_ex() in order to fix |
| 7 | a use-after-free bug that occurs when grub_cmd_chainloader() is executed |
| 8 | more than once before a boot attempt is performed. |
| 9 | |
| 10 | Fixes: CVE-2022-28736 |
| 11 | |
| 12 | Signed-off-by: Chris Coulson <chris.coulson@canonical.com> |
| 13 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> |
| 14 | |
| 15 | Upstream-Status: Backport |
| 16 | CVE: CVE-2022-28736 |
| 17 | |
| 18 | Reference to upstream patch: |
| 19 | https://git.savannah.gnu.org/cgit/grub.git/commit/?id=04c86e0bb7b58fc2f913f798cdb18934933e532d |
| 20 | |
| 21 | Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com> |
| 22 | --- |
| 23 | grub-core/loader/efi/chainloader.c | 16 +++++++--------- |
| 24 | 1 file changed, 7 insertions(+), 9 deletions(-) |
| 25 | |
| 26 | diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c |
| 27 | index d1602c89b..7557eb269 100644 |
| 28 | --- a/grub-core/loader/efi/chainloader.c |
| 29 | +++ b/grub-core/loader/efi/chainloader.c |
| 30 | @@ -44,11 +44,10 @@ GRUB_MOD_LICENSE ("GPLv3+"); |
| 31 | |
| 32 | static grub_dl_t my_mod; |
| 33 | |
| 34 | -static grub_efi_handle_t image_handle; |
| 35 | - |
| 36 | static grub_err_t |
| 37 | -grub_chainloader_unload (void) |
| 38 | +grub_chainloader_unload (void *context) |
| 39 | { |
| 40 | + grub_efi_handle_t image_handle = (grub_efi_handle_t) context; |
| 41 | grub_efi_loaded_image_t *loaded_image; |
| 42 | grub_efi_boot_services_t *b; |
| 43 | |
| 44 | @@ -64,8 +63,9 @@ grub_chainloader_unload (void) |
| 45 | } |
| 46 | |
| 47 | static grub_err_t |
| 48 | -grub_chainloader_boot (void) |
| 49 | +grub_chainloader_boot (void *context) |
| 50 | { |
| 51 | + grub_efi_handle_t image_handle = (grub_efi_handle_t) context; |
| 52 | grub_efi_boot_services_t *b; |
| 53 | grub_efi_status_t status; |
| 54 | grub_efi_uintn_t exit_data_size; |
| 55 | @@ -225,6 +225,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), |
| 56 | grub_efi_physical_address_t address = 0; |
| 57 | grub_efi_uintn_t pages = 0; |
| 58 | grub_efi_char16_t *cmdline = NULL; |
| 59 | + grub_efi_handle_t image_handle = NULL; |
| 60 | |
| 61 | if (argc == 0) |
| 62 | return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); |
| 63 | @@ -405,7 +406,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), |
| 64 | efi_call_2 (b->free_pages, address, pages); |
| 65 | grub_free (file_path); |
| 66 | |
| 67 | - grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0); |
| 68 | + grub_loader_set_ex (grub_chainloader_boot, grub_chainloader_unload, image_handle, 0); |
| 69 | return 0; |
| 70 | |
| 71 | fail: |
| 72 | @@ -423,10 +424,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), |
| 73 | efi_call_2 (b->free_pages, address, pages); |
| 74 | |
| 75 | if (image_handle != NULL) |
| 76 | - { |
| 77 | - efi_call_1 (b->unload_image, image_handle); |
| 78 | - image_handle = NULL; |
| 79 | - } |
| 80 | + efi_call_1 (b->unload_image, image_handle); |
| 81 | |
| 82 | grub_dl_unref (my_mod); |
| 83 | |
| 84 | -- |
| 85 | 2.34.1 |
| 86 | |