From 93d66514d745e9a8db6d3a978ccac0b42447ad30 Mon Sep 17 00:00:00 2001 From: c30030848 Date: Wed, 22 Jun 2022 19:04:04 +0800 Subject: [PATCH] fix CVE-2021-3697 CVE-2022-28735 CVE-2022-28736 CVE-2022-28734 CVE-2022-28733 CVE-2021-3695 CVE-2021-3696 --- ...ckdown-instead-of-hardcoding-a-dis-2.patch | 64 ++++ ...-Wsign-compare-in-rijndael-do_setkey.patch | 43 +++ backport-Fix-partmap_test-for-arm-efi.patch | 35 ++ ...ot-Add-API-to-pass-context-to-loader.patch | 161 +++++++++ ...port-correct-closing-of-SNP-protocol.patch | 112 ++++++ ...odisk-Fix-potential-integer-overflow.patch | 55 +++ backport-disk-ldm-Fix-resource-leak.patch | 38 ++ ...tree-must-be-in-EfiACPIReclaimMemory.patch | 45 +++ backport-enable-http-and-https-boot.patch | 92 +++++ backport-fix-CVE-2020-15705.patch | 122 +++++++ ...fix-misspelled-variable-BUILD_LDFAGS.patch | 30 ++ ...en-a-symlink-filesize-is-equal-to-60.patch | 52 +++ ...rd-prompts-to-enter-the-current-pass.patch | 305 ++++++++++++++++ ...uninitialized-variable-in-huft_build.patch | 35 ++ ...e-unnecessary-self-assignment-errors.patch | 43 +++ ...-Do-not-leak-device_name-on-error-in.patch | 43 +++ ...hainloader-Simplify-the-loader-state.patch | 337 ++++++++++++++++++ ...i-chainloader-Use-grub_loader_set_ex.patch | 153 ++++++++ ...loader-grub_load_and_start_image-doe.patch | 75 ++++ ...linux-Avoid-a-use-after-free-in-the-.patch | 44 +++ ...linux-Fix-a-memory-leak-in-the-initr.patch | 81 +++++ ...386-efi-linux-Use-grub_loader_set_ex.patch | 301 ++++++++++++++++ ...le_to_cpu32-for-relocatable-variable.patch | 36 ++ ...Dont-read-past-the-end-of-the-string.patch | 75 ++++ ...double-free-addresses-on-corrupt-DNS.patch | 61 ++++ ...-not-tear-down-socket-if-its-already.patch | 46 +++ ...or-out-on-headers-with-LF-without-CR.patch | 53 +++ ...Fix-OOB-write-for-split-http-headers.patch | 51 +++ ...t-net-ip-Do-IP-fragment-maths-safely.patch | 57 +++ ...ff-Block-overly-large-netbuff-allocs.patch | 58 +++ backport-net-tftp-Avoid-a-trivial-UAF.patch | 40 +++ ...p-Prevent-a-UAF-and-double-free-from.patch | 117 ++++++ ...t-Fix-array-out-of-bounds-formatting.patch | 39 ++ ...inux-Fix-md-array-device-enumeration.patch | 91 +++++ backport-support-TPM2.0.patch | 99 +++++ backport-use-default-timestamp.patch | 60 ++++ ...fstest-Fix-resource-leaks-in-cmd_cmp.patch | 45 +++ ...l-common-Fix-memory-leak-in-copy_all.patch | 38 ++ ...nt-Fix-memory-leak-in-write_font_pf2.patch | 35 ++ ...rescue-Fix-memory-leak-in-write_part.patch | 34 ++ ...g-PE32-section-sizes-for-some-arches.patch | 50 +++ ...-readers-jpeg-Abort-sooner-if-a-read.patch | 260 ++++++++++++++ ...eg-Block-int-underflow-wild-pointer-.patch | 79 ++++ ...aders-jpeg-Do-not-reallocate-a-given.patch | 34 ++ ...aders-jpeg-Refuse-to-handle-multiple.patch | 48 +++ ...o-readers-png-Abort-sooner-if-a-read.patch | 203 +++++++++++ ...g-Avoid-heap-OOB-R-W-inserting-huff-.patch | 44 +++ ...g-Drop-greyscale-support-to-fix-heap.patch | 174 +++++++++ ...use-to-handle-multiple-image-headers.patch | 33 ++ ...-png-Sanity-check-some-huffman-codes.patch | 45 +++ bugfix-double-grub-x86_64-efi-mm-pool.patch | 44 +++ ...nter-dereference-when-parsing-ICMP6_.patch | 34 ++ grub.patches | 52 +++ grub2.spec | 9 +- 54 files changed, 4409 insertions(+), 1 deletion(-) create mode 100644 backport-0081-efi-Use-grub_is_lockdown-instead-of-hardcoding-a-dis-2.patch create mode 100644 backport-Avoid-Wsign-compare-in-rijndael-do_setkey.patch create mode 100644 backport-Fix-partmap_test-for-arm-efi.patch create mode 100644 backport-commands-boot-Add-API-to-pass-context-to-loader.patch create mode 100644 backport-correct-closing-of-SNP-protocol.patch create mode 100644 backport-disk-cryptodisk-Fix-potential-integer-overflow.patch create mode 100644 backport-disk-ldm-Fix-resource-leak.patch create mode 100644 backport-efi-The-device-tree-must-be-in-EfiACPIReclaimMemory.patch create mode 100644 backport-enable-http-and-https-boot.patch create mode 100644 backport-fix-CVE-2020-15705.patch create mode 100644 backport-fix-misspelled-variable-BUILD_LDFAGS.patch create mode 100644 backport-fs-ext2-Fix-a-file-not-found-error-when-a-symlink-filesize-is-equal-to-60.patch create mode 100644 backport-grub2-set-password-prompts-to-enter-the-current-pass.patch create mode 100644 backport-io-gzio-Fix-possible-use-of-uninitialized-variable-in-huft_build.patch create mode 100644 backport-io-lzopio-Resolve-unnecessary-self-assignment-errors.patch create mode 100644 backport-kern-file-Do-not-leak-device_name-on-error-in.patch create mode 100644 backport-loader-efi-chainloader-Simplify-the-loader-state.patch create mode 100644 backport-loader-efi-chainloader-Use-grub_loader_set_ex.patch create mode 100644 backport-loader-efi-chainloader-grub_load_and_start_image-doe.patch create mode 100644 backport-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch create mode 100644 backport-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch create mode 100644 backport-loader-i386-efi-linux-Use-grub_loader_set_ex.patch create mode 100644 backport-loader-i386-linux-Do-not-use-grub_le_to_cpu32-for-relocatable-variable.patch create mode 100644 backport-net-dns-Dont-read-past-the-end-of-the-string.patch create mode 100644 backport-net-dns-Fix-double-free-addresses-on-corrupt-DNS.patch create mode 100644 backport-net-http-Do-not-tear-down-socket-if-its-already.patch create mode 100644 backport-net-http-Error-out-on-headers-with-LF-without-CR.patch create mode 100644 backport-net-http-Fix-OOB-write-for-split-http-headers.patch create mode 100644 backport-net-ip-Do-IP-fragment-maths-safely.patch create mode 100644 backport-net-netbuff-Block-overly-large-netbuff-allocs.patch create mode 100644 backport-net-tftp-Avoid-a-trivial-UAF.patch create mode 100644 backport-net-tftp-Prevent-a-UAF-and-double-free-from.patch create mode 100644 backport-normal-charset-Fix-array-out-of-bounds-formatting.patch create mode 100644 backport-osdep-linux-Fix-md-array-device-enumeration.patch create mode 100644 backport-support-TPM2.0.patch create mode 100644 backport-use-default-timestamp.patch create mode 100644 backport-util-grub-fstest-Fix-resource-leaks-in-cmd_cmp.patch create mode 100644 backport-util-grub-install-common-Fix-memory-leak-in-copy_all.patch create mode 100644 backport-util-grub-mkfont-Fix-memory-leak-in-write_font_pf2.patch create mode 100644 backport-util-grub-mkrescue-Fix-memory-leak-in-write_part.patch create mode 100644 backport-util-mkimage-Fix-wrong-PE32-section-sizes-for-some-arches.patch create mode 100644 backport-video-readers-jpeg-Abort-sooner-if-a-read.patch create mode 100644 backport-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch create mode 100644 backport-video-readers-jpeg-Do-not-reallocate-a-given.patch create mode 100644 backport-video-readers-jpeg-Refuse-to-handle-multiple.patch create mode 100644 backport-video-readers-png-Abort-sooner-if-a-read.patch create mode 100644 backport-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch create mode 100644 backport-video-readers-png-Drop-greyscale-support-to-fix-heap.patch create mode 100644 backport-video-readers-png-Refuse-to-handle-multiple-image-headers.patch create mode 100644 backport-video-readers-png-Sanity-check-some-huffman-codes.patch create mode 100644 bugfix-double-grub-x86_64-efi-mm-pool.patch create mode 100644 bugfix-net-fix-null-pointer-dereference-when-parsing-ICMP6_.patch diff --git a/backport-0081-efi-Use-grub_is_lockdown-instead-of-hardcoding-a-dis-2.patch b/backport-0081-efi-Use-grub_is_lockdown-instead-of-hardcoding-a-dis-2.patch new file mode 100644 index 0000000..dab462c --- /dev/null +++ b/backport-0081-efi-Use-grub_is_lockdown-instead-of-hardcoding-a-dis-2.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Mon, 28 Sep 2020 20:08:33 +0200 +Subject: [PATCH] efi: Use grub_is_lockdown() instead of hardcoding a disabled + modules list + +Conflict: NA +Reference: https://vault.centos.org/7.9.2009/updates/Source/SPackages/grub2-2.02-0.87.el7.centos.2.src.rpm +--- + grub-core/commands/iorw.c | 6 ------ + grub-core/commands/memrw.c | 6 ------ + 2 files changed, 12 deletions(-) + +diff --git a/grub-core/commands/iorw.c b/grub-core/commands/iorw.c +index dd79d7c..effefaf 100644 +--- a/grub-core/commands/iorw.c ++++ b/grub-core/commands/iorw.c +@@ -120,9 +120,6 @@ grub_cmd_write (grub_command_t cmd, int argc, char **argv) + + GRUB_MOD_INIT(memrw) + { +- if (grub_efi_secure_boot()) +- return; +- + cmd_read_byte = + grub_register_extcmd ("inb", grub_cmd_read, 0, + N_("PORT"), N_("Read 8-bit value from PORT."), +@@ -151,9 +148,6 @@ GRUB_MOD_INIT(memrw) + + GRUB_MOD_FINI(memrw) + { +- if (grub_efi_secure_boot()) +- return; +- + grub_unregister_extcmd (cmd_read_byte); + grub_unregister_extcmd (cmd_read_word); + grub_unregister_extcmd (cmd_read_dword); +diff --git a/grub-core/commands/memrw.c b/grub-core/commands/memrw.c +index 0fdd787..da9f1f3 100644 +--- a/grub-core/commands/memrw.c ++++ b/grub-core/commands/memrw.c +@@ -122,9 +122,6 @@ grub_cmd_write (grub_command_t cmd, int argc, char **argv) + + GRUB_MOD_INIT(memrw) + { +- if (grub_efi_secure_boot()) +- return; +- + cmd_read_byte = + grub_register_extcmd ("read_byte", grub_cmd_read, 0, + N_("ADDR"), N_("Read 8-bit value from ADDR."), +@@ -153,9 +150,6 @@ GRUB_MOD_INIT(memrw) + + GRUB_MOD_FINI(memrw) + { +- if (grub_efi_secure_boot()) +- return; +- + grub_unregister_extcmd (cmd_read_byte); + grub_unregister_extcmd (cmd_read_word); + grub_unregister_extcmd (cmd_read_dword); +-- +2.23.0 + diff --git a/backport-Avoid-Wsign-compare-in-rijndael-do_setkey.patch b/backport-Avoid-Wsign-compare-in-rijndael-do_setkey.patch new file mode 100644 index 0000000..fc3b46f --- /dev/null +++ b/backport-Avoid-Wsign-compare-in-rijndael-do_setkey.patch @@ -0,0 +1,43 @@ +From 0cb7a4491684648a819022a4e71820bbaf114734 Mon Sep 17 00:00:00 2001 +From: Heinrich Schuchardt +Date: Fri, 13 Aug 2021 16:15:33 +0200 +Subject: libgcrypt: Avoid -Wsign-compare in rijndael do_setkey() + +Conflict:NA +Reference:https://git.savannah.gnu.org/cgit/grub.git/patch/?id=0cb7a4491684648a819022a4e71820bbaf114734 + +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Avoid a warning + + lib/libgcrypt-grub/cipher/rijndael.c:352:21: warning: + comparison of integer expressions of different signedness: + ‘int’ and ‘unsigned int’ [-Wsign-compare] + 352 | for (i = 0; i < keylen; i++) + | + +Signed-off-by: Heinrich Schuchardt +Reviewed-by: Daniel Kiper +--- + grub-core/lib/libgcrypt/cipher/rijndael.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/grub-core/lib/libgcrypt/cipher/rijndael.c b/grub-core/lib/libgcrypt/cipher/rijndael.c +index 559550b50..38e9a7c08 100644 +--- a/grub-core/lib/libgcrypt/cipher/rijndael.c ++++ b/grub-core/lib/libgcrypt/cipher/rijndael.c +@@ -181,7 +181,8 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) + static int initialized = 0; + static const char *selftest_failed=0; + int rounds; +- int i,j, r, t, rconpointer = 0; ++ unsigned int i; ++ int j, r, t, rconpointer = 0; + int KC; + union + { +-- +cgit v1.2.1 + diff --git a/backport-Fix-partmap_test-for-arm-efi.patch b/backport-Fix-partmap_test-for-arm-efi.patch new file mode 100644 index 0000000..bd8d77a --- /dev/null +++ b/backport-Fix-partmap_test-for-arm-efi.patch @@ -0,0 +1,35 @@ +From 57a393ca59b3358aec61af10edbc79d8c366e5e4 Mon Sep 17 00:00:00 2001 +From: Glenn Washburn +Date: Tue, 12 Oct 2021 19:39:55 -0500 +Subject: tests: Fix partmap_test for arm*-efi, disk numbering has changed + +Perhaps using a newer UEFI firmware is the reason for the created test disk +showing up as hd2 instead of hd3. + +Conflict:NA +Reference:http://git.savannah.gnu.org/cgit/grub.git/patch/tests/partmap_test.in?id=57a393ca59b3358aec61af10edbc79d8c366e5e4 + +Signed-off-by: Glenn Washburn +Reviewed-by: Daniel Kiper +--- + tests/partmap_test.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +(limited to 'tests/partmap_test.in') + +diff --git a/tests/partmap_test.in b/tests/partmap_test.in +index 6ef518b..7353dc7 100644 +--- a/tests/partmap_test.in ++++ b/tests/partmap_test.in +@@ -89,7 +89,7 @@ case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in + disk=arc/scsi0/disk0/rdisk0 + ;; + arm*-efi) +- disk=hd3 ++ disk=hd2 + ;; + *) + disk=hd0 +-- +cgit v1.1 + diff --git a/backport-commands-boot-Add-API-to-pass-context-to-loader.patch b/backport-commands-boot-Add-API-to-pass-context-to-loader.patch new file mode 100644 index 0000000..e1e96a7 --- /dev/null +++ b/backport-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. + +Reference:https://src.fedoraproject.org/rpms/grub2/c/f0ad2aaa267a5d99b47f5c5770a55de0a702fdf0?branch=rawhide +Conflict:NA + +Signed-off-by: Chris Coulson +(cherry picked from commit 4322a64dde7e8fedb58e50b79408667129d45dd3) +--- + 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/backport-correct-closing-of-SNP-protocol.patch b/backport-correct-closing-of-SNP-protocol.patch new file mode 100644 index 0000000..485c745 --- /dev/null +++ b/backport-correct-closing-of-SNP-protocol.patch @@ -0,0 +1,112 @@ +From efd9406e12df2b66e6704bad0ce3225aa3051c0e Mon Sep 17 00:00:00 2001 +From: Heinrich Schuchardt +Date: Mon, 29 Nov 2021 16:00:28 +0100 +Subject: efinet: Correct closing of SNP protocol + +Conflict:NA +Reference:https://git.savannah.gnu.org/cgit/grub.git/patch/?id=efd9406e12df2b66e6704bad0ce3225aa3051c0e + +In the context of the implementation of the EFI_LOAD_FILE2_PROTOCOL for +the initial ramdisk it was observed that opening the SNP protocol failed. +https://lists.gnu.org/archive/html/grub-devel/2021-10/msg00020.html +This is due to an incorrect call to CloseProtocol(). + +The first parameter of CloseProtocol() is the handle, not the interface. + +We call OpenProtocol() with ControllerHandle == NULL. Hence we must also +call CloseProtcol() with ControllerHandel == NULL. + +Each call of OpenProtocol() for the same network card handle is expected to +return the same interface pointer. If we want to close the protocol which +we opened non-exclusively when searching for a card, we have to do this +before opening the protocol exclusively. + +As there is no guarantee that we successfully open the protocol add checks +in the transmit and receive functions. + +Reported-by: Andreas Schwab +Signed-off-by: Heinrich Schuchardt +Reviewed-by: Daniel Kiper +--- + grub-core/net/drivers/efi/efinet.c | 31 ++++++++++++++++++++++--------- + 1 file changed, 22 insertions(+), 9 deletions(-) + +diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c +index 5388f95..2c81fd0 100644 +--- a/grub-core/net/drivers/efi/efinet.c ++++ b/grub-core/net/drivers/efi/efinet.c +@@ -39,6 +39,9 @@ send_card_buffer (struct grub_net_card *dev, + grub_uint64_t limit_time = grub_get_time_ms () + 4000; + void *txbuf; + ++ if (net == NULL) ++ return grub_error (GRUB_ERR_IO, ++ N_("network protocol not available, can't send packet")); + if (dev->txbusy) + while (1) + { +@@ -101,6 +104,9 @@ get_card_packet (struct grub_net_card *dev) + struct grub_net_buff *nb; + int i; + ++ if (net == NULL) ++ return NULL; ++ + for (i = 0; i < 2; i++) + { + if (!dev->rcvbuf) +@@ -148,12 +154,20 @@ open_card (struct grub_net_card *dev) + { + grub_efi_simple_network_t *net; + +- /* Try to reopen SNP exlusively to close any active MNP protocol instance +- that may compete for packet polling ++ if (dev->efi_net != NULL) ++ { ++ efi_call_4 (grub_efi_system_table->boot_services->close_protocol, ++ dev->efi_handle, &net_io_guid, ++ grub_efi_image_handle, NULL); ++ dev->efi_net = NULL; ++ } ++ /* ++ * Try to reopen SNP exlusively to close any active MNP protocol instance ++ * that may compete for packet polling. + */ + net = grub_efi_open_protocol (dev->efi_handle, &net_io_guid, + GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE); +- if (net) ++ if (net != NULL) + { + if (net->mode->state == GRUB_EFI_NETWORK_STOPPED + && efi_call_1 (net->start, net) != GRUB_EFI_SUCCESS) +@@ -192,13 +206,12 @@ open_card (struct grub_net_card *dev) + efi_call_6 (net->receive_filters, net, filters, 0, 0, 0, NULL); + } + +- efi_call_4 (grub_efi_system_table->boot_services->close_protocol, +- dev->efi_net, &net_io_guid, +- grub_efi_image_handle, dev->efi_handle); + dev->efi_net = net; ++ } else { ++ return grub_error (GRUB_ERR_NET_NO_CARD, "%s: can't open protocol", ++ dev->name); + } + +- /* If it failed we just try to run as best as we can */ + return GRUB_ERR_NONE; + } + +@@ -208,8 +221,8 @@ close_card (struct grub_net_card *dev) + efi_call_1 (dev->efi_net->shutdown, dev->efi_net); + efi_call_1 (dev->efi_net->stop, dev->efi_net); + efi_call_4 (grub_efi_system_table->boot_services->close_protocol, +- dev->efi_net, &net_io_guid, +- grub_efi_image_handle, dev->efi_handle); ++ dev->efi_handle, &net_io_guid, ++ grub_efi_image_handle, 0); + } + + static struct grub_net_card_driver efidriver = +-- +cgit v1.1 + diff --git a/backport-disk-cryptodisk-Fix-potential-integer-overflow.patch b/backport-disk-cryptodisk-Fix-potential-integer-overflow.patch new file mode 100644 index 0000000..438ab22 --- /dev/null +++ b/backport-disk-cryptodisk-Fix-potential-integer-overflow.patch @@ -0,0 +1,55 @@ +From a201ad17caa430aa710654fdf2e6ab4c8166f031 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Thu, 21 Jan 2021 11:38:31 +0000 +Subject: disk/cryptodisk: Fix potential integer overflow + +The encrypt and decrypt functions expect a grub_size_t. So, we need to +ensure that the constant bit shift is using grub_size_t rather than +unsigned int when it is performing the shift. + +Fixes: CID 307788 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper + +Conflict:(1U << log_sector_size), iv) -> (1U << dev->log_sector_size), iv) + ((grub_size_t) 1 << log_sector_size), iv) -> ((grub_size_t) 1 << dev->log_sector_size), iv); +Reference:https://git.savannah.gnu.org/cgit/grub.git/patch/?id=a201ad17caa430aa710654fdf2e6ab4c8166f031 + +--- + grub-core/disk/cryptodisk.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index b62835acc..41866c62d 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -325,10 +325,10 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev, + case GRUB_CRYPTODISK_MODE_CBC: + if (do_encrypt) + err = grub_crypto_cbc_encrypt (dev->cipher, data + i, data + i, +- (1U << dev->log_sector_size), iv); ++ ((grub_size_t) 1 << dev->log_sector_size), iv); + else + err = grub_crypto_cbc_decrypt (dev->cipher, data + i, data + i, +- (1U << dev->log_sector_size), iv); ++ ((grub_size_t) 1 << dev->log_sector_size), iv); + if (err) + return err; + break; +@@ -336,10 +336,10 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev, + case GRUB_CRYPTODISK_MODE_PCBC: + if (do_encrypt) + err = grub_crypto_pcbc_encrypt (dev->cipher, data + i, data + i, +- (1U << dev->log_sector_size), iv); ++ ((grub_size_t) 1 << dev->log_sector_size), iv); + else + err = grub_crypto_pcbc_decrypt (dev->cipher, data + i, data + i, +- (1U << dev->log_sector_size), iv); ++ ((grub_size_t) 1 << dev->log_sector_size), iv); + if (err) + return err; + break; +-- +cgit v1.2.1 + diff --git a/backport-disk-ldm-Fix-resource-leak.patch b/backport-disk-ldm-Fix-resource-leak.patch new file mode 100644 index 0000000..e5b7c16 --- /dev/null +++ b/backport-disk-ldm-Fix-resource-leak.patch @@ -0,0 +1,38 @@ +From 971dd6599d838ed21f38f7261c7bdda59f9bbdae Mon Sep 17 00:00:00 2001 +From: Alec Brown +Date: Wed, 10 Nov 2021 15:49:29 -0500 +Subject: disk/ldm: Fix resource leak + +Commit 23e39f50ca7a (disk/ldm: Make sure comp data is freed before exiting from +make_vg()) fixed several spots in make_vg() where comp data was leaking memory +when an error was being handled but missed one. To avoid leaking memory, comp +should be freed when an error is being handled after comp has been successfully +allocated memory in the for loop. + +Fixes: 23e39f50ca7a (disk/ldm: Make sure comp data is freed before exiting from make_vg()) +Fixes: CID 73804 + +Conflict: NA +Reference: https://git.savannah.gnu.org/cgit/grub.git/commit?id=971dd6599d838ed21f38f7261c7bdda59f9bbdae + +Signed-off-by: Alec Brown +Reviewed-by: Daniel Kiper +--- + grub-core/disk/ldm.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c +index 4577a51..337abf7 100644 +--- a/grub-core/disk/ldm.c ++++ b/grub-core/disk/ldm.c +@@ -487,6 +487,7 @@ make_vg (grub_disk_t disk, + ptr = vblk[i].dynamic; + if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) + { ++ grub_free (comp); + goto fail2; + } + comp->internal_id = grub_malloc ((grub_size_t) ptr[0] + 2); +-- +cgit v1.1 + diff --git a/backport-efi-The-device-tree-must-be-in-EfiACPIReclaimMemory.patch b/backport-efi-The-device-tree-must-be-in-EfiACPIReclaimMemory.patch new file mode 100644 index 0000000..7c36677 --- /dev/null +++ b/backport-efi-The-device-tree-must-be-in-EfiACPIReclaimMemory.patch @@ -0,0 +1,45 @@ +From 30858eb59aff0e77b35dd5847375aab5cc3a8782 Mon Sep 17 00:00:00 2001 +From: Heinrich Schuchardt +Date: Fri, 29 Jan 2021 16:32:29 +0100 +Subject: efi: The device-tree must be in EfiACPIReclaimMemory + +According to the Embedded Base Boot Requirements (EBBR) specification the +device-tree passed to Linux as a configuration table must reside in +EfiACPIReclaimMemory. + +Signed-off-by: Heinrich Schuchardt +Reviewed-by: Daniel Kiper +Conflict: static void *loaded_fdt; -> GRUB_MOD_LICENSE ("GPLv3+"); +Reference:https://git.savannah.gnu.org/cgit/grub.git/patch/?id=30858eb59aff0e77b35dd5847375aab5cc3a8782 + +--- + grub-core/loader/efi/fdt.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c +index 003d07cd8..c86f283d7 100644 +--- a/grub-core/loader/efi/fdt.c ++++ b/grub-core/loader/efi/fdt.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -60,7 +61,10 @@ grub_fdt_load (grub_size_t additional_size) + size += additional_size; + + grub_dprintf ("linux", "allocating %d bytes for fdt\n", size); +- fdt = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (size)); ++ fdt = grub_efi_allocate_pages_real (GRUB_EFI_MAX_USABLE_ADDRESS, ++ GRUB_EFI_BYTES_TO_PAGES (size), ++ GRUB_EFI_ALLOCATE_MAX_ADDRESS, ++ GRUB_EFI_ACPI_RECLAIM_MEMORY); + if (!fdt) + return NULL; + +-- +cgit v1.2.1 + diff --git a/backport-enable-http-and-https-boot.patch b/backport-enable-http-and-https-boot.patch new file mode 100644 index 0000000..6b4c912 --- /dev/null +++ b/backport-enable-http-and-https-boot.patch @@ -0,0 +1,92 @@ +From 354c1679b70fd7f1773ab9bb3fffc7261be42e6b Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Wed, 22 Feb 2017 14:27:50 +0800 +Subject: [PATCH] enable http and https boot + +The patch adapts to the open source code for log printing. + +V1: + * Add preliminary support of UEFI networking protocols + * Support UEFI HTTPS Boot + +V2: + * Workaround http data access in firmware + * Fix DNS device path parsing for efinet device + * Relaxed UEFI Protocol requirement + * Support Intel OPA (Omni-Path Architecture) PXE Boot + +V3: + * Fix bufio in calculating address of next_buf + * Check HTTP respond code + * Use HEAD request method to test before GET + * Finish HTTP transaction in one go + * Fix bsc#1076132 + +Reference:https://src.fedoraproject.org/rpms/grub2/blob/f35/f/0095-Support-UEFI-networking-protocols.patch +Conflict:NA + +Signed-off-by: Michael Chang +[pjones: make efi_netfs not duplicate symbols from efinet] +Signed-off-by: Peter Jones +--- + grub-core/net/efi/http.c | 2 ++ + grub-core/net/efi/net.c | 5 +++++ + include/grub/efi/http.h | 4 ++-- + 3 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c +index fc8cb25..5dfe165 100644 +--- a/grub-core/net/efi/http.c ++++ b/grub-core/net/efi/http.c +@@ -187,6 +187,8 @@ efihttp_request (grub_efi_http_t *http, char *server, char *name, int use_https, + url = grub_xasprintf ("%s://%s%s", protocol, server, name); + } + ++ grub_dprintf ("httpboot", "url: %s\n", url); ++ + if (!url) + { + return grub_errno; +diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c +index a3f0535..6e3b37f 100644 +--- a/grub-core/net/efi/net.c ++++ b/grub-core/net/efi/net.c +@@ -795,7 +795,10 @@ match_route (const char *server) + err = grub_efi_net_parse_address (server, &ip4, &ip6, &is_ip6, 0); + + if (err) ++ { ++ grub_dprintf ("httpboot", "server parse failed, please check!\n"); + return NULL; ++ } + + if (is_ip6) + { +@@ -1227,6 +1230,8 @@ grub_net_open_real (const char *name __attribute__ ((unused))) + return NULL; + } + ++ grub_dprintf ("httpboot", "server: %s\n", server); ++ + /*FIXME: Use DNS translate name to address */ + net_interface = match_route (server); + +diff --git a/include/grub/efi/http.h b/include/grub/efi/http.h +index c5e9a89..ad164ba 100644 +--- a/include/grub/efi/http.h ++++ b/include/grub/efi/http.h +@@ -171,9 +171,9 @@ typedef struct { + grub_efi_http_request_data_t *request; + grub_efi_http_response_data_t *response; + } data; +- grub_efi_uint32_t header_count; ++ grub_efi_uintn_t header_count; + grub_efi_http_header_t *headers; +- grub_efi_uint32_t body_length; ++ grub_efi_uintn_t body_length; + void *body; + } grub_efi_http_message_t; + +-- +2.23.0 + diff --git a/backport-fix-CVE-2020-15705.patch b/backport-fix-CVE-2020-15705.patch new file mode 100644 index 0000000..0ba7f83 --- /dev/null +++ b/backport-fix-CVE-2020-15705.patch @@ -0,0 +1,122 @@ +From 3ddffe5b10cba0607ceaaae8c630ce5f870decbb Mon Sep 17 00:00:00 2001 +From: Dimitri John Ledkov +Date: Wed, 22 Jul 2020 11:31:43 +0100 +Subject: [PATCH] linuxefi: fail kernel validation without shim protocol. + +Conflict: NA +Reference:https://src.fedoraproject.org/rpms/grub2/blob/rawhide/f/0160-linuxefi-fail-kernel-validation-without-shim-protoco.patch + +If certificates that signed grub are installed into db, grub can be +booted directly. It will then boot any kernel without signature +validation. The booted kernel will think it was booted in secureboot +mode and will implement lockdown, yet it could have been tampered. + +This version of the patch skips calling verification, when booted +without secureboot. And is indented with gnu ident. + +CVE-2020-15705 + +Reported-by: Mathieu Trudel-Lapierre +Signed-off-by: Dimitri John Ledkov +--- + grub-core/kern/efi/sb.c | 14 +++++++++----- + grub-core/loader/arm64/linux.c | 11 ++++++----- + grub-core/loader/i386/efi/linux.c | 11 ++++++----- + 3 files changed, 21 insertions(+), 15 deletions(-) + +diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c +index d74778b..60cdef3 100644 +--- a/grub-core/kern/efi/sb.c ++++ b/grub-core/kern/efi/sb.c +@@ -31,9 +31,10 @@ grub_efi_secure_boot (void) + #ifdef GRUB_MACHINE_EFI + grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID; + grub_size_t datasize; +- char *secure_boot = NULL; +- char *setup_mode = NULL; ++ grub_uint8_t *secure_boot = NULL; ++ grub_uint8_t *setup_mode = NULL; + grub_efi_boolean_t ret = 0; ++ grub_uint8_t setupmode = 0; + + secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize); + if (datasize != 1 || !secure_boot) +@@ -47,11 +48,14 @@ grub_efi_secure_boot (void) + if (datasize != 1 || !setup_mode) + { + grub_dprintf ("secureboot", "No SetupMode variable\n"); +- goto out; + } +- grub_dprintf ("secureboot", "SetupMode: %d\n", *setup_mode); ++ else ++ { ++ grub_dprintf ("secure_boot", "SetupMode: %d\n", *setup_mode); ++ setupmode = *setup_mode; ++ } + +- if (*secure_boot && !*setup_mode) ++ if (*secure_boot && !setupmode) + ret = 1; + + out: +diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c +index a18c487..fad13cb 100644 +--- a/grub-core/loader/arm64/linux.c ++++ b/grub-core/loader/arm64/linux.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -387,11 +388,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + { + rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size); + if (rc <= 0) +- { +- grub_error (GRUB_ERR_INVALID_COMMAND, +- N_("%s has invalid signature"), argv[0]); +- goto fail; +- } ++ { ++ grub_error (GRUB_ERR_INVALID_COMMAND, ++ N_("%s has invalid signature"), argv[0]); ++ goto fail; ++ } + } + + pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset); +diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c +index e613115..0a5d086 100644 +--- a/grub-core/loader/i386/efi/linux.c ++++ b/grub-core/loader/i386/efi/linux.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -305,11 +306,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + { + rc = grub_linuxefi_secure_validate (kernel, filelen); + if (rc <= 0) +- { +- grub_error (GRUB_ERR_INVALID_COMMAND, +- N_("%s has invalid signature"), argv[0]); +- goto fail; +- } ++ { ++ grub_error (GRUB_ERR_INVALID_COMMAND, ++ N_("%s has invalid signature"), argv[0]); ++ goto fail; ++ } + } + + lh = (struct linux_i386_kernel_header *)kernel; +-- +2.19.1 + diff --git a/backport-fix-misspelled-variable-BUILD_LDFAGS.patch b/backport-fix-misspelled-variable-BUILD_LDFAGS.patch new file mode 100644 index 0000000..7a8188c --- /dev/null +++ b/backport-fix-misspelled-variable-BUILD_LDFAGS.patch @@ -0,0 +1,30 @@ +From d17eddab81eab790689b00172a9ee8351548de82 Mon Sep 17 00:00:00 2001 +From: Glenn Washburn +Date: Tue, 7 Dec 2021 23:36:31 -0600 +Subject: configure: Fix misspelled variable BUILD_LDFAGS -> BUILD_LDFLAGS + +Conflict:NA +Reference:https://git.savannah.gnu.org/cgit/grub.git/patch/?id=d17eddab81eab790689b00172a9ee8351548de82 + +Signed-off-by: Glenn Washburn +Reviewed-by: Daniel Kiper +--- + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/configure.ac b/configure.ac +index 8d1c81a..4f649ed 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1649,7 +1649,7 @@ CC="$BUILD_CC" + CPP="$BUILD_CPP" + CFLAGS="$BUILD_CFLAGS" + CPPFLAGS="$BUILD_CPPFLAGS" +-LDFLAGS="$BUILD_LDFAGS" ++LDFLAGS="$BUILD_LDFLAGS" + + unset ac_cv_c_bigendian + unset ac_cv_header_ft2build_h +-- +cgit v1.1 + diff --git a/backport-fs-ext2-Fix-a-file-not-found-error-when-a-symlink-filesize-is-equal-to-60.patch b/backport-fs-ext2-Fix-a-file-not-found-error-when-a-symlink-filesize-is-equal-to-60.patch new file mode 100644 index 0000000..e8c1755 --- /dev/null +++ b/backport-fs-ext2-Fix-a-file-not-found-error-when-a-symlink-filesize-is-equal-to-60.patch @@ -0,0 +1,52 @@ +From bd8b36d8aadbfad14604570540e76d52162c816a Mon Sep 17 00:00:00 2001 +From: Yi Zhao +Date: Fri, 8 Jan 2021 08:39:47 +0800 +Subject: fs/ext2: Fix a file not found error when a symlink filesize is equal + to 60 + +We encountered a file not found error when the symlink filesize is +equal to 60: + + $ ls -l initrd + lrwxrwxrwx 1 root root 60 Jan 6 16:37 initrd -> secure-core-image-initramfs-5.10.2-yoctodev-standard.cpio.gz + +When booting, we got the following error in the GRUB: + + error: file `/initrd' not found + +The root cause is that the size of diro->inode.symlink is equal to 60 +and a symlink name has to be terminated with NUL there. So, if the +symlink filesize is exactly 60 then it is also stored in a separate +block rather than in the inode itself. + +Signed-off-by: Yi Zhao +Reviewed-by: Daniel Kiper +Conflict:NA +Reference:https://git.savannah.gnu.org/cgit/grub.git/patch/?id=bd8b36d8aadbfad14604570540e76d52162c816a +--- + grub-core/fs/ext2.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c +index ac33bcd68..848bf939d 100644 +--- a/grub-core/fs/ext2.c ++++ b/grub-core/fs/ext2.c +@@ -729,10 +729,11 @@ grub_ext2_read_symlink (grub_fshelp_node_t node) + if (! symlink) + return 0; + +- /* If the filesize of the symlink is bigger than +- 60 the symlink is stored in a separate block, +- otherwise it is stored in the inode. */ +- if (grub_le_to_cpu32 (diro->inode.size) <= sizeof (diro->inode.symlink)) ++ /* ++ * If the filesize of the symlink is equal to or bigger than 60 the symlink ++ * is stored in a separate block, otherwise it is stored in the inode. ++ */ ++ if (grub_le_to_cpu32 (diro->inode.size) < sizeof (diro->inode.symlink)) + grub_memcpy (symlink, + diro->inode.symlink, + grub_le_to_cpu32 (diro->inode.size)); +-- +cgit v1.2.1 + diff --git a/backport-grub2-set-password-prompts-to-enter-the-current-pass.patch b/backport-grub2-set-password-prompts-to-enter-the-current-pass.patch new file mode 100644 index 0000000..238a82c --- /dev/null +++ b/backport-grub2-set-password-prompts-to-enter-the-current-pass.patch @@ -0,0 +1,305 @@ +From 5099013778b2433a4dee3ae5e4826d8add1c1fb7 Mon Sep 17 00:00:00 2001 +From: liuxin +Date: Thu, 2 Sep 2021 17:30:39 +0800 +Subject: [PATCH] grub2-set-password prompts to enter the current password and + add the password complexity check + +Conflict:NA +Reference:https://gitee.com/src-openeuler/grub2/commit/31e72c6b0a7d65b904afa2cb77e4e633cafacc6e.patch + +--- + util/grub-mkpasswd-pbkdf2.c | 95 +++++++++++++++++++++++++++++- + util/grub-set-password.in | 114 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 207 insertions(+), 2 deletions(-) + +diff --git a/util/grub-mkpasswd-pbkdf2.c b/util/grub-mkpasswd-pbkdf2.c +index 5805f3c..68c2032 100644 +--- a/util/grub-mkpasswd-pbkdf2.c ++++ b/util/grub-mkpasswd-pbkdf2.c +@@ -42,10 +42,14 @@ + + #include "progname.h" + ++#define GRUB_PARAM_ERROR 1 ++#define GRUB_PARAM_SUCCESS 0 ++ + static struct argp_option options[] = { + {"iteration-count", 'c', N_("NUM"), 0, N_("Number of PBKDF2 iterations"), 0}, + {"buflen", 'l', N_("NUM"), 0, N_("Length of generated hash"), 0}, + {"salt", 's', N_("NUM"), 0, N_("Length of salt"), 0}, ++ {"salt arg", 'a', N_("VARCHAR"), 0, N_("preset salt var(hex code)"), 0}, + { 0, 0, 0, 0, 0, 0 } + }; + +@@ -54,8 +58,45 @@ struct arguments + unsigned int count; + unsigned int buflen; + unsigned int saltlen; ++ char * salt; + }; + ++static int illegal_char(char t) ++{ ++ int illegal = GRUB_PARAM_ERROR; ++ char legal[] = "0123456789ABCDEF"; ++ for (int i = 0; i < grub_strlen(legal); ++i) { ++ if (t == legal[i]) { ++ illegal = GRUB_PARAM_SUCCESS; ++ break; ++ } ++ } ++ return illegal; ++} ++ ++static int check_salt_verify(const char * arg) ++{ ++ grub_size_t len = grub_strlen(arg); ++ if (len <= 0 || len >= GRUB_SIZE_MAX) ++ { ++ fprintf(stderr, "salt length may be empty or too long!\n"); ++ return GRUB_PARAM_ERROR; ++ } ++ if (len % 2 != 0) ++ { ++ fprintf(stderr, "the salt value length is an even number!\n"); ++ return GRUB_PARAM_ERROR; ++ } ++ for (int i = 0; i < len; ++i) ++ { ++ if (illegal_char(arg[i])) ++ { ++ return GRUB_PARAM_ERROR; ++ } ++ } ++ return GRUB_PARAM_SUCCESS; ++} ++ + static error_t + argp_parser (int key, char *arg, struct argp_state *state) + { +@@ -76,6 +117,16 @@ argp_parser (int key, char *arg, struct argp_state *state) + case 's': + arguments->saltlen = strtoul (arg, NULL, 0); + break; ++ ++ case 'a': ++ if (check_salt_verify(arg)) ++ { ++ fprintf(stderr, "only hexadecimal numbers consisting of digits and uppercase letters are supported\n"); ++ return ARGP_ERR_UNKNOWN; ++ } ++ arguments->saltlen = grub_strlen(arg) / 2; ++ arguments->salt = arg; ++ break; + default: + return ARGP_ERR_UNKNOWN; + } +@@ -110,13 +161,44 @@ hexify (char *hex, grub_uint8_t *bin, grub_size_t n) + *hex = 0; + } + ++static void ++hextobyte(const char *hex, grub_uint8_t *bin, grub_size_t n) ++{ ++ while(n) ++ { ++ grub_uint8_t tmp = 0x00; ++ if (((*hex) <= '9') && ((*hex) >= '0')) ++ { ++ tmp += (grub_uint8_t)((*hex) - '0') << 4 & 0xf0; ++ } ++ else ++ { ++ tmp += (grub_uint8_t)((*hex) - 'A' + 10) << 4 & 0xf0; ++ } ++ hex++; ++ if (((*hex) <= '9') && ((*hex) >= '0')) ++ { ++ tmp += (grub_uint8_t)((*hex) - '0') & 0x0f; ++ } ++ else ++ { ++ tmp += (grub_uint8_t)((*hex) - 'A' + 10) & 0x0f; ++ } ++ *bin = tmp; ++ bin++; ++ hex++; ++ n -= 2; ++ } ++} ++ + int + main (int argc, char *argv[]) + { + struct arguments arguments = { + .count = 10000, + .buflen = 64, +- .saltlen = 64 ++ .saltlen = 64, ++ .salt = NULL + }; + char *result, *ptr; + gcry_err_code_t gcry_err; +@@ -133,6 +215,12 @@ main (int argc, char *argv[]) + exit(1); + } + ++ if (arguments.salt != NULL && grub_strlen(arguments.salt) != 2 * arguments.saltlen) ++ { ++ fprintf(stderr, "%s", _("If the -a parameter is set, don't set the -s parameter again\n")); ++ exit(1); ++ } ++ + buf = xmalloc (arguments.buflen); + salt = xmalloc (arguments.saltlen); + +@@ -161,7 +249,10 @@ main (int argc, char *argv[]) + } + memset (pass2, 0, sizeof (pass2)); + +- if (grub_get_random (salt, arguments.saltlen)) ++ if (arguments.salt != NULL) ++ { ++ hextobyte(arguments.salt, salt, arguments.saltlen * 2); ++ } else if (grub_get_random (salt, arguments.saltlen)) + { + memset (pass1, 0, sizeof (pass1)); + free (buf); +diff --git a/util/grub-set-password.in b/util/grub-set-password.in +index 487fbb1..3d0be26 100644 +--- a/util/grub-set-password.in ++++ b/util/grub-set-password.in +@@ -87,16 +87,130 @@ fixtty() { + } + + trap fixtty EXIT ++ ++getsaltpass() { ++ local P0 ++ local P1 ++ P0="$1" && shift ++ P1="$1" && shift ++ P2="$1" && shift ++ ++ ( echo ${P0} ; echo ${P1} ) | \ ++ LC_ALL=C ${grub_mkpasswd} -a ${P2} | \ ++ grep -v '[eE]nter password:' | \ ++ sed -e "s/PBKDF2 hash of your password is //" ++} ++ ++verifyusercfgoldpasswd() { ++ # get old password salt ++ expectsalt=`cat ${grubdir}/user.cfg | cut -d "." -f 5` ++ # get expect password ++ expectpass=`cat ${grubdir}/user.cfg` ++ prefix="GRUB2_PASSWORD=" ++ ++ stty -echo ++ echo -n "Enter Current password: " ++ read PASSWORD_CURRENT ++ echo ++ ++ needcheckpass="${prefix}$(getsaltpass "${PASSWORD_CURRENT}" "${PASSWORD_CURRENT}" "${expectsalt}")" ++ if [ "$expectpass" != "$needcheckpass" ]; then ++ echo "Authentication failed" ++ exit 1 ++ fi ++ ++ stty ${ttyopt} ++} ++ ++verifygrubcfgoldpasswd() { ++ # get old password line ++ expectpass=`cat ${grubdir}/grub.cfg | grep "password_pbkdf2 root grub.pbkdf2.sha512" | cut -d " " -f 3` ++ # if not get password, try a quotation mark match ++ if [ -z "$expectpass" ];then ++ expectpass=`cat ${grubdir}/grub.cfg | grep "password_pbkdf2 root \"grub.pbkdf2.sha512" | cut -d " " -f 3 | cut -d "\"" -f 2` ++ fi ++ if [ -z "$expectpass" ];then ++ expectpass=`cat ${grubdir}/grub.cfg | grep "password_pbkdf2 root 'grub.pbkdf2.sha512" | cut -d " " -f 3 | cut -d "'" -f 2` ++ fi ++ if [ -n "$expectpass" ];then ++ # get old password salt ++ expectsalt=`echo ${expectpass} | cut -d "." -f 5` ++ stty -echo ++ echo -n "Enter Current password: " ++ read PASSWORD_CURRENT ++ echo ++ ++ needcheckpass="$(getsaltpass "${PASSWORD_CURRENT}" "${PASSWORD_CURRENT}" "${expectsalt}")" ++ if [ "$expectpass" != "$needcheckpass" ]; then ++ echo "Authentication failed" ++ exit 1 ++ fi ++ fi ++ ++} ++ ++if [ -e ${grubdir}/user.cfg ];then ++ verifyusercfgoldpasswd ++else ++ verifygrubcfgoldpasswd ++fi ++ ++checkcomplexity() { ++ set +e ++ USERNAME=`cat ${grubdir}/grub.cfg | grep "set superusers=" | cut -d "\"" -f 2 |tail -1` ++ local P1="$1" && shift ++ if [ "$P1" = "$USERNAME" ];then ++ echo "The password contains the user name in some form" ++ exit 1 ++ fi ++ # password len >= 8 ++ strlen=`echo "$P1" | grep -E '^(.{8,}).*$'` ++ if [ -z "$strlen" ];then ++ echo "The password is shorter than 8 characters" ++ exit 1 ++ fi ++ # lowercase ++ strlow=`echo "$P1" | grep -E --color '^(.*[a-z]+).*$'` ++ # uppercase ++ strupp=`echo $P1 | grep -E --color '^(.*[A-Z]).*$'` ++ # special character ++ strts=`echo $P1 | grep -E --color '^(.*\W).*$'` ++ # num ++ strnum=`echo $P1 | grep -E --color '^(.*[0-9]).*$'` ++ complexity=0 ++ if [ -n "$strlow" ];then ++ complexity=`expr $complexity + 1` ++ fi ++ if [ -n "$strupp" ];then ++ complexity=`expr $complexity + 1` ++ fi ++ if [ -n "$strts" ];then ++ complexity=`expr $complexity + 1` ++ fi ++ if [ -n "$strnum" ];then ++ complexity=`expr $complexity + 1` ++ fi ++ if [ $complexity -lt 3 ];then ++ echo "The password contains less than 3 character classes" ++ exit 1 ++ fi ++ set -e ++} ++ + stty -echo + + # prompt & confirm new grub2 root user password + echo -n "Enter password: " + read PASSWORD + echo ++stty ${ttyopt} ++checkcomplexity $PASSWORD ++stty -echo + echo -n "Confirm password: " + read PASSWORD_CONFIRM + echo + stty ${ttyopt} ++checkcomplexity $PASSWORD_CONFIRM + + getpass() { + local P0 +-- +2.23.0 + diff --git a/backport-io-gzio-Fix-possible-use-of-uninitialized-variable-in-huft_build.patch b/backport-io-gzio-Fix-possible-use-of-uninitialized-variable-in-huft_build.patch new file mode 100644 index 0000000..c3a8e56 --- /dev/null +++ b/backport-io-gzio-Fix-possible-use-of-uninitialized-variable-in-huft_build.patch @@ -0,0 +1,35 @@ +From 29d44a236a5e939b8ff24e6c31141d5b1e48f693 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Tue, 26 Oct 2021 15:02:40 +0000 +Subject: io/gzio: Fix possible use of uninitialized variable in huft_build() + +In huft_build() it is possible to reach the for loop where "r" is being +assigned to "q[j]" without "r.v" ever being initialized. + +Fixes: CID 314024 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper + +Conflict: NA +Reference: https://git.savannah.gnu.org/cgit/grub.git/commit?id=29d44a236a5e939b8ff24e6c31141d5b1e48f693 + +--- + grub-core/io/gzio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c +index aea86a0..10156e5 100644 +--- a/grub-core/io/gzio.c ++++ b/grub-core/io/gzio.c +@@ -447,7 +447,7 @@ huft_build (unsigned *b, /* code lengths in bits (all assumed <= BMAX) */ + int l; /* bits per table (returned in m) */ + register unsigned *p; /* pointer into c[], b[], or v[] */ + register struct huft *q; /* points to current table */ +- struct huft r; /* table entry for structure assignment */ ++ struct huft r = {0}; /* table entry for structure assignment */ + struct huft *u[BMAX]; /* table stack */ + unsigned v[N_MAX]; /* values in order of bit length */ + register int w; /* bits before this table == (l * h) */ +-- +cgit v1.1 diff --git a/backport-io-lzopio-Resolve-unnecessary-self-assignment-errors.patch b/backport-io-lzopio-Resolve-unnecessary-self-assignment-errors.patch new file mode 100644 index 0000000..36eaba6 --- /dev/null +++ b/backport-io-lzopio-Resolve-unnecessary-self-assignment-errors.patch @@ -0,0 +1,43 @@ +From 59666e520f44177c97b82a44c169b3b315d63b42 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Wed, 21 Oct 2020 14:44:10 +0000 +Subject: io/lzopio: Resolve unnecessary self-assignment errors + +These 2 assignments are unnecessary since they are just assigning +to themselves. + +Fixes: CID 73643 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +Conflict:NA +Reference:https://git.savannah.gnu.org/cgit/grub.git/patch/?id=59666e520f44177c97b82a44c169b3b315d63b42 +--- + grub-core/io/lzopio.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c +index 30144857d..a7d442543 100644 +--- a/grub-core/io/lzopio.c ++++ b/grub-core/io/lzopio.c +@@ -125,8 +125,6 @@ read_block_header (struct grub_lzopio *lzopio) + sizeof (lzopio->block.ucheck)) != + sizeof (lzopio->block.ucheck)) + return -1; +- +- lzopio->block.ucheck = lzopio->block.ucheck; + } + + /* Read checksum of compressed data. */ +@@ -143,8 +141,6 @@ read_block_header (struct grub_lzopio *lzopio) + sizeof (lzopio->block.ccheck)) != + sizeof (lzopio->block.ccheck)) + return -1; +- +- lzopio->block.ccheck = lzopio->block.ccheck; + } + } + +-- +cgit v1.2.1 + diff --git a/backport-kern-file-Do-not-leak-device_name-on-error-in.patch b/backport-kern-file-Do-not-leak-device_name-on-error-in.patch new file mode 100644 index 0000000..3c82587 --- /dev/null +++ b/backport-kern-file-Do-not-leak-device_name-on-error-in.patch @@ -0,0 +1,43 @@ +From f1ce0e15e70ea1aafcfa26ad93e7585f65783c6f Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Fri, 25 Jun 2021 02:19:05 +1000 +Subject: 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. + +Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=f1ce0e15e70ea1aafcfa26ad93e7585f65783c6f +Conflict:NA + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + 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 df24c1f..8d48fd5 100644 +--- a/grub-core/kern/file.c ++++ b/grub-core/kern/file.c +@@ -79,6 +79,7 @@ grub_file_open (const char *name, enum grub_file_type type) + + device = grub_device_open (device_name); + grub_free (device_name); ++ device_name = NULL; + if (! device) + goto fail; + +@@ -131,6 +132,7 @@ grub_file_open (const char *name, enum grub_file_type type) + return file; + + fail: ++ grub_free (device_name); + if (device) + grub_device_close (device); + +-- +cgit v1.1 + diff --git a/backport-loader-efi-chainloader-Simplify-the-loader-state.patch b/backport-loader-efi-chainloader-Simplify-the-loader-state.patch new file mode 100644 index 0000000..511dac2 --- /dev/null +++ b/backport-loader-efi-chainloader-Simplify-the-loader-state.patch @@ -0,0 +1,337 @@ +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. + +Reference:https://src.fedoraproject.org/rpms/grub2/c/f0ad2aaa267a5d99b47f5c5770a55de0a702fdf0?branch=rawhide +Conflict:NA + +Signed-off-by: Chris Coulson +(cherry picked from commit fa39862933b3be1553a580a3a5c28073257d8046) +[rharwood: fix unitialized handle and double-frees of file/dev] +Signed-off-by: Robbie Harwood +--- + grub-core/loader/efi/chainloader.c | 161 ++++++++++++++++++----------- + 1 file changed, 103 insertions(+), 58 deletions(-) + +diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c +index 26c9d85..a80d11f 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); +- +-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); +- grub_efi_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; +-} ++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_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) + grub_efi_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) +@@ -524,10 +533,12 @@ 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_loaded_image_t *li, li_bak; + grub_efi_status_t efi_status; ++ 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; +@@ -538,6 +549,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); + + rc = read_header (data, datasize, &context); + if (rc < 0) +@@ -795,10 +807,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"); +@@ -827,19 +839,22 @@ error_exit: + static grub_err_t + grub_secureboot_chainloader_unload (void) + { +- grub_efi_free_pages (address, pages); +- grub_free (file_path); +- grub_free (cmdline); +- cmdline = 0; +- file_path = 0; +- dev_handle = 0; ++ 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; + } + + 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; +@@ -848,7 +863,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) +@@ -861,7 +876,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"); +@@ -883,20 +898,26 @@ grub_secureboot_chainloader_boot (void) + { + grub_efi_boot_services_t *b; + int rc; +- rc = handle_image ((void *)(unsigned long)address, fsize); ++ grub_efi_handle_t handle = 0; ++ ++ 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; +@@ -910,9 +931,15 @@ 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; ++ 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; + int rc; + + if (argc == 0) +@@ -921,12 +948,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) +@@ -1078,17 +1099,35 @@ 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_device_close (dev); ++ + 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); + grub_device_close (dev); ++ ++ /* We're finished with the source image buffer and file path now */ ++ efi_call_2 (b->free_pages, address, pages); ++ grub_free (file_path); ++ + grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0); + + return 0; +@@ -1109,6 +1148,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; +-- +2.19.1 + diff --git a/backport-loader-efi-chainloader-Use-grub_loader_set_ex.patch b/backport-loader-efi-chainloader-Use-grub_loader_set_ex.patch new file mode 100644 index 0000000..b81ad2d --- /dev/null +++ b/backport-loader-efi-chainloader-Use-grub_loader_set_ex.patch @@ -0,0 +1,153 @@ +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. + +Reference:https://src.fedoraproject.org/rpms/grub2/c/f0ad2aaa267a5d99b47f5c5770a55de0a702fdf0?branch=rawhide +Conflict:NA + +Signed-off-by: Chris Coulson +(cherry picked from commit 4b7f0402b7cb0f67a93be736f2b75b818d7f44c9) +[rharwood: context sludge from other change] +Signed-off-by: Robbie Harwood +--- + 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 a80d11f..523d2ce 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 (); +@@ -837,15 +839,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; + } +@@ -894,12 +898,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) + { +@@ -940,6 +947,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; + int rc; + + if (argc == 0) +@@ -1113,8 +1122,8 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), + grub_file_close (file); + grub_device_close (dev); + +- 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) +@@ -1128,7 +1137,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; + } +@@ -1149,10 +1158,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); + +-- +2.19.1 + diff --git a/backport-loader-efi-chainloader-grub_load_and_start_image-doe.patch b/backport-loader-efi-chainloader-grub_load_and_start_image-doe.patch new file mode 100644 index 0000000..12008fd --- /dev/null +++ b/backport-loader-efi-chainloader-grub_load_and_start_image-doe.patch @@ -0,0 +1,75 @@ +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. + +Reference:https://src.fedoraproject.org/rpms/grub2/c/f0ad2aaa267a5d99b47f5c5770a55de0a702fdf0?branch=rawhide +Conflict:NA + +Signed-off-by: Chris Coulson +(cherry picked from commit b4d70820a65c00561045856b7b8355461a9545f6) +--- + grub-core/loader/efi/chainloader.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c +index 813dc0e..26c9d85 100644 +--- a/grub-core/loader/efi/chainloader.c ++++ b/grub-core/loader/efi/chainloader.c +@@ -839,7 +839,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; +@@ -881,13 +881,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 *)(unsigned long)address, fsize); + if (rc == 0) + { +- grub_load_and_start_image((void *)(unsigned long)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_device_close (dev); + grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0); +-- +2.19.1 + diff --git a/backport-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch b/backport-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch new file mode 100644 index 0000000..af58eab --- /dev/null +++ b/backport-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. + +Reference:https://src.fedoraproject.org/rpms/grub2/c/f0ad2aaa267a5d99b47f5c5770a55de0a702fdf0?branch=rawhide +Conflict:NA + +Signed-off-by: Chris Coulson +(cherry picked from commit 8224f5a71af94bec8697de17e7e579792db9f9e2) +--- + 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 941df6400b..27bc2aa161 100644 +--- a/grub-core/loader/i386/efi/linux.c ++++ b/grub-core/loader/i386/efi/linux.c +@@ -465,9 +465,6 @@ fail: + if (file) + grub_file_close (file); + +- if (kernel) +- grub_free (kernel); +- + if (grub_errno != GRUB_ERR_NONE) + { + grub_dl_unref (my_mod); +@@ -483,6 +480,8 @@ fail: + kernel_free (params, sizeof(*params)); + } + ++ grub_free (kernel); ++ + return grub_errno; + } + diff --git a/backport-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch b/backport-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch new file mode 100644 index 0000000..cd2b65f --- /dev/null +++ b/backport-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch @@ -0,0 +1,81 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chris Coulson +Date: Tue, 3 May 2022 09:47:35 +0200 +Subject: [PATCH] loader/i386/efi/linux: Fix a memory leak in the initrd + command + +Subsequent invocations of the initrd command result in the previous +initrd being leaked, so fix that. + +Reference:https://src.fedoraproject.org/rpms/grub2/c/f0ad2aaa267a5d99b47f5c5770a55de0a702fdf0?branch=rawhide +Conflict:NA + +Signed-off-by: Chris Coulson +(cherry picked from commit d98af31ce1e31bb22163960d53f5eb28c66582a0) +--- + grub-core/loader/i386/efi/linux.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c +index c82deac..0c98fe2 100644 +--- a/grub-core/loader/i386/efi/linux.c ++++ b/grub-core/loader/i386/efi/linux.c +@@ -207,6 +207,7 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[]) + grub_uint8_t *ptr; + struct grub_linuxefi_context *context = (struct grub_linuxefi_context *) cmd->data; + struct linux_kernel_params *params; ++ void *initrd_mem = 0; + + if (argc == 0) + { +@@ -235,19 +236,19 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[]) + size += ALIGN_UP (grub_file_size (files[i]), 4); + } + +- context->initrd_mem = kernel_alloc(size, N_("can't allocate initrd")); +- if (context->initrd_mem == NULL) ++ initrd_mem = kernel_alloc(size, N_("can't allocate initrd")); ++ if (initrd_mem == NULL) + goto fail; +- grub_dprintf ("linux", "initrd_mem = %p\n", context->initrd_mem); ++ grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem); + + params->ramdisk_size = LOW_U32(size); +- params->ramdisk_image = LOW_U32(context->initrd_mem); ++ params->ramdisk_image = LOW_U32(initrd_mem); + #if defined(__x86_64__) + params->ext_ramdisk_size = HIGH_U32(size); +- params->ext_ramdisk_image = HIGH_U32(context->initrd_mem); ++ params->ext_ramdisk_image = HIGH_U32(initrd_mem); + #endif + +- ptr = context->initrd_mem; ++ ptr = initrd_mem; + + for (i = 0; i < nfiles; i++) + { +@@ -264,6 +265,9 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[]) + ptr += ALIGN_UP_OVERHEAD (cursize, 4); + } + ++ kernel_free(context->initrd_mem, params->ramdisk_size); ++ ++ context->initrd_mem = initrd_mem; + params->ramdisk_size = size; + + fail: +@@ -271,9 +275,8 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[]) + grub_file_close (files[i]); + grub_free (files); + +- if (context->initrd_mem && grub_errno) +- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)context->initrd_mem, +- BYTES_TO_PAGES(size)); ++ if (initrd_mem && grub_errno) ++ kernel_free (initrd_mem, size); + + return grub_errno; + } +-- +2.19.1 + diff --git a/backport-loader-i386-efi-linux-Use-grub_loader_set_ex.patch b/backport-loader-i386-efi-linux-Use-grub_loader_set_ex.patch new file mode 100644 index 0000000..d0e111c --- /dev/null +++ b/backport-loader-i386-efi-linux-Use-grub_loader_set_ex.patch @@ -0,0 +1,301 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chris Coulson +Date: Mon, 2 May 2022 17:04:23 +0200 +Subject: [PATCH] loader/i386/efi/linux: Use grub_loader_set_ex + +This ports the linuxefi loader to use grub_loader_set_ex in order to fix +a use-after-fre bug that occurs when grub_cmd_linux is executed more than +once before a boot attempt is performed. + +This is more complicated than for the chainloader command, as the initrd +command needs access to the loader state. To solve this, the linuxefi +module registers a dummy initrd command at startup that returns an error. +The linuxefi command then registers a proper initrd command with a higher +priority that is passed the loader state. + +Reference:https://src.fedoraproject.org/rpms/grub2/c/f0ad2aaa267a5d99b47f5c5770a55de0a702fdf0?branch=rawhide +Conflict:NA + +Signed-off-by: Chris Coulson +(cherry picked from commit 7cf736436b4c934df5ddfa6f44b46a7e07d99fdc) +[rharwood/pjones: set kernel_size in context] +Signed-off-by: Robbie Harwood +--- + grub-core/loader/i386/efi/linux.c | 145 ++++++++++++++++++------------ + 1 file changed, 86 insertions(+), 59 deletions(-) + +diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c +index 98e832b..c82deac 100644 +--- a/grub-core/loader/i386/efi/linux.c ++++ b/grub-core/loader/i386/efi/linux.c +@@ -33,13 +33,19 @@ + GRUB_MOD_LICENSE ("GPLv3+"); + + static grub_dl_t my_mod; +-static int loaded; +-static void *kernel_mem; +-static grub_uint64_t kernel_size; +-static void *initrd_mem; +-static grub_uint32_t handover_offset; +-struct linux_kernel_params *params; +-static char *linux_cmdline; ++ ++static grub_command_t cmd_linux, cmd_initrd; ++static grub_command_t cmd_linuxefi, cmd_initrdefi; ++ ++struct grub_linuxefi_context { ++ void *kernel_mem; ++ grub_uint64_t kernel_size; ++ grub_uint32_t handover_offset; ++ struct linux_kernel_params *params; ++ char *cmdline; ++ ++ void *initrd_mem; ++}; + + #define MIN(a, b) \ + ({ typeof (a) _a = (a); \ +@@ -122,25 +128,31 @@ kernel_alloc(grub_efi_uintn_t size, const char * const errmsg) + } + + static grub_err_t +-grub_linuxefi_boot (void) ++grub_linuxefi_boot (void *data) + { ++ struct grub_linuxefi_context *context = (struct grub_linuxefi_context *) data; ++ + asm volatile ("cli"); + +- return grub_efi_linux_boot ((char *)kernel_mem, +- handover_offset, +- params); ++ return grub_efi_linux_boot ((char *)context->kernel_mem, ++ context->handover_offset, ++ context->params); + } + + static grub_err_t +-grub_linuxefi_unload (void) ++grub_linuxefi_unload (void *data) + { ++ struct grub_linuxefi_context *context = (struct grub_linuxefi_context *) data; ++ struct linux_kernel_params *params = context->params; + grub_dl_unref (my_mod); +- loaded = 0; + +- kernel_free(initrd_mem, params->ramdisk_size); +- kernel_free(linux_cmdline, params->cmdline_size + 1); +- kernel_free(kernel_mem, kernel_size); +- kernel_free(params, sizeof(*params)); ++ kernel_free (context->initrd_mem, params->ramdisk_size); ++ kernel_free (context->cmdline, params->cmdline_size + 1); ++ kernel_free (context->kernel_mem, context->kernel_size); ++ kernel_free (params, sizeof(*params)); ++ cmd_initrd->data = 0; ++ cmd_initrdefi->data = 0; ++ grub_free (context); + + return GRUB_ERR_NONE; + } +@@ -187,13 +199,14 @@ read(grub_file_t file, grub_uint8_t *bufp, grub_size_t len) + #define HIGH_U32(val) ((grub_uint32_t)(((grub_addr_t)(val) >> 32) & 0xffffffffull)) + + static grub_err_t +-grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), +- int argc, char *argv[]) ++grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[]) + { + grub_file_t *files = 0; + int i, nfiles = 0; + grub_size_t size = 0; + grub_uint8_t *ptr; ++ struct grub_linuxefi_context *context = (struct grub_linuxefi_context *) cmd->data; ++ struct linux_kernel_params *params; + + if (argc == 0) + { +@@ -201,12 +214,14 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + goto fail; + } + +- if (!loaded) ++ if (!context) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); + goto fail; + } + ++ params = context->params; ++ + files = grub_zalloc (argc * sizeof (files[0])); + if (!files) + goto fail; +@@ -220,19 +235,19 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + size += ALIGN_UP (grub_file_size (files[i]), 4); + } + +- initrd_mem = kernel_alloc(size, N_("can't allocate initrd")); +- if (initrd_mem == NULL) ++ context->initrd_mem = kernel_alloc(size, N_("can't allocate initrd")); ++ if (context->initrd_mem == NULL) + goto fail; +- grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem); ++ grub_dprintf ("linux", "initrd_mem = %p\n", context->initrd_mem); + + params->ramdisk_size = LOW_U32(size); +- params->ramdisk_image = LOW_U32(initrd_mem); ++ params->ramdisk_image = LOW_U32(context->initrd_mem); + #if defined(__x86_64__) + params->ext_ramdisk_size = HIGH_U32(size); +- params->ext_ramdisk_image = HIGH_U32(initrd_mem); ++ params->ext_ramdisk_image = HIGH_U32(context->initrd_mem); + #endif + +- ptr = initrd_mem; ++ ptr = context->initrd_mem; + + for (i = 0; i < nfiles; i++) + { +@@ -256,8 +271,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + grub_file_close (files[i]); + grub_free (files); + +- if (initrd_mem && grub_errno) +- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)initrd_mem, ++ if (context->initrd_mem && grub_errno) ++ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)context->initrd_mem, + BYTES_TO_PAGES(size)); + + return grub_errno; +@@ -272,6 +287,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + grub_ssize_t start, filelen; + void *kernel = NULL; + int setup_header_end_offset; ++ void *kernel_mem = 0; ++ grub_uint64_t kernel_size = 0; ++ grub_uint32_t handover_offset; ++ struct linux_kernel_params *params = 0; ++ char *cmdline = 0; ++ struct grub_linuxefi_context *context = 0; + int rc; + + grub_dl_ref (my_mod); +@@ -396,27 +417,27 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + grub_dprintf ("linux", "new lh is at %p\n", lh); + + grub_dprintf ("linux", "setting up cmdline\n"); +- linux_cmdline = kernel_alloc (lh->cmdline_size + 1, N_("can't allocate cmdline")); +- if (!linux_cmdline) ++ cmdline = kernel_alloc (lh->cmdline_size + 1, N_("can't allocate cmdline")); ++ if (!cmdline) + goto fail; +- grub_dprintf ("linux", "linux_cmdline = %p\n", linux_cmdline); ++ grub_dprintf ("linux", "cmdline = %p\n", cmdline); + +- grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); ++ grub_memcpy (cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); + grub_create_loader_cmdline (argc, argv, +- linux_cmdline + sizeof (LINUX_IMAGE) - 1, ++ cmdline + sizeof (LINUX_IMAGE) - 1, + lh->cmdline_size - (sizeof (LINUX_IMAGE) - 1), + GRUB_VERIFY_KERNEL_CMDLINE); + +- grub_dprintf ("linux", "cmdline:%s\n", linux_cmdline); ++ grub_dprintf ("linux", "cmdline:%s\n", cmdline); + grub_dprintf ("linux", "setting lh->cmd_line_ptr to 0x%08x\n", +- LOW_U32(linux_cmdline)); +- lh->cmd_line_ptr = LOW_U32(linux_cmdline); ++ LOW_U32(cmdline)); ++ lh->cmd_line_ptr = LOW_U32(cmdline); + #if defined(__x86_64__) +- if ((grub_efi_uintn_t)linux_cmdline > 0xffffffffull) ++ if ((grub_efi_uintn_t)cmdline > 0xffffffffull) + { + grub_dprintf ("linux", "setting params->ext_cmd_line_ptr to 0x%08x\n", +- HIGH_U32(linux_cmdline)); +- params->ext_cmd_line_ptr = HIGH_U32(linux_cmdline); ++ HIGH_U32(cmdline)); ++ params->ext_cmd_line_ptr = HIGH_U32(cmdline); + } + #endif + +@@ -441,16 +462,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + } + max_addresses[1].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS; + max_addresses[2].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS; +- kernel_mem = kernel_alloc (lh->init_size, N_("can't allocate kernel")); ++ kernel_size = lh->init_size; ++ kernel_mem = kernel_alloc (kernel_size, N_("can't allocate kernel")); + restore_addresses(); + if (!kernel_mem) + goto fail; + grub_dprintf("linux", "kernel_mem = %p\n", kernel_mem); + +- grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); +- +- loaded = 1; +- + grub_dprintf ("linux", "setting lh->code32_start to 0x%08x\n", + LOW_U32(kernel_mem)); + lh->code32_start = LOW_U32(kernel_mem); +@@ -467,33 +485,42 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + "setting lh->ext_loader_{type,ver} = {0x%02x,0x%02x}\n", + params->ext_loader_type, params->ext_loader_ver); + ++ context = grub_zalloc (sizeof (*context)); ++ if (!context) ++ goto fail; ++ context->kernel_mem = kernel_mem; ++ context->kernel_size = kernel_size; ++ context->handover_offset = handover_offset; ++ context->params = params; ++ context->cmdline = cmdline; ++ ++ grub_loader_set_ex (grub_linuxefi_boot, grub_linuxefi_unload, context, 0); ++ ++ cmd_initrd->data = context; ++ cmd_initrdefi->data = context; ++ ++ grub_file_close (file); ++ grub_free (kernel); ++ return 0; ++ + fail: + if (file) + grub_file_close (file); + +- if (grub_errno != GRUB_ERR_NONE) +- { +- grub_dl_unref (my_mod); +- loaded = 0; +- } ++ grub_dl_unref (my_mod); + +- if (!loaded) +- { +- if (lh) +- kernel_free (linux_cmdline, lh->cmdline_size + 1); ++ if (lh) ++ kernel_free (cmdline, lh->cmdline_size + 1); + +- kernel_free (kernel_mem, kernel_size); +- kernel_free (params, sizeof(*params)); +- } ++ kernel_free (kernel_mem, kernel_size); ++ kernel_free (params, sizeof(*params)); + ++ grub_free (context); + grub_free (kernel); + + return grub_errno; + } + +-static grub_command_t cmd_linux, cmd_initrd; +-static grub_command_t cmd_linuxefi, cmd_initrdefi; +- + GRUB_MOD_INIT(linux) + { + cmd_linux = +-- +2.19.1 + diff --git a/backport-loader-i386-linux-Do-not-use-grub_le_to_cpu32-for-relocatable-variable.patch b/backport-loader-i386-linux-Do-not-use-grub_le_to_cpu32-for-relocatable-variable.patch new file mode 100644 index 0000000..15d77f0 --- /dev/null +++ b/backport-loader-i386-linux-Do-not-use-grub_le_to_cpu32-for-relocatable-variable.patch @@ -0,0 +1,36 @@ +From 8fcfd1e0fc72d58766ce3dc09cf883c032f063f6 Mon Sep 17 00:00:00 2001 +From: Tianjia Zhang +Date: Mon, 11 Jan 2021 11:04:36 +0800 +Subject: loader/i386/linux: Do not use grub_le_to_cpu32() for relocatable + variable + +The relocatable variable is defined as grub_uint8_t. Relevant +member in setup_header structure is also defined as one byte +in Linux boot protocol. By semantic definition it is a bool type. +It is not appropriate to treat it as a four bytes. This patch +fixes the issue. + +Signed-off-by: Tianjia Zhang +Reviewed-by: Daniel Kiper +Conflict:NA +Reference:https://git.savannah.gnu.org/cgit/grub.git/patch/?id=8fcfd1e0fc72d58766ce3dc09cf883c032f063f6 +--- + grub-core/loader/i386/linux.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c +index 0eea64a20..9f74a96b1 100644 +--- a/grub-core/loader/i386/linux.c ++++ b/grub-core/loader/i386/linux.c +@@ -736,7 +736,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + for (align = 0; align < 32; align++) + if (grub_le_to_cpu32 (lh.kernel_alignment) & (1 << align)) + break; +- relocatable = grub_le_to_cpu32 (lh.relocatable); ++ relocatable = lh.relocatable; + } + else + { +-- +cgit v1.2.1 + diff --git a/backport-net-dns-Dont-read-past-the-end-of-the-string.patch b/backport-net-dns-Dont-read-past-the-end-of-the-string.patch new file mode 100644 index 0000000..751cc5d --- /dev/null +++ b/backport-net-dns-Dont-read-past-the-end-of-the-string.patch @@ -0,0 +1,75 @@ +From 96abf4fb9d829f4a405d5df39bc74bbccbd0e322 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Mon, 20 Dec 2021 21:55:43 +1100 +Subject: 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. + +Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=96abf4fb9d829f4a405d5df39bc74bbccbd0e322 +Conflict:NA + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + 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 135faac..17961a9 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; +-- +2.19.1 + diff --git a/backport-net-dns-Fix-double-free-addresses-on-corrupt-DNS.patch b/backport-net-dns-Fix-double-free-addresses-on-corrupt-DNS.patch new file mode 100644 index 0000000..5e9f6db --- /dev/null +++ b/backport-net-dns-Fix-double-free-addresses-on-corrupt-DNS.patch @@ -0,0 +1,61 @@ +From c1b7eef9fa4aaefbf7d0507505c3bb2914e1ad6b Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Thu, 16 Sep 2021 01:29:54 +1000 +Subject: 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. + +Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=c1b7eef9fa4aaefbf7d0507505c3bb2914e1ad6b +Conflict:NA + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + 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 27c5f41..841ede5 100644 +--- a/grub-core/net/dns.c ++++ b/grub-core/net/dns.c +@@ -667,9 +667,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")); + } + +-- +cgit v1.1 + diff --git a/backport-net-http-Do-not-tear-down-socket-if-its-already.patch b/backport-net-http-Do-not-tear-down-socket-if-its-already.patch new file mode 100644 index 0000000..bae7cc5 --- /dev/null +++ b/backport-net-http-Do-not-tear-down-socket-if-its-already.patch @@ -0,0 +1,46 @@ +From dad94fffe14be476df5f34a8e5a90ea62a41fe12 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Tue, 1 Mar 2022 23:14:15 +1100 +Subject: 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. + +Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=dad94fffe14be476df5f34a8e5a90ea62a41fe12 +Conflict:NA + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + 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 8d6c62c..f8d7bf0 100644 +--- a/grub-core/net/http.c ++++ b/grub-core/net/http.c +@@ -445,7 +445,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); +@@ -453,7 +453,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; +-- +cgit v1.1 + diff --git a/backport-net-http-Error-out-on-headers-with-LF-without-CR.patch b/backport-net-http-Error-out-on-headers-with-LF-without-CR.patch new file mode 100644 index 0000000..15fee8a --- /dev/null +++ b/backport-net-http-Error-out-on-headers-with-LF-without-CR.patch @@ -0,0 +1,53 @@ +From b26b4c08e7119281ff30d0fb4a6169bd2afa8fe4 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Tue, 8 Mar 2022 19:04:40 +1100 +Subject: 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 + +Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=b26b4c08e7119281ff30d0fb4a6169bd2afa8fe4 +Conflict:NA + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + 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 33a0a28..9291a13 100644 +--- a/grub-core/net/http.c ++++ b/grub-core/net/http.c +@@ -68,7 +68,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) + { +-- +cgit v1.1 + diff --git a/backport-net-http-Fix-OOB-write-for-split-http-headers.patch b/backport-net-http-Fix-OOB-write-for-split-http-headers.patch new file mode 100644 index 0000000..d9c7ff8 --- /dev/null +++ b/backport-net-http-Fix-OOB-write-for-split-http-headers.patch @@ -0,0 +1,51 @@ +From ec6bfd3237394c1c7dbf2fd73417173318d22f4b Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Tue, 8 Mar 2022 18:17:03 +1100 +Subject: 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 + +Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=ec6bfd3237394c1c7dbf2fd73417173318d22f4b +Conflict:NA + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + 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 f8d7bf0..33a0a28 100644 +--- a/grub-core/net/http.c ++++ b/grub-core/net/http.c +@@ -190,9 +190,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; +-- +cgit v1.1 + diff --git a/backport-net-ip-Do-IP-fragment-maths-safely.patch b/backport-net-ip-Do-IP-fragment-maths-safely.patch new file mode 100644 index 0000000..a9367c5 --- /dev/null +++ b/backport-net-ip-Do-IP-fragment-maths-safely.patch @@ -0,0 +1,57 @@ +From 3e4817538de828319ba6d59ced2fbb9b5ca13287 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Mon, 20 Dec 2021 19:41:21 +1100 +Subject: net/ip: Do IP fragment maths safely + +We can receive packets with invalid IP fragmentation information. This +can lead to rsm->total_len underflowing and becoming very large. + +Then, in grub_netbuff_alloc(), we add to this very large number, which can +cause it to overflow and wrap back around to a small positive number. +The allocation then succeeds, but the resulting buffer is too small and +subsequent operations can write past the end of the buffer. + +Catch the underflow here. + +Fixes: CVE-2022-28733 + +Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=3e4817538de828319ba6d59ced2fbb9b5ca13287 +Conflict:NA + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + 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 e3d62e9..3c3d0be 100644 +--- a/grub-core/net/ip.c ++++ b/grub-core/net/ip.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + + struct iphdr { +@@ -512,7 +513,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) + { +-- +cgit v1.1 + diff --git a/backport-net-netbuff-Block-overly-large-netbuff-allocs.patch b/backport-net-netbuff-Block-overly-large-netbuff-allocs.patch new file mode 100644 index 0000000..54a644f --- /dev/null +++ b/backport-net-netbuff-Block-overly-large-netbuff-allocs.patch @@ -0,0 +1,58 @@ +From f407e34f3871a4c402bbd516e7c28ea193cef1b7 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Tue, 8 Mar 2022 23:47:46 +1100 +Subject: net/netbuff: Block overly large netbuff allocs + +A netbuff shouldn't be too huge. It's bounded by MTU and TCP segment +reassembly. If we are asked to create one that is unreasonably big, refuse. + +This is a hardening measure: if we hit this code, there's a bug somewhere +else that we should catch and fix. + +This commit: + - stops the bug propagating any further. + - provides a spot to instrument in e.g. fuzzing to try to catch these bugs. + +I have put instrumentation (e.g. __builtin_trap() to force a crash) here and +have not been able to find any more crashes. + +Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=f407e34f3871a4c402bbd516e7c28ea193cef1b7 +Conflict:NA + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + 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 72e5296..8da327b 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 +-- +cgit v1.1 + diff --git a/backport-net-tftp-Avoid-a-trivial-UAF.patch b/backport-net-tftp-Avoid-a-trivial-UAF.patch new file mode 100644 index 0000000..a5595ce --- /dev/null +++ b/backport-net-tftp-Avoid-a-trivial-UAF.patch @@ -0,0 +1,40 @@ +From 8f287c3e13da2bf82049e2e464eca7ca4fef0a85 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Tue, 18 Jan 2022 14:29:20 +1100 +Subject: 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. + +Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=8f287c3e13da2bf82049e2e464eca7ca4fef0a85 +Conflict:NA + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + 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 0049d6c..7e9a8b6 100644 +--- a/grub-core/net/tftp.c ++++ b/grub-core/net/tftp.c +@@ -251,9 +251,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, (char *) tftph->u.err.errmsg); + grub_error_save (&data->save_err); ++ grub_netbuff_free (nb); + return GRUB_ERR_NONE; + default: + grub_netbuff_free (nb); +-- +2.19.1 + diff --git a/backport-net-tftp-Prevent-a-UAF-and-double-free-from.patch b/backport-net-tftp-Prevent-a-UAF-and-double-free-from.patch new file mode 100644 index 0000000..ea144ae --- /dev/null +++ b/backport-net-tftp-Prevent-a-UAF-and-double-free-from.patch @@ -0,0 +1,117 @@ +From ee9652031491326736714a988fbbaeab8ef9255c Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Mon, 20 Sep 2021 01:12:24 +1000 +Subject: 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. + +Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=ee9652031491326736714a988fbbaeab8ef9255c +Conflict:NA + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + 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 2b67715..9f09f8e 100644 +--- a/grub-core/net/net.c ++++ b/grub-core/net/net.c +@@ -1521,7 +1521,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; + } +@@ -1744,7 +1745,10 @@ grub_net_seek_real (struct grub_file *file, grub_off_t offset) + file->device->net->stall = 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; + } +@@ -1753,6 +1757,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 ebbafe7..ee305e1 100644 +--- a/grub-core/net/tftp.c ++++ b/grub-core/net/tftp.c +@@ -400,6 +400,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 db21e79..a64a04c 100644 +--- a/include/grub/net.h ++++ b/include/grub/net.h +@@ -276,6 +276,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); +-- +cgit v1.1 + diff --git a/backport-normal-charset-Fix-array-out-of-bounds-formatting.patch b/backport-normal-charset-Fix-array-out-of-bounds-formatting.patch new file mode 100644 index 0000000..1f010c4 --- /dev/null +++ b/backport-normal-charset-Fix-array-out-of-bounds-formatting.patch @@ -0,0 +1,39 @@ +From 830a9628b2c9e1b6388af624aaf4a80818ed6be0 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Tue, 13 Jul 2021 13:24:38 +1000 +Subject: 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. + +Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=830a9628b2c9e1b6388af624aaf4a80818ed6be0 +Conflict:NA + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + 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 7778f1a..000e687 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 +-- +cgit v1.1 + diff --git a/backport-osdep-linux-Fix-md-array-device-enumeration.patch b/backport-osdep-linux-Fix-md-array-device-enumeration.patch new file mode 100644 index 0000000..3542a54 --- /dev/null +++ b/backport-osdep-linux-Fix-md-array-device-enumeration.patch @@ -0,0 +1,91 @@ +From c39f27cd678d61e8e84c1386695a33575c9ded44 Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Thu, 7 Oct 2021 16:33:16 -0700 +Subject: osdep/linux: Fix md array device enumeration + +GET_ARRAY_INFO's info.nr_disks does not map to GET_DISK_INFO's +disk.number, which is an internal kernel index. If an array has had drives +added, removed, etc., there may be gaps in GET_DISK_INFO's results. But +since the consumer of devicelist cannot tolerate gaps (it expects to walk +a NULL-terminated list of device name strings), the devicelist index (j) +must be tracked separately from the disk.number index (i). + +As part of this, since GRUB wants to only examine active (i.e. present +and non-failed) disks, the count of remaining disks (remaining) must be +tracked separately from the devicelist index (j). + +Additionally, drop a line with empty spaces only. + +Fixes: 49de079bbe1c (... (grub_util_raid_getmembers): Handle "removed" disks) +Fixes: 2b00217369ac (... Added support for RAID and LVM) +Fixes: https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1912043 +Fixes: https://savannah.gnu.org/bugs/index.php?59887 + +Signed-off-by: Kees Cook +Reviewed-by: Petr Vorel +Reviewed-by: Daniel Kiper + +Conflict: NA +Reference: https://git.savannah.gnu.org/cgit/grub.git/commit?id=c39f27cd678d61e8e84c1386695a33575c9ded44 + +--- + grub-core/osdep/linux/getroot.c | 24 +++++++++++++++++------- + 1 file changed, 17 insertions(+), 7 deletions(-) + +diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c +index cd58858..df422c6 100644 +--- a/grub-core/osdep/linux/getroot.c ++++ b/grub-core/osdep/linux/getroot.c +@@ -130,10 +130,20 @@ struct mountinfo_entry + char fstype[ESCAPED_PATH_MAX + 1], device[ESCAPED_PATH_MAX + 1]; + }; + ++/* ++ * GET_DISK_INFO nr_disks (total count) does not map to disk.number, ++ * which is an internal kernel index. Instead, do what mdadm does ++ * and keep scanning until we find enough valid disks. The limit is ++ * copied from there, which notes that it is sufficiently high given ++ * that the on-disk metadata for v1.x can only support 1920. ++ */ ++#define MD_MAX_DISKS 4096 ++ + static char ** + grub_util_raid_getmembers (const char *name, int bootable) + { + int fd, ret, i, j; ++ int remaining; + char **devicelist; + mdu_version_t version; + mdu_array_info_t info; +@@ -165,22 +175,22 @@ grub_util_raid_getmembers (const char *name, int bootable) + + devicelist = xcalloc (info.nr_disks + 1, sizeof (char *)); + +- for (i = 0, j = 0; j < info.nr_disks; i++) ++ remaining = info.nr_disks; ++ for (i = 0, j = 0; i < MD_MAX_DISKS && remaining > 0; i++) + { + disk.number = i; + ret = ioctl (fd, GET_DISK_INFO, &disk); + if (ret != 0) + grub_util_error (_("ioctl GET_DISK_INFO error: %s"), strerror (errno)); +- ++ ++ /* Skip: MD_DISK_REMOVED slots don't contribute to "remaining" count. */ + if (disk.state & (1 << MD_DISK_REMOVED)) + continue; ++ remaining--; + ++ /* Only record disks that are actively participating in the array. */ + if (disk.state & (1 << MD_DISK_ACTIVE)) +- devicelist[j] = grub_find_device (NULL, +- makedev (disk.major, disk.minor)); +- else +- devicelist[j] = NULL; +- j++; ++ devicelist[j++] = grub_find_device (NULL, makedev (disk.major, disk.minor)); + } + + devicelist[j] = NULL; +-- +cgit v1.1 diff --git a/backport-support-TPM2.0.patch b/backport-support-TPM2.0.patch new file mode 100644 index 0000000..a9497fd --- /dev/null +++ b/backport-support-TPM2.0.patch @@ -0,0 +1,99 @@ +From c4c243d19d77cab3591f0272c8e36619ccbbddf3 Mon Sep 17 00:00:00 2001 +From: gaoyusong +Date: Thu, 13 May 2021 18:34:23 +0800 +Subject: [PATCH] support TPM2.0 + +Conflict:NA +Reference:https://gitee.com/src-openeuler/grub2/commit/31e72c6b0a7d65b904afa2cb77e4e633cafacc6e.patch + +--- + grub-core/kern/verifiers.c | 25 +++++++++++++++++++------ + grub-core/script/execute.c | 12 +++++++++++- + 2 files changed, 30 insertions(+), 7 deletions(-) + +diff --git a/grub-core/kern/verifiers.c b/grub-core/kern/verifiers.c +index aa3dc7c..dfd73e5 100644 +--- a/grub-core/kern/verifiers.c ++++ b/grub-core/kern/verifiers.c +@@ -84,9 +84,16 @@ grub_verifiers_open (grub_file_t io, enum grub_file_type type) + grub_file_t ret = 0; + grub_err_t err; + int defer = 0; ++ int grub_env_flag = 0; ++ char *ptr = NULL; + + grub_dprintf ("verify", "file: %s type: %d\n", io->name, type); + ++ ptr = grub_strstr(io->name, "grubenv"); ++ if (ptr) { ++ grub_env_flag = 1; ++ } ++ + if ((type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_SIGNATURE + || (type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_VERIFY_SIGNATURE + || (type & GRUB_FILE_TYPE_SKIP_SIGNATURE)) +@@ -148,6 +155,8 @@ grub_verifiers_open (grub_file_t io, enum grub_file_type type) + verified->buf = grub_malloc (ret->size); + if (!verified->buf) + { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ "cannot allocate verified buffer, the %s is too large\n", io->name); + goto fail; + } + if (grub_file_read (io, verified->buf, ret->size) != (grub_ssize_t) ret->size) +@@ -158,9 +167,11 @@ grub_verifiers_open (grub_file_t io, enum grub_file_type type) + goto fail; + } + +- err = ver->write (context, verified->buf, ret->size); +- if (err) +- goto fail; ++ if (!grub_env_flag) { ++ err = ver->write (context, verified->buf, ret->size); ++ if (err) ++ goto fail; ++ } + + err = ver->fini ? ver->fini (context) : GRUB_ERR_NONE; + if (err) +@@ -179,9 +190,11 @@ grub_verifiers_open (grub_file_t io, enum grub_file_type type) + /* Verification done earlier. So, we are happy here. */ + flags & GRUB_VERIFY_FLAGS_DEFER_AUTH) + continue; +- err = ver->write (context, verified->buf, ret->size); +- if (err) +- goto fail; ++ if (!grub_env_flag) { ++ err = ver->write (context, verified->buf, ret->size); ++ if (err) ++ goto fail; ++ } + + err = ver->fini ? ver->fini (context) : GRUB_ERR_NONE; + if (err) +diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c +index 0c6dd9c..3e761c4 100644 +--- a/grub-core/script/execute.c ++++ b/grub-core/script/execute.c +@@ -1002,7 +1002,17 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) + argv.args[i]); + } + cmdstring[cmdlen - 1] = '\0'; +- grub_verify_string (cmdstring, GRUB_VERIFY_COMMAND); ++ ++ if (grub_strncmp(cmdstring, "[ 0 = 1 ]", 9) == 0) { ++ char res_str[] = "[ = 1 ]"; ++ grub_verify_string (res_str, GRUB_VERIFY_COMMAND); ++ } else if (grub_strncmp(cmdstring, "[ 0 = 1 -o = 1 ]", 17) == 0) { ++ char res_str[] = "[ = 1 -o = 1 ]"; ++ grub_verify_string (res_str, GRUB_VERIFY_COMMAND); ++ } else { ++ grub_verify_string (cmdstring, GRUB_VERIFY_COMMAND); ++ } ++ + grub_free (cmdstring); + invert = 0; + argc = argv.argc - 1; +-- +2.19.1 + diff --git a/backport-use-default-timestamp.patch b/backport-use-default-timestamp.patch new file mode 100644 index 0000000..23a1645 --- /dev/null +++ b/backport-use-default-timestamp.patch @@ -0,0 +1,60 @@ +From 8922ea771163655f1d5dc8da589a6291976ae489 Mon Sep 17 00:00:00 2001 +From: zhouyihang +Date: Thu, 10 Jun 2021 20:01:54 +0800 +Subject: [PATCH] huawei use default timestamp + +Conflict:NA +Reference:https://gitee.com/src-openeuler/grub2/commit/31e72c6b0a7d65b904afa2cb77e4e633cafacc6e.patch + +--- + docs/grub-dev.texi | 4 ++-- + docs/grub.texi | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi +index f488e82..355764a 100644 +--- a/docs/grub-dev.texi ++++ b/docs/grub-dev.texi +@@ -18,7 +18,7 @@ + + @copying + This developer manual is for GNU GRUB (version @value{VERSION}, +-@value{UPDATED}). ++24 June 2019). + + Copyright @copyright{} 1999,2000,2001,2002,2004,2005,2006,2008,2009,2010,2011 Free Software Foundation, Inc. + +@@ -40,7 +40,7 @@ Invariant Sections. + @titlepage + @sp 10 + @title the GNU GRUB developer manual +-@subtitle The GRand Unified Bootloader, version @value{VERSION}, @value{UPDATED}. ++@subtitle The GRand Unified Bootloader, version @value{VERSION}, 24 June 2019. + @author Yoshinori K. Okuji + @author Colin D Bennett + @author Vesa Jääskeläinen +diff --git a/docs/grub.texi b/docs/grub.texi +index 262388c..41c1a89 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -18,7 +18,7 @@ + + @copying + This manual is for GNU GRUB (version @value{VERSION}, +-@value{UPDATED}). ++24 June 2019). + + Copyright @copyright{} 1999,2000,2001,2002,2004,2006,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. + +@@ -48,7 +48,7 @@ Invariant Sections. + @titlepage + @sp 10 + @title the GNU GRUB manual +-@subtitle The GRand Unified Bootloader, version @value{VERSION}, @value{UPDATED}. ++@subtitle The GRand Unified Bootloader, version @value{VERSION}, 24 June 2019. + @author Gordon Matzigkeit + @author Yoshinori K. Okuji + @author Colin Watson +-- +2.27.0 + diff --git a/backport-util-grub-fstest-Fix-resource-leaks-in-cmd_cmp.patch b/backport-util-grub-fstest-Fix-resource-leaks-in-cmd_cmp.patch new file mode 100644 index 0000000..4f15c7c --- /dev/null +++ b/backport-util-grub-fstest-Fix-resource-leaks-in-cmd_cmp.patch @@ -0,0 +1,45 @@ +From 53f08de12bfdd10207a8e6a062c9778f5ab6df87 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Tue, 26 Oct 2021 15:02:37 +0000 +Subject: util/grub-fstest: Fix resource leaks in cmd_cmp() + +In the function cmd_cmp() within the while loop, srcnew and destnew are +being allocated but are never freed either before leaving scope or in +the recursive calls being made to cmd_cmp(). + +Fixes: CID 314032 +Fixes: CID 314045 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper + +Conflict: NA +Reference: https://git.savannah.gnu.org/cgit/grub.git/commit?id=53f08de12bfdd10207a8e6a062c9778f5ab6df87 + +--- + util/grub-fstest.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/util/grub-fstest.c b/util/grub-fstest.c +index 8386564..486f1dc 100644 +--- a/util/grub-fstest.c ++++ b/util/grub-fstest.c +@@ -300,9 +300,15 @@ cmd_cmp (char *src, char *dest) + strcpy (ptr, entry->d_name); + + if (grub_util_is_special_file (destnew)) +- continue; ++ { ++ free (srcnew); ++ free (destnew); ++ continue; ++ } + + cmd_cmp (srcnew, destnew); ++ free (srcnew); ++ free (destnew); + } + grub_util_fd_closedir (dir); + return; +-- +cgit v1.1 diff --git a/backport-util-grub-install-common-Fix-memory-leak-in-copy_all.patch b/backport-util-grub-install-common-Fix-memory-leak-in-copy_all.patch new file mode 100644 index 0000000..ed3cced --- /dev/null +++ b/backport-util-grub-install-common-Fix-memory-leak-in-copy_all.patch @@ -0,0 +1,38 @@ +From e07fcea291ac8aa430db6e57d6e8e08894127fe2 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Tue, 26 Oct 2021 15:02:35 +0000 +Subject: util/grub-install-common: Fix memory leak in copy_all() + +The copy_all() function skips a section of code using continue, but +fails to free the memory in srcf first, leaking it. + +Fixes: CID 314026 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper + +Conflict: NA +Reference: https://git.savannah.gnu.org/cgit/grub.git/commit?id=e07fcea291ac8aa430db6e57d6e8e08894127fe2 + +--- + util/grub-install-common.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/util/grub-install-common.c b/util/grub-install-common.c +index 4e212e6..fe77e39 100644 +--- a/util/grub-install-common.c ++++ b/util/grub-install-common.c +@@ -754,7 +754,10 @@ copy_all (const char *srcd, + srcf = grub_util_path_concat (2, srcd, de->d_name); + if (grub_util_is_special_file (srcf) + || grub_util_is_directory (srcf)) +- continue; ++ { ++ free (srcf); ++ continue; ++ } + dstf = grub_util_path_concat (2, dstd, de->d_name); + grub_install_compress_file (srcf, dstf, 1); + free (srcf); +-- +cgit v1.1 diff --git a/backport-util-grub-mkfont-Fix-memory-leak-in-write_font_pf2.patch b/backport-util-grub-mkfont-Fix-memory-leak-in-write_font_pf2.patch new file mode 100644 index 0000000..0481a86 --- /dev/null +++ b/backport-util-grub-mkfont-Fix-memory-leak-in-write_font_pf2.patch @@ -0,0 +1,35 @@ +From b1fae9c1ba1f3ba4c9b4d39ad6eaedf9d77af7ed Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Tue, 26 Oct 2021 15:02:38 +0000 +Subject: util/grub-mkfont: Fix memory leak in write_font_pf2() + +In the function write_font_pf2() memory is allocated for font_name to +construct a new name, but it is not released before returning from the +function, leaking the allocated memory. + +Fixes: CID 314015 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper + +Conflict: NA +Reference: https://git.savannah.gnu.org/cgit/grub.git/commit?id=b1fae9c1ba1f3ba4c9b4d39ad6eaedf9d77af7ed + +--- + util/grub-mkfont.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c +index 0fe45a6..fdfd70d 100644 +--- a/util/grub-mkfont.c ++++ b/util/grub-mkfont.c +@@ -928,6 +928,7 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file) + file, output_file); + } + ++ free (font_name); + fclose (file); + } + +-- +cgit v1.1 diff --git a/backport-util-grub-mkrescue-Fix-memory-leak-in-write_part.patch b/backport-util-grub-mkrescue-Fix-memory-leak-in-write_part.patch new file mode 100644 index 0000000..3110e48 --- /dev/null +++ b/backport-util-grub-mkrescue-Fix-memory-leak-in-write_part.patch @@ -0,0 +1,34 @@ +From eff17a6b2d563fe9a0917e048776ed9ce2da4b80 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Tue, 26 Oct 2021 15:02:36 +0000 +Subject: util/grub-mkrescue: Fix memory leak in write_part() + +In the function write_part(), the value of inname is not used beyond +the grub_util_fopen() call, so it should be freed to avoid leakage. + +Fixes: CID 314028 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper + +Conflict: NA +Reference: https://git.savannah.gnu.org/cgit/grub.git/commit?id=eff17a6b2d563fe9a0917e048776ed9ce2da4b80 + +--- + util/grub-mkrescue.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c +index fb4dcc6..59c48b1 100644 +--- a/util/grub-mkrescue.c ++++ b/util/grub-mkrescue.c +@@ -229,6 +229,7 @@ write_part (FILE *f, const char *srcdir) + char *inname = grub_util_path_concat (2, srcdir, "partmap.lst"); + char buf[260]; + in = grub_util_fopen (inname, "rb"); ++ free (inname); + if (!in) + return; + while (fgets (buf, 256, in)) +-- +cgit v1.1 diff --git a/backport-util-mkimage-Fix-wrong-PE32-section-sizes-for-some-arches.patch b/backport-util-mkimage-Fix-wrong-PE32-section-sizes-for-some-arches.patch new file mode 100644 index 0000000..e986a31 --- /dev/null +++ b/backport-util-mkimage-Fix-wrong-PE32-section-sizes-for-some-arches.patch @@ -0,0 +1,50 @@ +From c0e647eb0e2bd09315612446cb4d90f7f75cb44c Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Tue, 27 Apr 2021 12:25:08 +0200 +Subject: util/mkimage: Fix wrong PE32+ section sizes for some arches + +The commit f60ba9e5945 (util/mkimage: Refactor section setup to use a helper) +added a helper function to setup PE sections. But it also changed how the +raw data offsets were calculated since all the section sizes are aligned. +However, for some platforms, i.e ia64-efi and arm64-efi, the kernel image +size is not aligned using the section alignment. This leads to the situation +in which the mods section offset in its PE section header does not match its +real placement in the PE file. So, finally the GRUB is not able to locate +and load built-in modules. + +The problem surfaces on ia64-efi and arm64-efi because both platforms +require additional relocation data which is added behind .bss section. +So, we have to add some padding behind this extra data to make the +beginning of mods section properly aligned in the PE file. Fix it by +aligning the kernel_size to the section alignment. That makes the sizes +and offsets in the PE section headers to match relevant sections in the +PE32+ binary file. + +Reported-by: John Paul Adrian Glaubitz +Signed-off-by: Javier Martinez Canillas +Tested-by: John Paul Adrian Glaubitz +Reviewed-by: Daniel Kiper +Conflict:NA +Reference:https://git.savannah.gnu.org/cgit/grub.git/patch/?id=c0e647eb0e2bd09315612446cb4d90f7f75cb44c +--- + util/grub-mkimagexx.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c +index 00f49ccaa..d78fa3e53 100644 +--- a/util/grub-mkimagexx.c ++++ b/util/grub-mkimagexx.c +@@ -2388,6 +2388,10 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path, + layout->kernel_size += ALIGN_UP (layout->got_size, 16); + } + #endif ++ ++ if (image_target->id == IMAGE_EFI) ++ layout->kernel_size = ALIGN_UP (layout->kernel_size, ++ GRUB_PE32_FILE_ALIGNMENT); + } + else + { +-- +cgit v1.2.1 + diff --git a/backport-video-readers-jpeg-Abort-sooner-if-a-read.patch b/backport-video-readers-jpeg-Abort-sooner-if-a-read.patch new file mode 100644 index 0000000..501d56f --- /dev/null +++ b/backport-video-readers-jpeg-Abort-sooner-if-a-read.patch @@ -0,0 +1,260 @@ +From d5caac8ab79d068ad9a41030c772d03a4d4fbd7b Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Mon, 28 Jun 2021 14:16:14 +1000 +Subject: 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. + +Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=d5caac8ab79d068ad9a41030c772d03a4d4fbd7b +Conflict:NA + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + 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 c47ffd6..806c56c 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); +@@ -208,6 +234,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) +@@ -258,6 +286,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) + { +@@ -269,6 +299,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"); +@@ -300,6 +332,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"); +@@ -325,6 +360,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; +@@ -504,7 +541,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; +@@ -519,6 +556,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])) +@@ -533,11 +573,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]; +@@ -545,6 +587,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 +@@ -603,7 +646,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"); +@@ -616,7 +660,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; +@@ -624,11 +669,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"); + +@@ -646,6 +694,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; +@@ -666,17 +715,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; + +-- +cgit v1.1 + diff --git a/backport-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch b/backport-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch new file mode 100644 index 0000000..6d260fe --- /dev/null +++ b/backport-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch @@ -0,0 +1,79 @@ +From 22a3f97d39f6a10b08ad7fd1cc47c4dcd10413f6 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Wed, 7 Jul 2021 15:38:19 +1000 +Subject: 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 + +Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=22a3f97d39f6a10b08ad7fd1cc47c4dcd10413f6 +Conflict:NA + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/video/readers/jpeg.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c +index 579bbe8..09596fb 100644 +--- a/grub-core/video/readers/jpeg.c ++++ b/grub-core/video/readers/jpeg.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -699,6 +700,7 @@ static grub_err_t + grub_jpeg_decode_data (struct grub_jpeg_data *data) + { + unsigned c1, vb, hb, nr1, nc1; ++ unsigned stride_a, stride_b, stride; + int rst = data->dri; + grub_err_t err = GRUB_ERR_NONE; + +@@ -711,8 +713,14 @@ 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 (grub_mul(vb, data->image_width, &stride_a) || ++ grub_mul(hb, nc1, &stride_b) || ++ grub_sub(stride_a, stride_b, &stride)) ++ 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) ++ data->r1++, data->bitmap_ptr += stride * 3) + for (c1 = 0; c1 < nc1 && (!data->dri || rst); + c1++, rst--, data->bitmap_ptr += hb * 3) + { +-- +cgit v1.1 + diff --git a/backport-video-readers-jpeg-Do-not-reallocate-a-given.patch b/backport-video-readers-jpeg-Do-not-reallocate-a-given.patch new file mode 100644 index 0000000..fc862b3 --- /dev/null +++ b/backport-video-readers-jpeg-Do-not-reallocate-a-given.patch @@ -0,0 +1,34 @@ +From 768ef2199e0265cf455b154f1a80a612f02274c8 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Mon, 28 Jun 2021 14:16:58 +1000 +Subject: 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. + +Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=768ef2199e0265cf455b154f1a80a612f02274c8 +Conflict:NA + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + 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 806c56c..2284a6c 100644 +--- a/grub-core/video/readers/jpeg.c ++++ b/grub-core/video/readers/jpeg.c +@@ -251,6 +251,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; +-- +cgit v1.1 + diff --git a/backport-video-readers-jpeg-Refuse-to-handle-multiple.patch b/backport-video-readers-jpeg-Refuse-to-handle-multiple.patch new file mode 100644 index 0000000..3b3f381 --- /dev/null +++ b/backport-video-readers-jpeg-Refuse-to-handle-multiple.patch @@ -0,0 +1,48 @@ +From 166a4d61448f74745afe1dac2f2cfb85d04909bf Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Mon, 28 Jun 2021 14:25:17 +1000 +Subject: 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. + +Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=166a4d61448f74745afe1dac2f2cfb85d04909bf +Conflict:NA + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + 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 2284a6c..579bbe8 100644 +--- a/grub-core/video/readers/jpeg.c ++++ b/grub-core/video/readers/jpeg.c +@@ -683,6 +683,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)) +@@ -705,8 +708,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) +-- +cgit v1.1 + diff --git a/backport-video-readers-png-Abort-sooner-if-a-read.patch b/backport-video-readers-png-Abort-sooner-if-a-read.patch new file mode 100644 index 0000000..61ad6bb --- /dev/null +++ b/backport-video-readers-png-Abort-sooner-if-a-read.patch @@ -0,0 +1,203 @@ +From 5bff31cdb6b93d738f850834e6291df1d0b136fa Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Tue, 6 Jul 2021 14:02:55 +1000 +Subject: 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. + +Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=5bff31cdb6b93d738f850834e6291df1d0b136fa +Conflict:NA + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + 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 54dfedf..d715c46 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) + 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; +@@ -1045,6 +1082,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) +-- +cgit v1.1 + diff --git a/backport-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch b/backport-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch new file mode 100644 index 0000000..9f7eae6 --- /dev/null +++ b/backport-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch @@ -0,0 +1,44 @@ +From 210245129c932dc9e1c2748d9d35524fb95b5042 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Tue, 6 Jul 2021 23:25:07 +1000 +Subject: 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 + +Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=210245129c932dc9e1c2748d9d35524fb95b5042 +Conflict:NA + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + 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 a3161e2..d7ed5aa 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]; + +-- +cgit v1.1 + diff --git a/backport-video-readers-png-Drop-greyscale-support-to-fix-heap.patch b/backport-video-readers-png-Drop-greyscale-support-to-fix-heap.patch new file mode 100644 index 0000000..e42c0de --- /dev/null +++ b/backport-video-readers-png-Drop-greyscale-support-to-fix-heap.patch @@ -0,0 +1,174 @@ +From e623866d9286410156e8b9d2c82d6253a1b22d08 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Tue, 6 Jul 2021 18:51:35 +1000 +Subject: 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 + +Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=e623866d9286410156e8b9d2c82d6253a1b22d08 +Conflict:NA + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/video/readers/png.c | 87 +++-------------------------------- + 1 file changed, 7 insertions(+), 80 deletions(-) + +diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c +index 8955b8e..ccc2e36 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, +@@ -957,60 +938,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. */ + #ifndef GRUB_CPU_WORDS_BIGENDIAN +-- +2.19.1 + diff --git a/backport-video-readers-png-Refuse-to-handle-multiple-image-headers.patch b/backport-video-readers-png-Refuse-to-handle-multiple-image-headers.patch new file mode 100644 index 0000000..88d8bff --- /dev/null +++ b/backport-video-readers-png-Refuse-to-handle-multiple-image-headers.patch @@ -0,0 +1,33 @@ +From 347880a13c239b4c2811c94c9a7cf78b607332e3 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Tue, 6 Jul 2021 14:13:40 +1000 +Subject: video/readers/png: Refuse to handle multiple image headers + +This causes the bitmap to be leaked. Do not permit multiple image headers. + +Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=347880a13c239b4c2811c94c9a7cf78b607332e3 +Conflict:NA + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + 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 d715c46..35ae553 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); + +-- +cgit v1.1 + diff --git a/backport-video-readers-png-Sanity-check-some-huffman-codes.patch b/backport-video-readers-png-Sanity-check-some-huffman-codes.patch new file mode 100644 index 0000000..3961eea --- /dev/null +++ b/backport-video-readers-png-Sanity-check-some-huffman-codes.patch @@ -0,0 +1,45 @@ +From 690bee69fae6b4bd911293d6b7e56774e29fdf64 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Tue, 6 Jul 2021 19:19:11 +1000 +Subject: 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. + +Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=690bee69fae6b4bd911293d6b7e56774e29fdf64 +Conflict:NA + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + 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 d7ed5aa..7f2ba78 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]); +-- +cgit v1.1 + diff --git a/bugfix-double-grub-x86_64-efi-mm-pool.patch b/bugfix-double-grub-x86_64-efi-mm-pool.patch new file mode 100644 index 0000000..92e2f3d --- /dev/null +++ b/bugfix-double-grub-x86_64-efi-mm-pool.patch @@ -0,0 +1,44 @@ +From 6d56530bd04534f038f775624e1c4942a8bf95de Mon Sep 17 00:00:00 2001 +From: fengtao +Date: Mon, 14 Feb 2022 16:17:15 +0800 +Subject: [PATCH] double grub x86_64-efi mm pool + +grub2 will construct mm pool by uefi memory function +for grub memory manger, grub_malloc, grub_free, etc. + +but we have limit memory address under x86_64 platform in +commit:456eb8632e7(Try to pick better locations for kernel and initrd) +so, x86_64 can only address available ram under 4GB. + +there comes a problem, when available memory under 4GB is not enough, +and initrd is large, like 200MB~300MB. we got out of memory when +verifiers use grub_malloc. + +Finally, we descide to double grub mm pool when we init it. And what +the point is, we cannot init all of the available memory under 4GB. +you can read commit:5ff84fb244b +(x86-efi: Allow initrd+params+cmdline allocations above 4GB.) + +--- + grub-core/kern/efi/mm.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c +index f64f79e..50116a6 100644 +--- a/grub-core/kern/efi/mm.c ++++ b/grub-core/kern/efi/mm.c +@@ -658,7 +658,11 @@ grub_efi_mm_init (void) + /* By default, request a quarter of the available memory. */ + total_pages = get_total_pages (filtered_memory_map, desc_size, + filtered_memory_map_end); ++#if defined(__x86_64__) ++ required_pages = (total_pages >> 1); ++#else + required_pages = (total_pages >> 2); ++#endif + if (required_pages < BYTES_TO_PAGES (MIN_HEAP_SIZE)) + required_pages = BYTES_TO_PAGES (MIN_HEAP_SIZE); + else if (required_pages > BYTES_TO_PAGES (MAX_HEAP_SIZE)) +-- +2.27.0 + diff --git a/bugfix-net-fix-null-pointer-dereference-when-parsing-ICMP6_.patch b/bugfix-net-fix-null-pointer-dereference-when-parsing-ICMP6_.patch new file mode 100644 index 0000000..8d6c071 --- /dev/null +++ b/bugfix-net-fix-null-pointer-dereference-when-parsing-ICMP6_.patch @@ -0,0 +1,34 @@ +From 17216748c827290d32336c6ed0af71bcf0849672 Mon Sep 17 00:00:00 2001 +From: Qiumiao Zhang +Date: Thu, 17 Feb 2022 07:27:58 -0500 +Subject: [PATCH] net: fix null pointer dereference when parsing + ICMP6_ROUTER_ADVERTISE messages + +During UEFI PXE boot in IPv6 network, if the DHCP server adopts +stateful automatic configuration, then the client receives a +ICMP6_ROUTER_ADVERTISE multicast message from the server. This may be +received without the interfaced having a configured network address, +so orig_inf will be null, which can lead to a null dereference when +creating the default route. + +Fixes bug: https://savannah.gnu.org/bugs/index.php?62072 +--- + grub-core/net/icmp6.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/net/icmp6.c b/grub-core/net/icmp6.c +index 2cbd95d..264fc4a 100644 +--- a/grub-core/net/icmp6.c ++++ b/grub-core/net/icmp6.c +@@ -477,7 +477,7 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb, + + /* May not have gotten slaac info, find a global address on this + card. */ +- if (route_inf == NULL) ++ if (route_inf == NULL && orig_inf != NULL) + { + FOR_NET_NETWORK_LEVEL_INTERFACES (inf) + { +-- +2.19.1 + diff --git a/grub.patches b/grub.patches index fa8b776..b019c06 100644 --- a/grub.patches +++ b/grub.patches @@ -354,3 +354,55 @@ Patch0353: backport-0080-misc-Add-parentheses-around-ALIGN_UP-and-ALIGN_DOWN-.pa Patch0354: backport-0081-verifiers-Fix-calling-uninitialized-function-pointer.patch Patch0355: backport-templates-Fix-bad-test-on-GRUB_DISABLE_SUBMENU.patch Patch0356: backport-CVE-2021-3981-restore-umask-for-the-grub.patch +Patch0357: backport-0081-efi-Use-grub_is_lockdown-instead-of-hardcoding-a-dis-2.patch +Patch0358: backport-disk-cryptodisk-Fix-potential-integer-overflow.patch +Patch0359: backport-efi-The-device-tree-must-be-in-EfiACPIReclaimMemory.patch +Patch0360: backport-fs-ext2-Fix-a-file-not-found-error-when-a-symlink-filesize-is-equal-to-60.patch +Patch0361: backport-io-lzopio-Resolve-unnecessary-self-assignment-errors.patch +Patch0362: backport-loader-i386-linux-Do-not-use-grub_le_to_cpu32-for-relocatable-variable.patch +Patch0363: backport-util-mkimage-Fix-wrong-PE32-section-sizes-for-some-arches.patch +Patch0364: backport-enable-http-and-https-boot.patch +Patch0365: backport-support-TPM2.0.patch +Patch0366: backport-use-default-timestamp.patch +Patch0367: backport-fix-CVE-2020-15705.patch +Patch0368: backport-grub2-set-password-prompts-to-enter-the-current-pass.patch +Patch0369: backport-Avoid-Wsign-compare-in-rijndael-do_setkey.patch +Patch0370: backport-disk-ldm-Fix-resource-leak.patch +Patch0371: backport-io-gzio-Fix-possible-use-of-uninitialized-variable-in-huft_build.patch +Patch0372: backport-osdep-linux-Fix-md-array-device-enumeration.patch +Patch0373: backport-util-grub-fstest-Fix-resource-leaks-in-cmd_cmp.patch +Patch0374: backport-util-grub-install-common-Fix-memory-leak-in-copy_all.patch +Patch0375: backport-util-grub-mkfont-Fix-memory-leak-in-write_font_pf2.patch +Patch0376: backport-util-grub-mkrescue-Fix-memory-leak-in-write_part.patch +Patch0377: bugfix-double-grub-x86_64-efi-mm-pool.patch +Patch0378: bugfix-net-fix-null-pointer-dereference-when-parsing-ICMP6_.patch +Patch0379: backport-correct-closing-of-SNP-protocol.patch +Patch0380: backport-fix-misspelled-variable-BUILD_LDFAGS.patch +Patch0381: backport-Fix-partmap_test-for-arm-efi.patch +Patch0382: backport-loader-efi-chainloader-grub_load_and_start_image-doe.patch +Patch0383: backport-loader-efi-chainloader-Simplify-the-loader-state.patch +Patch0384: backport-commands-boot-Add-API-to-pass-context-to-loader.patch +Patch0385: backport-loader-efi-chainloader-Use-grub_loader_set_ex.patch +Patch0386: backport-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch +Patch0387: backport-loader-i386-efi-linux-Use-grub_loader_set_ex.patch +Patch0388: backport-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch +Patch0389: backport-kern-file-Do-not-leak-device_name-on-error-in.patch +Patch0390: backport-video-readers-png-Abort-sooner-if-a-read.patch +Patch0391: backport-video-readers-png-Refuse-to-handle-multiple-image-headers.patch +Patch0392: backport-video-readers-png-Drop-greyscale-support-to-fix-heap.patch +Patch0393: backport-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch +Patch0394: backport-video-readers-png-Sanity-check-some-huffman-codes.patch +Patch0395: backport-video-readers-jpeg-Abort-sooner-if-a-read.patch +Patch0396: backport-video-readers-jpeg-Do-not-reallocate-a-given.patch +Patch0397: backport-video-readers-jpeg-Refuse-to-handle-multiple.patch +Patch0398: backport-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch +Patch0399: backport-normal-charset-Fix-array-out-of-bounds-formatting.patch +Patch0400: backport-net-ip-Do-IP-fragment-maths-safely.patch +Patch0401: backport-net-netbuff-Block-overly-large-netbuff-allocs.patch +Patch0402: backport-net-dns-Fix-double-free-addresses-on-corrupt-DNS.patch +Patch0403: backport-net-dns-Dont-read-past-the-end-of-the-string.patch +Patch0404: backport-net-tftp-Prevent-a-UAF-and-double-free-from.patch +Patch0405: backport-net-tftp-Avoid-a-trivial-UAF.patch +Patch0406: backport-net-http-Do-not-tear-down-socket-if-its-already.patch +Patch0407: backport-net-http-Fix-OOB-write-for-split-http-headers.patch +Patch0408: backport-net-http-Error-out-on-headers-with-LF-without-CR.patch \ No newline at end of file diff --git a/grub2.spec b/grub2.spec index ed9b917..ea686a5 100644 --- a/grub2.spec +++ b/grub2.spec @@ -8,7 +8,7 @@ Name: grub2 Epoch: 1 Version: 2.04 -Release: 23 +Release: 24 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -450,6 +450,13 @@ rm -r /boot/grub2.tmp/ || : %{_datadir}/man/man* %changelog + +* Tue Jun 14 2022 chenjirong - 2.04-24 +- Type:CVE +- CVE:CVE-2021-3697 CVE-2022-28735 CVE-2022-28736 CVE-2022-28734 CVE-2022-28733 CVE-2021-3695 CVE-2021-3696 +- SUG:NA +- DESC:fix CVE-2021-3697 CVE-2022-28735 CVE-2022-28736 CVE-2022-28734 CVE-2022-28733 CVE-2021-3695 CVE-2021-3696 + * Wed Mar 16 2022 xihaochen - 2.04-23 - Type:CVE - CVE:CVE-2021-3981