diff --git a/SOURCES/0449-ieee1275-ofdisk-retry-on-open-failure.patch b/SOURCES/0449-ieee1275-ofdisk-retry-on-open-failure.patch index dc4aa2a..cdc08c1 100644 --- a/SOURCES/0449-ieee1275-ofdisk-retry-on-open-failure.patch +++ b/SOURCES/0449-ieee1275-ofdisk-retry-on-open-failure.patch @@ -1,4 +1,4 @@ -From c23e77a9abea3402e29062fdc4dd60d10c9f3c07 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Diego Domingos Date: Mon, 17 May 2021 16:59:04 +0200 Subject: [PATCH] ieee1275/ofdisk: retry on open failure @@ -15,7 +15,7 @@ Signed-off-by: Diego Domingos 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c -index 5fabe365eca..578d2833273 100644 +index 5fabe365ec..578d283327 100644 --- a/grub-core/disk/ieee1275/ofdisk.c +++ b/grub-core/disk/ieee1275/ofdisk.c @@ -220,7 +220,9 @@ dev_iterate (const struct grub_ieee1275_devalias *alias) @@ -79,7 +79,7 @@ index 5fabe365eca..578d2833273 100644 return 0; } diff --git a/include/grub/ieee1275/ofdisk.h b/include/grub/ieee1275/ofdisk.h -index 3f583178748..7446b670213 100644 +index 3f58317874..7446b67021 100644 --- a/include/grub/ieee1275/ofdisk.h +++ b/include/grub/ieee1275/ofdisk.h @@ -25,4 +25,12 @@ extern void grub_ofdisk_fini (void); @@ -95,6 +95,3 @@ index 3f583178748..7446b670213 100644 + grub_dprintf("ofdisk","Opening disk %s failed. Retrying...\n",device); } + #endif /* ! GRUB_INIT_HEADER */ --- -2.31.1 - diff --git a/SOURCES/0450-loader-efi-chainloader-grub_load_and_start_image-doe.patch b/SOURCES/0450-loader-efi-chainloader-grub_load_and_start_image-doe.patch new file mode 100644 index 0000000..ca35bcc --- /dev/null +++ b/SOURCES/0450-loader-efi-chainloader-grub_load_and_start_image-doe.patch @@ -0,0 +1,74 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chris Coulson +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 +(cherry picked from commit b4d70820a65c00561045856b7b8355461a9545f6) +(cherry picked from commit 05b16a6be50b1910609740a66b561276fa490538) +(cherry picked from commit 16486a34f3aa41a94e334e86db1a1e21e9b0a45f) +(cherry picked from commit 0bbd693019567b2c55e8be121378d4875f44369a) +[rharwood: chainloader handle_image casting] +--- + grub-core/loader/efi/chainloader.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c +index 001766bdf6..eeef52acde 100644 +--- a/grub-core/loader/efi/chainloader.c ++++ b/grub-core/loader/efi/chainloader.c +@@ -840,7 +840,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; +@@ -882,13 +882,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 *)address, fsize); ++ ++ rc = handle_image ((void *)(unsigned long)address, fsize); + if (rc == 0) + { +- grub_load_and_start_image((void *)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; + } +@@ -1076,7 +1086,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_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0); + diff --git a/SOURCES/0451-loader-efi-chainloader-simplify-the-loader-state.patch b/SOURCES/0451-loader-efi-chainloader-simplify-the-loader-state.patch new file mode 100644 index 0000000..753a090 --- /dev/null +++ b/SOURCES/0451-loader-efi-chainloader-simplify-the-loader-state.patch @@ -0,0 +1,339 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chris Coulson +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 +(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] +(cherry picked from commit b44b88ae45008611ec0469fb47139f4c0d1ee233) +[rharwood: missing sb support in chainloader] +Signed-off-by: Robbie Harwood +--- + grub-core/loader/efi/chainloader.c | 163 +++++++++++++++++++++++-------------- + 1 file changed, 102 insertions(+), 61 deletions(-) + +diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c +index eeef52acde..8d7072ee1a 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); +- efi_call_2 (b->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) + efi_call_1 (b->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,12 +529,14 @@ 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_boot_services_t *b; + grub_efi_loaded_image_t *li, li_bak; + grub_efi_status_t efi_status; +- char *buffer = NULL; ++ 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; + struct grub_pe32_section_table *section; +@@ -535,6 +546,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); + + b = grub_efi_system_table->boot_services; + +@@ -794,10 +806,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"); +@@ -825,22 +837,22 @@ error_exit: + static grub_err_t + grub_secureboot_chainloader_unload (void) + { +- grub_efi_boot_services_t *b; ++ 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); + +- b = grub_efi_system_table->boot_services; +- efi_call_2 (b->free_pages, address, pages); +- grub_free (file_path); +- grub_free (cmdline); +- cmdline = 0; +- file_path = 0; +- dev_handle = 0; ++ 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; +@@ -849,7 +861,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) +@@ -862,7 +874,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"); +@@ -884,20 +896,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; +@@ -911,10 +928,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")); +@@ -922,12 +945,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) +@@ -1079,15 +1096,33 @@ 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_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); ++ ++ /* 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; +@@ -1109,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/0452-commands-boot-Add-API-to-pass-context-to-loader.patch b/SOURCES/0452-commands-boot-Add-API-to-pass-context-to-loader.patch new file mode 100644 index 0000000..24c6a97 --- /dev/null +++ b/SOURCES/0452-commands-boot-Add-API-to-pass-context-to-loader.patch @@ -0,0 +1,161 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chris Coulson +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 +(cherry picked from commit 4322a64dde7e8fedb58e50b79408667129d45dd3) +(cherry picked from commit 937ad0e2159b6b8cb0d2ce3515da3a8b797c7927) +(cherry picked from commit 873038ae7048f6cae8a3ebb2f97a8d361a080e13) +(cherry picked from commit 32ca6dd0281503696f003ba259bfcdad708f6314) +--- + 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/0453-loader-efi-chainloader-Use-grub_loader_set_ex.patch b/SOURCES/0453-loader-efi-chainloader-Use-grub_loader_set_ex.patch new file mode 100644 index 0000000..2ce96a6 --- /dev/null +++ b/SOURCES/0453-loader-efi-chainloader-Use-grub_loader_set_ex.patch @@ -0,0 +1,150 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chris Coulson +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 +(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 +(cherry picked from commit 058d2bccb637ad618d1a23ecf7c9528b766966f6) +--- + 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 8d7072ee1a..3185a7a1c2 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 (); +@@ -835,15 +837,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; + } +@@ -892,12 +896,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) + { +@@ -938,6 +945,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")); +@@ -1109,8 +1118,8 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), + + grub_file_close (file); + +- 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/0454-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch b/SOURCES/0454-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch new file mode 100644 index 0000000..61f9753 --- /dev/null +++ b/SOURCES/0454-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chris Coulson +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 +(cherry picked from commit 8224f5a71af94bec8697de17e7e579792db9f9e2) +(cherry picked from commit 4744b62e20d07674017213ac54d7442d679f9d1a) +(cherry picked from commit 329633cb060957c3d2aca677ac733f07b213a63f) +(cherry picked from commit c74456404adfb1ed0043c1de0b475e0d84c5c480) +--- + 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 c146bc58e3..bafee49852 100644 +--- a/grub-core/loader/i386/efi/linux.c ++++ b/grub-core/loader/i386/efi/linux.c +@@ -343,9 +343,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + if (file) + grub_file_close (file); + +- if (kernel) +- grub_free (kernel); +- + if (grub_errno != GRUB_ERR_NONE) + { + grub_dl_unref (my_mod); +@@ -365,6 +362,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)params, + BYTES_TO_PAGES(16384)); + ++ grub_free (kernel); ++ + return grub_errno; + } + diff --git a/SOURCES/0455-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch b/SOURCES/0455-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch new file mode 100644 index 0000000..ddcbff1 --- /dev/null +++ b/SOURCES/0455-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit 1499a5068839fa37cb77ecef4b5bdacbd1ed12ea) +(cherry picked from commit 2ec50b289d8b24922433439533113087f111f110) +(cherry picked from commit 17c36ae88d7d6040cabc01cd4a21e71ff4731668) +(cherry picked from commit 9c2f4b2da5ce570d5614a0849bdae9a95ed1f311) +--- + 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 24da12bb99..ec8c0265bc 100644 +--- a/grub-core/kern/file.c ++++ b/grub-core/kern/file.c +@@ -80,6 +80,7 @@ grub_file_open (const char *name) + + device = grub_device_open (device_name); + grub_free (device_name); ++ device_name = NULL; + if (! device) + goto fail; + +@@ -121,6 +122,7 @@ grub_file_open (const char *name) + return file; + + fail: ++ grub_free (device_name); + if (device) + grub_device_close (device); + diff --git a/SOURCES/0456-video-readers-png-Abort-sooner-if-a-read-operation-f.patch b/SOURCES/0456-video-readers-png-Abort-sooner-if-a-read-operation-f.patch new file mode 100644 index 0000000..a465005 --- /dev/null +++ b/SOURCES/0456-video-readers-png-Abort-sooner-if-a-read-operation-f.patch @@ -0,0 +1,201 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit 882be97d1df6449b9fd4d593f0cb70005fde3494) +(cherry picked from commit 3f6fc3ebfd58fcdb3fe6c2f7a5a4fa05772ae786) +(cherry picked from commit aac5b8257d4078c3f764216aeae3367bdc19043f) +(cherry picked from commit 3cdacdadbe289d3e73a8f58df5db05d8fe4d30c4) +--- + 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 39560f56fd..70beff905e 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 || len % 3 != 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; +@@ -1034,6 +1071,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/0457-video-readers-png-Refuse-to-handle-multiple-image-he.patch b/SOURCES/0457-video-readers-png-Refuse-to-handle-multiple-image-he.patch new file mode 100644 index 0000000..748b978 --- /dev/null +++ b/SOURCES/0457-video-readers-png-Refuse-to-handle-multiple-image-he.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit 8ce433557adeadbc46429aabb9f850b02ad2bdfb) +(cherry picked from commit 6e10bba6a4cbfd6c7bf116f41fd4e037465e19d8) +(cherry picked from commit 812272d919ecfd368c008f15b677d369616ada54) +(cherry picked from commit 571397816409f36f3d8ff0fad1695fe54e6926a4) +--- + 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 70beff905e..a9066658f2 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/0458-png-Optimize-by-avoiding-divisions.patch b/SOURCES/0458-png-Optimize-by-avoiding-divisions.patch new file mode 100644 index 0000000..b64fedb --- /dev/null +++ b/SOURCES/0458-png-Optimize-by-avoiding-divisions.patch @@ -0,0 +1,58 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Vladimir Serbinenko +Date: Thu, 26 Feb 2015 18:27:43 +0100 +Subject: [PATCH] png: Optimize by avoiding divisions. + +(cherry picked from commit 18125877eec4e6d7b0b6567b6c92eab1df946f47) +--- + grub-core/video/readers/png.c | 29 ++++++++++++++++++++--------- + 1 file changed, 20 insertions(+), 9 deletions(-) + +diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c +index a9066658f2..71bb76f9c4 100644 +--- a/grub-core/video/readers/png.c ++++ b/grub-core/video/readers/png.c +@@ -236,7 +236,7 @@ grub_png_decode_image_palette (struct grub_png_data *data, + { + unsigned i = 0, j; + +- if (len == 0 || len % 3 != 0) ++ if (len == 0) + return GRUB_ERR_NONE; + + grub_errno = GRUB_ERR_NONE; +@@ -900,15 +900,26 @@ grub_png_convert_image (struct grub_png_data *data) + int mask = (1 << data->color_bits) - 1; + unsigned j; + if (data->is_gray) +- for (i = 0; i < (1U << data->color_bits); i++) +- { +- grub_uint8_t col = (0xff * i) / ((1U << data->color_bits) - 1); +- palette[i][0] = col; +- palette[i][1] = col; +- palette[i][2] = col; +- } ++ { ++ /* 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, 16 * 3); ++ 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, diff --git a/SOURCES/0459-video-readers-png-Drop-greyscale-support-to-fix-heap.patch b/SOURCES/0459-video-readers-png-Drop-greyscale-support-to-fix-heap.patch new file mode 100644 index 0000000..bce235c --- /dev/null +++ b/SOURCES/0459-video-readers-png-Drop-greyscale-support-to-fix-heap.patch @@ -0,0 +1,173 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit 0e1d163382669bd734439d8864ee969616d971d9) +[rharwood: context conflict] +Signed-off-by: Robbie Harwood +(cherry picked from commit 4c631c8119206b3178912df2905434d967661c3d) +(cherry picked from commit 6d5d5f51266b8113c6ba560835500e3c135f3722) +(cherry picked from commit b134798cc28f7989e729d8c3fc83734444cdd00a) +--- + 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 71bb76f9c4..dcfdaa8596 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/0460-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch b/SOURCES/0460-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch new file mode 100644 index 0000000..4b70554 --- /dev/null +++ b/SOURCES/0460-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit 1ae9a91d42cb40da8a6f11fac65541858e340afa) +(cherry picked from commit 132ccc681cf642ad748580f26b54c9259a7f43fd) +(cherry picked from commit 3a70e1f6e69af6e0d3c3cf526faa44dc0c80ac19) +(cherry picked from commit 9990cee64b053a1593cf9883d73b630405519be2) +--- + 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 dcfdaa8596..24e972d1ba 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/0461-video-readers-png-Sanity-check-some-huffman-codes.patch b/SOURCES/0461-video-readers-png-Sanity-check-some-huffman-codes.patch new file mode 100644 index 0000000..1a9f178 --- /dev/null +++ b/SOURCES/0461-video-readers-png-Sanity-check-some-huffman-codes.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit c3a8ab0cbd24153ec7b1f84a96ddfdd72ef8d117) +(cherry picked from commit 5d09addf58086aa11d5f9a91af5632ff87c2d2ee) +(cherry picked from commit ff12584f9376a472f37d4ec14213fd29bf3b233a) +(cherry picked from commit e953feb46429355bb09f2cd01886296068d48a7c) +--- + 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 24e972d1ba..6c37678c40 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/0462-grub-core-video-readers-jpeg.c-Avoid-division-by-zer.patch b/SOURCES/0462-grub-core-video-readers-jpeg.c-Avoid-division-by-zer.patch new file mode 100644 index 0000000..34ae800 --- /dev/null +++ b/SOURCES/0462-grub-core-video-readers-jpeg.c-Avoid-division-by-zer.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Vladimir Serbinenko +Date: Tue, 20 Jan 2015 19:35:49 +0100 +Subject: [PATCH] * grub-core/video/readers/jpeg.c: Avoid division by + zero. + +(cherry picked from commit 4816dcac19a05a1209822015d88903faef3d6f44) +[rharwood: drop ChangeLog] +Signed-off-by: Robbie Harwood +--- + grub-core/video/readers/jpeg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c +index a6742a96b1..84cf5ceec9 100644 +--- a/grub-core/video/readers/jpeg.c ++++ b/grub-core/video/readers/jpeg.c +@@ -323,7 +323,7 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data) + { + data->vs = ss & 0xF; /* Vertical sampling. */ + data->hs = ss >> 4; /* Horizontal sampling. */ +- if ((data->vs > 2) || (data->hs > 2)) ++ if ((data->vs > 2) || (data->hs > 2) || (data->vs == 0) || (data->hs == 0)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: sampling method not supported"); + } diff --git a/SOURCES/0463-jpeg-Optimise-by-replacing-division-with-shifts.patch b/SOURCES/0463-jpeg-Optimise-by-replacing-division-with-shifts.patch new file mode 100644 index 0000000..48c7249 --- /dev/null +++ b/SOURCES/0463-jpeg-Optimise-by-replacing-division-with-shifts.patch @@ -0,0 +1,76 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Vladimir Serbinenko +Date: Thu, 26 Feb 2015 21:27:32 +0100 +Subject: [PATCH] jpeg: Optimise by replacing division with shifts. + +(cherry picked from commit 7213c1e02807e760febec06a0f19b11173abc55a) +--- + grub-core/video/readers/jpeg.c | 25 ++++++++++++++----------- + 1 file changed, 14 insertions(+), 11 deletions(-) + +diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c +index 84cf5ceec9..55bd95b797 100644 +--- a/grub-core/video/readers/jpeg.c ++++ b/grub-core/video/readers/jpeg.c +@@ -94,7 +94,7 @@ struct grub_jpeg_data + jpeg_data_unit_t crdu; + jpeg_data_unit_t cbdu; + +- unsigned vs, hs; ++ unsigned log_vs, log_hs; + int dri; + unsigned r1; + +@@ -321,11 +321,14 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data) + ss = grub_jpeg_get_byte (data); /* Sampling factor. */ + if (!id) + { +- data->vs = ss & 0xF; /* Vertical sampling. */ +- data->hs = ss >> 4; /* Horizontal sampling. */ +- if ((data->vs > 2) || (data->hs > 2) || (data->vs == 0) || (data->hs == 0)) ++ grub_uint8_t vs, hs; ++ vs = ss & 0xF; /* Vertical sampling. */ ++ hs = ss >> 4; /* Horizontal sampling. */ ++ if ((vs > 2) || (hs > 2) || (vs == 0) || (hs == 0)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: sampling method not supported"); ++ data->log_vs = (vs == 2); ++ data->log_hs = (hs == 2); + } + else if (ss != JPEG_SAMPLING_1x1) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, +@@ -638,10 +641,10 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data) + unsigned c1, vb, hb, nr1, nc1; + int rst = data->dri; + +- vb = data->vs * 8; +- hb = data->hs * 8; +- nr1 = (data->image_height + vb - 1) / vb; +- nc1 = (data->image_width + hb - 1) / hb; ++ vb = 8 << data->log_vs; ++ hb = 8 << data->log_hs; ++ nr1 = (data->image_height + vb - 1) >> (3 + data->log_vs); ++ nc1 = (data->image_width + hb - 1) >> (3 + data->log_hs); + + if (data->bitmap_ptr == NULL) + return grub_error(GRUB_ERR_BAD_FILE_TYPE, +@@ -655,8 +658,8 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data) + unsigned r2, c2, nr2, nc2; + grub_uint8_t *ptr2; + +- for (r2 = 0; r2 < data->vs; r2++) +- for (c2 = 0; c2 < data->hs; c2++) ++ 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]); + + if (data->color_components >= 3) +@@ -678,7 +681,7 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data) + unsigned i0; + int yy; + +- i0 = (r2 / data->vs) * 8 + (c2 / data->hs); ++ i0 = (r2 >> data->log_vs) * 8 + (c2 >> data->log_hs); + yy = data->ydu[(r2 / 8) * 2 + (c2 / 8)][(r2 % 8) * 8 + (c2 % 8)]; + + if (data->color_components >= 3) diff --git a/SOURCES/0464-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch b/SOURCES/0464-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch new file mode 100644 index 0000000..75ce1a3 --- /dev/null +++ b/SOURCES/0464-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch @@ -0,0 +1,258 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit ab2e5d2e4bff488bbb557ed435a61ae102ef9f0c) +(cherry picked from commit 1ff8df0d2dea8ec7c8575241d5e7d6622c204ec3) +(cherry picked from commit b07767383b74a0ce7135c09ba8701510d4ad32f0) +(cherry picked from commit 4f07a3be4499e569ba8f261c0c53e81012afa003) +--- + 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 55bd95b797..5cea6ba894 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/0465-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch b/SOURCES/0465-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch new file mode 100644 index 0000000..e7a8e89 --- /dev/null +++ b/SOURCES/0465-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit bc06e12b4de55cc6f926af9f064170c82b1403e9) +(cherry picked from commit 5298bf758ea39a90537f9a1c76541ff2f21b970b) +(cherry picked from commit aae6bac7f26c6b848156ed7adcff83309b833664) +(cherry picked from commit 9e1e766d635fa473dcc4178549a2ab15d5867ec1) +--- + 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 5cea6ba894..03b56ea91c 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/0466-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch b/SOURCES/0466-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch new file mode 100644 index 0000000..3dca964 --- /dev/null +++ b/SOURCES/0466-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit f3a854def3e281b7ad4bbea730cd3046de1da52f) +(cherry picked from commit db0154828989a0a52ee59a4dda8c3803752bc827) +(cherry picked from commit 75afb375ef46bc99a7faf5879d0283934e34db97) +(cherry picked from commit 9d39f2826e0244858a1b531a839a3130a476ecf2) +--- + 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 03b56ea91c..5e46a55710 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/0467-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch b/SOURCES/0467-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch new file mode 100644 index 0000000..097dbef --- /dev/null +++ b/SOURCES/0467-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch @@ -0,0 +1,56 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit 41aeb2004db9924fecd9f2dd64bc2a5a5594a4b5) +(cherry picked from commit 5f9582490792108306d047379fed2371bee286f8) +(cherry picked from commit 7e4bf25d9bb5219fbf11c523296dc3bd78b80698) +(cherry picked from commit a062059a004c9b3c7409ea29e721a08f64d7413b) +--- + 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 5e46a55710..572250ae68 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/0468-normal-charset-Fix-array-out-of-bounds-formatting-un.patch b/SOURCES/0468-normal-charset-Fix-array-out-of-bounds-formatting-un.patch new file mode 100644 index 0000000..8cf46fa --- /dev/null +++ b/SOURCES/0468-normal-charset-Fix-array-out-of-bounds-formatting-un.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit fdf32abc7a3928852422c0f291d8cd1dd6b34a8d) +(cherry picked from commit f2c10aaf335b88a69885375c4d68ffab2429df77) +(cherry picked from commit 4c942e1ba8d1f1199a58d2eb139022ae22f75cb2) +(cherry picked from commit f39239401ac1d8a54086376ca9e62682873342cd) +--- + 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 d89c0dafd5..d228caa643 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/0469-net-netbuff-Block-overly-large-netbuff-allocs.patch b/SOURCES/0469-net-netbuff-Block-overly-large-netbuff-allocs.patch new file mode 100644 index 0000000..c79b3bc --- /dev/null +++ b/SOURCES/0469-net-netbuff-Block-overly-large-netbuff-allocs.patch @@ -0,0 +1,49 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit ee9591103004cd13b4efadda671536090ca7fd57) +(cherry picked from commit acde668bb9d9fa862a1a63e3bbd5fa47fdfa9183) +(cherry picked from commit e47ad2eb4fe38ef2bdcab52245286f31170e73e3) +(cherry picked from commit e763a37047e8b684f412ecbef32de2e997ee0b63) +--- + 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/0470-net-ip-Do-IP-fragment-maths-safely.patch b/SOURCES/0470-net-ip-Do-IP-fragment-maths-safely.patch new file mode 100644 index 0000000..5315fc3 --- /dev/null +++ b/SOURCES/0470-net-ip-Do-IP-fragment-maths-safely.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit eb74e5743ca7e18a5e75c392fe0b21d1549a1936) +(cherry picked from commit 552ad34583e788542e9ca08524a0d4bc8f98c297) +(cherry picked from commit 2c8cb7e3b8b48b136a950e5692fa6251b76df90e) +(cherry picked from commit ec7f66954d81f3bb28f4c93581e0c562c8608fa1) +--- + 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 daa5b03516..bca6504c2e 100644 +--- a/grub-core/net/ip.c ++++ b/grub-core/net/ip.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + + struct iphdr { +@@ -536,7 +537,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/0471-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch b/SOURCES/0471-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch new file mode 100644 index 0000000..ed3665e --- /dev/null +++ b/SOURCES/0471-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch @@ -0,0 +1,59 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit eb2e69fcf51307757e43f55ee8c9354d1ee42dd1) +(cherry picked from commit d801a27e7acec6c1a83067fab0bb975877eaf704) +(cherry picked from commit 4d8b6e36ddfda4084e370b3b08c432e8a462e9be) +(cherry picked from commit 6e1ece695de550ed1a00b92afae5c980630aca29) +--- + 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 bded12f22e..0ea823078b 100644 +--- a/grub-core/net/dns.c ++++ b/grub-core/net/dns.c +@@ -661,9 +661,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/0472-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch b/SOURCES/0472-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch new file mode 100644 index 0000000..20baf0d --- /dev/null +++ b/SOURCES/0472-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch @@ -0,0 +1,74 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit 6a97b3f4b1d5173aa516edc6dedbc63de7306d21) +(cherry picked from commit e0589624e86bc96666cbdb62f6e55cafec2871b3) +(cherry picked from commit 95ecbc0b9aacfd43ba96cccc50daaf39eccd9f7f) +(cherry picked from commit 38b008ce855f818e36dfeeea83871659e1c6b083) +--- + 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 0ea823078b..2cbc114913 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/0473-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch b/SOURCES/0473-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch new file mode 100644 index 0000000..be15aa5 --- /dev/null +++ b/SOURCES/0473-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch @@ -0,0 +1,115 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit dada1dda695439bb55b2848dddc2d89843552f81) +(cherry picked from commit 352c5ae8a9fc715712e6ecbd7ccb6218122c748f) +(cherry picked from commit 61a010085ab9f0ecf42677773a6fc212f1579b0a) +(cherry picked from commit 14e15ef7b027c39528b19bfe69145c29f9795566) +--- + 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 1f62aa10f2..7e7f79143c 100644 +--- a/grub-core/net/net.c ++++ b/grub-core/net/net.c +@@ -1590,7 +1590,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; + } +@@ -1811,7 +1812,10 @@ grub_net_seek_real (struct grub_file *file, grub_off_t offset) + file->device->net->eof = 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; + } +@@ -1820,6 +1824,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 1ec827b9bf..50578c3ce3 100644 +--- a/include/grub/net.h ++++ b/include/grub/net.h +@@ -268,6 +268,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/0474-misc-Format-string-for-grub_error-should-be-a-litera.patch b/SOURCES/0474-misc-Format-string-for-grub_error-should-be-a-litera.patch new file mode 100644 index 0000000..8f7a430 --- /dev/null +++ b/SOURCES/0474-misc-Format-string-for-grub_error-should-be-a-litera.patch @@ -0,0 +1,54 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Glenn Washburn +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 +Reviewed-by: Daniel Kiper +(cherry-picked from commit 60875f4e15d704b875969b415501802b531c4db3) +(cherry picked from commit 9103b9e99e3541dea7a131cb1fbfb904c2ab249e) +--- + 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 3185a7a1c2..bfb4aa34cb 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 1c8bca0a32..71d0acf9d4 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/0475-net-tftp-Avoid-a-trivial-UAF.patch b/SOURCES/0475-net-tftp-Avoid-a-trivial-UAF.patch new file mode 100644 index 0000000..c05798f --- /dev/null +++ b/SOURCES/0475-net-tftp-Avoid-a-trivial-UAF.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit 956f4329cec23e4375182030ca9b2be631a61ba5) +(cherry picked from commit dbe9abcdee6ce796811111b67e3f24eefe2135d1) +(cherry picked from commit 72ae9c5d389d2c0337c44edead6e00db0bb84039) +(cherry picked from commit e98cfb24fb3c80b0ccc8ca10c521456b4ae8c535) +--- + 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/0476-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch b/SOURCES/0476-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch new file mode 100644 index 0000000..1ac21a3 --- /dev/null +++ b/SOURCES/0476-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch @@ -0,0 +1,45 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit ec233d3ecf995293304de443579aab5c46c49e85) +(cherry picked from commit d39cf87ed701b9f0900daed7f672e07994d37ce8) +(cherry picked from commit e0aa5c3acec70eac3489d6df1893a93726cbce3a) +(cherry picked from commit b417892b907ad5e22f0a81f142a2e186bcad9f1a) +--- + 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 82515f352d..4d787a52cd 100644 +--- a/grub-core/net/http.c ++++ b/grub-core/net/http.c +@@ -428,7 +428,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); +@@ -436,7 +436,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/0477-net-http-Fix-OOB-write-for-split-http-headers.patch b/SOURCES/0477-net-http-Fix-OOB-write-for-split-http-headers.patch new file mode 100644 index 0000000..3e7cb1f --- /dev/null +++ b/SOURCES/0477-net-http-Fix-OOB-write-for-split-http-headers.patch @@ -0,0 +1,49 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit e9fb459638811c12b0989dbf64e3e124974ef617) +(cherry picked from commit b604916beb6c39e8ed27f72851eb16f3eaa293c5) +(cherry picked from commit c3c6b1167a43275991efd6847160a46ce3839fae) +(cherry picked from commit 33f4f314fa4ba2d0bec9f95dc77f93395b742fdd) +--- + 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 4d787a52cd..443b8ffe87 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/0478-net-http-Error-out-on-headers-with-LF-without-CR.patch b/SOURCES/0478-net-http-Error-out-on-headers-with-LF-without-CR.patch new file mode 100644 index 0000000..e509215 --- /dev/null +++ b/SOURCES/0478-net-http-Error-out-on-headers-with-LF-without-CR.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit d232ad41ac4979a9de4d746e5fdff9caf0e303de) +(cherry picked from commit 8960e6d6137090a7e8c6592077da6e387a4ef972) +(cherry picked from commit 9b6b9398c90dd76ce0b935d21c4ecb8954c4b2b7) +(cherry picked from commit 939f44bae027c2f11fad5e730f1fda34b07a43a4) +--- + 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 443b8ffe87..e260e2defe 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/0479-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch b/SOURCES/0479-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch new file mode 100644 index 0000000..a2f929d --- /dev/null +++ b/SOURCES/0479-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch @@ -0,0 +1,83 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +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 +Reviewed-by: Daniel Kiper +(cherry picked from commit 6d3f06c0b6a8992b9b1bb0e62af93ac5ff2781f0) +[rharwood: we've an extra variable here] +(cherry picked from commit e3e21b9a81aea09dd43368cf097c1029a8380d82) +(cherry picked from commit ab14a39777edb60c99751d4fdf1cc254a4faebf5) +(cherry picked from commit b9944efba5b8a232ad1e07b4582fc371de138f1a) +[rharwood: remove the extra variable] +Signed-off-by: Robbie Harwood +--- + 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 918f7b7b22..d8d71226ac 100644 +--- a/grub-core/fs/btrfs.c ++++ b/grub-core/fs/btrfs.c +@@ -1534,6 +1534,7 @@ grub_btrfs_dir (grub_device_t device, const char *path, + int r = 0; + grub_uint64_t tree; + grub_uint8_t type; ++ grub_size_t est_size = 0; + + if (!data) + return grub_errno; +@@ -1592,6 +1593,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; +@@ -1602,6 +1615,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/0480-grub-core-fs-btrfs.c-Avoid-divisions-by-zero.patch b/SOURCES/0480-grub-core-fs-btrfs.c-Avoid-divisions-by-zero.patch new file mode 100644 index 0000000..b36b91d --- /dev/null +++ b/SOURCES/0480-grub-core-fs-btrfs.c-Avoid-divisions-by-zero.patch @@ -0,0 +1,103 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Vladimir Serbinenko +Date: Tue, 20 Jan 2015 17:36:29 +0100 +Subject: [PATCH] * grub-core/fs/btrfs.c: Avoid divisions by zero. + +(cherry picked from commit 9deb46e363a341d8c243e4c85754e673b4b68571) +[rharwood: drop ChangeLog] +Signed-off-by: Robbie Harwood +--- + grub-core/fs/btrfs.c | 35 +++++++++++++++++++++-------------- + 1 file changed, 21 insertions(+), 14 deletions(-) + +diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c +index d8d71226ac..a401374690 100644 +--- a/grub-core/fs/btrfs.c ++++ b/grub-core/fs/btrfs.c +@@ -701,6 +701,8 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + grub_uint64_t stripen; + grub_uint64_t stripe_offset; + grub_uint64_t off = addr - grub_le_to_cpu64 (key->offset); ++ grub_uint64_t chunk_stripe_length; ++ grub_uint16_t nstripes; + unsigned redundancy = 1; + unsigned i, j; + +@@ -711,15 +713,17 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + "couldn't find the chunk descriptor"); + } + ++ nstripes = grub_le_to_cpu16 (chunk->nstripes) ? : 1; ++ chunk_stripe_length = grub_le_to_cpu64 (chunk->stripe_length) ? : 512; + grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T + "+0x%" PRIxGRUB_UINT64_T + " (%d stripes (%d substripes) of %" + PRIxGRUB_UINT64_T ")\n", + grub_le_to_cpu64 (key->offset), + grub_le_to_cpu64 (chunk->size), +- grub_le_to_cpu16 (chunk->nstripes), ++ nstripes, + grub_le_to_cpu16 (chunk->nsubstripes), +- grub_le_to_cpu64 (chunk->stripe_length)); ++ chunk_stripe_length); + + switch (grub_le_to_cpu64 (chunk->type) + & ~GRUB_BTRFS_CHUNK_TYPE_BITS_DONTCARE) +@@ -729,8 +733,10 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + grub_uint64_t stripe_length; + grub_dprintf ("btrfs", "single\n"); + stripe_length = grub_divmod64 (grub_le_to_cpu64 (chunk->size), +- grub_le_to_cpu16 (chunk->nstripes), ++ nstripes, + NULL); ++ if (stripe_length == 0) ++ stripe_length = 512; + stripen = grub_divmod64 (off, stripe_length, &stripe_offset); + csize = (stripen + 1) * stripe_length - off; + break; +@@ -751,33 +757,34 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + grub_uint64_t low; + grub_dprintf ("btrfs", "RAID0\n"); + middle = grub_divmod64 (off, +- grub_le_to_cpu64 (chunk->stripe_length), ++ chunk_stripe_length, + &low); + +- high = grub_divmod64 (middle, grub_le_to_cpu16 (chunk->nstripes), ++ high = grub_divmod64 (middle, nstripes, + &stripen); + stripe_offset = +- low + grub_le_to_cpu64 (chunk->stripe_length) * high; +- csize = grub_le_to_cpu64 (chunk->stripe_length) - low; ++ low + chunk_stripe_length * high; ++ csize = chunk_stripe_length - low; + break; + } + case GRUB_BTRFS_CHUNK_TYPE_RAID10: + { + grub_uint64_t middle, high; + grub_uint64_t low; ++ grub_uint16_t nsubstripes; ++ nsubstripes = grub_le_to_cpu16 (chunk->nsubstripes) ? : 1; + middle = grub_divmod64 (off, +- grub_le_to_cpu64 (chunk->stripe_length), ++ chunk_stripe_length, + &low); + + high = grub_divmod64 (middle, +- grub_le_to_cpu16 (chunk->nstripes) +- / grub_le_to_cpu16 (chunk->nsubstripes), ++ nstripes / nsubstripes ? : 1, + &stripen); +- stripen *= grub_le_to_cpu16 (chunk->nsubstripes); +- redundancy = grub_le_to_cpu16 (chunk->nsubstripes); +- stripe_offset = low + grub_le_to_cpu64 (chunk->stripe_length) ++ stripen *= nsubstripes; ++ redundancy = nsubstripes; ++ stripe_offset = low + chunk_stripe_length + * high; +- csize = grub_le_to_cpu64 (chunk->stripe_length) - low; ++ csize = chunk_stripe_length - low; + break; + } + default: diff --git a/SOURCES/0481-btrfs-Add-support-for-reading-a-filesystem-with-a-RA.patch b/SOURCES/0481-btrfs-Add-support-for-reading-a-filesystem-with-a-RA.patch new file mode 100644 index 0000000..3cd2908 --- /dev/null +++ b/SOURCES/0481-btrfs-Add-support-for-reading-a-filesystem-with-a-RA.patch @@ -0,0 +1,105 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Goffredo Baroncelli +Date: Mon, 22 Oct 2018 19:29:31 +0200 +Subject: [PATCH] btrfs: Add support for reading a filesystem with a RAID 5 or + RAID 6 profile + +Signed-off-by: Goffredo Baroncelli +Signed-off-by: Daniel Kiper +Reviewed-by: Daniel Kiper +(cherry picked from commit 81e2673fb60a200a33bb064fbffe9e3956f37974) +--- + grub-core/fs/btrfs.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 73 insertions(+) + +diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c +index a401374690..6f17f5d0eb 100644 +--- a/grub-core/fs/btrfs.c ++++ b/grub-core/fs/btrfs.c +@@ -120,6 +120,8 @@ struct grub_btrfs_chunk_item + #define GRUB_BTRFS_CHUNK_TYPE_RAID1 0x10 + #define GRUB_BTRFS_CHUNK_TYPE_DUPLICATED 0x20 + #define GRUB_BTRFS_CHUNK_TYPE_RAID10 0x40 ++#define GRUB_BTRFS_CHUNK_TYPE_RAID5 0x80 ++#define GRUB_BTRFS_CHUNK_TYPE_RAID6 0x100 + grub_uint8_t dummy2[0xc]; + grub_uint16_t nstripes; + grub_uint16_t nsubstripes; +@@ -785,6 +787,77 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + stripe_offset = low + chunk_stripe_length + * high; + csize = chunk_stripe_length - low; ++ break; ++ } ++ case GRUB_BTRFS_CHUNK_TYPE_RAID5: ++ case GRUB_BTRFS_CHUNK_TYPE_RAID6: ++ { ++ grub_uint64_t nparities, stripe_nr, high, low; ++ ++ redundancy = 1; /* no redundancy for now */ ++ ++ if (grub_le_to_cpu64 (chunk->type) & GRUB_BTRFS_CHUNK_TYPE_RAID5) ++ { ++ grub_dprintf ("btrfs", "RAID5\n"); ++ nparities = 1; ++ } ++ else ++ { ++ grub_dprintf ("btrfs", "RAID6\n"); ++ nparities = 2; ++ } ++ ++ /* ++ * RAID 6 layout consists of several stripes spread over ++ * the disks, e.g.: ++ * ++ * Disk_0 Disk_1 Disk_2 Disk_3 ++ * A0 B0 P0 Q0 ++ * Q1 A1 B1 P1 ++ * P2 Q2 A2 B2 ++ * ++ * Note: placement of the parities depend on row number. ++ * ++ * Pay attention that the btrfs terminology may differ from ++ * terminology used in other RAID implementations, e.g. LVM, ++ * dm or md. The main difference is that btrfs calls contiguous ++ * block of data on a given disk, e.g. A0, stripe instead of chunk. ++ * ++ * The variables listed below have following meaning: ++ * - stripe_nr is the stripe number excluding the parities ++ * (A0 = 0, B0 = 1, A1 = 2, B1 = 3, etc.), ++ * - high is the row number (0 for A0...Q0, 1 for Q1...P1, etc.), ++ * - stripen is the disk number in a row (0 for A0, Q1, P2, ++ * 1 for B0, A1, Q2, etc.), ++ * - off is the logical address to read, ++ * - chunk_stripe_length is the size of a stripe (typically 64 KiB), ++ * - nstripes is the number of disks in a row, ++ * - low is the offset of the data inside a stripe, ++ * - stripe_offset is the data offset in an array, ++ * - csize is the "potential" data to read; it will be reduced ++ * to size if the latter is smaller, ++ * - nparities is the number of parities (1 for RAID 5, 2 for ++ * RAID 6); used only in RAID 5/6 code. ++ */ ++ stripe_nr = grub_divmod64 (off, chunk_stripe_length, &low); ++ ++ /* ++ * stripen is computed without the parities ++ * (0 for A0, A1, A2, 1 for B0, B1, B2, etc.). ++ */ ++ high = grub_divmod64 (stripe_nr, nstripes - nparities, &stripen); ++ ++ /* ++ * The stripes are spread over the disks. Every each row their ++ * positions are shifted by 1 place. So, the real disks number ++ * change. Hence, we have to take into account current row number ++ * modulo nstripes (0 for A0, 1 for A1, 2 for A2, etc.). ++ */ ++ grub_divmod64 (high + stripen, nstripes, &stripen); ++ ++ stripe_offset = chunk_stripe_length * high + low; ++ csize = chunk_stripe_length - low; ++ + break; + } + default: diff --git a/SOURCES/0482-btrfs-Add-support-for-new-RAID1C34-profiles.patch b/SOURCES/0482-btrfs-Add-support-for-new-RAID1C34-profiles.patch new file mode 100644 index 0000000..1704abc --- /dev/null +++ b/SOURCES/0482-btrfs-Add-support-for-new-RAID1C34-profiles.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: David Sterba +Date: Mon, 4 Nov 2019 17:23:22 +0100 +Subject: [PATCH] btrfs: Add support for new RAID1C34 profiles + +New 3- and 4-copy variants of RAID1 were merged into Linux kernel 5.5. +Add the two new profiles to the list of recognized ones. As this builds +on the same code as RAID1, only the redundancy level needs to be +adjusted, the rest is done by the existing code. + +Signed-off-by: David Sterba +Reviewed-by: Daniel Kiper +(cherry picked from commit 495781f5ed1b48bf27f16c53940d6700c181c74c) +--- + grub-core/fs/btrfs.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c +index 6f17f5d0eb..2d92d9c1b2 100644 +--- a/grub-core/fs/btrfs.c ++++ b/grub-core/fs/btrfs.c +@@ -122,6 +122,8 @@ struct grub_btrfs_chunk_item + #define GRUB_BTRFS_CHUNK_TYPE_RAID10 0x40 + #define GRUB_BTRFS_CHUNK_TYPE_RAID5 0x80 + #define GRUB_BTRFS_CHUNK_TYPE_RAID6 0x100 ++#define GRUB_BTRFS_CHUNK_TYPE_RAID1C3 0x200 ++#define GRUB_BTRFS_CHUNK_TYPE_RAID1C4 0x400 + grub_uint8_t dummy2[0xc]; + grub_uint16_t nstripes; + grub_uint16_t nsubstripes; +@@ -743,14 +745,19 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + csize = (stripen + 1) * stripe_length - off; + break; + } ++ case GRUB_BTRFS_CHUNK_TYPE_RAID1C4: ++ redundancy++; ++ /* fall through */ ++ case GRUB_BTRFS_CHUNK_TYPE_RAID1C3: ++ redundancy++; ++ /* fall through */ + case GRUB_BTRFS_CHUNK_TYPE_DUPLICATED: + case GRUB_BTRFS_CHUNK_TYPE_RAID1: + { +- grub_dprintf ("btrfs", "RAID1\n"); ++ grub_dprintf ("btrfs", "RAID1 (copies: %d)\n", ++redundancy); + stripen = 0; + stripe_offset = off; + csize = grub_le_to_cpu64 (chunk->size) - off; +- redundancy = 2; + break; + } + case GRUB_BTRFS_CHUNK_TYPE_RAID0: diff --git a/SOURCES/0483-btrfs-Move-logging-code-in-grub_btrfs_read_logical.patch b/SOURCES/0483-btrfs-Move-logging-code-in-grub_btrfs_read_logical.patch new file mode 100644 index 0000000..0ec0406 --- /dev/null +++ b/SOURCES/0483-btrfs-Move-logging-code-in-grub_btrfs_read_logical.patch @@ -0,0 +1,65 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Goffredo Baroncelli +Date: Mon, 22 Oct 2018 19:29:35 +0200 +Subject: [PATCH] btrfs: Move logging code in grub_btrfs_read_logical() + +A portion of the logging code is moved outside of internal for(;;). The part +that is left inside is the one which depends on the internal for(;;) index. + +This is a preparatory patch. The next one will refactor the code inside +the for(;;) into an another function. + +Signed-off-by: Goffredo Baroncelli +Reviewed-by: Daniel Kiper +(cherry picked from commit c6f79aca8030689ab2087686654ac431db411fa3) +--- + grub-core/fs/btrfs.c | 27 +++++++++++++++------------ + 1 file changed, 15 insertions(+), 12 deletions(-) + +diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c +index 2d92d9c1b2..671dbd8918 100644 +--- a/grub-core/fs/btrfs.c ++++ b/grub-core/fs/btrfs.c +@@ -881,6 +881,18 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + + for (j = 0; j < 2; j++) + { ++ grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T ++ "+0x%" PRIxGRUB_UINT64_T ++ " (%d stripes (%d substripes) of %" ++ PRIxGRUB_UINT64_T ")\n", ++ grub_le_to_cpu64 (key->offset), ++ grub_le_to_cpu64 (chunk->size), ++ grub_le_to_cpu16 (chunk->nstripes), ++ grub_le_to_cpu16 (chunk->nsubstripes), ++ grub_le_to_cpu64 (chunk->stripe_length)); ++ grub_dprintf ("btrfs", "reading laddr 0x%" PRIxGRUB_UINT64_T "\n", ++ addr); ++ + for (i = 0; i < redundancy; i++) + { + struct grub_btrfs_chunk_stripe *stripe; +@@ -893,20 +905,11 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + + paddr = grub_le_to_cpu64 (stripe->offset) + stripe_offset; + +- grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T +- "+0x%" PRIxGRUB_UINT64_T +- " (%d stripes (%d substripes) of %" +- PRIxGRUB_UINT64_T ") stripe %" PRIxGRUB_UINT64_T ++ grub_dprintf ("btrfs", "stripe %" PRIxGRUB_UINT64_T + " maps to 0x%" PRIxGRUB_UINT64_T "\n", +- grub_le_to_cpu64 (key->offset), +- grub_le_to_cpu64 (chunk->size), +- grub_le_to_cpu16 (chunk->nstripes), +- grub_le_to_cpu16 (chunk->nsubstripes), +- grub_le_to_cpu64 (chunk->stripe_length), + stripen, stripe->offset); +- grub_dprintf ("btrfs", "reading paddr 0x%" PRIxGRUB_UINT64_T +- " for laddr 0x%" PRIxGRUB_UINT64_T "\n", paddr, +- addr); ++ grub_dprintf ("btrfs", "reading paddr 0x%" PRIxGRUB_UINT64_T "\n", ++ paddr); + + dev = find_device (data, stripe->device_id, j); + if (!dev) diff --git a/SOURCES/0484-btrfs-Move-the-error-logging-from-find_device-to-its.patch b/SOURCES/0484-btrfs-Move-the-error-logging-from-find_device-to-its.patch new file mode 100644 index 0000000..08965be --- /dev/null +++ b/SOURCES/0484-btrfs-Move-the-error-logging-from-find_device-to-its.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Goffredo Baroncelli +Date: Mon, 22 Oct 2018 19:29:33 +0200 +Subject: [PATCH] btrfs: Move the error logging from find_device() to its + caller + +The caller knows better if this error is fatal or not, i.e. another disk is +available or not. + +This is a preparatory patch. + +Signed-off-by: Goffredo Baroncelli +Reviewed-by: Daniel Kiper +(cherry picked from commit 908cdb1d029e27f8059f9e3571e8dcbd67f74d8a) +--- + grub-core/fs/btrfs.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c +index 671dbd8918..2fb8fb323b 100644 +--- a/grub-core/fs/btrfs.c ++++ b/grub-core/fs/btrfs.c +@@ -593,12 +593,7 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan) + if (do_rescan) + grub_device_iterate (find_device_iter, &ctx); + if (!ctx.dev_found) +- { +- grub_error (GRUB_ERR_BAD_FS, +- N_("couldn't find a necessary member device " +- "of multi-device filesystem")); +- return NULL; +- } ++ return NULL; + data->n_devices_attached++; + if (data->n_devices_attached > data->n_devices_allocated) + { +@@ -914,6 +909,9 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + dev = find_device (data, stripe->device_id, j); + if (!dev) + { ++ grub_dprintf ("btrfs", ++ "couldn't find a necessary member device " ++ "of multi-device filesystem\n"); + err = grub_errno; + grub_errno = GRUB_ERR_NONE; + continue; diff --git a/SOURCES/0485-fs-btrfs-Fix-more-ASAN-and-SEGV-issues-found-with-fu.patch b/SOURCES/0485-fs-btrfs-Fix-more-ASAN-and-SEGV-issues-found-with-fu.patch new file mode 100644 index 0000000..7a82ff9 --- /dev/null +++ b/SOURCES/0485-fs-btrfs-Fix-more-ASAN-and-SEGV-issues-found-with-fu.patch @@ -0,0 +1,138 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Tue, 29 Mar 2022 15:52:46 +0000 +Subject: [PATCH] fs/btrfs: Fix more ASAN and SEGV issues found with fuzzing + +The fuzzer is generating btrfs file systems that have chunks with +invalid combinations of stripes and substripes for the given RAID +configurations. + +After examining the Linux kernel fs/btrfs/tree-checker.c code, it +appears that sub-stripes should only be applied to RAID10, and in that +case there should only ever be 2 of them. + +Similarly, RAID single should only have 1 stripe, and RAID1/1C3/1C4 +should have 2. 3 or 4 stripes respectively, which is what redundancy +corresponds. + +Some of the chunks ended up with a size of 0, which grub_malloc() still +returned memory for and in turn generated ASAN errors later when +accessed. + +While it would be possible to specifically limit the number of stripes, +a more correct test was on the combination of the chunk item, and the +number of stripes by the size of the chunk stripe structure in +comparison to the size of the chunk itself. + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +(cherry picked from commit 3849647b4b98a4419366708fc4b7f339c6f55ec7) +(cherry picked from commit fa5a02a8930bbd8a3b5ae6ed9612307611f18500) +(cherry picked from commit cf2f58925dbe069d23fa1068ac3634c6a2cf2d51) +[rharwood: don't want to backport raid56 and all its deps] +Signed-off-by: Robbie Harwood +--- + grub-core/fs/btrfs.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 55 insertions(+) + +diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c +index 2fb8fb323b..038da07020 100644 +--- a/grub-core/fs/btrfs.c ++++ b/grub-core/fs/btrfs.c +@@ -682,6 +682,12 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + return grub_error (GRUB_ERR_BAD_FS, + "couldn't find the chunk descriptor"); + ++ if (!chsize) ++ { ++ grub_dprintf ("btrfs", "zero-size chunk\n"); ++ return grub_error (GRUB_ERR_BAD_FS, ++ "got an invalid zero-size chunk"); ++ } + chunk = grub_malloc (chsize); + if (!chunk) + return grub_errno; +@@ -734,6 +740,16 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + stripe_length = grub_divmod64 (grub_le_to_cpu64 (chunk->size), + nstripes, + NULL); ++ ++ /* For single, there should be exactly 1 stripe. */ ++ if (grub_le_to_cpu16 (chunk->nstripes) != 1) ++ { ++ grub_dprintf ("btrfs", "invalid RAID_SINGLE: nstripes != 1 (%u)\n", ++ grub_le_to_cpu16 (chunk->nstripes)); ++ return grub_error (GRUB_ERR_BAD_FS, ++ "invalid RAID_SINGLE: nstripes != 1 (%u)", ++ grub_le_to_cpu16 (chunk->nstripes)); ++ } + if (stripe_length == 0) + stripe_length = 512; + stripen = grub_divmod64 (off, stripe_length, &stripe_offset); +@@ -753,6 +769,19 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + stripen = 0; + stripe_offset = off; + csize = grub_le_to_cpu64 (chunk->size) - off; ++ ++ /* ++ * Redundancy, and substripes only apply to RAID10, and there ++ * should be exactly 2 sub-stripes. ++ */ ++ if (grub_le_to_cpu16 (chunk->nstripes) != redundancy) ++ { ++ grub_dprintf ("btrfs", "invalid RAID1: nstripes != %u (%u)\n", ++ redundancy, grub_le_to_cpu16 (chunk->nstripes)); ++ return grub_error (GRUB_ERR_BAD_FS, ++ "invalid RAID1: nstripes != %u (%u)", ++ redundancy, grub_le_to_cpu16 (chunk->nstripes)); ++ } + break; + } + case GRUB_BTRFS_CHUNK_TYPE_RAID0: +@@ -789,6 +818,20 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + stripe_offset = low + chunk_stripe_length + * high; + csize = chunk_stripe_length - low; ++ ++ /* ++ * Substripes only apply to RAID10, and there ++ * should be exactly 2 sub-stripes. ++ */ ++ if (grub_le_to_cpu16 (chunk->nsubstripes) != 2) ++ { ++ grub_dprintf ("btrfs", "invalid RAID10: nsubstripes != 2 (%u)", ++ grub_le_to_cpu16 (chunk->nsubstripes)); ++ return grub_error (GRUB_ERR_BAD_FS, ++ "invalid RAID10: nsubstripes != 2 (%u)", ++ grub_le_to_cpu16 (chunk->nsubstripes)); ++ } ++ + break; + } + case GRUB_BTRFS_CHUNK_TYPE_RAID5: +@@ -876,6 +919,8 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + + for (j = 0; j < 2; j++) + { ++ grub_size_t est_chunk_alloc = 0; ++ + grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T + "+0x%" PRIxGRUB_UINT64_T + " (%d stripes (%d substripes) of %" +@@ -888,6 +933,16 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + grub_dprintf ("btrfs", "reading laddr 0x%" PRIxGRUB_UINT64_T "\n", + addr); + ++ if (grub_mul (sizeof (struct grub_btrfs_chunk_stripe), ++ grub_le_to_cpu16 (chunk->nstripes), &est_chunk_alloc) || ++ grub_add (est_chunk_alloc, ++ sizeof (struct grub_btrfs_chunk_item), &est_chunk_alloc) || ++ est_chunk_alloc > chunk->size) ++ { ++ err = GRUB_ERR_BAD_FS; ++ break; ++ } ++ + for (i = 0; i < redundancy; i++) + { + struct grub_btrfs_chunk_stripe *stripe; diff --git a/SOURCES/0486-fs-btrfs-Fix-more-fuzz-issues-related-to-chunks.patch b/SOURCES/0486-fs-btrfs-Fix-more-fuzz-issues-related-to-chunks.patch new file mode 100644 index 0000000..767e091 --- /dev/null +++ b/SOURCES/0486-fs-btrfs-Fix-more-fuzz-issues-related-to-chunks.patch @@ -0,0 +1,79 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Thu, 7 Apr 2022 15:18:12 +0000 +Subject: [PATCH] fs/btrfs: Fix more fuzz issues related to chunks + +The corpus we generating issues in grub_btrfs_read_logical() when +attempting to iterate over nstripes entries in the boot mapping. + +In most cases the reason for the failure was that the number of strips +exceeded the possible space statically allocated in superblock bootmapping +space. Each stripe entry in the bootmapping block consists of +a grub_btrfs_key followed by a grub_btrfs_chunk_stripe. + +Another issue that came up was that while calculating the chunk size, +in an earlier piece of code in that function, depending on the data +provided in the btrfs file system, it would end up calculating a size +that was too small to contain even 1 grub_btrfs_chunk_item, which is +obviously invalid too. + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +(cherry picked from commit e00cd76cbadcc897a9cc4087cb2fcb5dbe15e596) +(cherry picked from commit b74a6fc95b0839937acf4f2b7445ae9d179f49ec) +(cherry picked from commit fe06e6c9f97be3550fe36a01a9f9795d7530a01a) +[rharwood: didn't want to backport raid56 and all it deps] +Signed-off-by: Robbie Harwood +--- + grub-core/fs/btrfs.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c +index 038da07020..d8102506a7 100644 +--- a/grub-core/fs/btrfs.c ++++ b/grub-core/fs/btrfs.c +@@ -688,6 +688,17 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + return grub_error (GRUB_ERR_BAD_FS, + "got an invalid zero-size chunk"); + } ++ ++ /* ++ * The space being allocated for a chunk should at least be able to ++ * contain one chunk item. ++ */ ++ if (chsize < sizeof (struct grub_btrfs_chunk_item)) ++ { ++ grub_dprintf ("btrfs", "chunk-size too small\n"); ++ return grub_error (GRUB_ERR_BAD_FS, ++ "got an invalid chunk size"); ++ } + chunk = grub_malloc (chsize); + if (!chunk) + return grub_errno; +@@ -917,6 +928,13 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + if (csize > (grub_uint64_t) size) + csize = size; + ++ /* ++ * The space for a chunk stripe is limited to the space provide in the super-block's ++ * bootstrap mapping with an initial btrfs key at the start of each chunk. ++ */ ++ grub_size_t avail_stripes = sizeof (data->sblock.bootstrap_mapping) / ++ (sizeof (struct grub_btrfs_key) + sizeof (struct grub_btrfs_chunk_stripe)); ++ + for (j = 0; j < 2; j++) + { + grub_size_t est_chunk_alloc = 0; +@@ -943,6 +961,12 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + break; + } + ++ if (grub_le_to_cpu16 (chunk->nstripes) > avail_stripes) ++ { ++ err = GRUB_ERR_BAD_FS; ++ break; ++ } ++ + for (i = 0; i < redundancy; i++) + { + struct grub_btrfs_chunk_stripe *stripe; diff --git a/SOURCES/centos-ca-secureboot.der b/SOURCES/centos-ca-secureboot.der deleted file mode 100644 index 44a2563..0000000 Binary files a/SOURCES/centos-ca-secureboot.der and /dev/null differ diff --git a/SOURCES/centossecureboot001.crt b/SOURCES/centossecureboot001.crt deleted file mode 100644 index 294b05f..0000000 --- a/SOURCES/centossecureboot001.crt +++ /dev/null @@ -1,425 +0,0 @@ - - - - - - Tree - rpms/kernel - CentOS Git server - - - - - - - - - - - - - - - - -
- - -
-
-
-
-
-
-

-

-
-
-

-rpms / kernel -

-
-
-
-
-
-
- - - Clone - - - -
-
-
-
- - -
-
- -
-
- -
- -
-
- -
- -
-
-
- - -
- - Blob - - Blame - - Raw -
- -
Certificate:
-    Data:
-        Version: 3 (0x2)
-        Serial Number:
-            b6:16:15:71:72:fb:31:7e
-        Signature Algorithm: sha256WithRSAEncryption
-        Issuer: CN=CentOS Secure Boot (CA key 1)/emailAddress=security@centos.org
-        Validity
-            Not Before: Aug  1 11:47:30 2018 GMT
-            Not After : Dec 31 11:47:30 2037 GMT
-        Subject: CN=CentOS Secure Boot (key 1)/emailAddress=security@centos.org
-        Subject Public Key Info:
-            Public Key Algorithm: rsaEncryption
-            RSA Public Key: (2048 bit)
-                Modulus (2048 bit):
-                    00:c1:a3:6a:f4:2d:71:83:6c:21:ca:0c:b7:ac:fa:
-                    76:80:43:03:40:87:5d:de:e9:1e:df:ad:e7:2b:51:
-                    cb:f8:31:0f:9a:db:ab:23:25:04:11:05:57:7d:f2:
-                    4b:8d:1e:b3:75:78:1d:b9:57:8b:18:0b:bb:7e:e3:
-                    24:0f:6a:40:5f:2b:4f:03:a5:85:94:d2:f9:08:a0:
-                    bc:db:a5:ea:4f:7f:e8:7c:d1:a9:f8:f0:9c:25:18:
-                    00:14:c4:c4:35:7d:1d:4c:8a:8d:95:f8:ed:65:97:
-                    a5:a4:da:7d:cb:f0:33:3b:b7:03:94:68:47:05:57:
-                    6c:96:91:ac:14:f2:e3:f6:6d:4a:18:cf:68:8a:35:
-                    6f:8e:26:99:7f:db:c9:83:54:c2:c3:bf:ad:45:a0:
-                    aa:a0:86:5f:20:b1:86:1b:ae:b7:28:15:11:f9:65:
-                    53:5d:70:33:9b:a3:c7:b5:c8:11:ff:55:3b:e7:46:
-                    f1:6c:6b:8c:bb:f2:9f:36:23:b1:2d:23:2f:8f:4f:
-                    6c:a8:cc:ae:f5:56:9e:22:6c:0e:9a:4a:b1:bd:b2:
-                    76:15:5c:05:85:b8:5e:dc:8c:a5:c3:e0:75:51:a4:
-                    94:9b:03:2e:7b:f8:d3:b9:dd:7f:88:ce:2e:2f:28:
-                    4c:b4:92:2f:e6:e0:67:0a:d0:ff:c5:d2:79:a6:ef:
-                    94:0f
-                Exponent: 65537 (0x10001)
-        X509v3 extensions:
-            X509v3 Basic Constraints: critical
-                CA:FALSE
-            X509v3 Key Usage: 
-                Digital Signature
-            X509v3 Subject Key Identifier: 
-                F0:37:C6:EA:EC:36:D4:05:7A:52:6C:0E:C6:D5:A9:5B:32:4E:E1:29
-            X509v3 Authority Key Identifier: 
-                keyid:54:EC:81:85:89:3E:E9:1A:DB:08:F7:44:88:54:7E:8E:3F:74:3A:F3
-
-    Signature Algorithm: sha256WithRSAEncryption
-        97:97:ba:a6:0b:5b:bb:84:39:2e:ef:8b:51:9a:89:bb:65:3c:
-        dc:15:d0:5a:88:c5:af:ce:93:f5:c1:74:98:15:59:a9:38:da:
-        11:fd:46:d5:4f:23:7c:03:1f:ae:0c:70:93:94:a7:61:2f:4b:
-        2f:5f:bb:cc:8a:d7:4a:24:66:73:85:b4:19:13:fc:6a:61:4a:
-        28:1f:a2:38:f4:72:90:03:c4:3e:64:63:8b:fb:15:22:22:4e:
-        b9:43:d9:b4:3d:3a:60:c1:4d:3a:09:85:68:7a:bc:3b:f9:ef:
-        f3:f5:e9:c9:4f:80:8c:c6:e9:cb:ef:28:44:b0:5d:d4:9e:4f:
-        0f:02:9a:65:aa:98:35:b4:6f:d2:80:e3:08:ef:12:d0:17:56:
-        a6:a1:42:1e:1d:ab:e5:33:c0:fd:88:0d:40:42:81:c8:27:30:
-        17:07:57:3e:05:9d:aa:05:0e:5b:3a:79:b4:29:aa:7c:42:5a:
-        ad:43:59:fb:34:4d:dc:62:58:63:e4:fb:de:bb:fd:6c:4e:97:
-        58:f4:b9:99:4a:71:fe:7f:16:50:55:25:46:39:96:9b:88:6c:
-        75:19:33:9e:70:b3:04:82:fe:16:a8:8e:22:47:83:6d:16:77:
-        da:26:ad:31:d8:06:6d:c5:7e:46:4b:21:ab:ae:ec:2a:93:71:
-        da:7f:89:1d
------BEGIN CERTIFICATE-----
-MIIDdTCCAl2gAwIBAgIJALYWFXFy+zF+MA0GCSqGSIb3DQEBCwUAMEwxJjAkBgNV
-BAMMHUNlbnRPUyBTZWN1cmUgQm9vdCAoQ0Ega2V5IDEpMSIwIAYJKoZIhvcNAQkB
-FhNzZWN1cml0eUBjZW50b3Mub3JnMB4XDTE4MDgwMTExNDczMFoXDTM3MTIzMTEx
-NDczMFowSTEjMCEGA1UEAxMaQ2VudE9TIFNlY3VyZSBCb290IChrZXkgMSkxIjAg
-BgkqhkiG9w0BCQEWE3NlY3VyaXR5QGNlbnRvcy5vcmcwggEiMA0GCSqGSIb3DQEB
-AQUAA4IBDwAwggEKAoIBAQDBo2r0LXGDbCHKDLes+naAQwNAh13e6R7frecrUcv4
-MQ+a26sjJQQRBVd98kuNHrN1eB25V4sYC7t+4yQPakBfK08DpYWU0vkIoLzbpepP
-f+h80an48JwlGAAUxMQ1fR1Mio2V+O1ll6Wk2n3L8DM7twOUaEcFV2yWkawU8uP2
-bUoYz2iKNW+OJpl/28mDVMLDv61FoKqghl8gsYYbrrcoFRH5ZVNdcDObo8e1yBH/
-VTvnRvFsa4y78p82I7EtIy+PT2yozK71Vp4ibA6aSrG9snYVXAWFuF7cjKXD4HVR
-pJSbAy57+NO53X+Izi4vKEy0ki/m4GcK0P/F0nmm75QPAgMBAAGjXTBbMAwGA1Ud
-EwEB/wQCMAAwCwYDVR0PBAQDAgeAMB0GA1UdDgQWBBTwN8bq7DbUBXpSbA7G1alb
-Mk7hKTAfBgNVHSMEGDAWgBRU7IGFiT7pGtsI90SIVH6OP3Q68zANBgkqhkiG9w0B
-AQsFAAOCAQEAl5e6pgtbu4Q5Lu+LUZqJu2U83BXQWojFr86T9cF0mBVZqTjaEf1G
-1U8jfAMfrgxwk5SnYS9LL1+7zIrXSiRmc4W0GRP8amFKKB+iOPRykAPEPmRji/sV
-IiJOuUPZtD06YMFNOgmFaHq8O/nv8/XpyU+AjMbpy+8oRLBd1J5PDwKaZaqYNbRv
-0oDjCO8S0BdWpqFCHh2r5TPA/YgNQEKByCcwFwdXPgWdqgUOWzp5tCmqfEJarUNZ
-+zRN3GJYY+T73rv9bE6XWPS5mUpx/n8WUFUlRjmWm4hsdRkznnCzBIL+FqiOIkeD
-bRZ32iatMdgGbcV+Rkshq67sKpNx2n+JHQ==
------END CERTIFICATE-----
-
-
-
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/SOURCES/centossecureboot202.crt b/SOURCES/centossecureboot202.crt deleted file mode 100644 index fba3730..0000000 --- a/SOURCES/centossecureboot202.crt +++ /dev/null @@ -1,84 +0,0 @@ -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 93:c2:04:d8:bd:77:6b:12 - Signature Algorithm: sha256WithRSAEncryption - Issuer: CN=CentOS Secure Boot CA 2/emailAddress=security@centos.org - Validity - Not Before: Jun 9 10:37:54 2020 GMT - Not After : Jan 18 10:37:54 2038 GMT - Subject: CN=CentOS Secure Boot Signing 202/emailAddress=security@centos.org - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:d4:f0:32:4d:50:7a:c0:41:d6:61:68:59:5e:5b: - ce:65:e3:e9:7b:01:e4:53:94:c9:b7:c1:6b:b7:12: - 0b:bc:8f:d7:17:1b:c1:77:3a:08:17:ba:23:f1:bd: - 98:f0:7c:cb:96:70:2e:0e:2e:96:66:b7:9f:29:12: - 6f:ee:30:33:a1:a5:ee:f9:4b:a3:fb:52:45:d8:7e: - c2:e8:a9:20:a9:f2:2e:f4:44:b7:85:3f:34:7c:c0: - 73:1d:73:63:2f:11:a0:7d:df:e7:5a:20:b9:b9:ff: - 5d:0e:6d:90:86:1f:2e:fa:c7:b5:94:37:80:46:0d: - fb:5f:f8:26:f4:ce:2f:0d:5b:bf:e5:8d:a5:12:d7: - ba:cf:16:f2:5c:10:ae:a0:80:a8:dc:c4:6b:00:24: - f4:4b:f0:01:82:7e:4b:1c:b6:d6:ac:e1:72:32:07: - 5d:48:4a:cd:ba:5c:9c:09:72:89:b2:2e:60:f7:b7: - ed:ea:b6:0d:ae:63:f8:09:a1:8f:62:ee:09:d2:cb: - 0a:81:df:7c:72:4b:bf:bd:fb:59:24:84:1f:1d:ce: - 36:bc:4c:13:84:ca:c5:e0:81:bb:ec:61:8f:9f:78: - 88:43:8d:e0:16:b2:ab:90:14:23:29:ce:1d:e7:a1: - bb:4a:93:f9:f8:8d:b8:ff:2f:30:74:66:b2:31:89: - b1:7d - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:FALSE - X509v3 Key Usage: critical - Digital Signature - X509v3 Extended Key Usage: critical - Code Signing - X509v3 Subject Key Identifier: - 1E:55:FF:FF:01:71:5F:F1:28:7F:C8:A9:7C:AF:83:9F:ED:7A:33:0B - X509v3 Authority Key Identifier: - keyid:70:00:7F:99:20:9C:12:6B:E1:47:74:EA:EC:7B:6D:96:31:F3:4D:CA - - Signature Algorithm: sha256WithRSAEncryption - 6b:1b:fa:f3:a8:c0:1e:e7:55:49:f2:4e:16:1f:9a:1b:22:9c: - ff:c9:81:d0:5b:d6:28:3c:38:91:65:b5:ca:63:e6:9d:13:2d: - 5f:f5:cc:67:c2:82:55:73:8f:8b:0c:0c:a9:60:2a:a8:b2:19: - c1:a7:87:94:d8:69:5e:3c:88:e5:32:8a:4c:a6:6f:69:8b:c5: - f2:7e:8e:d2:af:37:2d:27:73:c7:ad:9d:bc:14:08:a8:aa:57: - 22:37:be:c6:d2:2d:a3:70:81:4a:88:8c:a3:44:89:6c:7d:9d: - 9f:db:ff:5c:c6:ec:6d:97:b0:08:8d:76:c6:14:d0:25:81:a3: - 09:b6:f2:89:32:12:b2:f2:71:71:b6:ac:c1:65:d1:9c:6b:e1: - a4:4e:74:d0:01:17:ad:38:0f:17:86:07:56:b3:a1:86:5d:99: - ef:d6:55:98:b9:ce:63:46:8b:37:c4:53:55:8b:7a:10:75:90: - fd:e6:62:f0:6c:af:89:91:17:34:f7:99:77:6d:29:fa:92:bb: - c3:45:77:fe:a3:15:da:54:7d:47:16:b6:6f:94:09:b8:5f:ca: - e9:34:a2:bf:18:cd:d3:f4:17:2c:98:e4:e4:ca:46:ad:4b:a4: - 34:77:47:ec:5d:21:a6:cf:5c:b9:5a:47:ca:04:a1:93:56:13: - 0a:cc:47:91 ------BEGIN CERTIFICATE----- -MIIDjjCCAnagAwIBAgIJAJPCBNi9d2sSMA0GCSqGSIb3DQEBCwUAMEYxIDAeBgNV -BAMMF0NlbnRPUyBTZWN1cmUgQm9vdCBDQSAyMSIwIAYJKoZIhvcNAQkBFhNzZWN1 -cml0eUBjZW50b3Mub3JnMB4XDTIwMDYwOTEwMzc1NFoXDTM4MDExODEwMzc1NFow -TTEnMCUGA1UEAwweQ2VudE9TIFNlY3VyZSBCb290IFNpZ25pbmcgMjAyMSIwIAYJ -KoZIhvcNAQkBFhNzZWN1cml0eUBjZW50b3Mub3JnMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEA1PAyTVB6wEHWYWhZXlvOZePpewHkU5TJt8FrtxILvI/X -FxvBdzoIF7oj8b2Y8HzLlnAuDi6WZrefKRJv7jAzoaXu+Uuj+1JF2H7C6KkgqfIu -9ES3hT80fMBzHXNjLxGgfd/nWiC5uf9dDm2Qhh8u+se1lDeARg37X/gm9M4vDVu/ -5Y2lEte6zxbyXBCuoICo3MRrACT0S/ABgn5LHLbWrOFyMgddSErNulycCXKJsi5g -97ft6rYNrmP4CaGPYu4J0ssKgd98cku/vftZJIQfHc42vEwThMrF4IG77GGPn3iI -Q43gFrKrkBQjKc4d56G7SpP5+I24/y8wdGayMYmxfQIDAQABo3gwdjAMBgNVHRMB -Af8EAjAAMA4GA1UdDwEB/wQEAwIHgDAWBgNVHSUBAf8EDDAKBggrBgEFBQcDAzAd -BgNVHQ4EFgQUHlX//wFxX/Eof8ipfK+Dn+16MwswHwYDVR0jBBgwFoAUcAB/mSCc -EmvhR3Tq7HttljHzTcowDQYJKoZIhvcNAQELBQADggEBAGsb+vOowB7nVUnyThYf -mhsinP/JgdBb1ig8OJFltcpj5p0TLV/1zGfCglVzj4sMDKlgKqiyGcGnh5TYaV48 -iOUyikymb2mLxfJ+jtKvNy0nc8etnbwUCKiqVyI3vsbSLaNwgUqIjKNEiWx9nZ/b -/1zG7G2XsAiNdsYU0CWBowm28okyErLycXG2rMFl0Zxr4aROdNABF604DxeGB1az -oYZdme/WVZi5zmNGizfEU1WLehB1kP3mYvBsr4mRFzT3mXdtKfqSu8NFd/6jFdpU -fUcWtm+UCbhfyuk0or8YzdP0FyyY5OTKRq1LpDR3R+xdIabPXLlaR8oEoZNWEwrM -R5E= ------END CERTIFICATE----- diff --git a/SOURCES/centossecurebootca2.crt b/SOURCES/centossecurebootca2.crt deleted file mode 100644 index ff4e981..0000000 --- a/SOURCES/centossecurebootca2.crt +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDYjCCAkqgAwIBAgIJAIlReu6IOzL7MA0GCSqGSIb3DQEBCwUAMEYxIDAeBgNV -BAMMF0NlbnRPUyBTZWN1cmUgQm9vdCBDQSAyMSIwIAYJKoZIhvcNAQkBFhNzZWN1 -cml0eUBjZW50b3Mub3JnMB4XDTIwMDYwOTA4MTkzMloXDTM4MDExODA4MTkzMlow -RjEgMB4GA1UEAwwXQ2VudE9TIFNlY3VyZSBCb290IENBIDIxIjAgBgkqhkiG9w0B -CQEWE3NlY3VyaXR5QGNlbnRvcy5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQChatbNaQDV0RTCqff1tl92xI6gu1k8jYufW8FyzZ6uDnxoGpBT0LiU -WKuGjMQ89JgiApFzDYSLWrZg8NbTnVdz0hny4SMyspe5weUk6IToKXvEejZNFn6i -vae2vfT0/ASKsgIvUcz4sWHMK43vbfv/pVpYGLgoG5aNUkt7VhkeURwJzR3ODgDp -aL4bQ/7qEo8ASHCEvQx6klG330Z06O0kjS6GK12cPC1t5ZlimVXCNWP1jf0pMWmh -aBrZjbyY0j8R7Yns3cEovAM230chsVdyFxSYpqCLzMlmWNxiIlvcAoDIRMWEa7Da -SSAfJWH+ygAzad1PHlnCB0zAFbLAMJH1AgMBAAGjUzBRMB0GA1UdDgQWBBRwAH+Z -IJwSa+FHdOrse22WMfNNyjAfBgNVHSMEGDAWgBRwAH+ZIJwSa+FHdOrse22WMfNN -yjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAe5NcVSUd/POZs -Jkiep8ATNwXglLAeYxB55F42sXx5OOdKMBmhqWQIVJvaih/wsfKIBfdUGv2L9dH8 -IQgiU1PRYx0baSVJno3HcQTbCqLvnvckusR7IUTDAFj774MvXwS6yV6pXzxDmuh2 -t8hRktOKFeUtdlDYqg9X3Ia3GkoB5huyEbuaZTNcV4TAfU/yAERNIAgRs+fLQU70 -OgGlWsp35J8qPkZKabGf0surDa2xa6iAoFyknxruoKQ8uNSB9KB7/0JvVouNx90+ -ncykWW96GVKs8+H5WGza10FqrchtThSNCSXTtLbTXoK0Atdvu0o04XUbsCGMnlcG -zAVb3/m0 ------END CERTIFICATE----- diff --git a/SOURCES/grub.macros b/SOURCES/grub.macros index a4291b2..0dade27 100644 --- a/SOURCES/grub.macros +++ b/SOURCES/grub.macros @@ -101,6 +101,16 @@ -e 's/-m64//g' \\\ ) %{nil} %endif +%ifarch %{ix86} +%global target_cpu_name %{_arch} +%global grub_target_name %{_arch}-pc + +%global legacy_target_cpu_name i386 +%global legacy_package_arch pc +%global platform pc + +%global with_legacy_arch 0 +%endif %ifarch aarch64 %global efiarch aa64 @@ -152,6 +162,14 @@ %global with_efi_common 1 %global with_legacy_common 0 %endif +%ifarch %{ix86} +%global with_efi_arch 0 +%global with_alt_efi_arch 0 +%global with_efi_common 0 +%global with_legacy_common 1 +%global with_legacy_utils 1 +%global with_legacy_arch 0 +%endif %if 0%{with_efi_common} %global common_srcdir grub-%{grubefiarch}-%{tarversion} @@ -331,7 +349,7 @@ GRUB_MODULES=" all_video boot btrfs cat chain configfile echo \\\ gzio halt hfsplus iso9660 jpeg loadenv loopback \\\ lvm mdraid09 mdraid1x minicmd normal part_apple \\\ part_msdos part_gpt password_pbkdf2 png reboot \\\ - search search_fs_uuid search_fs_file \\\ + regexp search search_fs_uuid search_fs_file \\\ search_label serial sleep syslinuxcfg test tftp \\\ video xfs" \ GRUB_MODULES+=%{efi_modules} \ diff --git a/SOURCES/grub.patches b/SOURCES/grub.patches index 4937bc1..191482a 100644 --- a/SOURCES/grub.patches +++ b/SOURCES/grub.patches @@ -447,3 +447,40 @@ Patch0446: 0446-ieee1275-powerpc-implements-fibre-channel-discovery-.patch Patch0447: 0447-ieee1275-powerpc-enables-device-mapper-discovery.patch Patch0448: 0448-ieee1275-Avoiding-many-unecessary-open-close.patch Patch0449: 0449-ieee1275-ofdisk-retry-on-open-failure.patch +Patch0450: 0450-loader-efi-chainloader-grub_load_and_start_image-doe.patch +Patch0451: 0451-loader-efi-chainloader-simplify-the-loader-state.patch +Patch0452: 0452-commands-boot-Add-API-to-pass-context-to-loader.patch +Patch0453: 0453-loader-efi-chainloader-Use-grub_loader_set_ex.patch +Patch0454: 0454-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch +Patch0455: 0455-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch +Patch0456: 0456-video-readers-png-Abort-sooner-if-a-read-operation-f.patch +Patch0457: 0457-video-readers-png-Refuse-to-handle-multiple-image-he.patch +Patch0458: 0458-png-Optimize-by-avoiding-divisions.patch +Patch0459: 0459-video-readers-png-Drop-greyscale-support-to-fix-heap.patch +Patch0460: 0460-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch +Patch0461: 0461-video-readers-png-Sanity-check-some-huffman-codes.patch +Patch0462: 0462-grub-core-video-readers-jpeg.c-Avoid-division-by-zer.patch +Patch0463: 0463-jpeg-Optimise-by-replacing-division-with-shifts.patch +Patch0464: 0464-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch +Patch0465: 0465-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch +Patch0466: 0466-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch +Patch0467: 0467-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch +Patch0468: 0468-normal-charset-Fix-array-out-of-bounds-formatting-un.patch +Patch0469: 0469-net-netbuff-Block-overly-large-netbuff-allocs.patch +Patch0470: 0470-net-ip-Do-IP-fragment-maths-safely.patch +Patch0471: 0471-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch +Patch0472: 0472-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch +Patch0473: 0473-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch +Patch0474: 0474-misc-Format-string-for-grub_error-should-be-a-litera.patch +Patch0475: 0475-net-tftp-Avoid-a-trivial-UAF.patch +Patch0476: 0476-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch +Patch0477: 0477-net-http-Fix-OOB-write-for-split-http-headers.patch +Patch0478: 0478-net-http-Error-out-on-headers-with-LF-without-CR.patch +Patch0479: 0479-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch +Patch0480: 0480-grub-core-fs-btrfs.c-Avoid-divisions-by-zero.patch +Patch0481: 0481-btrfs-Add-support-for-reading-a-filesystem-with-a-RA.patch +Patch0482: 0482-btrfs-Add-support-for-new-RAID1C34-profiles.patch +Patch0483: 0483-btrfs-Move-logging-code-in-grub_btrfs_read_logical.patch +Patch0484: 0484-btrfs-Move-the-error-logging-from-find_device-to-its.patch +Patch0485: 0485-fs-btrfs-Fix-more-ASAN-and-SEGV-issues-found-with-fu.patch +Patch0486: 0486-fs-btrfs-Fix-more-fuzz-issues-related-to-chunks.patch diff --git a/SOURCES/sbat.csv.in b/SOURCES/sbat.csv.in index 33d1d27..fdc0e9f 100755 --- a/SOURCES/sbat.csv.in +++ b/SOURCES/sbat.csv.in @@ -1,3 +1,3 @@ sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md -grub,1,Free Software Foundation,grub,2.02,https://www.gnu.org/software/grub/ -grub.rhel7,1,Red Hat Enterprise Linux 7,grub2,@@VERSION@@,mail:secalert@redhat.com +grub,2,Free Software Foundation,grub,2.02,https://www.gnu.org/software/grub/ +grub.rhel7,2,Red Hat Enterprise Linux 7,grub2,@@VERSION@@,mail:secalert@redhat.com diff --git a/SPECS/grub2.spec b/SPECS/grub2.spec index a98f8c3..6f30f20 100644 --- a/SPECS/grub2.spec +++ b/SPECS/grub2.spec @@ -1,22 +1,12 @@ %undefine _hardened_build -%global flagday 1:2.02-0.87.el7.centos.2 + %global tarversion 2.02~beta2 %undefine _missing_build_ids_terminate_build -%ifarch i686 -%define platform pc -%define legacy_package_arch i386 -%define legacy_target_cpu_name i386 -%define target_cpu_name i386 -%endif -%ifarch x86_64 -%define mock 1 -%endif - Name: grub2 Epoch: 1 Version: 2.02 -Release: 0.87.0.1%{?dist}%{?buildid}.9 +Release: 0.87%{?dist}%{?buildid}.11 Summary: Bootloader with support for Linux, Multiboot and more Group: System Environment/Base License: GPLv3+ @@ -27,10 +17,10 @@ Source1: grub.macros Source2: grub.patches Source3: http://unifoundry.com/unifont-5.1.20080820.pcf.gz Source4: gitignore -Source5: centos-ca-secureboot.der -Source6: centossecureboot001.crt -Source7: centossecurebootca2.crt -Source8: centossecureboot202.crt +Source5: redhatsecurebootca3.cer +Source6: redhatsecureboot301.cer +Source7: redhatsecurebootca5.cer +Source8: redhatsecureboot502.cer Source9: sbat.csv.in %include %{SOURCE1} @@ -64,11 +54,8 @@ BuildRequires: pesign >= 0.99-8 %if %{?_with_ccache: 1}%{?!_with_ccache: 0} BuildRequires: ccache %endif -%if 0%{?centos} -%global efidir centos -%endif -ExcludeArch: s390 s390x %{arm} +ExcludeArch: s390 s390x %{arm} %{?ix86} Obsoletes: %{name} <= %{flagday} %if 0%{with_legacy_arch} @@ -153,10 +140,6 @@ This subpackage provides tools for support of all platforms. %prep %setup -T -c -n grub-%{tarversion} %do_common_setup -sed -i.orig -e 's@/efi/EFI/redhat/@/efi/EFI/%{efidir}/@' \ - grub-%{tarversion}/util/grub-setpassword.in -touch --reference=grub-%{tarversion}/util/grub-setpassword.in.orig \ - grub-%{tarversion}/util/grub-setpassword.in %if 0%{with_efi_arch} %do_setup %{grubefiarch} sed -e "s,@@VERSION@@,%{evr},g" %{SOURCE9} \ @@ -171,10 +154,10 @@ sed -e "s,@@VERSION@@,%{evr},g" %{SOURCE9} \ %build %if 0%{with_efi_arch} -%do_primary_efi_build %{grubefiarch} %{grubefiname} %{grubeficdname} %{_target_platform} "'%{efi_cflags}'" %{SOURCE5} %{SOURCE6} centossecureboot001 %{SOURCE7} %{SOURCE8} centossecureboot202 +%do_primary_efi_build %{grubefiarch} %{grubefiname} %{grubeficdname} %{_target_platform} "'%{efi_cflags}'" %{SOURCE5} %{SOURCE6} redhatsecureboot301 %{SOURCE7} %{SOURCE8} redhatsecureboot502 %endif %if 0%{with_alt_efi_arch} -%do_alt_efi_build %{grubaltefiarch} %{grubaltefiname} %{grubalteficdname} %{_alt_target_platform} "'%{alt_efi_cflags}'" %{SOURCE5} %{SOURCE6} centossecureboot001 %{SOURCE7} %{SOURCE8} centossecureboot202 +%do_alt_efi_build %{grubaltefiarch} %{grubaltefiname} %{grubalteficdname} %{_alt_target_platform} "'%{alt_efi_cflags}'" %{SOURCE5} %{SOURCE6} redhatsecureboot301 %{SOURCE7} %{SOURCE8} redhatsecureboot502 %endif %if 0%{with_legacy_arch}%{with_legacy_utils} %do_legacy_build %{grublegacyarch} @@ -486,35 +469,43 @@ fi %endif %changelog -* Tue Mar 29 2022 Robbie Harwood - 2.02-087.e7.9 +* Wed Nov 16 2022 Robbie Harwood - 2.02-087.el7.11 +- Bump sbat +- Resolves: CVE-2022-28733 + +* Thu Sep 15 2022 Robbie Harwood - 2.02-087.el7.10 +- Backport the relevant CVE fixes from the 2022-05-24 drop +- Resolves: CVE-2022-28733 + +* Tue Mar 29 2022 Robbie Harwood - 2.02-087.el7.9 - Bump for signing - Resolves: #1892860 -* Wed Mar 09 2022 Robbie Harwood - 2.02-0.87.e7.8 +* Wed Mar 09 2022 Robbie Harwood - 2.02-0.87.el7.8 - Fix accidental reboot in grub_exit - Resolves: #1892860 -* Mon May 17 2021 Javier Martinez Canillas - 2.02-0.87.e7.7 +* Mon May 17 2021 Javier Martinez Canillas - 2.02-0.87.el7.7 - Fix boot failures in ppc64le caused by storage race condition (diegodo) Resolves: rhbz#1942148 -* Fri Mar 05 2021 Javier Martinez Canillas - 2.02-0.87.e7.6 +* Fri Mar 05 2021 Javier Martinez Canillas - 2.02-0.87.el7.6 - Fix ppc64le performance issues (diegodo) Resolves: rhbz#1759298 -* Thu Mar 04 2021 Javier Martinez Canillas - 2.02-0.87.e7.5 +* Thu Mar 04 2021 Javier Martinez Canillas - 2.02-0.87.el7.5 - Add the at keyboard patches that weren't included Resolves: rhbz#1892240 -* Thu Mar 04 2021 Javier Martinez Canillas - 2.02-0.87.e7.4 +* Thu Mar 04 2021 Javier Martinez Canillas - 2.02-0.87.el7.4 - add keylayouts and at_keyboard modules to EFI binary Resolves: rhbz#1892240 -* Wed Mar 03 2021 Javier Martinez Canillas - 2.02-0.87.e7.3 +* Wed Mar 03 2021 Javier Martinez Canillas - 2.02-0.87.el7.3 - at_keyboard: use set 1 when keyboard is in Translate mode (rmetrich) Resolves: rhbz#1892240 -* Fri Feb 26 2021 Javier Martinez Canillas - 2.02-0.87.e7.2 +* Fri Feb 26 2021 Javier Martinez Canillas - 2.02-0.87.el7.2 - Fix another batch of CVEs Resolves: CVE-2020-14372 Resolves: CVE-2020-25632