From 110f853c69f4a25046083d74fbb91139f384ba1b Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Mar 16 2021 13:32:22 +0000 Subject: import grub2-2.02-0.87.el7_9.6 --- diff --git a/README.debrand b/README.debrand deleted file mode 100644 index 01c46d2..0000000 --- a/README.debrand +++ /dev/null @@ -1,2 +0,0 @@ -Warning: This package was configured for automatic debranding, but the changes -failed to apply. diff --git a/SOURCES/0335-tftp-roll-over-block-counter-to-prevent-timeouts-wit.patch b/SOURCES/0335-tftp-roll-over-block-counter-to-prevent-timeouts-wit.patch new file mode 100644 index 0000000..2348e91 --- /dev/null +++ b/SOURCES/0335-tftp-roll-over-block-counter-to-prevent-timeouts-wit.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Mon, 24 Aug 2020 14:46:27 +0200 +Subject: [PATCH] tftp: roll over block counter to prevent timeouts with data + packets + +The block number is a 16-bit counter which only allows to fetch +files no bigger than 65535 * blksize. To avoid this limit, the +counter is rolled over. This behavior isn't defined in RFC 1350 +but is handled by many TFTP servers and it's what GRUB was doing +before implicitly due an overflow. + +Fixing that bug led to TFTP timeouts, since GRUB wasn't acking +data packets anymore for files with size bigger than the maximum +mentioned above. Restore the old behavior to prevent this issue. + +Resolves: rhbz#1869987 + +Suggested-by: Peter Jones +Signed-off-by: Javier Martinez Canillas +--- + grub-core/net/tftp.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c +index 79c16f9b041..b9a4b607a3d 100644 +--- a/grub-core/net/tftp.c ++++ b/grub-core/net/tftp.c +@@ -183,8 +183,20 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)), + return GRUB_ERR_NONE; + } + +- /* Ack old/retransmitted block. */ +- if (grub_be_to_cpu16 (tftph->u.data.block) < data->block + 1) ++ /* ++ * Ack old/retransmitted block. ++ * ++ * The block number is a 16-bit counter which only allows to fetch ++ * files no bigger than 65535 * blksize. To avoid this limit, the ++ * counter is rolled over. This behavior isn't defined in RFC 1350 ++ * but is handled by many TFTP servers and it's what GRUB was doing ++ * before implicitly due an overflow. ++ * ++ * Fixing that bug led to TFTP timeouts, since GRUB wasn't acking ++ * data packets anymore for files with size bigger than the maximum ++ * mentioned above. Restore the old behavior to prevent this issue. ++ */ ++ if (grub_be_to_cpu16 (tftph->u.data.block) < ((data->block + 1) & 0xffffu)) + ack (data, grub_be_to_cpu16 (tftph->u.data.block)); + /* Ignore unexpected block. */ + else if (grub_be_to_cpu16 (tftph->u.data.block) > data->block + 1) diff --git a/SOURCES/0335-tftp-roll-over-block-counter-to-prevent-timeouts-with.patch b/SOURCES/0335-tftp-roll-over-block-counter-to-prevent-timeouts-with.patch deleted file mode 100644 index 2348e91..0000000 --- a/SOURCES/0335-tftp-roll-over-block-counter-to-prevent-timeouts-with.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Mon, 24 Aug 2020 14:46:27 +0200 -Subject: [PATCH] tftp: roll over block counter to prevent timeouts with data - packets - -The block number is a 16-bit counter which only allows to fetch -files no bigger than 65535 * blksize. To avoid this limit, the -counter is rolled over. This behavior isn't defined in RFC 1350 -but is handled by many TFTP servers and it's what GRUB was doing -before implicitly due an overflow. - -Fixing that bug led to TFTP timeouts, since GRUB wasn't acking -data packets anymore for files with size bigger than the maximum -mentioned above. Restore the old behavior to prevent this issue. - -Resolves: rhbz#1869987 - -Suggested-by: Peter Jones -Signed-off-by: Javier Martinez Canillas ---- - grub-core/net/tftp.c | 16 ++++++++++++++-- - 1 file changed, 14 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c -index 79c16f9b041..b9a4b607a3d 100644 ---- a/grub-core/net/tftp.c -+++ b/grub-core/net/tftp.c -@@ -183,8 +183,20 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)), - return GRUB_ERR_NONE; - } - -- /* Ack old/retransmitted block. */ -- if (grub_be_to_cpu16 (tftph->u.data.block) < data->block + 1) -+ /* -+ * Ack old/retransmitted block. -+ * -+ * The block number is a 16-bit counter which only allows to fetch -+ * files no bigger than 65535 * blksize. To avoid this limit, the -+ * counter is rolled over. This behavior isn't defined in RFC 1350 -+ * but is handled by many TFTP servers and it's what GRUB was doing -+ * before implicitly due an overflow. -+ * -+ * Fixing that bug led to TFTP timeouts, since GRUB wasn't acking -+ * data packets anymore for files with size bigger than the maximum -+ * mentioned above. Restore the old behavior to prevent this issue. -+ */ -+ if (grub_be_to_cpu16 (tftph->u.data.block) < ((data->block + 1) & 0xffffu)) - ack (data, grub_be_to_cpu16 (tftph->u.data.block)); - /* Ignore unexpected block. */ - else if (grub_be_to_cpu16 (tftph->u.data.block) > data->block + 1) diff --git a/SOURCES/0336-at_keyboard-Fix-keyboards-that-report-IBM-PC-AT-scan.patch b/SOURCES/0336-at_keyboard-Fix-keyboards-that-report-IBM-PC-AT-scan.patch deleted file mode 100644 index 868153b..0000000 --- a/SOURCES/0336-at_keyboard-Fix-keyboards-that-report-IBM-PC-AT-scan.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Fri, 6 Nov 2020 14:14:24 +0100 -Subject: [PATCH] at_keyboard: Fix keyboards that report IBM PC AT scan codes -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -GRUB has support for both the IBM PC XT (Set 1) and IBM PC AT (Set 2) key -scan code mappings. But the driver always hardcodes to Set 1, overwriting -the mode that was queried in the grub_keyboard_controller_init() function. - -This breaks keyboard mapping on machines whose firmwares are not using the -Set 1. For example, this is the case in Lenovo P71 and HP Elitebook 8770W -laptops that report key scan codes using Set 2. - -Instead of hardcoding to Set 1, use the value that was queried before. - -Reported-by: Renaud Métrich -Signed-off-by: Javier Martinez Canillas ---- - grub-core/term/at_keyboard.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c -index b4257e84a04..cbec595d166 100644 ---- a/grub-core/term/at_keyboard.c -+++ b/grub-core/term/at_keyboard.c -@@ -355,7 +355,7 @@ set_scancodes (void) - } - - #if !USE_SCANCODE_SET -- current_set = 1; -+ current_set = grub_keyboard_orig_set; - return; - #else - diff --git a/SOURCES/0336-kern-Add-lockdown-support.patch b/SOURCES/0336-kern-Add-lockdown-support.patch new file mode 100644 index 0000000..f76e7e9 --- /dev/null +++ b/SOURCES/0336-kern-Add-lockdown-support.patch @@ -0,0 +1,441 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Fri, 19 Feb 2021 10:33:54 +0100 +Subject: [PATCH] kern: Add lockdown support + +When the GRUB starts on a secure boot platform, some commands can be +used to subvert the protections provided by the verification mechanism and +could lead to booting untrusted system. + +To prevent that situation, allow GRUB to be locked down. That way the code +may check if GRUB has been locked down and further restrict the commands +that are registered or what subset of their functionality could be used. + +The lockdown support adds the following components: + +* The grub_lockdown() function which can be used to lockdown GRUB if, + e.g., UEFI Secure Boot is enabled. + +* The grub_is_lockdown() function which can be used to check if the GRUB + was locked down. + +* A verifier that flags OS kernels, the GRUB modules, Device Trees and ACPI + tables as GRUB_VERIFY_FLAGS_DEFER_AUTH to defer verification to other + verifiers. These files are only successfully verified if another registered + verifier returns success. Otherwise, the whole verification process fails. + + For example, PE/COFF binaries verification can be done by the shim_lock + verifier which validates the signatures using the shim_lock protocol. + However, the verification is not deferred directly to the shim_lock verifier. + The shim_lock verifier is hooked into the verification process instead. + +* A set of grub_{command,extcmd}_lockdown functions that can be used by + code registering command handlers, to only register unsafe commands if + the GRUB has not been locked down. + +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + grub-core/Makefile.core.def | 1 + + grub-core/commands/extcmd.c | 23 +++++++++++ + grub-core/kern/command.c | 24 ++++++++++++ + grub-core/kern/lockdown.c | 93 +++++++++++++++++++++++++++++++++++++++++++++ + include/grub/command.h | 5 +++ + include/grub/extcmd.h | 7 ++++ + include/grub/lockdown.h | 44 +++++++++++++++++++++ + conf/Makefile.common | 2 + + docs/grub-dev.texi | 27 +++++++++++++ + docs/grub.texi | 9 +++++ + grub-core/Makefile.am | 5 ++- + 11 files changed, 239 insertions(+), 1 deletion(-) + create mode 100644 grub-core/kern/lockdown.c + create mode 100644 include/grub/lockdown.h + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 00110ae5efd..2beb1d83a63 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -173,6 +173,7 @@ kernel = { + efi = kern/efi/init.c; + efi = kern/efi/mm.c; + efi = term/efi/console.c; ++ efi = kern/lockdown.c; + efi = lib/envblk.c; + + common = kern/efi/sb.c; +diff --git a/grub-core/commands/extcmd.c b/grub-core/commands/extcmd.c +index 69574e2b05b..90a5ca24a64 100644 +--- a/grub-core/commands/extcmd.c ++++ b/grub-core/commands/extcmd.c +@@ -19,6 +19,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -110,6 +111,28 @@ grub_register_extcmd (const char *name, grub_extcmd_func_t func, + summary, description, parser, 1); + } + ++static grub_err_t ++grub_extcmd_lockdown (grub_extcmd_context_t ctxt __attribute__ ((unused)), ++ int argc __attribute__ ((unused)), ++ char **argv __attribute__ ((unused))) ++{ ++ return grub_error (GRUB_ERR_ACCESS_DENIED, ++ N_("%s: the command is not allowed when lockdown is enforced"), ++ ctxt->extcmd->cmd->name); ++} ++ ++grub_extcmd_t ++grub_register_extcmd_lockdown (const char *name, grub_extcmd_func_t func, ++ grub_command_flags_t flags, const char *summary, ++ const char *description, ++ const struct grub_arg_option *parser) ++{ ++ if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED) ++ func = grub_extcmd_lockdown; ++ ++ return grub_register_extcmd (name, func, flags, summary, description, parser); ++} ++ + void + grub_unregister_extcmd (grub_extcmd_t ext) + { +diff --git a/grub-core/kern/command.c b/grub-core/kern/command.c +index acd72187992..4aabcd4b5f9 100644 +--- a/grub-core/kern/command.c ++++ b/grub-core/kern/command.c +@@ -17,6 +17,7 @@ + * along with GRUB. If not, see . + */ + ++#include + #include + #include + +@@ -77,6 +78,29 @@ grub_register_command_prio (const char *name, + return cmd; + } + ++static grub_err_t ++grub_cmd_lockdown (grub_command_t cmd __attribute__ ((unused)), ++ int argc __attribute__ ((unused)), ++ char **argv __attribute__ ((unused))) ++ ++{ ++ return grub_error (GRUB_ERR_ACCESS_DENIED, ++ N_("%s: the command is not allowed when lockdown is enforced"), ++ cmd->name); ++} ++ ++grub_command_t ++grub_register_command_lockdown (const char *name, ++ grub_command_func_t func, ++ const char *summary, ++ const char *description) ++{ ++ if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED) ++ func = grub_cmd_lockdown; ++ ++ return grub_register_command_prio (name, func, summary, description, 0); ++} ++ + void + grub_unregister_command (grub_command_t cmd) + { +diff --git a/grub-core/kern/lockdown.c b/grub-core/kern/lockdown.c +new file mode 100644 +index 00000000000..f87ddaeb1ee +--- /dev/null ++++ b/grub-core/kern/lockdown.c +@@ -0,0 +1,93 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2020 Free Software Foundation, Inc. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ * ++ */ ++ ++#include ++#include ++#include ++ ++/* There is no verifier framework in grub 2.02 */ ++#if 0 ++#include ++#endif ++ ++static int lockdown = GRUB_LOCKDOWN_DISABLED; ++ ++/* There is no verifier framework in grub 2.02 */ ++#if 0 ++static grub_err_t ++lockdown_verifier_init (grub_file_t io __attribute__ ((unused)), ++ enum grub_file_type type, ++ void **context __attribute__ ((unused)), ++ enum grub_verify_flags *flags) ++{ ++ *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION; ++ ++ switch (type & GRUB_FILE_TYPE_MASK) ++ { ++ case GRUB_FILE_TYPE_GRUB_MODULE: ++ case GRUB_FILE_TYPE_LINUX_KERNEL: ++ case GRUB_FILE_TYPE_MULTIBOOT_KERNEL: ++ case GRUB_FILE_TYPE_XEN_HYPERVISOR: ++ case GRUB_FILE_TYPE_BSD_KERNEL: ++ case GRUB_FILE_TYPE_XNU_KERNEL: ++ case GRUB_FILE_TYPE_PLAN9_KERNEL: ++ case GRUB_FILE_TYPE_NTLDR: ++ case GRUB_FILE_TYPE_TRUECRYPT: ++ case GRUB_FILE_TYPE_FREEDOS: ++ case GRUB_FILE_TYPE_PXECHAINLOADER: ++ case GRUB_FILE_TYPE_PCCHAINLOADER: ++ case GRUB_FILE_TYPE_COREBOOT_CHAINLOADER: ++ case GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE: ++ case GRUB_FILE_TYPE_ACPI_TABLE: ++ case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE: ++ *flags = GRUB_VERIFY_FLAGS_DEFER_AUTH; ++ ++ /* Fall through. */ ++ ++ default: ++ return GRUB_ERR_NONE; ++ } ++} ++ ++struct grub_file_verifier lockdown_verifier = ++ { ++ .name = "lockdown_verifier", ++ .init = lockdown_verifier_init, ++ }; ++#endif ++ ++void ++grub_lockdown (void) ++{ ++ lockdown = GRUB_LOCKDOWN_ENABLED; ++ ++ /* ++ * XXX: The lockdown verifier doesn't make sense until ++ * GRUB has moved to the shim_lock verifier. ++ */ ++#if 0 ++ grub_verifier_register (&lockdown_verifier); ++#endif ++} ++ ++int ++grub_is_lockdown (void) ++{ ++ return lockdown; ++} +diff --git a/include/grub/command.h b/include/grub/command.h +index eee4e847ee4..2a6f7f84697 100644 +--- a/include/grub/command.h ++++ b/include/grub/command.h +@@ -86,6 +86,11 @@ EXPORT_FUNC(grub_register_command_prio) (const char *name, + const char *summary, + const char *description, + int prio); ++grub_command_t ++EXPORT_FUNC(grub_register_command_lockdown) (const char *name, ++ grub_command_func_t func, ++ const char *summary, ++ const char *description); + void EXPORT_FUNC(grub_unregister_command) (grub_command_t cmd); + + static inline grub_command_t +diff --git a/include/grub/extcmd.h b/include/grub/extcmd.h +index 19fe592669e..fe9248b8bb6 100644 +--- a/include/grub/extcmd.h ++++ b/include/grub/extcmd.h +@@ -62,6 +62,13 @@ grub_extcmd_t EXPORT_FUNC(grub_register_extcmd) (const char *name, + const char *description, + const struct grub_arg_option *parser); + ++grub_extcmd_t EXPORT_FUNC(grub_register_extcmd_lockdown) (const char *name, ++ grub_extcmd_func_t func, ++ grub_command_flags_t flags, ++ const char *summary, ++ const char *description, ++ const struct grub_arg_option *parser); ++ + grub_extcmd_t EXPORT_FUNC(grub_register_extcmd_prio) (const char *name, + grub_extcmd_func_t func, + grub_command_flags_t flags, +diff --git a/include/grub/lockdown.h b/include/grub/lockdown.h +new file mode 100644 +index 00000000000..40531fa823b +--- /dev/null ++++ b/include/grub/lockdown.h +@@ -0,0 +1,44 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2020 Free Software Foundation, Inc. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#ifndef GRUB_LOCKDOWN_H ++#define GRUB_LOCKDOWN_H 1 ++ ++#include ++ ++#define GRUB_LOCKDOWN_DISABLED 0 ++#define GRUB_LOCKDOWN_ENABLED 1 ++ ++#ifdef GRUB_MACHINE_EFI ++extern void ++EXPORT_FUNC (grub_lockdown) (void); ++extern int ++EXPORT_FUNC (grub_is_lockdown) (void); ++#else ++static inline void ++grub_lockdown (void) ++{ ++} ++ ++static inline int ++grub_is_lockdown (void) ++{ ++ return GRUB_LOCKDOWN_DISABLED; ++} ++#endif ++#endif /* ! GRUB_LOCKDOWN_H */ +diff --git a/conf/Makefile.common b/conf/Makefile.common +index 9e0e8364f38..c7c3ab48d8e 100644 +--- a/conf/Makefile.common ++++ b/conf/Makefile.common +@@ -91,7 +91,9 @@ CPPFLAGS_PARTTOOL_LIST = -Dgrub_parttool_register=PARTTOOL_LIST_MARKER + CPPFLAGS_TERMINAL_LIST = '-Dgrub_term_register_input(...)=INPUT_TERMINAL_LIST_MARKER(__VA_ARGS__)' + CPPFLAGS_TERMINAL_LIST += '-Dgrub_term_register_output(...)=OUTPUT_TERMINAL_LIST_MARKER(__VA_ARGS__)' + CPPFLAGS_COMMAND_LIST = '-Dgrub_register_command(...)=COMMAND_LIST_MARKER(__VA_ARGS__)' ++CPPFLAGS_COMMAND_LIST += '-Dgrub_register_command_lockdown(...)=COMMAND_LOCKDOWN_LIST_MARKER(__VA_ARGS__)' + CPPFLAGS_COMMAND_LIST += '-Dgrub_register_extcmd(...)=EXTCOMMAND_LIST_MARKER(__VA_ARGS__)' ++CPPFLAGS_COMMAND_LIST += '-Dgrub_register_extcmd_lockdown(...)=EXTCOMMAND_LOCKDOWN_LIST_MARKER(__VA_ARGS__)' + CPPFLAGS_COMMAND_LIST += '-Dgrub_register_command_p1(...)=P1COMMAND_LIST_MARKER(__VA_ARGS__)' + CPPFLAGS_MARKER = $(CPPFLAGS_FS_LIST) $(CPPFLAGS_VIDEO_LIST) \ + $(CPPFLAGS_PARTTOOL_LIST) $(CPPFLAGS_PARTMAP_LIST) \ +diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi +index 7c6244cdb71..eb03856d2f1 100644 +--- a/docs/grub-dev.texi ++++ b/docs/grub-dev.texi +@@ -84,6 +84,7 @@ This edition documents version @value{VERSION}. + * Video Subsystem:: + * PFF2 Font File Format:: + * Graphical Menu Software Design:: ++* Lockdown framework:: + * Copying This Manual:: Copying This Manual + * Index:: + @end menu +@@ -1949,6 +1950,32 @@ the graphics mode that was in use before @code{grub_video_setup()} was called + might fix some of the problems. + + ++@node Lockdown framework ++@chapter Lockdown framework ++ ++The GRUB can be locked down, which is a restricted mode where some operations ++are not allowed. For instance, some commands cannot be used when the GRUB is ++locked down. ++ ++The function ++@code{grub_lockdown()} is used to lockdown GRUB and the function ++@code{grub_is_lockdown()} function can be used to check whether lockdown is ++enabled or not. When enabled, the function returns @samp{GRUB_LOCKDOWN_ENABLED} ++and @samp{GRUB_LOCKDOWN_DISABLED} when is not enabled. ++ ++The following functions can be used to register the commands that can only be ++used when lockdown is disabled: ++ ++@itemize ++ ++@item @code{grub_cmd_lockdown()} registers command which should not run when the ++GRUB is in lockdown mode. ++ ++@item @code{grub_cmd_lockdown()} registers extended command which should not run ++when the GRUB is in lockdown mode. ++ ++@end itemize ++ + @node Copying This Manual + @appendix Copying This Manual + +diff --git a/docs/grub.texi b/docs/grub.texi +index bd3457af9a9..cb52684367f 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -5466,6 +5466,8 @@ environment variables and commands are listed in the same order. + @menu + * Authentication and authorisation:: Users and access control + * Using digital signatures:: Booting digitally signed code ++* Lockdown:: Lockdown when booting on a secure setup ++ + @end menu + + @node Authentication and authorisation +@@ -5626,6 +5628,13 @@ or BIOS) configuration to cause the machine to boot from a different + (attacker-controlled) device. GRUB is at best only one link in a + secure boot chain. + ++@node Lockdown ++@section Lockdown when booting on a secure setup ++ ++The GRUB can be locked down when booted on a secure boot environment, for example ++if the UEFI secure boot is enabled. On a locked down configuration, the GRUB will ++be restricted and some operations/commands cannot be executed. ++ + @node Platform limitations + @chapter Platform limitations + +diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am +index 59a00f11fab..e15846ba75b 100644 +--- a/grub-core/Makefile.am ++++ b/grub-core/Makefile.am +@@ -80,6 +80,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fs.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i18n.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/kernel.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/list.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lockdown.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/misc.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h +@@ -327,8 +328,10 @@ command.lst: $(MARKER_FILES) + b=`basename $$pp .marker`; \ + sed -n \ + -e "/EXTCOMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \ ++ -e "/EXTCOMMAND_LOCKDOWN_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \ + -e "/P1COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \ +- -e "/COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \ ++ -e "/COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" \ ++ -e "/COMMAND_LOCKDOWN_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \ + done) | sort -u > $@ + platform_DATA += command.lst + CLEANFILES += command.lst diff --git a/SOURCES/0337-kern-Add-lockdown-support.patch b/SOURCES/0337-kern-Add-lockdown-support.patch deleted file mode 100644 index f76e7e9..0000000 --- a/SOURCES/0337-kern-Add-lockdown-support.patch +++ /dev/null @@ -1,441 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Fri, 19 Feb 2021 10:33:54 +0100 -Subject: [PATCH] kern: Add lockdown support - -When the GRUB starts on a secure boot platform, some commands can be -used to subvert the protections provided by the verification mechanism and -could lead to booting untrusted system. - -To prevent that situation, allow GRUB to be locked down. That way the code -may check if GRUB has been locked down and further restrict the commands -that are registered or what subset of their functionality could be used. - -The lockdown support adds the following components: - -* The grub_lockdown() function which can be used to lockdown GRUB if, - e.g., UEFI Secure Boot is enabled. - -* The grub_is_lockdown() function which can be used to check if the GRUB - was locked down. - -* A verifier that flags OS kernels, the GRUB modules, Device Trees and ACPI - tables as GRUB_VERIFY_FLAGS_DEFER_AUTH to defer verification to other - verifiers. These files are only successfully verified if another registered - verifier returns success. Otherwise, the whole verification process fails. - - For example, PE/COFF binaries verification can be done by the shim_lock - verifier which validates the signatures using the shim_lock protocol. - However, the verification is not deferred directly to the shim_lock verifier. - The shim_lock verifier is hooked into the verification process instead. - -* A set of grub_{command,extcmd}_lockdown functions that can be used by - code registering command handlers, to only register unsafe commands if - the GRUB has not been locked down. - -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - grub-core/Makefile.core.def | 1 + - grub-core/commands/extcmd.c | 23 +++++++++++ - grub-core/kern/command.c | 24 ++++++++++++ - grub-core/kern/lockdown.c | 93 +++++++++++++++++++++++++++++++++++++++++++++ - include/grub/command.h | 5 +++ - include/grub/extcmd.h | 7 ++++ - include/grub/lockdown.h | 44 +++++++++++++++++++++ - conf/Makefile.common | 2 + - docs/grub-dev.texi | 27 +++++++++++++ - docs/grub.texi | 9 +++++ - grub-core/Makefile.am | 5 ++- - 11 files changed, 239 insertions(+), 1 deletion(-) - create mode 100644 grub-core/kern/lockdown.c - create mode 100644 include/grub/lockdown.h - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 00110ae5efd..2beb1d83a63 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -173,6 +173,7 @@ kernel = { - efi = kern/efi/init.c; - efi = kern/efi/mm.c; - efi = term/efi/console.c; -+ efi = kern/lockdown.c; - efi = lib/envblk.c; - - common = kern/efi/sb.c; -diff --git a/grub-core/commands/extcmd.c b/grub-core/commands/extcmd.c -index 69574e2b05b..90a5ca24a64 100644 ---- a/grub-core/commands/extcmd.c -+++ b/grub-core/commands/extcmd.c -@@ -19,6 +19,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -110,6 +111,28 @@ grub_register_extcmd (const char *name, grub_extcmd_func_t func, - summary, description, parser, 1); - } - -+static grub_err_t -+grub_extcmd_lockdown (grub_extcmd_context_t ctxt __attribute__ ((unused)), -+ int argc __attribute__ ((unused)), -+ char **argv __attribute__ ((unused))) -+{ -+ return grub_error (GRUB_ERR_ACCESS_DENIED, -+ N_("%s: the command is not allowed when lockdown is enforced"), -+ ctxt->extcmd->cmd->name); -+} -+ -+grub_extcmd_t -+grub_register_extcmd_lockdown (const char *name, grub_extcmd_func_t func, -+ grub_command_flags_t flags, const char *summary, -+ const char *description, -+ const struct grub_arg_option *parser) -+{ -+ if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED) -+ func = grub_extcmd_lockdown; -+ -+ return grub_register_extcmd (name, func, flags, summary, description, parser); -+} -+ - void - grub_unregister_extcmd (grub_extcmd_t ext) - { -diff --git a/grub-core/kern/command.c b/grub-core/kern/command.c -index acd72187992..4aabcd4b5f9 100644 ---- a/grub-core/kern/command.c -+++ b/grub-core/kern/command.c -@@ -17,6 +17,7 @@ - * along with GRUB. If not, see . - */ - -+#include - #include - #include - -@@ -77,6 +78,29 @@ grub_register_command_prio (const char *name, - return cmd; - } - -+static grub_err_t -+grub_cmd_lockdown (grub_command_t cmd __attribute__ ((unused)), -+ int argc __attribute__ ((unused)), -+ char **argv __attribute__ ((unused))) -+ -+{ -+ return grub_error (GRUB_ERR_ACCESS_DENIED, -+ N_("%s: the command is not allowed when lockdown is enforced"), -+ cmd->name); -+} -+ -+grub_command_t -+grub_register_command_lockdown (const char *name, -+ grub_command_func_t func, -+ const char *summary, -+ const char *description) -+{ -+ if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED) -+ func = grub_cmd_lockdown; -+ -+ return grub_register_command_prio (name, func, summary, description, 0); -+} -+ - void - grub_unregister_command (grub_command_t cmd) - { -diff --git a/grub-core/kern/lockdown.c b/grub-core/kern/lockdown.c -new file mode 100644 -index 00000000000..f87ddaeb1ee ---- /dev/null -+++ b/grub-core/kern/lockdown.c -@@ -0,0 +1,93 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2020 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ * -+ */ -+ -+#include -+#include -+#include -+ -+/* There is no verifier framework in grub 2.02 */ -+#if 0 -+#include -+#endif -+ -+static int lockdown = GRUB_LOCKDOWN_DISABLED; -+ -+/* There is no verifier framework in grub 2.02 */ -+#if 0 -+static grub_err_t -+lockdown_verifier_init (grub_file_t io __attribute__ ((unused)), -+ enum grub_file_type type, -+ void **context __attribute__ ((unused)), -+ enum grub_verify_flags *flags) -+{ -+ *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION; -+ -+ switch (type & GRUB_FILE_TYPE_MASK) -+ { -+ case GRUB_FILE_TYPE_GRUB_MODULE: -+ case GRUB_FILE_TYPE_LINUX_KERNEL: -+ case GRUB_FILE_TYPE_MULTIBOOT_KERNEL: -+ case GRUB_FILE_TYPE_XEN_HYPERVISOR: -+ case GRUB_FILE_TYPE_BSD_KERNEL: -+ case GRUB_FILE_TYPE_XNU_KERNEL: -+ case GRUB_FILE_TYPE_PLAN9_KERNEL: -+ case GRUB_FILE_TYPE_NTLDR: -+ case GRUB_FILE_TYPE_TRUECRYPT: -+ case GRUB_FILE_TYPE_FREEDOS: -+ case GRUB_FILE_TYPE_PXECHAINLOADER: -+ case GRUB_FILE_TYPE_PCCHAINLOADER: -+ case GRUB_FILE_TYPE_COREBOOT_CHAINLOADER: -+ case GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE: -+ case GRUB_FILE_TYPE_ACPI_TABLE: -+ case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE: -+ *flags = GRUB_VERIFY_FLAGS_DEFER_AUTH; -+ -+ /* Fall through. */ -+ -+ default: -+ return GRUB_ERR_NONE; -+ } -+} -+ -+struct grub_file_verifier lockdown_verifier = -+ { -+ .name = "lockdown_verifier", -+ .init = lockdown_verifier_init, -+ }; -+#endif -+ -+void -+grub_lockdown (void) -+{ -+ lockdown = GRUB_LOCKDOWN_ENABLED; -+ -+ /* -+ * XXX: The lockdown verifier doesn't make sense until -+ * GRUB has moved to the shim_lock verifier. -+ */ -+#if 0 -+ grub_verifier_register (&lockdown_verifier); -+#endif -+} -+ -+int -+grub_is_lockdown (void) -+{ -+ return lockdown; -+} -diff --git a/include/grub/command.h b/include/grub/command.h -index eee4e847ee4..2a6f7f84697 100644 ---- a/include/grub/command.h -+++ b/include/grub/command.h -@@ -86,6 +86,11 @@ EXPORT_FUNC(grub_register_command_prio) (const char *name, - const char *summary, - const char *description, - int prio); -+grub_command_t -+EXPORT_FUNC(grub_register_command_lockdown) (const char *name, -+ grub_command_func_t func, -+ const char *summary, -+ const char *description); - void EXPORT_FUNC(grub_unregister_command) (grub_command_t cmd); - - static inline grub_command_t -diff --git a/include/grub/extcmd.h b/include/grub/extcmd.h -index 19fe592669e..fe9248b8bb6 100644 ---- a/include/grub/extcmd.h -+++ b/include/grub/extcmd.h -@@ -62,6 +62,13 @@ grub_extcmd_t EXPORT_FUNC(grub_register_extcmd) (const char *name, - const char *description, - const struct grub_arg_option *parser); - -+grub_extcmd_t EXPORT_FUNC(grub_register_extcmd_lockdown) (const char *name, -+ grub_extcmd_func_t func, -+ grub_command_flags_t flags, -+ const char *summary, -+ const char *description, -+ const struct grub_arg_option *parser); -+ - grub_extcmd_t EXPORT_FUNC(grub_register_extcmd_prio) (const char *name, - grub_extcmd_func_t func, - grub_command_flags_t flags, -diff --git a/include/grub/lockdown.h b/include/grub/lockdown.h -new file mode 100644 -index 00000000000..40531fa823b ---- /dev/null -+++ b/include/grub/lockdown.h -@@ -0,0 +1,44 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2020 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_LOCKDOWN_H -+#define GRUB_LOCKDOWN_H 1 -+ -+#include -+ -+#define GRUB_LOCKDOWN_DISABLED 0 -+#define GRUB_LOCKDOWN_ENABLED 1 -+ -+#ifdef GRUB_MACHINE_EFI -+extern void -+EXPORT_FUNC (grub_lockdown) (void); -+extern int -+EXPORT_FUNC (grub_is_lockdown) (void); -+#else -+static inline void -+grub_lockdown (void) -+{ -+} -+ -+static inline int -+grub_is_lockdown (void) -+{ -+ return GRUB_LOCKDOWN_DISABLED; -+} -+#endif -+#endif /* ! GRUB_LOCKDOWN_H */ -diff --git a/conf/Makefile.common b/conf/Makefile.common -index 9e0e8364f38..c7c3ab48d8e 100644 ---- a/conf/Makefile.common -+++ b/conf/Makefile.common -@@ -91,7 +91,9 @@ CPPFLAGS_PARTTOOL_LIST = -Dgrub_parttool_register=PARTTOOL_LIST_MARKER - CPPFLAGS_TERMINAL_LIST = '-Dgrub_term_register_input(...)=INPUT_TERMINAL_LIST_MARKER(__VA_ARGS__)' - CPPFLAGS_TERMINAL_LIST += '-Dgrub_term_register_output(...)=OUTPUT_TERMINAL_LIST_MARKER(__VA_ARGS__)' - CPPFLAGS_COMMAND_LIST = '-Dgrub_register_command(...)=COMMAND_LIST_MARKER(__VA_ARGS__)' -+CPPFLAGS_COMMAND_LIST += '-Dgrub_register_command_lockdown(...)=COMMAND_LOCKDOWN_LIST_MARKER(__VA_ARGS__)' - CPPFLAGS_COMMAND_LIST += '-Dgrub_register_extcmd(...)=EXTCOMMAND_LIST_MARKER(__VA_ARGS__)' -+CPPFLAGS_COMMAND_LIST += '-Dgrub_register_extcmd_lockdown(...)=EXTCOMMAND_LOCKDOWN_LIST_MARKER(__VA_ARGS__)' - CPPFLAGS_COMMAND_LIST += '-Dgrub_register_command_p1(...)=P1COMMAND_LIST_MARKER(__VA_ARGS__)' - CPPFLAGS_MARKER = $(CPPFLAGS_FS_LIST) $(CPPFLAGS_VIDEO_LIST) \ - $(CPPFLAGS_PARTTOOL_LIST) $(CPPFLAGS_PARTMAP_LIST) \ -diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi -index 7c6244cdb71..eb03856d2f1 100644 ---- a/docs/grub-dev.texi -+++ b/docs/grub-dev.texi -@@ -84,6 +84,7 @@ This edition documents version @value{VERSION}. - * Video Subsystem:: - * PFF2 Font File Format:: - * Graphical Menu Software Design:: -+* Lockdown framework:: - * Copying This Manual:: Copying This Manual - * Index:: - @end menu -@@ -1949,6 +1950,32 @@ the graphics mode that was in use before @code{grub_video_setup()} was called - might fix some of the problems. - - -+@node Lockdown framework -+@chapter Lockdown framework -+ -+The GRUB can be locked down, which is a restricted mode where some operations -+are not allowed. For instance, some commands cannot be used when the GRUB is -+locked down. -+ -+The function -+@code{grub_lockdown()} is used to lockdown GRUB and the function -+@code{grub_is_lockdown()} function can be used to check whether lockdown is -+enabled or not. When enabled, the function returns @samp{GRUB_LOCKDOWN_ENABLED} -+and @samp{GRUB_LOCKDOWN_DISABLED} when is not enabled. -+ -+The following functions can be used to register the commands that can only be -+used when lockdown is disabled: -+ -+@itemize -+ -+@item @code{grub_cmd_lockdown()} registers command which should not run when the -+GRUB is in lockdown mode. -+ -+@item @code{grub_cmd_lockdown()} registers extended command which should not run -+when the GRUB is in lockdown mode. -+ -+@end itemize -+ - @node Copying This Manual - @appendix Copying This Manual - -diff --git a/docs/grub.texi b/docs/grub.texi -index bd3457af9a9..cb52684367f 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -5466,6 +5466,8 @@ environment variables and commands are listed in the same order. - @menu - * Authentication and authorisation:: Users and access control - * Using digital signatures:: Booting digitally signed code -+* Lockdown:: Lockdown when booting on a secure setup -+ - @end menu - - @node Authentication and authorisation -@@ -5626,6 +5628,13 @@ or BIOS) configuration to cause the machine to boot from a different - (attacker-controlled) device. GRUB is at best only one link in a - secure boot chain. - -+@node Lockdown -+@section Lockdown when booting on a secure setup -+ -+The GRUB can be locked down when booted on a secure boot environment, for example -+if the UEFI secure boot is enabled. On a locked down configuration, the GRUB will -+be restricted and some operations/commands cannot be executed. -+ - @node Platform limitations - @chapter Platform limitations - -diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am -index 59a00f11fab..e15846ba75b 100644 ---- a/grub-core/Makefile.am -+++ b/grub-core/Makefile.am -@@ -80,6 +80,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fs.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i18n.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/kernel.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/list.h -+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lockdown.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/misc.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h -@@ -327,8 +328,10 @@ command.lst: $(MARKER_FILES) - b=`basename $$pp .marker`; \ - sed -n \ - -e "/EXTCOMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \ -+ -e "/EXTCOMMAND_LOCKDOWN_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \ - -e "/P1COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \ -- -e "/COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \ -+ -e "/COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" \ -+ -e "/COMMAND_LOCKDOWN_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \ - done) | sort -u > $@ - platform_DATA += command.lst - CLEANFILES += command.lst diff --git a/SOURCES/0337-kern-lockdown-Set-a-variable-if-the-GRUB-is-locked-d.patch b/SOURCES/0337-kern-lockdown-Set-a-variable-if-the-GRUB-is-locked-d.patch new file mode 100644 index 0000000..5a2b26a --- /dev/null +++ b/SOURCES/0337-kern-lockdown-Set-a-variable-if-the-GRUB-is-locked-d.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Tue, 2 Feb 2021 19:59:48 +0100 +Subject: [PATCH] kern/lockdown: Set a variable if the GRUB is locked down + +It may be useful for scripts to determine whether the GRUB is locked +down or not. Add the lockdown variable which is set to "y" when the GRUB +is locked down. + +Suggested-by: Dimitri John Ledkov +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + grub-core/kern/lockdown.c | 4 ++++ + docs/grub.texi | 3 +++ + 2 files changed, 7 insertions(+) + +diff --git a/grub-core/kern/lockdown.c b/grub-core/kern/lockdown.c +index f87ddaeb1ee..30cba7f5ea2 100644 +--- a/grub-core/kern/lockdown.c ++++ b/grub-core/kern/lockdown.c +@@ -18,6 +18,7 @@ + */ + + #include ++#include + #include + #include + +@@ -84,6 +85,9 @@ grub_lockdown (void) + #if 0 + grub_verifier_register (&lockdown_verifier); + #endif ++ ++ grub_env_set ("lockdown", "y"); ++ grub_env_export ("lockdown"); + } + + int +diff --git a/docs/grub.texi b/docs/grub.texi +index cb52684367f..6f331422bd3 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -5635,6 +5635,9 @@ The GRUB can be locked down when booted on a secure boot environment, for exampl + if the UEFI secure boot is enabled. On a locked down configuration, the GRUB will + be restricted and some operations/commands cannot be executed. + ++The @samp{lockdown} variable is set to @samp{y} when the GRUB is locked down. ++Otherwise it does not exit. ++ + @node Platform limitations + @chapter Platform limitations + diff --git a/SOURCES/0338-efi-Lockdown-the-GRUB-when-the-UEFI-Secure-Boot-is-e.patch b/SOURCES/0338-efi-Lockdown-the-GRUB-when-the-UEFI-Secure-Boot-is-e.patch new file mode 100644 index 0000000..9ba2bb6 --- /dev/null +++ b/SOURCES/0338-efi-Lockdown-the-GRUB-when-the-UEFI-Secure-Boot-is-e.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Mon, 28 Sep 2020 20:08:29 +0200 +Subject: [PATCH] efi: Lockdown the GRUB when the UEFI Secure Boot is enabled + +If the UEFI Secure Boot is enabled then the GRUB must be locked down +to prevent executing code that can potentially be used to subvert its +verification mechanisms. + +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + grub-core/kern/efi/init.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c +index e8bf993f6d4..ed33201f12a 100644 +--- a/grub-core/kern/efi/init.c ++++ b/grub-core/kern/efi/init.c +@@ -20,6 +20,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -70,6 +72,23 @@ grub_efi_init (void) + /* Initialize the memory management system. */ + grub_efi_mm_init (); + ++ /* ++ * Lockdown the GRUB and register the shim_lock verifier ++ * if the UEFI Secure Boot is enabled. ++ */ ++ if (grub_efi_secure_boot ()) ++ { ++ grub_lockdown (); ++ ++ /* ++ * TODO: Move GRUB to using the shim_lock verifier and ++ * enable the lockdown verifier. ++ */ ++#if 0 ++ grub_shim_lock_verifier_setup (); ++#endif ++ } ++ + efi_call_4 (grub_efi_system_table->boot_services->set_watchdog_timer, + 0, 0, 0, NULL); + diff --git a/SOURCES/0338-kern-lockdown-Set-a-variable-if-the-GRUB-is-locked-d.patch b/SOURCES/0338-kern-lockdown-Set-a-variable-if-the-GRUB-is-locked-d.patch deleted file mode 100644 index 5a2b26a..0000000 --- a/SOURCES/0338-kern-lockdown-Set-a-variable-if-the-GRUB-is-locked-d.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 2 Feb 2021 19:59:48 +0100 -Subject: [PATCH] kern/lockdown: Set a variable if the GRUB is locked down - -It may be useful for scripts to determine whether the GRUB is locked -down or not. Add the lockdown variable which is set to "y" when the GRUB -is locked down. - -Suggested-by: Dimitri John Ledkov -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - grub-core/kern/lockdown.c | 4 ++++ - docs/grub.texi | 3 +++ - 2 files changed, 7 insertions(+) - -diff --git a/grub-core/kern/lockdown.c b/grub-core/kern/lockdown.c -index f87ddaeb1ee..30cba7f5ea2 100644 ---- a/grub-core/kern/lockdown.c -+++ b/grub-core/kern/lockdown.c -@@ -18,6 +18,7 @@ - */ - - #include -+#include - #include - #include - -@@ -84,6 +85,9 @@ grub_lockdown (void) - #if 0 - grub_verifier_register (&lockdown_verifier); - #endif -+ -+ grub_env_set ("lockdown", "y"); -+ grub_env_export ("lockdown"); - } - - int -diff --git a/docs/grub.texi b/docs/grub.texi -index cb52684367f..6f331422bd3 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -5635,6 +5635,9 @@ The GRUB can be locked down when booted on a secure boot environment, for exampl - if the UEFI secure boot is enabled. On a locked down configuration, the GRUB will - be restricted and some operations/commands cannot be executed. - -+The @samp{lockdown} variable is set to @samp{y} when the GRUB is locked down. -+Otherwise it does not exit. -+ - @node Platform limitations - @chapter Platform limitations - diff --git a/SOURCES/0339-efi-Lockdown-the-GRUB-when-the-UEFI-Secure-Boot-is-e.patch b/SOURCES/0339-efi-Lockdown-the-GRUB-when-the-UEFI-Secure-Boot-is-e.patch deleted file mode 100644 index 9ba2bb6..0000000 --- a/SOURCES/0339-efi-Lockdown-the-GRUB-when-the-UEFI-Secure-Boot-is-e.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Mon, 28 Sep 2020 20:08:29 +0200 -Subject: [PATCH] efi: Lockdown the GRUB when the UEFI Secure Boot is enabled - -If the UEFI Secure Boot is enabled then the GRUB must be locked down -to prevent executing code that can potentially be used to subvert its -verification mechanisms. - -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - grub-core/kern/efi/init.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - -diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c -index e8bf993f6d4..ed33201f12a 100644 ---- a/grub-core/kern/efi/init.c -+++ b/grub-core/kern/efi/init.c -@@ -20,6 +20,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -70,6 +72,23 @@ grub_efi_init (void) - /* Initialize the memory management system. */ - grub_efi_mm_init (); - -+ /* -+ * Lockdown the GRUB and register the shim_lock verifier -+ * if the UEFI Secure Boot is enabled. -+ */ -+ if (grub_efi_secure_boot ()) -+ { -+ grub_lockdown (); -+ -+ /* -+ * TODO: Move GRUB to using the shim_lock verifier and -+ * enable the lockdown verifier. -+ */ -+#if 0 -+ grub_shim_lock_verifier_setup (); -+#endif -+ } -+ - efi_call_4 (grub_efi_system_table->boot_services->set_watchdog_timer, - 0, 0, 0, NULL); - diff --git a/SOURCES/0339-efi-Use-grub_is_lockdown-instead-of-hardcoding-a-dis.patch b/SOURCES/0339-efi-Use-grub_is_lockdown-instead-of-hardcoding-a-dis.patch new file mode 100644 index 0000000..a902271 --- /dev/null +++ b/SOURCES/0339-efi-Use-grub_is_lockdown-instead-of-hardcoding-a-dis.patch @@ -0,0 +1,137 @@ +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 + +Now the GRUB can check if it has been locked down and this can be used to +prevent executing commands that can be utilized to circumvent the UEFI +Secure Boot mechanisms. So, instead of hardcoding a list of modules that +have to be disabled, prevent the usage of commands that can be dangerous. + +This not only allows the commands to be disabled on other platforms, but +also properly separate the concerns. Since the shim_lock verifier logic +should be only about preventing to run untrusted binaries and not about +defining these kind of policies. + +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + grub-core/commands/iorw.c | 26 ++++++++++---------------- + grub-core/commands/memrw.c | 26 ++++++++++---------------- + 2 files changed, 20 insertions(+), 32 deletions(-) + +diff --git a/grub-core/commands/iorw.c b/grub-core/commands/iorw.c +index 41a7f3f0466..584baec8f91 100644 +--- a/grub-core/commands/iorw.c ++++ b/grub-core/commands/iorw.c +@@ -23,7 +23,7 @@ + #include + #include + #include +-#include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -119,9 +119,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."), +@@ -135,24 +132,21 @@ GRUB_MOD_INIT(memrw) + N_("PORT"), N_("Read 32-bit value from PORT."), + options); + cmd_write_byte = +- grub_register_command ("outb", grub_cmd_write, +- N_("PORT VALUE [MASK]"), +- N_("Write 8-bit VALUE to PORT.")); ++ grub_register_command_lockdown ("outb", grub_cmd_write, ++ N_("PORT VALUE [MASK]"), ++ N_("Write 8-bit VALUE to PORT.")); + cmd_write_word = +- grub_register_command ("outw", grub_cmd_write, +- N_("PORT VALUE [MASK]"), +- N_("Write 16-bit VALUE to PORT.")); ++ grub_register_command_lockdown ("outw", grub_cmd_write, ++ N_("PORT VALUE [MASK]"), ++ N_("Write 16-bit VALUE to PORT.")); + cmd_write_dword = +- grub_register_command ("outl", grub_cmd_write, +- N_("ADDR VALUE [MASK]"), +- N_("Write 32-bit VALUE to PORT.")); ++ grub_register_command_lockdown ("outl", grub_cmd_write, ++ N_("ADDR VALUE [MASK]"), ++ N_("Write 32-bit VALUE to PORT.")); + } + + 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 088cbe9e2bc..d401a6db0ef 100644 +--- a/grub-core/commands/memrw.c ++++ b/grub-core/commands/memrw.c +@@ -22,7 +22,7 @@ + #include + #include + #include +-#include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -121,9 +121,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."), +@@ -137,24 +134,21 @@ GRUB_MOD_INIT(memrw) + N_("ADDR"), N_("Read 32-bit value from ADDR."), + options); + cmd_write_byte = +- grub_register_command ("write_byte", grub_cmd_write, +- N_("ADDR VALUE [MASK]"), +- N_("Write 8-bit VALUE to ADDR.")); ++ grub_register_command_lockdown ("write_byte", grub_cmd_write, ++ N_("ADDR VALUE [MASK]"), ++ N_("Write 8-bit VALUE to ADDR.")); + cmd_write_word = +- grub_register_command ("write_word", grub_cmd_write, +- N_("ADDR VALUE [MASK]"), +- N_("Write 16-bit VALUE to ADDR.")); ++ grub_register_command_lockdown ("write_word", grub_cmd_write, ++ N_("ADDR VALUE [MASK]"), ++ N_("Write 16-bit VALUE to ADDR.")); + cmd_write_dword = +- grub_register_command ("write_dword", grub_cmd_write, +- N_("ADDR VALUE [MASK]"), +- N_("Write 32-bit VALUE to ADDR.")); ++ grub_register_command_lockdown ("write_dword", grub_cmd_write, ++ N_("ADDR VALUE [MASK]"), ++ N_("Write 32-bit VALUE to ADDR.")); + } + + 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/SOURCES/0340-acpi-Don-t-register-the-acpi-command-when-locked-dow.patch b/SOURCES/0340-acpi-Don-t-register-the-acpi-command-when-locked-dow.patch new file mode 100644 index 0000000..2b925ba --- /dev/null +++ b/SOURCES/0340-acpi-Don-t-register-the-acpi-command-when-locked-dow.patch @@ -0,0 +1,72 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Mon, 28 Sep 2020 20:08:41 +0200 +Subject: [PATCH] acpi: Don't register the acpi command when locked down +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The command is not allowed when lockdown is enforced. Otherwise an +attacker can instruct the GRUB to load an SSDT table to overwrite +the kernel lockdown configuration and later load and execute +unsigned code. + +Fixes: CVE-2020-14372 + +Reported-by: Máté Kukri +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + grub-core/commands/acpi.c | 15 ++++++++------- + docs/grub.texi | 5 +++++ + 2 files changed, 13 insertions(+), 7 deletions(-) + +diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c +index 97c2cf282f9..230e710a19e 100644 +--- a/grub-core/commands/acpi.c ++++ b/grub-core/commands/acpi.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + #ifdef GRUB_MACHINE_EFI + #include +@@ -779,13 +780,13 @@ static grub_extcmd_t cmd; + + GRUB_MOD_INIT(acpi) + { +- cmd = grub_register_extcmd ("acpi", grub_cmd_acpi, 0, +- N_("[-1|-2] [--exclude=TABLE1,TABLE2|" +- "--load-only=TABLE1,TABLE2] FILE1" +- " [FILE2] [...]"), +- N_("Load host ACPI tables and tables " +- "specified by arguments."), +- options); ++ cmd = grub_register_extcmd_lockdown ("acpi", grub_cmd_acpi, 0, ++ N_("[-1|-2] [--exclude=TABLE1,TABLE2|" ++ "--load-only=TABLE1,TABLE2] FILE1" ++ " [FILE2] [...]"), ++ N_("Load host ACPI tables and tables " ++ "specified by arguments."), ++ options); + } + + GRUB_MOD_FINI(acpi) +diff --git a/docs/grub.texi b/docs/grub.texi +index 6f331422bd3..741f6c3fb51 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -3917,6 +3917,11 @@ Normally, this command will replace the Root System Description Pointer + (RSDP) in the Extended BIOS Data Area to point to the new tables. If the + @option{--no-ebda} option is used, the new tables will be known only to + GRUB, but may be used by GRUB's EFI emulation. ++ ++Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}). ++ Otherwise an attacker can instruct the GRUB to load an SSDT table to ++ overwrite the kernel lockdown configuration and later load and execute ++ unsigned code. + @end deffn + + diff --git a/SOURCES/0340-efi-Use-grub_is_lockdown-instead-of-hardcoding-a-dis.patch b/SOURCES/0340-efi-Use-grub_is_lockdown-instead-of-hardcoding-a-dis.patch deleted file mode 100644 index a902271..0000000 --- a/SOURCES/0340-efi-Use-grub_is_lockdown-instead-of-hardcoding-a-dis.patch +++ /dev/null @@ -1,137 +0,0 @@ -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 - -Now the GRUB can check if it has been locked down and this can be used to -prevent executing commands that can be utilized to circumvent the UEFI -Secure Boot mechanisms. So, instead of hardcoding a list of modules that -have to be disabled, prevent the usage of commands that can be dangerous. - -This not only allows the commands to be disabled on other platforms, but -also properly separate the concerns. Since the shim_lock verifier logic -should be only about preventing to run untrusted binaries and not about -defining these kind of policies. - -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - grub-core/commands/iorw.c | 26 ++++++++++---------------- - grub-core/commands/memrw.c | 26 ++++++++++---------------- - 2 files changed, 20 insertions(+), 32 deletions(-) - -diff --git a/grub-core/commands/iorw.c b/grub-core/commands/iorw.c -index 41a7f3f0466..584baec8f91 100644 ---- a/grub-core/commands/iorw.c -+++ b/grub-core/commands/iorw.c -@@ -23,7 +23,7 @@ - #include - #include - #include --#include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -119,9 +119,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."), -@@ -135,24 +132,21 @@ GRUB_MOD_INIT(memrw) - N_("PORT"), N_("Read 32-bit value from PORT."), - options); - cmd_write_byte = -- grub_register_command ("outb", grub_cmd_write, -- N_("PORT VALUE [MASK]"), -- N_("Write 8-bit VALUE to PORT.")); -+ grub_register_command_lockdown ("outb", grub_cmd_write, -+ N_("PORT VALUE [MASK]"), -+ N_("Write 8-bit VALUE to PORT.")); - cmd_write_word = -- grub_register_command ("outw", grub_cmd_write, -- N_("PORT VALUE [MASK]"), -- N_("Write 16-bit VALUE to PORT.")); -+ grub_register_command_lockdown ("outw", grub_cmd_write, -+ N_("PORT VALUE [MASK]"), -+ N_("Write 16-bit VALUE to PORT.")); - cmd_write_dword = -- grub_register_command ("outl", grub_cmd_write, -- N_("ADDR VALUE [MASK]"), -- N_("Write 32-bit VALUE to PORT.")); -+ grub_register_command_lockdown ("outl", grub_cmd_write, -+ N_("ADDR VALUE [MASK]"), -+ N_("Write 32-bit VALUE to PORT.")); - } - - 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 088cbe9e2bc..d401a6db0ef 100644 ---- a/grub-core/commands/memrw.c -+++ b/grub-core/commands/memrw.c -@@ -22,7 +22,7 @@ - #include - #include - #include --#include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -121,9 +121,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."), -@@ -137,24 +134,21 @@ GRUB_MOD_INIT(memrw) - N_("ADDR"), N_("Read 32-bit value from ADDR."), - options); - cmd_write_byte = -- grub_register_command ("write_byte", grub_cmd_write, -- N_("ADDR VALUE [MASK]"), -- N_("Write 8-bit VALUE to ADDR.")); -+ grub_register_command_lockdown ("write_byte", grub_cmd_write, -+ N_("ADDR VALUE [MASK]"), -+ N_("Write 8-bit VALUE to ADDR.")); - cmd_write_word = -- grub_register_command ("write_word", grub_cmd_write, -- N_("ADDR VALUE [MASK]"), -- N_("Write 16-bit VALUE to ADDR.")); -+ grub_register_command_lockdown ("write_word", grub_cmd_write, -+ N_("ADDR VALUE [MASK]"), -+ N_("Write 16-bit VALUE to ADDR.")); - cmd_write_dword = -- grub_register_command ("write_dword", grub_cmd_write, -- N_("ADDR VALUE [MASK]"), -- N_("Write 32-bit VALUE to ADDR.")); -+ grub_register_command_lockdown ("write_dword", grub_cmd_write, -+ N_("ADDR VALUE [MASK]"), -+ N_("Write 32-bit VALUE to ADDR.")); - } - - 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/SOURCES/0341-acpi-Don-t-register-the-acpi-command-when-locked-dow.patch b/SOURCES/0341-acpi-Don-t-register-the-acpi-command-when-locked-dow.patch deleted file mode 100644 index 2b925ba..0000000 --- a/SOURCES/0341-acpi-Don-t-register-the-acpi-command-when-locked-dow.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Mon, 28 Sep 2020 20:08:41 +0200 -Subject: [PATCH] acpi: Don't register the acpi command when locked down -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The command is not allowed when lockdown is enforced. Otherwise an -attacker can instruct the GRUB to load an SSDT table to overwrite -the kernel lockdown configuration and later load and execute -unsigned code. - -Fixes: CVE-2020-14372 - -Reported-by: Máté Kukri -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - grub-core/commands/acpi.c | 15 ++++++++------- - docs/grub.texi | 5 +++++ - 2 files changed, 13 insertions(+), 7 deletions(-) - -diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c -index 97c2cf282f9..230e710a19e 100644 ---- a/grub-core/commands/acpi.c -+++ b/grub-core/commands/acpi.c -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - - #ifdef GRUB_MACHINE_EFI - #include -@@ -779,13 +780,13 @@ static grub_extcmd_t cmd; - - GRUB_MOD_INIT(acpi) - { -- cmd = grub_register_extcmd ("acpi", grub_cmd_acpi, 0, -- N_("[-1|-2] [--exclude=TABLE1,TABLE2|" -- "--load-only=TABLE1,TABLE2] FILE1" -- " [FILE2] [...]"), -- N_("Load host ACPI tables and tables " -- "specified by arguments."), -- options); -+ cmd = grub_register_extcmd_lockdown ("acpi", grub_cmd_acpi, 0, -+ N_("[-1|-2] [--exclude=TABLE1,TABLE2|" -+ "--load-only=TABLE1,TABLE2] FILE1" -+ " [FILE2] [...]"), -+ N_("Load host ACPI tables and tables " -+ "specified by arguments."), -+ options); - } - - GRUB_MOD_FINI(acpi) -diff --git a/docs/grub.texi b/docs/grub.texi -index 6f331422bd3..741f6c3fb51 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -3917,6 +3917,11 @@ Normally, this command will replace the Root System Description Pointer - (RSDP) in the Extended BIOS Data Area to point to the new tables. If the - @option{--no-ebda} option is used, the new tables will be known only to - GRUB, but may be used by GRUB's EFI emulation. -+ -+Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}). -+ Otherwise an attacker can instruct the GRUB to load an SSDT table to -+ overwrite the kernel lockdown configuration and later load and execute -+ unsigned code. - @end deffn - - diff --git a/SOURCES/0341-mmap-Don-t-register-cutmem-and-badram-commands-when-.patch b/SOURCES/0341-mmap-Don-t-register-cutmem-and-badram-commands-when-.patch new file mode 100644 index 0000000..2f77833 --- /dev/null +++ b/SOURCES/0341-mmap-Don-t-register-cutmem-and-badram-commands-when-.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Wed, 14 Oct 2020 16:33:42 +0200 +Subject: [PATCH] mmap: Don't register cutmem and badram commands when lockdown + is enforced + +The cutmem and badram commands can be used to remove EFI memory regions +and potentially disable the UEFI Secure Boot. Prevent the commands to be +registered if the GRUB is locked down. + +Fixes: CVE-2020-27779 + +Reported-by: Teddy Reed +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + grub-core/mmap/mmap.c | 13 +++++++------ + docs/grub.texi | 4 ++++ + 2 files changed, 11 insertions(+), 6 deletions(-) + +diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c +index 57b4e9a72a9..7ebf32e1e5e 100644 +--- a/grub-core/mmap/mmap.c ++++ b/grub-core/mmap/mmap.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -534,12 +535,12 @@ static grub_command_t cmd, cmd_cut; + + GRUB_MOD_INIT(mmap) + { +- cmd = grub_register_command ("badram", grub_cmd_badram, +- N_("ADDR1,MASK1[,ADDR2,MASK2[,...]]"), +- N_("Declare memory regions as faulty (badram).")); +- cmd_cut = grub_register_command ("cutmem", grub_cmd_cutmem, +- N_("FROM[K|M|G] TO[K|M|G]"), +- N_("Remove any memory regions in specified range.")); ++ cmd = grub_register_command_lockdown ("badram", grub_cmd_badram, ++ N_("ADDR1,MASK1[,ADDR2,MASK2[,...]]"), ++ N_("Declare memory regions as faulty (badram).")); ++ cmd_cut = grub_register_command_lockdown ("cutmem", grub_cmd_cutmem, ++ N_("FROM[K|M|G] TO[K|M|G]"), ++ N_("Remove any memory regions in specified range.")); + + } + +diff --git a/docs/grub.texi b/docs/grub.texi +index 741f6c3fb51..5a1cfd4aea9 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -3982,6 +3982,10 @@ this page is to be filtered. This syntax makes it easy to represent patterns + that are often result of memory damage, due to physical distribution of memory + cells. + ++Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}). ++ This prevents removing EFI memory regions to potentially subvert the ++ security mechanisms provided by the UEFI secure boot. ++ + @node blocklist + @subsection blocklist + diff --git a/SOURCES/0342-commands-Restrict-commands-that-can-load-BIOS-or-DT-.patch b/SOURCES/0342-commands-Restrict-commands-that-can-load-BIOS-or-DT-.patch new file mode 100644 index 0000000..47cfd28 --- /dev/null +++ b/SOURCES/0342-commands-Restrict-commands-that-can-load-BIOS-or-DT-.patch @@ -0,0 +1,92 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Wed, 24 Feb 2021 09:00:05 +0100 +Subject: [PATCH] commands: Restrict commands that can load BIOS or DT blobs + when locked down + +There are some more commands that should be restricted when the GRUB is +locked down. Following is the list of commands and reasons to restrict: + + * fakebios: creates BIOS-like structures for backward compatibility with + existing OSes. This should not be allowed when locked down. + + * loadbios: reads a BIOS dump from storage and loads it. This action + should not be allowed when locked down. + + * devicetree: loads a Device Tree blob and passes it to the OS. It replaces + any Device Tree provided by the firmware. This also should + not be allowed when locked down. + +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + grub-core/commands/efi/loadbios.c | 14 +++++++------- + grub-core/loader/arm/linux.c | 6 +++--- + docs/grub.texi | 6 ++++-- + 3 files changed, 14 insertions(+), 12 deletions(-) + +diff --git a/grub-core/commands/efi/loadbios.c b/grub-core/commands/efi/loadbios.c +index 132cadbc764..3da4c26df7a 100644 +--- a/grub-core/commands/efi/loadbios.c ++++ b/grub-core/commands/efi/loadbios.c +@@ -205,14 +205,14 @@ static grub_command_t cmd_fakebios, cmd_loadbios; + + GRUB_MOD_INIT(loadbios) + { +- cmd_fakebios = grub_register_command ("fakebios", grub_cmd_fakebios, +- 0, N_("Create BIOS-like structures for" +- " backward compatibility with" +- " existing OS.")); ++ cmd_fakebios = grub_register_command_lockdown ("fakebios", grub_cmd_fakebios, ++ 0, N_("Create BIOS-like structures for" ++ " backward compatibility with" ++ " existing OS.")); + +- cmd_loadbios = grub_register_command ("loadbios", grub_cmd_loadbios, +- N_("BIOS_DUMP [INT10_DUMP]"), +- N_("Load BIOS dump.")); ++ cmd_loadbios = grub_register_command_lockdown ("loadbios", grub_cmd_loadbios, ++ N_("BIOS_DUMP [INT10_DUMP]"), ++ N_("Load BIOS dump.")); + } + + GRUB_MOD_FINI(loadbios) +diff --git a/grub-core/loader/arm/linux.c b/grub-core/loader/arm/linux.c +index 1b195e0899e..8fc905e26ca 100644 +--- a/grub-core/loader/arm/linux.c ++++ b/grub-core/loader/arm/linux.c +@@ -513,9 +513,9 @@ GRUB_MOD_INIT (linux) + 0, N_("Load Linux.")); + cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, + 0, N_("Load initrd.")); +- cmd_devicetree = grub_register_command ("devicetree", grub_cmd_devicetree, +- /* TRANSLATORS: DTB stands for device tree blob. */ +- 0, N_("Load DTB file.")); ++ cmd_devicetree = grub_register_command_lockdown ("devicetree", grub_cmd_devicetree, ++ /* TRANSLATORS: DTB stands for device tree blob. */ ++ 0, N_("Load DTB file.")); + my_mod = mod; + fdt_addr = (void *) grub_arm_firmware_get_boot_data (); + machine_type = grub_arm_firmware_get_machine_type (); +diff --git a/docs/grub.texi b/docs/grub.texi +index 5a1cfd4aea9..432610991b7 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -4157,13 +4157,15 @@ hour, minute, and second unchanged. + + + @node devicetree +-@subsection linux ++@subsection devicetree + + @deffn Command devicetree file + Load a device tree blob (.dtb) from a filesystem, for later use by a Linux + kernel. Does not perform merging with any device tree supplied by firmware, + but rather replaces it completely. +-@ref{GNU/Linux}. ++ ++Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}). ++ This is done to prevent subverting various security mechanisms. + @end deffn + + @node distrust diff --git a/SOURCES/0342-mmap-Don-t-register-cutmem-and-badram-commands-when-.patch b/SOURCES/0342-mmap-Don-t-register-cutmem-and-badram-commands-when-.patch deleted file mode 100644 index 2f77833..0000000 --- a/SOURCES/0342-mmap-Don-t-register-cutmem-and-badram-commands-when-.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Wed, 14 Oct 2020 16:33:42 +0200 -Subject: [PATCH] mmap: Don't register cutmem and badram commands when lockdown - is enforced - -The cutmem and badram commands can be used to remove EFI memory regions -and potentially disable the UEFI Secure Boot. Prevent the commands to be -registered if the GRUB is locked down. - -Fixes: CVE-2020-27779 - -Reported-by: Teddy Reed -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - grub-core/mmap/mmap.c | 13 +++++++------ - docs/grub.texi | 4 ++++ - 2 files changed, 11 insertions(+), 6 deletions(-) - -diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c -index 57b4e9a72a9..7ebf32e1e5e 100644 ---- a/grub-core/mmap/mmap.c -+++ b/grub-core/mmap/mmap.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -534,12 +535,12 @@ static grub_command_t cmd, cmd_cut; - - GRUB_MOD_INIT(mmap) - { -- cmd = grub_register_command ("badram", grub_cmd_badram, -- N_("ADDR1,MASK1[,ADDR2,MASK2[,...]]"), -- N_("Declare memory regions as faulty (badram).")); -- cmd_cut = grub_register_command ("cutmem", grub_cmd_cutmem, -- N_("FROM[K|M|G] TO[K|M|G]"), -- N_("Remove any memory regions in specified range.")); -+ cmd = grub_register_command_lockdown ("badram", grub_cmd_badram, -+ N_("ADDR1,MASK1[,ADDR2,MASK2[,...]]"), -+ N_("Declare memory regions as faulty (badram).")); -+ cmd_cut = grub_register_command_lockdown ("cutmem", grub_cmd_cutmem, -+ N_("FROM[K|M|G] TO[K|M|G]"), -+ N_("Remove any memory regions in specified range.")); - - } - -diff --git a/docs/grub.texi b/docs/grub.texi -index 741f6c3fb51..5a1cfd4aea9 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -3982,6 +3982,10 @@ this page is to be filtered. This syntax makes it easy to represent patterns - that are often result of memory damage, due to physical distribution of memory - cells. - -+Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}). -+ This prevents removing EFI memory regions to potentially subvert the -+ security mechanisms provided by the UEFI secure boot. -+ - @node blocklist - @subsection blocklist - diff --git a/SOURCES/0343-commands-Restrict-commands-that-can-load-BIOS-or-DT-.patch b/SOURCES/0343-commands-Restrict-commands-that-can-load-BIOS-or-DT-.patch deleted file mode 100644 index 47cfd28..0000000 --- a/SOURCES/0343-commands-Restrict-commands-that-can-load-BIOS-or-DT-.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Wed, 24 Feb 2021 09:00:05 +0100 -Subject: [PATCH] commands: Restrict commands that can load BIOS or DT blobs - when locked down - -There are some more commands that should be restricted when the GRUB is -locked down. Following is the list of commands and reasons to restrict: - - * fakebios: creates BIOS-like structures for backward compatibility with - existing OSes. This should not be allowed when locked down. - - * loadbios: reads a BIOS dump from storage and loads it. This action - should not be allowed when locked down. - - * devicetree: loads a Device Tree blob and passes it to the OS. It replaces - any Device Tree provided by the firmware. This also should - not be allowed when locked down. - -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - grub-core/commands/efi/loadbios.c | 14 +++++++------- - grub-core/loader/arm/linux.c | 6 +++--- - docs/grub.texi | 6 ++++-- - 3 files changed, 14 insertions(+), 12 deletions(-) - -diff --git a/grub-core/commands/efi/loadbios.c b/grub-core/commands/efi/loadbios.c -index 132cadbc764..3da4c26df7a 100644 ---- a/grub-core/commands/efi/loadbios.c -+++ b/grub-core/commands/efi/loadbios.c -@@ -205,14 +205,14 @@ static grub_command_t cmd_fakebios, cmd_loadbios; - - GRUB_MOD_INIT(loadbios) - { -- cmd_fakebios = grub_register_command ("fakebios", grub_cmd_fakebios, -- 0, N_("Create BIOS-like structures for" -- " backward compatibility with" -- " existing OS.")); -+ cmd_fakebios = grub_register_command_lockdown ("fakebios", grub_cmd_fakebios, -+ 0, N_("Create BIOS-like structures for" -+ " backward compatibility with" -+ " existing OS.")); - -- cmd_loadbios = grub_register_command ("loadbios", grub_cmd_loadbios, -- N_("BIOS_DUMP [INT10_DUMP]"), -- N_("Load BIOS dump.")); -+ cmd_loadbios = grub_register_command_lockdown ("loadbios", grub_cmd_loadbios, -+ N_("BIOS_DUMP [INT10_DUMP]"), -+ N_("Load BIOS dump.")); - } - - GRUB_MOD_FINI(loadbios) -diff --git a/grub-core/loader/arm/linux.c b/grub-core/loader/arm/linux.c -index 1b195e0899e..8fc905e26ca 100644 ---- a/grub-core/loader/arm/linux.c -+++ b/grub-core/loader/arm/linux.c -@@ -513,9 +513,9 @@ GRUB_MOD_INIT (linux) - 0, N_("Load Linux.")); - cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, - 0, N_("Load initrd.")); -- cmd_devicetree = grub_register_command ("devicetree", grub_cmd_devicetree, -- /* TRANSLATORS: DTB stands for device tree blob. */ -- 0, N_("Load DTB file.")); -+ cmd_devicetree = grub_register_command_lockdown ("devicetree", grub_cmd_devicetree, -+ /* TRANSLATORS: DTB stands for device tree blob. */ -+ 0, N_("Load DTB file.")); - my_mod = mod; - fdt_addr = (void *) grub_arm_firmware_get_boot_data (); - machine_type = grub_arm_firmware_get_machine_type (); -diff --git a/docs/grub.texi b/docs/grub.texi -index 5a1cfd4aea9..432610991b7 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -4157,13 +4157,15 @@ hour, minute, and second unchanged. - - - @node devicetree --@subsection linux -+@subsection devicetree - - @deffn Command devicetree file - Load a device tree blob (.dtb) from a filesystem, for later use by a Linux - kernel. Does not perform merging with any device tree supplied by firmware, - but rather replaces it completely. --@ref{GNU/Linux}. -+ -+Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}). -+ This is done to prevent subverting various security mechanisms. - @end deffn - - @node distrust diff --git a/SOURCES/0343-commands-setpci-Restrict-setpci-command-when-locked-.patch b/SOURCES/0343-commands-setpci-Restrict-setpci-command-when-locked-.patch new file mode 100644 index 0000000..1bb09d4 --- /dev/null +++ b/SOURCES/0343-commands-setpci-Restrict-setpci-command-when-locked-.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Wed, 24 Feb 2021 22:59:59 +0100 +Subject: [PATCH] commands/setpci: Restrict setpci command when locked down + +This command can set PCI devices register values, which makes it dangerous +in a locked down configuration. Restrict it so can't be used on this setup. + +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + grub-core/commands/setpci.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/grub-core/commands/setpci.c b/grub-core/commands/setpci.c +index d5bc97d60b2..fa2ba7d8919 100644 +--- a/grub-core/commands/setpci.c ++++ b/grub-core/commands/setpci.c +@@ -329,10 +329,10 @@ static grub_extcmd_t cmd; + + GRUB_MOD_INIT(setpci) + { +- cmd = grub_register_extcmd ("setpci", grub_cmd_setpci, 0, +- N_("[-s POSITION] [-d DEVICE] [-v VAR] " +- "REGISTER[=VALUE[:MASK]]"), +- N_("Manipulate PCI devices."), options); ++ cmd = grub_register_extcmd_lockdown ("setpci", grub_cmd_setpci, 0, ++ N_("[-s POSITION] [-d DEVICE] [-v VAR] " ++ "REGISTER[=VALUE[:MASK]]"), ++ N_("Manipulate PCI devices."), options); + } + + GRUB_MOD_FINI(setpci) diff --git a/SOURCES/0344-commands-hdparm-Restrict-hdparm-command-when-locked-.patch b/SOURCES/0344-commands-hdparm-Restrict-hdparm-command-when-locked-.patch new file mode 100644 index 0000000..f5ec026 --- /dev/null +++ b/SOURCES/0344-commands-hdparm-Restrict-hdparm-command-when-locked-.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Wed, 24 Feb 2021 12:59:29 +0100 +Subject: [PATCH] commands/hdparm: Restrict hdparm command when locked down + +The command can be used to get/set ATA disk parameters. Some of these can +be dangerous since change the disk behavior. Restrict it when locked down. + +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + grub-core/commands/hdparm.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/grub-core/commands/hdparm.c b/grub-core/commands/hdparm.c +index 3fb08912d82..809b89ea5ab 100644 +--- a/grub-core/commands/hdparm.c ++++ b/grub-core/commands/hdparm.c +@@ -434,9 +434,9 @@ static grub_extcmd_t cmd; + + GRUB_MOD_INIT(hdparm) + { +- cmd = grub_register_extcmd ("hdparm", grub_cmd_hdparm, 0, +- N_("[OPTIONS] DISK"), +- N_("Get/set ATA disk parameters."), options); ++ cmd = grub_register_extcmd_lockdown ("hdparm", grub_cmd_hdparm, 0, ++ N_("[OPTIONS] DISK"), ++ N_("Get/set ATA disk parameters."), options); + } + + GRUB_MOD_FINI(hdparm) diff --git a/SOURCES/0344-commands-setpci-Restrict-setpci-command-when-locked-.patch b/SOURCES/0344-commands-setpci-Restrict-setpci-command-when-locked-.patch deleted file mode 100644 index 1bb09d4..0000000 --- a/SOURCES/0344-commands-setpci-Restrict-setpci-command-when-locked-.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Wed, 24 Feb 2021 22:59:59 +0100 -Subject: [PATCH] commands/setpci: Restrict setpci command when locked down - -This command can set PCI devices register values, which makes it dangerous -in a locked down configuration. Restrict it so can't be used on this setup. - -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - grub-core/commands/setpci.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/grub-core/commands/setpci.c b/grub-core/commands/setpci.c -index d5bc97d60b2..fa2ba7d8919 100644 ---- a/grub-core/commands/setpci.c -+++ b/grub-core/commands/setpci.c -@@ -329,10 +329,10 @@ static grub_extcmd_t cmd; - - GRUB_MOD_INIT(setpci) - { -- cmd = grub_register_extcmd ("setpci", grub_cmd_setpci, 0, -- N_("[-s POSITION] [-d DEVICE] [-v VAR] " -- "REGISTER[=VALUE[:MASK]]"), -- N_("Manipulate PCI devices."), options); -+ cmd = grub_register_extcmd_lockdown ("setpci", grub_cmd_setpci, 0, -+ N_("[-s POSITION] [-d DEVICE] [-v VAR] " -+ "REGISTER[=VALUE[:MASK]]"), -+ N_("Manipulate PCI devices."), options); - } - - GRUB_MOD_FINI(setpci) diff --git a/SOURCES/0345-commands-hdparm-Restrict-hdparm-command-when-locked-.patch b/SOURCES/0345-commands-hdparm-Restrict-hdparm-command-when-locked-.patch deleted file mode 100644 index f5ec026..0000000 --- a/SOURCES/0345-commands-hdparm-Restrict-hdparm-command-when-locked-.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Wed, 24 Feb 2021 12:59:29 +0100 -Subject: [PATCH] commands/hdparm: Restrict hdparm command when locked down - -The command can be used to get/set ATA disk parameters. Some of these can -be dangerous since change the disk behavior. Restrict it when locked down. - -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - grub-core/commands/hdparm.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/grub-core/commands/hdparm.c b/grub-core/commands/hdparm.c -index 3fb08912d82..809b89ea5ab 100644 ---- a/grub-core/commands/hdparm.c -+++ b/grub-core/commands/hdparm.c -@@ -434,9 +434,9 @@ static grub_extcmd_t cmd; - - GRUB_MOD_INIT(hdparm) - { -- cmd = grub_register_extcmd ("hdparm", grub_cmd_hdparm, 0, -- N_("[OPTIONS] DISK"), -- N_("Get/set ATA disk parameters."), options); -+ cmd = grub_register_extcmd_lockdown ("hdparm", grub_cmd_hdparm, 0, -+ N_("[OPTIONS] DISK"), -+ N_("Get/set ATA disk parameters."), options); - } - - GRUB_MOD_FINI(hdparm) diff --git a/SOURCES/0345-gdb-Restrict-GDB-access-when-locked-down.patch b/SOURCES/0345-gdb-Restrict-GDB-access-when-locked-down.patch new file mode 100644 index 0000000..b392d22 --- /dev/null +++ b/SOURCES/0345-gdb-Restrict-GDB-access-when-locked-down.patch @@ -0,0 +1,58 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Wed, 24 Feb 2021 15:03:26 +0100 +Subject: [PATCH] gdb: Restrict GDB access when locked down + +The gdbstub* commands allow to start and control a GDB stub running on +local host that can be used to connect from a remote debugger. Restrict +this functionality when the GRUB is locked down. + +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + grub-core/gdb/gdb.c | 32 ++++++++++++++++++-------------- + 1 file changed, 18 insertions(+), 14 deletions(-) + +diff --git a/grub-core/gdb/gdb.c b/grub-core/gdb/gdb.c +index 847a1e1e36f..1818cb6f8eb 100644 +--- a/grub-core/gdb/gdb.c ++++ b/grub-core/gdb/gdb.c +@@ -75,20 +75,24 @@ static grub_command_t cmd, cmd_stop, cmd_break; + GRUB_MOD_INIT (gdb) + { + grub_gdb_idtinit (); +- cmd = grub_register_command ("gdbstub", grub_cmd_gdbstub, +- N_("PORT"), +- /* TRANSLATORS: GDB stub is a small part of +- GDB functionality running on local host +- which allows remote debugger to +- connect to it. */ +- N_("Start GDB stub on given port")); +- cmd_break = grub_register_command ("gdbstub_break", grub_cmd_gdb_break, +- /* TRANSLATORS: this refers to triggering +- a breakpoint so that the user will land +- into GDB. */ +- 0, N_("Break into GDB")); +- cmd_stop = grub_register_command ("gdbstub_stop", grub_cmd_gdbstop, +- 0, N_("Stop GDB stub")); ++ cmd = grub_register_command_lockdown ("gdbstub", grub_cmd_gdbstub, ++ N_("PORT"), ++ /* ++ * TRANSLATORS: GDB stub is a small part of ++ * GDB functionality running on local host ++ * which allows remote debugger to ++ * connect to it. ++ */ ++ N_("Start GDB stub on given port")); ++ cmd_break = grub_register_command_lockdown ("gdbstub_break", grub_cmd_gdb_break, ++ /* ++ * TRANSLATORS: this refers to triggering ++ * a breakpoint so that the user will land ++ * into GDB. ++ */ ++ 0, N_("Break into GDB")); ++ cmd_stop = grub_register_command_lockdown ("gdbstub_stop", grub_cmd_gdbstop, ++ 0, N_("Stop GDB stub")); + } + + GRUB_MOD_FINI (gdb) diff --git a/SOURCES/0346-gdb-Restrict-GDB-access-when-locked-down.patch b/SOURCES/0346-gdb-Restrict-GDB-access-when-locked-down.patch deleted file mode 100644 index b392d22..0000000 --- a/SOURCES/0346-gdb-Restrict-GDB-access-when-locked-down.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Wed, 24 Feb 2021 15:03:26 +0100 -Subject: [PATCH] gdb: Restrict GDB access when locked down - -The gdbstub* commands allow to start and control a GDB stub running on -local host that can be used to connect from a remote debugger. Restrict -this functionality when the GRUB is locked down. - -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - grub-core/gdb/gdb.c | 32 ++++++++++++++++++-------------- - 1 file changed, 18 insertions(+), 14 deletions(-) - -diff --git a/grub-core/gdb/gdb.c b/grub-core/gdb/gdb.c -index 847a1e1e36f..1818cb6f8eb 100644 ---- a/grub-core/gdb/gdb.c -+++ b/grub-core/gdb/gdb.c -@@ -75,20 +75,24 @@ static grub_command_t cmd, cmd_stop, cmd_break; - GRUB_MOD_INIT (gdb) - { - grub_gdb_idtinit (); -- cmd = grub_register_command ("gdbstub", grub_cmd_gdbstub, -- N_("PORT"), -- /* TRANSLATORS: GDB stub is a small part of -- GDB functionality running on local host -- which allows remote debugger to -- connect to it. */ -- N_("Start GDB stub on given port")); -- cmd_break = grub_register_command ("gdbstub_break", grub_cmd_gdb_break, -- /* TRANSLATORS: this refers to triggering -- a breakpoint so that the user will land -- into GDB. */ -- 0, N_("Break into GDB")); -- cmd_stop = grub_register_command ("gdbstub_stop", grub_cmd_gdbstop, -- 0, N_("Stop GDB stub")); -+ cmd = grub_register_command_lockdown ("gdbstub", grub_cmd_gdbstub, -+ N_("PORT"), -+ /* -+ * TRANSLATORS: GDB stub is a small part of -+ * GDB functionality running on local host -+ * which allows remote debugger to -+ * connect to it. -+ */ -+ N_("Start GDB stub on given port")); -+ cmd_break = grub_register_command_lockdown ("gdbstub_break", grub_cmd_gdb_break, -+ /* -+ * TRANSLATORS: this refers to triggering -+ * a breakpoint so that the user will land -+ * into GDB. -+ */ -+ 0, N_("Break into GDB")); -+ cmd_stop = grub_register_command_lockdown ("gdbstub_stop", grub_cmd_gdbstop, -+ 0, N_("Stop GDB stub")); - } - - GRUB_MOD_FINI (gdb) diff --git a/SOURCES/0346-loader-xnu-Don-t-allow-loading-extension-and-package.patch b/SOURCES/0346-loader-xnu-Don-t-allow-loading-extension-and-package.patch new file mode 100644 index 0000000..e153024 --- /dev/null +++ b/SOURCES/0346-loader-xnu-Don-t-allow-loading-extension-and-package.patch @@ -0,0 +1,57 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Wed, 24 Feb 2021 14:44:38 +0100 +Subject: [PATCH] loader/xnu: Don't allow loading extension and packages when + locked down + +The shim_lock verifier validates the XNU kernels but no its extensions +and packages. Prevent these to be loaded when the GRUB is locked down. + +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + grub-core/loader/xnu.c | 31 +++++++++++++++++-------------- + 1 file changed, 17 insertions(+), 14 deletions(-) + +diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c +index 66731d2528b..14e0d65cd27 100644 +--- a/grub-core/loader/xnu.c ++++ b/grub-core/loader/xnu.c +@@ -1477,20 +1477,23 @@ GRUB_MOD_INIT(xnu) + N_("Load XNU image.")); + cmd_kernel64 = grub_register_command ("xnu_kernel64", grub_cmd_xnu_kernel64, + 0, N_("Load 64-bit XNU image.")); +- cmd_mkext = grub_register_command ("xnu_mkext", grub_cmd_xnu_mkext, 0, +- N_("Load XNU extension package.")); +- cmd_kext = grub_register_command ("xnu_kext", grub_cmd_xnu_kext, 0, +- N_("Load XNU extension.")); +- cmd_kextdir = grub_register_command ("xnu_kextdir", grub_cmd_xnu_kextdir, +- /* TRANSLATORS: OSBundleRequired is a +- variable name in xnu extensions +- manifests. It behaves mostly like +- GNU/Linux runlevels. +- */ +- N_("DIRECTORY [OSBundleRequired]"), +- /* TRANSLATORS: There are many extensions +- in extension directory. */ +- N_("Load XNU extension directory.")); ++ cmd_mkext = grub_register_command_lockdown ("xnu_mkext", grub_cmd_xnu_mkext, 0, ++ N_("Load XNU extension package.")); ++ cmd_kext = grub_register_command_lockdown ("xnu_kext", grub_cmd_xnu_kext, 0, ++ N_("Load XNU extension.")); ++ cmd_kextdir = grub_register_command_lockdown ("xnu_kextdir", grub_cmd_xnu_kextdir, ++ /* ++ * TRANSLATORS: OSBundleRequired is ++ * a variable name in xnu extensions ++ * manifests. It behaves mostly like ++ * GNU/Linux runlevels. ++ */ ++ N_("DIRECTORY [OSBundleRequired]"), ++ /* ++ * TRANSLATORS: There are many extensions ++ * in extension directory. ++ */ ++ N_("Load XNU extension directory.")); + cmd_ramdisk = grub_register_command ("xnu_ramdisk", grub_cmd_xnu_ramdisk, 0, + /* TRANSLATORS: ramdisk here isn't identifier. It can be translated. */ + N_("Load XNU ramdisk. " diff --git a/SOURCES/0347-docs-Document-the-cutmem-command.patch b/SOURCES/0347-docs-Document-the-cutmem-command.patch new file mode 100644 index 0000000..ec6aeb8 --- /dev/null +++ b/SOURCES/0347-docs-Document-the-cutmem-command.patch @@ -0,0 +1,61 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Sat, 7 Nov 2020 01:03:18 +0100 +Subject: [PATCH] docs: Document the cutmem command + +The command is not present in the docs/grub.texi user documentation. + +Reported-by: Daniel Kiper +Signed-off-by: Javier Martinez Canillas +Signed-off-by: Daniel Kiper +Reviewed-by: Javier Martinez Canillas +--- + docs/grub.texi | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/docs/grub.texi b/docs/grub.texi +index 432610991b7..446574f3ddb 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -3828,6 +3828,7 @@ you forget a command, you can run the command @command{help} + * cpuid:: Check for CPU features + * crc:: Compute or check CRC32 checksums + * cryptomount:: Mount a crypto device ++* cutmem:: Remove memory regions + * date:: Display or set current date and time + * devicetree:: Load a device tree blob + * distrust:: Remove a pubkey from trusted keys +@@ -3982,6 +3983,8 @@ this page is to be filtered. This syntax makes it easy to represent patterns + that are often result of memory damage, due to physical distribution of memory + cells. + ++The command is similar to @command{cutmem} command. ++ + Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}). + This prevents removing EFI memory regions to potentially subvert the + security mechanisms provided by the UEFI secure boot. +@@ -4142,6 +4145,24 @@ GRUB suports devices encrypted using LUKS and geli. Note that necessary modules + be used. + @end deffn + ++@node cutmem ++@subsection cutmem ++ ++@deffn Command cutmem from[K|M|G] to[K|M|G] ++Remove any memory regions in specified range. ++@end deffn ++ ++This command notifies the memory manager that specified regions of RAM ought to ++be filtered out. This remains in effect after a payload kernel has been loaded ++by GRUB, as long as the loaded kernel obtains its memory map from GRUB. Kernels ++that support this include Linux, GNU Mach, the kernel of FreeBSD and Multiboot ++kernels in general. ++ ++The command is similar to @command{badram} command. ++ ++Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}). ++ This prevents removing EFI memory regions to potentially subvert the ++ security mechanisms provided by the UEFI secure boot. + + @node date + @subsection date diff --git a/SOURCES/0347-loader-xnu-Don-t-allow-loading-extension-and-package.patch b/SOURCES/0347-loader-xnu-Don-t-allow-loading-extension-and-package.patch deleted file mode 100644 index e153024..0000000 --- a/SOURCES/0347-loader-xnu-Don-t-allow-loading-extension-and-package.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Wed, 24 Feb 2021 14:44:38 +0100 -Subject: [PATCH] loader/xnu: Don't allow loading extension and packages when - locked down - -The shim_lock verifier validates the XNU kernels but no its extensions -and packages. Prevent these to be loaded when the GRUB is locked down. - -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - grub-core/loader/xnu.c | 31 +++++++++++++++++-------------- - 1 file changed, 17 insertions(+), 14 deletions(-) - -diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c -index 66731d2528b..14e0d65cd27 100644 ---- a/grub-core/loader/xnu.c -+++ b/grub-core/loader/xnu.c -@@ -1477,20 +1477,23 @@ GRUB_MOD_INIT(xnu) - N_("Load XNU image.")); - cmd_kernel64 = grub_register_command ("xnu_kernel64", grub_cmd_xnu_kernel64, - 0, N_("Load 64-bit XNU image.")); -- cmd_mkext = grub_register_command ("xnu_mkext", grub_cmd_xnu_mkext, 0, -- N_("Load XNU extension package.")); -- cmd_kext = grub_register_command ("xnu_kext", grub_cmd_xnu_kext, 0, -- N_("Load XNU extension.")); -- cmd_kextdir = grub_register_command ("xnu_kextdir", grub_cmd_xnu_kextdir, -- /* TRANSLATORS: OSBundleRequired is a -- variable name in xnu extensions -- manifests. It behaves mostly like -- GNU/Linux runlevels. -- */ -- N_("DIRECTORY [OSBundleRequired]"), -- /* TRANSLATORS: There are many extensions -- in extension directory. */ -- N_("Load XNU extension directory.")); -+ cmd_mkext = grub_register_command_lockdown ("xnu_mkext", grub_cmd_xnu_mkext, 0, -+ N_("Load XNU extension package.")); -+ cmd_kext = grub_register_command_lockdown ("xnu_kext", grub_cmd_xnu_kext, 0, -+ N_("Load XNU extension.")); -+ cmd_kextdir = grub_register_command_lockdown ("xnu_kextdir", grub_cmd_xnu_kextdir, -+ /* -+ * TRANSLATORS: OSBundleRequired is -+ * a variable name in xnu extensions -+ * manifests. It behaves mostly like -+ * GNU/Linux runlevels. -+ */ -+ N_("DIRECTORY [OSBundleRequired]"), -+ /* -+ * TRANSLATORS: There are many extensions -+ * in extension directory. -+ */ -+ N_("Load XNU extension directory.")); - cmd_ramdisk = grub_register_command ("xnu_ramdisk", grub_cmd_xnu_ramdisk, 0, - /* TRANSLATORS: ramdisk here isn't identifier. It can be translated. */ - N_("Load XNU ramdisk. " diff --git a/SOURCES/0348-dl-Only-allow-unloading-modules-that-are-not-depende.patch b/SOURCES/0348-dl-Only-allow-unloading-modules-that-are-not-depende.patch new file mode 100644 index 0000000..51fc1a5 --- /dev/null +++ b/SOURCES/0348-dl-Only-allow-unloading-modules-that-are-not-depende.patch @@ -0,0 +1,83 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Tue, 29 Sep 2020 14:08:55 +0200 +Subject: [PATCH] dl: Only allow unloading modules that are not dependencies + +When a module is attempted to be removed its reference counter is always +decremented. This means that repeated rmmod invocations will cause the +module to be unloaded even if another module depends on it. + +This may lead to a use-after-free scenario allowing an attacker to execute +arbitrary code and by-pass the UEFI Secure Boot protection. + +While being there, add the extern keyword to some function declarations in +that header file. + +Fixes: CVE-2020-25632 + +Reported-by: Chris Coulson +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + grub-core/commands/minicmd.c | 7 +++++-- + grub-core/kern/dl.c | 9 +++++++++ + include/grub/dl.h | 8 +++++--- + 3 files changed, 19 insertions(+), 5 deletions(-) + +diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c +index b25ca4b9f17..4660a020bda 100644 +--- a/grub-core/commands/minicmd.c ++++ b/grub-core/commands/minicmd.c +@@ -137,8 +137,11 @@ grub_mini_cmd_rmmod (struct grub_command *cmd __attribute__ ((unused)), + if (! mod) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such module"); + +- if (grub_dl_unref (mod) <= 0) +- grub_dl_unload (mod); ++ if (grub_dl_ref_count (mod) > 1) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "cannot unload referenced module"); ++ ++ grub_dl_unref (mod); ++ grub_dl_unload (mod); + + return 0; + } +diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c +index c45afc64950..fb88894aba5 100644 +--- a/grub-core/kern/dl.c ++++ b/grub-core/kern/dl.c +@@ -557,6 +557,15 @@ grub_dl_unref (grub_dl_t mod) + return --mod->ref_count; + } + ++int ++grub_dl_ref_count (grub_dl_t mod) ++{ ++ if (mod == NULL) ++ return 0; ++ ++ return mod->ref_count; ++} ++ + static void + grub_dl_flush_cache (grub_dl_t mod) + { +diff --git a/include/grub/dl.h b/include/grub/dl.h +index 9562fa6634c..c0e2c55c8c7 100644 +--- a/include/grub/dl.h ++++ b/include/grub/dl.h +@@ -202,9 +202,11 @@ grub_dl_t EXPORT_FUNC(grub_dl_load) (const char *name); + grub_dl_t grub_dl_load_core (void *addr, grub_size_t size); + grub_dl_t EXPORT_FUNC(grub_dl_load_core_noinit) (void *addr, grub_size_t size); + int EXPORT_FUNC(grub_dl_unload) (grub_dl_t mod); +-void grub_dl_unload_unneeded (void); +-int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod); +-int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod); ++extern void grub_dl_unload_unneeded (void); ++extern int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod); ++extern int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod); ++extern int EXPORT_FUNC(grub_dl_ref_count) (grub_dl_t mod); ++ + extern grub_dl_t EXPORT_VAR(grub_dl_head); + + #ifndef GRUB_UTIL diff --git a/SOURCES/0348-docs-Document-the-cutmem-command.patch b/SOURCES/0348-docs-Document-the-cutmem-command.patch deleted file mode 100644 index ec6aeb8..0000000 --- a/SOURCES/0348-docs-Document-the-cutmem-command.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Sat, 7 Nov 2020 01:03:18 +0100 -Subject: [PATCH] docs: Document the cutmem command - -The command is not present in the docs/grub.texi user documentation. - -Reported-by: Daniel Kiper -Signed-off-by: Javier Martinez Canillas -Signed-off-by: Daniel Kiper -Reviewed-by: Javier Martinez Canillas ---- - docs/grub.texi | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - -diff --git a/docs/grub.texi b/docs/grub.texi -index 432610991b7..446574f3ddb 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -3828,6 +3828,7 @@ you forget a command, you can run the command @command{help} - * cpuid:: Check for CPU features - * crc:: Compute or check CRC32 checksums - * cryptomount:: Mount a crypto device -+* cutmem:: Remove memory regions - * date:: Display or set current date and time - * devicetree:: Load a device tree blob - * distrust:: Remove a pubkey from trusted keys -@@ -3982,6 +3983,8 @@ this page is to be filtered. This syntax makes it easy to represent patterns - that are often result of memory damage, due to physical distribution of memory - cells. - -+The command is similar to @command{cutmem} command. -+ - Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}). - This prevents removing EFI memory regions to potentially subvert the - security mechanisms provided by the UEFI secure boot. -@@ -4142,6 +4145,24 @@ GRUB suports devices encrypted using LUKS and geli. Note that necessary modules - be used. - @end deffn - -+@node cutmem -+@subsection cutmem -+ -+@deffn Command cutmem from[K|M|G] to[K|M|G] -+Remove any memory regions in specified range. -+@end deffn -+ -+This command notifies the memory manager that specified regions of RAM ought to -+be filtered out. This remains in effect after a payload kernel has been loaded -+by GRUB, as long as the loaded kernel obtains its memory map from GRUB. Kernels -+that support this include Linux, GNU Mach, the kernel of FreeBSD and Multiboot -+kernels in general. -+ -+The command is similar to @command{badram} command. -+ -+Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}). -+ This prevents removing EFI memory regions to potentially subvert the -+ security mechanisms provided by the UEFI secure boot. - - @node date - @subsection date diff --git a/SOURCES/0349-dl-Only-allow-unloading-modules-that-are-not-depende.patch b/SOURCES/0349-dl-Only-allow-unloading-modules-that-are-not-depende.patch deleted file mode 100644 index 51fc1a5..0000000 --- a/SOURCES/0349-dl-Only-allow-unloading-modules-that-are-not-depende.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 29 Sep 2020 14:08:55 +0200 -Subject: [PATCH] dl: Only allow unloading modules that are not dependencies - -When a module is attempted to be removed its reference counter is always -decremented. This means that repeated rmmod invocations will cause the -module to be unloaded even if another module depends on it. - -This may lead to a use-after-free scenario allowing an attacker to execute -arbitrary code and by-pass the UEFI Secure Boot protection. - -While being there, add the extern keyword to some function declarations in -that header file. - -Fixes: CVE-2020-25632 - -Reported-by: Chris Coulson -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - grub-core/commands/minicmd.c | 7 +++++-- - grub-core/kern/dl.c | 9 +++++++++ - include/grub/dl.h | 8 +++++--- - 3 files changed, 19 insertions(+), 5 deletions(-) - -diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c -index b25ca4b9f17..4660a020bda 100644 ---- a/grub-core/commands/minicmd.c -+++ b/grub-core/commands/minicmd.c -@@ -137,8 +137,11 @@ grub_mini_cmd_rmmod (struct grub_command *cmd __attribute__ ((unused)), - if (! mod) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such module"); - -- if (grub_dl_unref (mod) <= 0) -- grub_dl_unload (mod); -+ if (grub_dl_ref_count (mod) > 1) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "cannot unload referenced module"); -+ -+ grub_dl_unref (mod); -+ grub_dl_unload (mod); - - return 0; - } -diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c -index c45afc64950..fb88894aba5 100644 ---- a/grub-core/kern/dl.c -+++ b/grub-core/kern/dl.c -@@ -557,6 +557,15 @@ grub_dl_unref (grub_dl_t mod) - return --mod->ref_count; - } - -+int -+grub_dl_ref_count (grub_dl_t mod) -+{ -+ if (mod == NULL) -+ return 0; -+ -+ return mod->ref_count; -+} -+ - static void - grub_dl_flush_cache (grub_dl_t mod) - { -diff --git a/include/grub/dl.h b/include/grub/dl.h -index 9562fa6634c..c0e2c55c8c7 100644 ---- a/include/grub/dl.h -+++ b/include/grub/dl.h -@@ -202,9 +202,11 @@ grub_dl_t EXPORT_FUNC(grub_dl_load) (const char *name); - grub_dl_t grub_dl_load_core (void *addr, grub_size_t size); - grub_dl_t EXPORT_FUNC(grub_dl_load_core_noinit) (void *addr, grub_size_t size); - int EXPORT_FUNC(grub_dl_unload) (grub_dl_t mod); --void grub_dl_unload_unneeded (void); --int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod); --int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod); -+extern void grub_dl_unload_unneeded (void); -+extern int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod); -+extern int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod); -+extern int EXPORT_FUNC(grub_dl_ref_count) (grub_dl_t mod); -+ - extern grub_dl_t EXPORT_VAR(grub_dl_head); - - #ifndef GRUB_UTIL diff --git a/SOURCES/0349-usb-Avoid-possible-out-of-bound-accesses-caused-by-m.patch b/SOURCES/0349-usb-Avoid-possible-out-of-bound-accesses-caused-by-m.patch new file mode 100644 index 0000000..2ac3c27 --- /dev/null +++ b/SOURCES/0349-usb-Avoid-possible-out-of-bound-accesses-caused-by-m.patch @@ -0,0 +1,112 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Fri, 11 Dec 2020 19:19:21 +0100 +Subject: [PATCH] usb: Avoid possible out-of-bound accesses caused by malicious + devices + +The maximum number of configurations and interfaces are fixed but there is +no out-of-bound checking to prevent a malicious USB device to report large +values for these and cause accesses outside the arrays' memory. + +Fixes: CVE-2020-25647 + +Reported-by: Joseph Tartaro (IOActive) +Reported-by: Ilja Van Sprundel +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + grub-core/bus/usb/usb.c | 15 ++++++++++++--- + include/grub/usb.h | 10 +++++++--- + 2 files changed, 19 insertions(+), 6 deletions(-) + +diff --git a/grub-core/bus/usb/usb.c b/grub-core/bus/usb/usb.c +index 8da5e4c7491..7cb3cc230b2 100644 +--- a/grub-core/bus/usb/usb.c ++++ b/grub-core/bus/usb/usb.c +@@ -75,6 +75,9 @@ grub_usb_controller_iterate (grub_usb_controller_iterate_hook_t hook, + grub_usb_err_t + grub_usb_clear_halt (grub_usb_device_t dev, int endpoint) + { ++ if (endpoint >= GRUB_USB_MAX_TOGGLE) ++ return GRUB_USB_ERR_BADDEVICE; ++ + dev->toggle[endpoint] = 0; + return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT + | GRUB_USB_REQTYPE_STANDARD +@@ -134,10 +137,10 @@ grub_usb_device_initialize (grub_usb_device_t dev) + return err; + descdev = &dev->descdev; + +- for (i = 0; i < 8; i++) ++ for (i = 0; i < GRUB_USB_MAX_CONF; i++) + dev->config[i].descconf = NULL; + +- if (descdev->configcnt == 0) ++ if (descdev->configcnt == 0 || descdev->configcnt > GRUB_USB_MAX_CONF) + { + err = GRUB_USB_ERR_BADDEVICE; + goto fail; +@@ -172,6 +175,12 @@ grub_usb_device_initialize (grub_usb_device_t dev) + /* Skip the configuration descriptor. */ + pos = dev->config[i].descconf->length; + ++ if (dev->config[i].descconf->numif > GRUB_USB_MAX_IF) ++ { ++ err = GRUB_USB_ERR_BADDEVICE; ++ goto fail; ++ } ++ + /* Read all interfaces. */ + for (currif = 0; currif < dev->config[i].descconf->numif; currif++) + { +@@ -217,7 +226,7 @@ grub_usb_device_initialize (grub_usb_device_t dev) + + fail: + +- for (i = 0; i < 8; i++) ++ for (i = 0; i < GRUB_USB_MAX_CONF; i++) + grub_free (dev->config[i].descconf); + + return err; +diff --git a/include/grub/usb.h b/include/grub/usb.h +index 11d96481ff6..f26b89b7fd4 100644 +--- a/include/grub/usb.h ++++ b/include/grub/usb.h +@@ -23,6 +23,10 @@ + #include + #include + ++#define GRUB_USB_MAX_CONF 8 ++#define GRUB_USB_MAX_IF 32 ++#define GRUB_USB_MAX_TOGGLE 256 ++ + typedef struct grub_usb_device *grub_usb_device_t; + typedef struct grub_usb_controller *grub_usb_controller_t; + typedef struct grub_usb_controller_dev *grub_usb_controller_dev_t; +@@ -167,7 +171,7 @@ struct grub_usb_configuration + struct grub_usb_desc_config *descconf; + + /* Interfaces associated to this configuration. */ +- struct grub_usb_interface interf[32]; ++ struct grub_usb_interface interf[GRUB_USB_MAX_IF]; + }; + + struct grub_usb_hub_port +@@ -191,7 +195,7 @@ struct grub_usb_device + struct grub_usb_controller controller; + + /* Device configurations (after opening the device). */ +- struct grub_usb_configuration config[8]; ++ struct grub_usb_configuration config[GRUB_USB_MAX_CONF]; + + /* Device address. */ + int addr; +@@ -203,7 +207,7 @@ struct grub_usb_device + int initialized; + + /* Data toggle values (used for bulk transfers only). */ +- int toggle[256]; ++ int toggle[GRUB_USB_MAX_TOGGLE]; + + /* Used by libusb wrapper. Schedulded for removal. */ + void *data; diff --git a/SOURCES/0350-mmap-Fix-memory-leak-when-iterating-over-mapped-memo.patch b/SOURCES/0350-mmap-Fix-memory-leak-when-iterating-over-mapped-memo.patch new file mode 100644 index 0000000..66e3744 --- /dev/null +++ b/SOURCES/0350-mmap-Fix-memory-leak-when-iterating-over-mapped-memo.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Thu, 3 Dec 2020 14:39:45 +0000 +Subject: [PATCH] mmap: Fix memory leak when iterating over mapped memory + +When returning from grub_mmap_iterate() the memory allocated to present +is not being released causing it to leak. + +Fixes: CID 96655 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/mmap/mmap.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c +index 7ebf32e1e5e..8bf235f3400 100644 +--- a/grub-core/mmap/mmap.c ++++ b/grub-core/mmap/mmap.c +@@ -270,6 +270,7 @@ grub_mmap_iterate (grub_memory_hook_t hook, void *hook_data) + hook_data)) + { + grub_free (ctx.scanline_events); ++ grub_free (present); + return GRUB_ERR_NONE; + } + +@@ -282,6 +283,7 @@ grub_mmap_iterate (grub_memory_hook_t hook, void *hook_data) + } + + grub_free (ctx.scanline_events); ++ grub_free (present); + return GRUB_ERR_NONE; + } + diff --git a/SOURCES/0350-usb-Avoid-possible-out-of-bound-accesses-caused-by-m.patch b/SOURCES/0350-usb-Avoid-possible-out-of-bound-accesses-caused-by-m.patch deleted file mode 100644 index 2ac3c27..0000000 --- a/SOURCES/0350-usb-Avoid-possible-out-of-bound-accesses-caused-by-m.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Fri, 11 Dec 2020 19:19:21 +0100 -Subject: [PATCH] usb: Avoid possible out-of-bound accesses caused by malicious - devices - -The maximum number of configurations and interfaces are fixed but there is -no out-of-bound checking to prevent a malicious USB device to report large -values for these and cause accesses outside the arrays' memory. - -Fixes: CVE-2020-25647 - -Reported-by: Joseph Tartaro (IOActive) -Reported-by: Ilja Van Sprundel -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - grub-core/bus/usb/usb.c | 15 ++++++++++++--- - include/grub/usb.h | 10 +++++++--- - 2 files changed, 19 insertions(+), 6 deletions(-) - -diff --git a/grub-core/bus/usb/usb.c b/grub-core/bus/usb/usb.c -index 8da5e4c7491..7cb3cc230b2 100644 ---- a/grub-core/bus/usb/usb.c -+++ b/grub-core/bus/usb/usb.c -@@ -75,6 +75,9 @@ grub_usb_controller_iterate (grub_usb_controller_iterate_hook_t hook, - grub_usb_err_t - grub_usb_clear_halt (grub_usb_device_t dev, int endpoint) - { -+ if (endpoint >= GRUB_USB_MAX_TOGGLE) -+ return GRUB_USB_ERR_BADDEVICE; -+ - dev->toggle[endpoint] = 0; - return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT - | GRUB_USB_REQTYPE_STANDARD -@@ -134,10 +137,10 @@ grub_usb_device_initialize (grub_usb_device_t dev) - return err; - descdev = &dev->descdev; - -- for (i = 0; i < 8; i++) -+ for (i = 0; i < GRUB_USB_MAX_CONF; i++) - dev->config[i].descconf = NULL; - -- if (descdev->configcnt == 0) -+ if (descdev->configcnt == 0 || descdev->configcnt > GRUB_USB_MAX_CONF) - { - err = GRUB_USB_ERR_BADDEVICE; - goto fail; -@@ -172,6 +175,12 @@ grub_usb_device_initialize (grub_usb_device_t dev) - /* Skip the configuration descriptor. */ - pos = dev->config[i].descconf->length; - -+ if (dev->config[i].descconf->numif > GRUB_USB_MAX_IF) -+ { -+ err = GRUB_USB_ERR_BADDEVICE; -+ goto fail; -+ } -+ - /* Read all interfaces. */ - for (currif = 0; currif < dev->config[i].descconf->numif; currif++) - { -@@ -217,7 +226,7 @@ grub_usb_device_initialize (grub_usb_device_t dev) - - fail: - -- for (i = 0; i < 8; i++) -+ for (i = 0; i < GRUB_USB_MAX_CONF; i++) - grub_free (dev->config[i].descconf); - - return err; -diff --git a/include/grub/usb.h b/include/grub/usb.h -index 11d96481ff6..f26b89b7fd4 100644 ---- a/include/grub/usb.h -+++ b/include/grub/usb.h -@@ -23,6 +23,10 @@ - #include - #include - -+#define GRUB_USB_MAX_CONF 8 -+#define GRUB_USB_MAX_IF 32 -+#define GRUB_USB_MAX_TOGGLE 256 -+ - typedef struct grub_usb_device *grub_usb_device_t; - typedef struct grub_usb_controller *grub_usb_controller_t; - typedef struct grub_usb_controller_dev *grub_usb_controller_dev_t; -@@ -167,7 +171,7 @@ struct grub_usb_configuration - struct grub_usb_desc_config *descconf; - - /* Interfaces associated to this configuration. */ -- struct grub_usb_interface interf[32]; -+ struct grub_usb_interface interf[GRUB_USB_MAX_IF]; - }; - - struct grub_usb_hub_port -@@ -191,7 +195,7 @@ struct grub_usb_device - struct grub_usb_controller controller; - - /* Device configurations (after opening the device). */ -- struct grub_usb_configuration config[8]; -+ struct grub_usb_configuration config[GRUB_USB_MAX_CONF]; - - /* Device address. */ - int addr; -@@ -203,7 +207,7 @@ struct grub_usb_device - int initialized; - - /* Data toggle values (used for bulk transfers only). */ -- int toggle[256]; -+ int toggle[GRUB_USB_MAX_TOGGLE]; - - /* Used by libusb wrapper. Schedulded for removal. */ - void *data; diff --git a/SOURCES/0351-mmap-Fix-memory-leak-when-iterating-over-mapped-memo.patch b/SOURCES/0351-mmap-Fix-memory-leak-when-iterating-over-mapped-memo.patch deleted file mode 100644 index 66e3744..0000000 --- a/SOURCES/0351-mmap-Fix-memory-leak-when-iterating-over-mapped-memo.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Thu, 3 Dec 2020 14:39:45 +0000 -Subject: [PATCH] mmap: Fix memory leak when iterating over mapped memory - -When returning from grub_mmap_iterate() the memory allocated to present -is not being released causing it to leak. - -Fixes: CID 96655 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/mmap/mmap.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c -index 7ebf32e1e5e..8bf235f3400 100644 ---- a/grub-core/mmap/mmap.c -+++ b/grub-core/mmap/mmap.c -@@ -270,6 +270,7 @@ grub_mmap_iterate (grub_memory_hook_t hook, void *hook_data) - hook_data)) - { - grub_free (ctx.scanline_events); -+ grub_free (present); - return GRUB_ERR_NONE; - } - -@@ -282,6 +283,7 @@ grub_mmap_iterate (grub_memory_hook_t hook, void *hook_data) - } - - grub_free (ctx.scanline_events); -+ grub_free (present); - return GRUB_ERR_NONE; - } - diff --git a/SOURCES/0351-net-net-Fix-possible-dereference-to-of-a-NULL-pointe.patch b/SOURCES/0351-net-net-Fix-possible-dereference-to-of-a-NULL-pointe.patch new file mode 100644 index 0000000..ed8a408 --- /dev/null +++ b/SOURCES/0351-net-net-Fix-possible-dereference-to-of-a-NULL-pointe.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Fri, 27 Nov 2020 15:10:26 +0000 +Subject: [PATCH] net/net: Fix possible dereference to of a NULL pointer + +It is always possible that grub_zalloc() could fail, so we should check for +a NULL return. Otherwise we run the risk of dereferencing a NULL pointer. + +Fixes: CID 296221 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/net/net.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/grub-core/net/net.c b/grub-core/net/net.c +index 80310ff4e7a..1f62aa10f2f 100644 +--- a/grub-core/net/net.c ++++ b/grub-core/net/net.c +@@ -104,8 +104,13 @@ grub_net_link_layer_add_address (struct grub_net_card *card, + + /* Add sender to cache table. */ + if (card->link_layer_table == NULL) +- card->link_layer_table = grub_zalloc (LINK_LAYER_CACHE_SIZE +- * sizeof (card->link_layer_table[0])); ++ { ++ card->link_layer_table = grub_zalloc (LINK_LAYER_CACHE_SIZE ++ * sizeof (card->link_layer_table[0])); ++ if (card->link_layer_table == NULL) ++ return; ++ } ++ + entry = &(card->link_layer_table[card->new_ll_entry]); + entry->avail = 1; + grub_memcpy (&entry->ll_address, ll, sizeof (entry->ll_address)); diff --git a/SOURCES/0352-net-net-Fix-possible-dereference-to-of-a-NULL-pointe.patch b/SOURCES/0352-net-net-Fix-possible-dereference-to-of-a-NULL-pointe.patch deleted file mode 100644 index ed8a408..0000000 --- a/SOURCES/0352-net-net-Fix-possible-dereference-to-of-a-NULL-pointe.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Fri, 27 Nov 2020 15:10:26 +0000 -Subject: [PATCH] net/net: Fix possible dereference to of a NULL pointer - -It is always possible that grub_zalloc() could fail, so we should check for -a NULL return. Otherwise we run the risk of dereferencing a NULL pointer. - -Fixes: CID 296221 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/net/net.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/net.c b/grub-core/net/net.c -index 80310ff4e7a..1f62aa10f2f 100644 ---- a/grub-core/net/net.c -+++ b/grub-core/net/net.c -@@ -104,8 +104,13 @@ grub_net_link_layer_add_address (struct grub_net_card *card, - - /* Add sender to cache table. */ - if (card->link_layer_table == NULL) -- card->link_layer_table = grub_zalloc (LINK_LAYER_CACHE_SIZE -- * sizeof (card->link_layer_table[0])); -+ { -+ card->link_layer_table = grub_zalloc (LINK_LAYER_CACHE_SIZE -+ * sizeof (card->link_layer_table[0])); -+ if (card->link_layer_table == NULL) -+ return; -+ } -+ - entry = &(card->link_layer_table[card->new_ll_entry]); - entry->avail = 1; - grub_memcpy (&entry->ll_address, ll, sizeof (entry->ll_address)); diff --git a/SOURCES/0352-net-tftp-Fix-dangling-memory-pointer.patch b/SOURCES/0352-net-tftp-Fix-dangling-memory-pointer.patch new file mode 100644 index 0000000..193d893 --- /dev/null +++ b/SOURCES/0352-net-tftp-Fix-dangling-memory-pointer.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Fri, 19 Feb 2021 17:12:23 +0000 +Subject: [PATCH] net/tftp: Fix dangling memory pointer + +The static code analysis tool, Parfait, reported that the valid of +file->data was left referencing memory that was freed by the call to +grub_free(data) where data was initialized from file->data. + +To ensure that there is no unintentional access to this memory +referenced by file->data we should set the pointer to NULL. + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/net/tftp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c +index b9a4b607a3d..aa0424dcee3 100644 +--- a/grub-core/net/tftp.c ++++ b/grub-core/net/tftp.c +@@ -444,6 +444,7 @@ tftp_close (struct grub_file *file) + grub_net_udp_close (data->sock); + } + grub_free (data); ++ file->data = NULL; + return GRUB_ERR_NONE; + } + diff --git a/SOURCES/0353-kern-parser-Fix-resource-leak-if-argc-0.patch b/SOURCES/0353-kern-parser-Fix-resource-leak-if-argc-0.patch new file mode 100644 index 0000000..a422623 --- /dev/null +++ b/SOURCES/0353-kern-parser-Fix-resource-leak-if-argc-0.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Fri, 22 Jan 2021 12:32:41 +0000 +Subject: [PATCH] kern/parser: Fix resource leak if argc == 0 + +After processing the command-line yet arriving at the point where we are +setting argv, we are allocating memory, even if argc == 0, which makes +no sense since we never put anything into the allocated argv. + +The solution is to simply return that we've successfully processed the +arguments but that argc == 0, and also ensure that argv is NULL when +we're not allocating anything in it. + +There are only 2 callers of this function, and both are handling a zero +value in argc assuming nothing is allocated in argv. + +Fixes: CID 96680 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/kern/parser.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c +index 5de8559e777..94e8728d59a 100644 +--- a/grub-core/kern/parser.c ++++ b/grub-core/kern/parser.c +@@ -146,6 +146,7 @@ grub_parser_split_cmdline (const char *cmdline, + int i; + + *argc = 0; ++ *argv = NULL; + do + { + if (!rd || !*rd) +@@ -207,6 +208,10 @@ grub_parser_split_cmdline (const char *cmdline, + (*argc)++; + } + ++ /* If there are no args, then we're done. */ ++ if (!*argc) ++ return 0; ++ + /* Reserve memory for the return values. */ + args = grub_malloc (bp - buffer); + if (!args) diff --git a/SOURCES/0353-net-tftp-Fix-dangling-memory-pointer.patch b/SOURCES/0353-net-tftp-Fix-dangling-memory-pointer.patch deleted file mode 100644 index 193d893..0000000 --- a/SOURCES/0353-net-tftp-Fix-dangling-memory-pointer.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Fri, 19 Feb 2021 17:12:23 +0000 -Subject: [PATCH] net/tftp: Fix dangling memory pointer - -The static code analysis tool, Parfait, reported that the valid of -file->data was left referencing memory that was freed by the call to -grub_free(data) where data was initialized from file->data. - -To ensure that there is no unintentional access to this memory -referenced by file->data we should set the pointer to NULL. - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/net/tftp.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c -index b9a4b607a3d..aa0424dcee3 100644 ---- a/grub-core/net/tftp.c -+++ b/grub-core/net/tftp.c -@@ -444,6 +444,7 @@ tftp_close (struct grub_file *file) - grub_net_udp_close (data->sock); - } - grub_free (data); -+ file->data = NULL; - return GRUB_ERR_NONE; - } - diff --git a/SOURCES/0354-kern-efi-Fix-memory-leak-on-failure.patch b/SOURCES/0354-kern-efi-Fix-memory-leak-on-failure.patch new file mode 100644 index 0000000..06b02e8 --- /dev/null +++ b/SOURCES/0354-kern-efi-Fix-memory-leak-on-failure.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Thu, 5 Nov 2020 10:15:25 +0000 +Subject: [PATCH] kern/efi: Fix memory leak on failure + +Free the memory allocated to name before returning on failure. + +Fixes: CID 296222 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/kern/efi/efi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c +index 6c4099a685d..fce4ca05c65 100644 +--- a/grub-core/kern/efi/efi.c ++++ b/grub-core/kern/efi/efi.c +@@ -381,6 +381,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, + "malformed EFI Device Path node has length=%d", len); ++ grub_free (name); + return NULL; + } + diff --git a/SOURCES/0354-kern-parser-Fix-resource-leak-if-argc-0.patch b/SOURCES/0354-kern-parser-Fix-resource-leak-if-argc-0.patch deleted file mode 100644 index a422623..0000000 --- a/SOURCES/0354-kern-parser-Fix-resource-leak-if-argc-0.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Fri, 22 Jan 2021 12:32:41 +0000 -Subject: [PATCH] kern/parser: Fix resource leak if argc == 0 - -After processing the command-line yet arriving at the point where we are -setting argv, we are allocating memory, even if argc == 0, which makes -no sense since we never put anything into the allocated argv. - -The solution is to simply return that we've successfully processed the -arguments but that argc == 0, and also ensure that argv is NULL when -we're not allocating anything in it. - -There are only 2 callers of this function, and both are handling a zero -value in argc assuming nothing is allocated in argv. - -Fixes: CID 96680 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/kern/parser.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c -index 5de8559e777..94e8728d59a 100644 ---- a/grub-core/kern/parser.c -+++ b/grub-core/kern/parser.c -@@ -146,6 +146,7 @@ grub_parser_split_cmdline (const char *cmdline, - int i; - - *argc = 0; -+ *argv = NULL; - do - { - if (!rd || !*rd) -@@ -207,6 +208,10 @@ grub_parser_split_cmdline (const char *cmdline, - (*argc)++; - } - -+ /* If there are no args, then we're done. */ -+ if (!*argc) -+ return 0; -+ - /* Reserve memory for the return values. */ - args = grub_malloc (bp - buffer); - if (!args) diff --git a/SOURCES/0355-kern-efi-Fix-memory-leak-on-failure.patch b/SOURCES/0355-kern-efi-Fix-memory-leak-on-failure.patch deleted file mode 100644 index 06b02e8..0000000 --- a/SOURCES/0355-kern-efi-Fix-memory-leak-on-failure.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Thu, 5 Nov 2020 10:15:25 +0000 -Subject: [PATCH] kern/efi: Fix memory leak on failure - -Free the memory allocated to name before returning on failure. - -Fixes: CID 296222 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/kern/efi/efi.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index 6c4099a685d..fce4ca05c65 100644 ---- a/grub-core/kern/efi/efi.c -+++ b/grub-core/kern/efi/efi.c -@@ -381,6 +381,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, - "malformed EFI Device Path node has length=%d", len); -+ grub_free (name); - return NULL; - } - diff --git a/SOURCES/0355-kern-efi-mm-Fix-possible-NULL-pointer-dereference.patch b/SOURCES/0355-kern-efi-mm-Fix-possible-NULL-pointer-dereference.patch new file mode 100644 index 0000000..7b92857 --- /dev/null +++ b/SOURCES/0355-kern-efi-mm-Fix-possible-NULL-pointer-dereference.patch @@ -0,0 +1,65 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Fri, 11 Dec 2020 15:03:13 +0000 +Subject: [PATCH] kern/efi/mm: Fix possible NULL pointer dereference + +The model of grub_efi_get_memory_map() is that if memory_map is NULL, +then the purpose is to discover how much memory should be allocated to +it for the subsequent call. + +The problem here is that with grub_efi_is_finished set to 1, there is no +check at all that the function is being called with a non-NULL memory_map. + +While this MAY be true, we shouldn't assume it. + +The solution to this is to behave as expected, and if memory_map is NULL, +then don't try to use it and allow memory_map_size to be filled in, and +return 0 as is done later in the code if the buffer is too small (or NULL). + +Additionally, drop unneeded ret = 1. + +Fixes: CID 96632 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/kern/efi/mm.c | 23 ++++++++++++++++------- + 1 file changed, 16 insertions(+), 7 deletions(-) + +diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c +index abe9c70557f..bb022f43e91 100644 +--- a/grub-core/kern/efi/mm.c ++++ b/grub-core/kern/efi/mm.c +@@ -334,16 +334,25 @@ grub_efi_get_memory_map (grub_efi_uintn_t *memory_map_size, + if (grub_efi_is_finished) + { + int ret = 1; +- if (*memory_map_size < finish_mmap_size) ++ ++ if (memory_map != NULL) + { +- grub_memcpy (memory_map, finish_mmap_buf, *memory_map_size); ++ if (*memory_map_size < finish_mmap_size) ++ { ++ grub_memcpy (memory_map, finish_mmap_buf, *memory_map_size); ++ ret = 0; ++ } ++ else ++ grub_memcpy (memory_map, finish_mmap_buf, finish_mmap_size); ++ } ++ else ++ { ++ /* ++ * Incomplete, no buffer to copy into, same as ++ * GRUB_EFI_BUFFER_TOO_SMALL below. ++ */ + ret = 0; + } +- else +- { +- grub_memcpy (memory_map, finish_mmap_buf, finish_mmap_size); +- ret = 1; +- } + *memory_map_size = finish_mmap_size; + if (map_key) + *map_key = finish_key; diff --git a/SOURCES/0356-gnulib-regexec-Resolve-unused-variable.patch b/SOURCES/0356-gnulib-regexec-Resolve-unused-variable.patch new file mode 100644 index 0000000..54c8148 --- /dev/null +++ b/SOURCES/0356-gnulib-regexec-Resolve-unused-variable.patch @@ -0,0 +1,73 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Wed, 21 Oct 2020 14:41:27 +0000 +Subject: [PATCH] gnulib/regexec: Resolve unused variable + +This is a really minor issue where a variable is being assigned to but +not checked before it is overwritten again. + +The reason for this issue is that we are not building with DEBUG set and +this in turn means that the assert() that reads the value of the +variable match_last is being processed out. + +The solution, move the assignment to match_last in to an ifdef DEBUG too. + +Fixes: CID 292459 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/gnulib/regexec.c | 4 ++++ + conf/Makefile.extra-dist | 1 + + grub-core/gnulib-fix-unused-value.patch | 14 ++++++++++++++ + 3 files changed, 19 insertions(+) + create mode 100644 grub-core/gnulib-fix-unused-value.patch + +diff --git a/grub-core/gnulib/regexec.c b/grub-core/gnulib/regexec.c +index f632cd47b3a..fdc178e07a4 100644 +--- a/grub-core/gnulib/regexec.c ++++ b/grub-core/gnulib/regexec.c +@@ -879,7 +879,11 @@ re_search_internal (const regex_t *preg, + break; + if (BE (err != REG_NOMATCH, 0)) + goto free_return; ++#ifdef DEBUG ++ /* Only used for assertion below when DEBUG is set, otherwise ++ it will be over-written when we loop around. */ + match_last = REG_MISSING; ++#endif + } + else + break; /* We found a match. */ +diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist +index e914dfd897e..7b305bce766 100644 +--- a/conf/Makefile.extra-dist ++++ b/conf/Makefile.extra-dist +@@ -27,6 +27,7 @@ EXTRA_DIST += grub-core/genemuinit.sh + EXTRA_DIST += grub-core/genemuinitheader.sh + + EXTRA_DIST += grub-core/gnulib-fix-null-deref.diff ++EXTRA_DIST += grub-core/gnulib-fix-unused-value.patch + EXTRA_DIST += grub-core/gnulib-fix-width.diff + EXTRA_DIST += grub-core/gnulib-no-abort.diff + EXTRA_DIST += grub-core/gnulib-no-gets.diff +diff --git a/grub-core/gnulib-fix-unused-value.patch b/grub-core/gnulib-fix-unused-value.patch +new file mode 100644 +index 00000000000..452a8732922 +--- /dev/null ++++ b/grub-core/gnulib-fix-unused-value.patch +@@ -0,0 +1,14 @@ ++--- grub-core/gnulib/regexec.c 2020-10-21 14:25:35.310195912 +0000 +++++ grub-core/gnulib/regexec.c 2020-10-21 14:32:07.961765604 +0000 ++@@ -828,7 +828,11 @@ ++ break; ++ if (BE (err != REG_NOMATCH, 0)) ++ goto free_return; +++#ifdef DEBUG +++ /* Only used for assertion below when DEBUG is set, otherwise +++ it will be over-written when we loop around. */ ++ match_last = REG_MISSING; +++#endif ++ } ++ else ++ break; /* We found a match. */ diff --git a/SOURCES/0356-kern-efi-mm-Fix-possible-NULL-pointer-dereference.patch b/SOURCES/0356-kern-efi-mm-Fix-possible-NULL-pointer-dereference.patch deleted file mode 100644 index 7b92857..0000000 --- a/SOURCES/0356-kern-efi-mm-Fix-possible-NULL-pointer-dereference.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Fri, 11 Dec 2020 15:03:13 +0000 -Subject: [PATCH] kern/efi/mm: Fix possible NULL pointer dereference - -The model of grub_efi_get_memory_map() is that if memory_map is NULL, -then the purpose is to discover how much memory should be allocated to -it for the subsequent call. - -The problem here is that with grub_efi_is_finished set to 1, there is no -check at all that the function is being called with a non-NULL memory_map. - -While this MAY be true, we shouldn't assume it. - -The solution to this is to behave as expected, and if memory_map is NULL, -then don't try to use it and allow memory_map_size to be filled in, and -return 0 as is done later in the code if the buffer is too small (or NULL). - -Additionally, drop unneeded ret = 1. - -Fixes: CID 96632 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/kern/efi/mm.c | 23 ++++++++++++++++------- - 1 file changed, 16 insertions(+), 7 deletions(-) - -diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c -index abe9c70557f..bb022f43e91 100644 ---- a/grub-core/kern/efi/mm.c -+++ b/grub-core/kern/efi/mm.c -@@ -334,16 +334,25 @@ grub_efi_get_memory_map (grub_efi_uintn_t *memory_map_size, - if (grub_efi_is_finished) - { - int ret = 1; -- if (*memory_map_size < finish_mmap_size) -+ -+ if (memory_map != NULL) - { -- grub_memcpy (memory_map, finish_mmap_buf, *memory_map_size); -+ if (*memory_map_size < finish_mmap_size) -+ { -+ grub_memcpy (memory_map, finish_mmap_buf, *memory_map_size); -+ ret = 0; -+ } -+ else -+ grub_memcpy (memory_map, finish_mmap_buf, finish_mmap_size); -+ } -+ else -+ { -+ /* -+ * Incomplete, no buffer to copy into, same as -+ * GRUB_EFI_BUFFER_TOO_SMALL below. -+ */ - ret = 0; - } -- else -- { -- grub_memcpy (memory_map, finish_mmap_buf, finish_mmap_size); -- ret = 1; -- } - *memory_map_size = finish_mmap_size; - if (map_key) - *map_key = finish_key; diff --git a/SOURCES/0357-gnulib-regcomp-Fix-uninitialized-token-structure.patch b/SOURCES/0357-gnulib-regcomp-Fix-uninitialized-token-structure.patch new file mode 100644 index 0000000..3a6beb6 --- /dev/null +++ b/SOURCES/0357-gnulib-regcomp-Fix-uninitialized-token-structure.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Thu, 22 Oct 2020 13:54:06 +0000 +Subject: [PATCH] gnulib/regcomp: Fix uninitialized token structure + +The code is assuming that the value of br_token.constraint was +initialized to zero when it wasn't. + +While some compilers will ensure that, not all do, so it is better to +fix this explicitly than leave it to chance. + +Fixes: CID 73749 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/gnulib/regcomp.c | 2 +- + conf/Makefile.extra-dist | 1 + + grub-core/gnulib-fix-uninit-structure.patch | 11 +++++++++++ + 3 files changed, 13 insertions(+), 1 deletion(-) + create mode 100644 grub-core/gnulib-fix-uninit-structure.patch + +diff --git a/grub-core/gnulib/regcomp.c b/grub-core/gnulib/regcomp.c +index 596e0cf3ef7..de9f622088f 100644 +--- a/grub-core/gnulib/regcomp.c ++++ b/grub-core/gnulib/regcomp.c +@@ -3641,7 +3641,7 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans, + Idx alloc = 0; + #endif /* not RE_ENABLE_I18N */ + reg_errcode_t ret; +- re_token_t br_token; ++ re_token_t br_token = {0}; + bin_tree_t *tree; + + sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); +diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist +index 7b305bce766..8baa6a831f7 100644 +--- a/conf/Makefile.extra-dist ++++ b/conf/Makefile.extra-dist +@@ -27,6 +27,7 @@ EXTRA_DIST += grub-core/genemuinit.sh + EXTRA_DIST += grub-core/genemuinitheader.sh + + EXTRA_DIST += grub-core/gnulib-fix-null-deref.diff ++EXTRA_DIST += grub-core/gnulib-fix-uninit-structure.patch + EXTRA_DIST += grub-core/gnulib-fix-unused-value.patch + EXTRA_DIST += grub-core/gnulib-fix-width.diff + EXTRA_DIST += grub-core/gnulib-no-abort.diff +diff --git a/grub-core/gnulib-fix-uninit-structure.patch b/grub-core/gnulib-fix-uninit-structure.patch +new file mode 100644 +index 00000000000..7b4d9f67af4 +--- /dev/null ++++ b/grub-core/gnulib-fix-uninit-structure.patch +@@ -0,0 +1,11 @@ ++--- a/lib/regcomp.c 2020-10-22 13:49:06.770168928 +0000 +++++ b/lib/regcomp.c 2020-10-22 13:50:37.026528298 +0000 ++@@ -3662,7 +3662,7 @@ ++ Idx alloc = 0; ++ #endif /* not RE_ENABLE_I18N */ ++ reg_errcode_t ret; ++- re_token_t br_token; +++ re_token_t br_token = {0}; ++ bin_tree_t *tree; ++ ++ sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); diff --git a/SOURCES/0357-gnulib-regexec-Resolve-unused-variable.patch b/SOURCES/0357-gnulib-regexec-Resolve-unused-variable.patch deleted file mode 100644 index 54c8148..0000000 --- a/SOURCES/0357-gnulib-regexec-Resolve-unused-variable.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Wed, 21 Oct 2020 14:41:27 +0000 -Subject: [PATCH] gnulib/regexec: Resolve unused variable - -This is a really minor issue where a variable is being assigned to but -not checked before it is overwritten again. - -The reason for this issue is that we are not building with DEBUG set and -this in turn means that the assert() that reads the value of the -variable match_last is being processed out. - -The solution, move the assignment to match_last in to an ifdef DEBUG too. - -Fixes: CID 292459 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/gnulib/regexec.c | 4 ++++ - conf/Makefile.extra-dist | 1 + - grub-core/gnulib-fix-unused-value.patch | 14 ++++++++++++++ - 3 files changed, 19 insertions(+) - create mode 100644 grub-core/gnulib-fix-unused-value.patch - -diff --git a/grub-core/gnulib/regexec.c b/grub-core/gnulib/regexec.c -index f632cd47b3a..fdc178e07a4 100644 ---- a/grub-core/gnulib/regexec.c -+++ b/grub-core/gnulib/regexec.c -@@ -879,7 +879,11 @@ re_search_internal (const regex_t *preg, - break; - if (BE (err != REG_NOMATCH, 0)) - goto free_return; -+#ifdef DEBUG -+ /* Only used for assertion below when DEBUG is set, otherwise -+ it will be over-written when we loop around. */ - match_last = REG_MISSING; -+#endif - } - else - break; /* We found a match. */ -diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist -index e914dfd897e..7b305bce766 100644 ---- a/conf/Makefile.extra-dist -+++ b/conf/Makefile.extra-dist -@@ -27,6 +27,7 @@ EXTRA_DIST += grub-core/genemuinit.sh - EXTRA_DIST += grub-core/genemuinitheader.sh - - EXTRA_DIST += grub-core/gnulib-fix-null-deref.diff -+EXTRA_DIST += grub-core/gnulib-fix-unused-value.patch - EXTRA_DIST += grub-core/gnulib-fix-width.diff - EXTRA_DIST += grub-core/gnulib-no-abort.diff - EXTRA_DIST += grub-core/gnulib-no-gets.diff -diff --git a/grub-core/gnulib-fix-unused-value.patch b/grub-core/gnulib-fix-unused-value.patch -new file mode 100644 -index 00000000000..452a8732922 ---- /dev/null -+++ b/grub-core/gnulib-fix-unused-value.patch -@@ -0,0 +1,14 @@ -+--- grub-core/gnulib/regexec.c 2020-10-21 14:25:35.310195912 +0000 -++++ grub-core/gnulib/regexec.c 2020-10-21 14:32:07.961765604 +0000 -+@@ -828,7 +828,11 @@ -+ break; -+ if (BE (err != REG_NOMATCH, 0)) -+ goto free_return; -++#ifdef DEBUG -++ /* Only used for assertion below when DEBUG is set, otherwise -++ it will be over-written when we loop around. */ -+ match_last = REG_MISSING; -++#endif -+ } -+ else -+ break; /* We found a match. */ diff --git a/SOURCES/0358-gnulib-argp-help-Fix-dereference-of-a-possibly-NULL-.patch b/SOURCES/0358-gnulib-argp-help-Fix-dereference-of-a-possibly-NULL-.patch new file mode 100644 index 0000000..c308833 --- /dev/null +++ b/SOURCES/0358-gnulib-argp-help-Fix-dereference-of-a-possibly-NULL-.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Wed, 28 Oct 2020 14:43:01 +0000 +Subject: [PATCH] gnulib/argp-help: Fix dereference of a possibly NULL state + +All other instances of call to __argp_failure() where there is +a dgettext() call is first checking whether state is NULL before +attempting to dereference it to get the root_argp->argp_domain. + +Fixes: CID 292436 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/gnulib/argp-help.c | 3 ++- + conf/Makefile.extra-dist | 1 + + grub-core/gnulib-fix-null-state-deref.patch | 12 ++++++++++++ + 3 files changed, 15 insertions(+), 1 deletion(-) + create mode 100644 grub-core/gnulib-fix-null-state-deref.patch + +diff --git a/grub-core/gnulib/argp-help.c b/grub-core/gnulib/argp-help.c +index 2914f4723c6..1b21c3500db 100644 +--- a/grub-core/gnulib/argp-help.c ++++ b/grub-core/gnulib/argp-help.c +@@ -145,7 +145,8 @@ validate_uparams (const struct argp_state *state, struct uparams *upptr) + if (*(int *)((char *)upptr + up->uparams_offs) >= upptr->rmargin) + { + __argp_failure (state, 0, 0, +- dgettext (state->root_argp->argp_domain, ++ dgettext (state == NULL ? NULL ++ : state->root_argp->argp_domain, + "\ + ARGP_HELP_FMT: %s value is less than or equal to %s"), + "rmargin", up->name); +diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist +index 8baa6a831f7..c3506afe792 100644 +--- a/conf/Makefile.extra-dist ++++ b/conf/Makefile.extra-dist +@@ -27,6 +27,7 @@ EXTRA_DIST += grub-core/genemuinit.sh + EXTRA_DIST += grub-core/genemuinitheader.sh + + EXTRA_DIST += grub-core/gnulib-fix-null-deref.diff ++EXTRA_DIST += grub-core/gnulib-fix-null-state-deref.patch + EXTRA_DIST += grub-core/gnulib-fix-uninit-structure.patch + EXTRA_DIST += grub-core/gnulib-fix-unused-value.patch + EXTRA_DIST += grub-core/gnulib-fix-width.diff +diff --git a/grub-core/gnulib-fix-null-state-deref.patch b/grub-core/gnulib-fix-null-state-deref.patch +new file mode 100644 +index 00000000000..813ec09c8a1 +--- /dev/null ++++ b/grub-core/gnulib-fix-null-state-deref.patch +@@ -0,0 +1,12 @@ ++--- a/lib/argp-help.c 2020-10-28 14:32:19.189215988 +0000 +++++ b/lib/argp-help.c 2020-10-28 14:38:21.204673940 +0000 ++@@ -145,7 +145,8 @@ ++ if (*(int *)((char *)upptr + up->uparams_offs) >= upptr->rmargin) ++ { ++ __argp_failure (state, 0, 0, ++- dgettext (state->root_argp->argp_domain, +++ dgettext (state == NULL ? NULL +++ : state->root_argp->argp_domain, ++ "\ ++ ARGP_HELP_FMT: %s value is less than or equal to %s"), ++ "rmargin", up->name); diff --git a/SOURCES/0358-gnulib-regcomp-Fix-uninitialized-token-structure.patch b/SOURCES/0358-gnulib-regcomp-Fix-uninitialized-token-structure.patch deleted file mode 100644 index 3a6beb6..0000000 --- a/SOURCES/0358-gnulib-regcomp-Fix-uninitialized-token-structure.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Thu, 22 Oct 2020 13:54:06 +0000 -Subject: [PATCH] gnulib/regcomp: Fix uninitialized token structure - -The code is assuming that the value of br_token.constraint was -initialized to zero when it wasn't. - -While some compilers will ensure that, not all do, so it is better to -fix this explicitly than leave it to chance. - -Fixes: CID 73749 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/gnulib/regcomp.c | 2 +- - conf/Makefile.extra-dist | 1 + - grub-core/gnulib-fix-uninit-structure.patch | 11 +++++++++++ - 3 files changed, 13 insertions(+), 1 deletion(-) - create mode 100644 grub-core/gnulib-fix-uninit-structure.patch - -diff --git a/grub-core/gnulib/regcomp.c b/grub-core/gnulib/regcomp.c -index 596e0cf3ef7..de9f622088f 100644 ---- a/grub-core/gnulib/regcomp.c -+++ b/grub-core/gnulib/regcomp.c -@@ -3641,7 +3641,7 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans, - Idx alloc = 0; - #endif /* not RE_ENABLE_I18N */ - reg_errcode_t ret; -- re_token_t br_token; -+ re_token_t br_token = {0}; - bin_tree_t *tree; - - sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); -diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist -index 7b305bce766..8baa6a831f7 100644 ---- a/conf/Makefile.extra-dist -+++ b/conf/Makefile.extra-dist -@@ -27,6 +27,7 @@ EXTRA_DIST += grub-core/genemuinit.sh - EXTRA_DIST += grub-core/genemuinitheader.sh - - EXTRA_DIST += grub-core/gnulib-fix-null-deref.diff -+EXTRA_DIST += grub-core/gnulib-fix-uninit-structure.patch - EXTRA_DIST += grub-core/gnulib-fix-unused-value.patch - EXTRA_DIST += grub-core/gnulib-fix-width.diff - EXTRA_DIST += grub-core/gnulib-no-abort.diff -diff --git a/grub-core/gnulib-fix-uninit-structure.patch b/grub-core/gnulib-fix-uninit-structure.patch -new file mode 100644 -index 00000000000..7b4d9f67af4 ---- /dev/null -+++ b/grub-core/gnulib-fix-uninit-structure.patch -@@ -0,0 +1,11 @@ -+--- a/lib/regcomp.c 2020-10-22 13:49:06.770168928 +0000 -++++ b/lib/regcomp.c 2020-10-22 13:50:37.026528298 +0000 -+@@ -3662,7 +3662,7 @@ -+ Idx alloc = 0; -+ #endif /* not RE_ENABLE_I18N */ -+ reg_errcode_t ret; -+- re_token_t br_token; -++ re_token_t br_token = {0}; -+ bin_tree_t *tree; -+ -+ sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); diff --git a/SOURCES/0359-gnulib-argp-help-Fix-dereference-of-a-possibly-NULL-.patch b/SOURCES/0359-gnulib-argp-help-Fix-dereference-of-a-possibly-NULL-.patch deleted file mode 100644 index c308833..0000000 --- a/SOURCES/0359-gnulib-argp-help-Fix-dereference-of-a-possibly-NULL-.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Wed, 28 Oct 2020 14:43:01 +0000 -Subject: [PATCH] gnulib/argp-help: Fix dereference of a possibly NULL state - -All other instances of call to __argp_failure() where there is -a dgettext() call is first checking whether state is NULL before -attempting to dereference it to get the root_argp->argp_domain. - -Fixes: CID 292436 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/gnulib/argp-help.c | 3 ++- - conf/Makefile.extra-dist | 1 + - grub-core/gnulib-fix-null-state-deref.patch | 12 ++++++++++++ - 3 files changed, 15 insertions(+), 1 deletion(-) - create mode 100644 grub-core/gnulib-fix-null-state-deref.patch - -diff --git a/grub-core/gnulib/argp-help.c b/grub-core/gnulib/argp-help.c -index 2914f4723c6..1b21c3500db 100644 ---- a/grub-core/gnulib/argp-help.c -+++ b/grub-core/gnulib/argp-help.c -@@ -145,7 +145,8 @@ validate_uparams (const struct argp_state *state, struct uparams *upptr) - if (*(int *)((char *)upptr + up->uparams_offs) >= upptr->rmargin) - { - __argp_failure (state, 0, 0, -- dgettext (state->root_argp->argp_domain, -+ dgettext (state == NULL ? NULL -+ : state->root_argp->argp_domain, - "\ - ARGP_HELP_FMT: %s value is less than or equal to %s"), - "rmargin", up->name); -diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist -index 8baa6a831f7..c3506afe792 100644 ---- a/conf/Makefile.extra-dist -+++ b/conf/Makefile.extra-dist -@@ -27,6 +27,7 @@ EXTRA_DIST += grub-core/genemuinit.sh - EXTRA_DIST += grub-core/genemuinitheader.sh - - EXTRA_DIST += grub-core/gnulib-fix-null-deref.diff -+EXTRA_DIST += grub-core/gnulib-fix-null-state-deref.patch - EXTRA_DIST += grub-core/gnulib-fix-uninit-structure.patch - EXTRA_DIST += grub-core/gnulib-fix-unused-value.patch - EXTRA_DIST += grub-core/gnulib-fix-width.diff -diff --git a/grub-core/gnulib-fix-null-state-deref.patch b/grub-core/gnulib-fix-null-state-deref.patch -new file mode 100644 -index 00000000000..813ec09c8a1 ---- /dev/null -+++ b/grub-core/gnulib-fix-null-state-deref.patch -@@ -0,0 +1,12 @@ -+--- a/lib/argp-help.c 2020-10-28 14:32:19.189215988 +0000 -++++ b/lib/argp-help.c 2020-10-28 14:38:21.204673940 +0000 -+@@ -145,7 +145,8 @@ -+ if (*(int *)((char *)upptr + up->uparams_offs) >= upptr->rmargin) -+ { -+ __argp_failure (state, 0, 0, -+- dgettext (state->root_argp->argp_domain, -++ dgettext (state == NULL ? NULL -++ : state->root_argp->argp_domain, -+ "\ -+ ARGP_HELP_FMT: %s value is less than or equal to %s"), -+ "rmargin", up->name); diff --git a/SOURCES/0359-gnulib-regexec-Fix-possible-null-dereference.patch b/SOURCES/0359-gnulib-regexec-Fix-possible-null-dereference.patch new file mode 100644 index 0000000..de970a9 --- /dev/null +++ b/SOURCES/0359-gnulib-regexec-Fix-possible-null-dereference.patch @@ -0,0 +1,65 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Thu, 5 Nov 2020 10:57:14 +0000 +Subject: [PATCH] gnulib/regexec: Fix possible null-dereference + +It appears to be possible that the mctx->state_log field may be NULL, +and the name of this function, clean_state_log_if_needed(), suggests +that it should be checking that it is valid to be cleaned before +assuming that it does. + +Fixes: CID 86720 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/gnulib/regexec.c | 3 +++ + conf/Makefile.extra-dist | 1 + + grub-core/gnulib-fix-regexec-null-deref.patch | 12 ++++++++++++ + 3 files changed, 16 insertions(+) + create mode 100644 grub-core/gnulib-fix-regexec-null-deref.patch + +diff --git a/grub-core/gnulib/regexec.c b/grub-core/gnulib/regexec.c +index fdc178e07a4..1e4cb2df4e3 100644 +--- a/grub-core/gnulib/regexec.c ++++ b/grub-core/gnulib/regexec.c +@@ -1754,6 +1754,9 @@ clean_state_log_if_needed (re_match_context_t *mctx, Idx next_state_log_idx) + { + Idx top = mctx->state_log_top; + ++ if (mctx->state_log == NULL) ++ return REG_NOERROR; ++ + if ((next_state_log_idx >= mctx->input.bufs_len + && mctx->input.bufs_len < mctx->input.len) + || (next_state_log_idx >= mctx->input.valid_len +diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist +index c3506afe792..60d9f564236 100644 +--- a/conf/Makefile.extra-dist ++++ b/conf/Makefile.extra-dist +@@ -28,6 +28,7 @@ EXTRA_DIST += grub-core/genemuinitheader.sh + + EXTRA_DIST += grub-core/gnulib-fix-null-deref.diff + EXTRA_DIST += grub-core/gnulib-fix-null-state-deref.patch ++EXTRA_DIST += grub-core/gnulib-fix-regexec-null-deref.patch + EXTRA_DIST += grub-core/gnulib-fix-uninit-structure.patch + EXTRA_DIST += grub-core/gnulib-fix-unused-value.patch + EXTRA_DIST += grub-core/gnulib-fix-width.diff +diff --git a/grub-core/gnulib-fix-regexec-null-deref.patch b/grub-core/gnulib-fix-regexec-null-deref.patch +new file mode 100644 +index 00000000000..db6dac9c9e3 +--- /dev/null ++++ b/grub-core/gnulib-fix-regexec-null-deref.patch +@@ -0,0 +1,12 @@ ++--- a/lib/regexec.c 2020-10-21 14:25:35.310195912 +0000 +++++ b/lib/regexec.c 2020-11-05 10:55:09.621542984 +0000 ++@@ -1692,6 +1692,9 @@ ++ { ++ Idx top = mctx->state_log_top; ++ +++ if (mctx->state_log == NULL) +++ return REG_NOERROR; +++ ++ if ((next_state_log_idx >= mctx->input.bufs_len ++ && mctx->input.bufs_len < mctx->input.len) ++ || (next_state_log_idx >= mctx->input.valid_len diff --git a/SOURCES/0360-gnulib-regcomp-Fix-uninitialized-re_token.patch b/SOURCES/0360-gnulib-regcomp-Fix-uninitialized-re_token.patch new file mode 100644 index 0000000..2820f25 --- /dev/null +++ b/SOURCES/0360-gnulib-regcomp-Fix-uninitialized-re_token.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Tue, 24 Nov 2020 18:04:22 +0000 +Subject: [PATCH] gnulib/regcomp: Fix uninitialized re_token + +This issue has been fixed in the latest version of gnulib, so to +maintain consistency, I've backported that change rather than doing +something different. + +Fixes: CID 73828 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/gnulib/regcomp.c | 3 +-- + conf/Makefile.extra-dist | 1 + + grub-core/gnulib-fix-regcomp-uninit-token.patch | 12 ++++++++++++ + 3 files changed, 14 insertions(+), 2 deletions(-) + create mode 100644 grub-core/gnulib-fix-regcomp-uninit-token.patch + +diff --git a/grub-core/gnulib/regcomp.c b/grub-core/gnulib/regcomp.c +index de9f622088f..6d0830ac691 100644 +--- a/grub-core/gnulib/regcomp.c ++++ b/grub-core/gnulib/regcomp.c +@@ -3790,8 +3790,7 @@ static bin_tree_t * + create_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, + re_token_type_t type) + { +- re_token_t t; +- t.type = type; ++ re_token_t t = { .type = type }; + return create_token_tree (dfa, left, right, &t); + } + +diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist +index 60d9f564236..68e5d0eda7b 100644 +--- a/conf/Makefile.extra-dist ++++ b/conf/Makefile.extra-dist +@@ -28,6 +28,7 @@ EXTRA_DIST += grub-core/genemuinitheader.sh + + EXTRA_DIST += grub-core/gnulib-fix-null-deref.diff + EXTRA_DIST += grub-core/gnulib-fix-null-state-deref.patch ++EXTRA_DIST += grub-core/gnulib-fix-regcomp-uninit-token.patch + EXTRA_DIST += grub-core/gnulib-fix-regexec-null-deref.patch + EXTRA_DIST += grub-core/gnulib-fix-uninit-structure.patch + EXTRA_DIST += grub-core/gnulib-fix-unused-value.patch +diff --git a/grub-core/gnulib-fix-regcomp-uninit-token.patch b/grub-core/gnulib-fix-regcomp-uninit-token.patch +new file mode 100644 +index 00000000000..d615745221b +--- /dev/null ++++ b/grub-core/gnulib-fix-regcomp-uninit-token.patch +@@ -0,0 +1,12 @@ ++--- grub-core/gnulib/regcomp.c +++++ grub-core/gnulib/regcomp.c ++@@ -3808,8 +3808,7 @@ static bin_tree_t * ++ create_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, ++ re_token_type_t type) ++ { ++- re_token_t t; ++- t.type = type; +++ re_token_t t = { .type = type }; ++ return create_token_tree (dfa, left, right, &t); ++ } ++ diff --git a/SOURCES/0360-gnulib-regexec-Fix-possible-null-dereference.patch b/SOURCES/0360-gnulib-regexec-Fix-possible-null-dereference.patch deleted file mode 100644 index de970a9..0000000 --- a/SOURCES/0360-gnulib-regexec-Fix-possible-null-dereference.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Thu, 5 Nov 2020 10:57:14 +0000 -Subject: [PATCH] gnulib/regexec: Fix possible null-dereference - -It appears to be possible that the mctx->state_log field may be NULL, -and the name of this function, clean_state_log_if_needed(), suggests -that it should be checking that it is valid to be cleaned before -assuming that it does. - -Fixes: CID 86720 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/gnulib/regexec.c | 3 +++ - conf/Makefile.extra-dist | 1 + - grub-core/gnulib-fix-regexec-null-deref.patch | 12 ++++++++++++ - 3 files changed, 16 insertions(+) - create mode 100644 grub-core/gnulib-fix-regexec-null-deref.patch - -diff --git a/grub-core/gnulib/regexec.c b/grub-core/gnulib/regexec.c -index fdc178e07a4..1e4cb2df4e3 100644 ---- a/grub-core/gnulib/regexec.c -+++ b/grub-core/gnulib/regexec.c -@@ -1754,6 +1754,9 @@ clean_state_log_if_needed (re_match_context_t *mctx, Idx next_state_log_idx) - { - Idx top = mctx->state_log_top; - -+ if (mctx->state_log == NULL) -+ return REG_NOERROR; -+ - if ((next_state_log_idx >= mctx->input.bufs_len - && mctx->input.bufs_len < mctx->input.len) - || (next_state_log_idx >= mctx->input.valid_len -diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist -index c3506afe792..60d9f564236 100644 ---- a/conf/Makefile.extra-dist -+++ b/conf/Makefile.extra-dist -@@ -28,6 +28,7 @@ EXTRA_DIST += grub-core/genemuinitheader.sh - - EXTRA_DIST += grub-core/gnulib-fix-null-deref.diff - EXTRA_DIST += grub-core/gnulib-fix-null-state-deref.patch -+EXTRA_DIST += grub-core/gnulib-fix-regexec-null-deref.patch - EXTRA_DIST += grub-core/gnulib-fix-uninit-structure.patch - EXTRA_DIST += grub-core/gnulib-fix-unused-value.patch - EXTRA_DIST += grub-core/gnulib-fix-width.diff -diff --git a/grub-core/gnulib-fix-regexec-null-deref.patch b/grub-core/gnulib-fix-regexec-null-deref.patch -new file mode 100644 -index 00000000000..db6dac9c9e3 ---- /dev/null -+++ b/grub-core/gnulib-fix-regexec-null-deref.patch -@@ -0,0 +1,12 @@ -+--- a/lib/regexec.c 2020-10-21 14:25:35.310195912 +0000 -++++ b/lib/regexec.c 2020-11-05 10:55:09.621542984 +0000 -+@@ -1692,6 +1692,9 @@ -+ { -+ Idx top = mctx->state_log_top; -+ -++ if (mctx->state_log == NULL) -++ return REG_NOERROR; -++ -+ if ((next_state_log_idx >= mctx->input.bufs_len -+ && mctx->input.bufs_len < mctx->input.len) -+ || (next_state_log_idx >= mctx->input.valid_len diff --git a/SOURCES/0361-gnulib-regcomp-Fix-uninitialized-re_token.patch b/SOURCES/0361-gnulib-regcomp-Fix-uninitialized-re_token.patch deleted file mode 100644 index 2820f25..0000000 --- a/SOURCES/0361-gnulib-regcomp-Fix-uninitialized-re_token.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Tue, 24 Nov 2020 18:04:22 +0000 -Subject: [PATCH] gnulib/regcomp: Fix uninitialized re_token - -This issue has been fixed in the latest version of gnulib, so to -maintain consistency, I've backported that change rather than doing -something different. - -Fixes: CID 73828 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/gnulib/regcomp.c | 3 +-- - conf/Makefile.extra-dist | 1 + - grub-core/gnulib-fix-regcomp-uninit-token.patch | 12 ++++++++++++ - 3 files changed, 14 insertions(+), 2 deletions(-) - create mode 100644 grub-core/gnulib-fix-regcomp-uninit-token.patch - -diff --git a/grub-core/gnulib/regcomp.c b/grub-core/gnulib/regcomp.c -index de9f622088f..6d0830ac691 100644 ---- a/grub-core/gnulib/regcomp.c -+++ b/grub-core/gnulib/regcomp.c -@@ -3790,8 +3790,7 @@ static bin_tree_t * - create_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, - re_token_type_t type) - { -- re_token_t t; -- t.type = type; -+ re_token_t t = { .type = type }; - return create_token_tree (dfa, left, right, &t); - } - -diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist -index 60d9f564236..68e5d0eda7b 100644 ---- a/conf/Makefile.extra-dist -+++ b/conf/Makefile.extra-dist -@@ -28,6 +28,7 @@ EXTRA_DIST += grub-core/genemuinitheader.sh - - EXTRA_DIST += grub-core/gnulib-fix-null-deref.diff - EXTRA_DIST += grub-core/gnulib-fix-null-state-deref.patch -+EXTRA_DIST += grub-core/gnulib-fix-regcomp-uninit-token.patch - EXTRA_DIST += grub-core/gnulib-fix-regexec-null-deref.patch - EXTRA_DIST += grub-core/gnulib-fix-uninit-structure.patch - EXTRA_DIST += grub-core/gnulib-fix-unused-value.patch -diff --git a/grub-core/gnulib-fix-regcomp-uninit-token.patch b/grub-core/gnulib-fix-regcomp-uninit-token.patch -new file mode 100644 -index 00000000000..d615745221b ---- /dev/null -+++ b/grub-core/gnulib-fix-regcomp-uninit-token.patch -@@ -0,0 +1,12 @@ -+--- grub-core/gnulib/regcomp.c -++++ grub-core/gnulib/regcomp.c -+@@ -3808,8 +3808,7 @@ static bin_tree_t * -+ create_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, -+ re_token_type_t type) -+ { -+- re_token_t t; -+- t.type = type; -++ re_token_t t = { .type = type }; -+ return create_token_tree (dfa, left, right, &t); -+ } -+ diff --git a/SOURCES/0361-io-lzopio-Resolve-unnecessary-self-assignment-errors.patch b/SOURCES/0361-io-lzopio-Resolve-unnecessary-self-assignment-errors.patch new file mode 100644 index 0000000..40cfa4e --- /dev/null +++ b/SOURCES/0361-io-lzopio-Resolve-unnecessary-self-assignment-errors.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Wed, 21 Oct 2020 14:44:10 +0000 +Subject: [PATCH] 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 +--- + 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 de2ea6778e2..987485fa2dd 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; + } + } + diff --git a/SOURCES/0362-io-lzopio-Resolve-unnecessary-self-assignment-errors.patch b/SOURCES/0362-io-lzopio-Resolve-unnecessary-self-assignment-errors.patch deleted file mode 100644 index 40cfa4e..0000000 --- a/SOURCES/0362-io-lzopio-Resolve-unnecessary-self-assignment-errors.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Wed, 21 Oct 2020 14:44:10 +0000 -Subject: [PATCH] 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 ---- - 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 de2ea6778e2..987485fa2dd 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; - } - } - diff --git a/SOURCES/0362-kern-partition-Check-for-NULL-before-dereferencing-i.patch b/SOURCES/0362-kern-partition-Check-for-NULL-before-dereferencing-i.patch new file mode 100644 index 0000000..373cae3 --- /dev/null +++ b/SOURCES/0362-kern-partition-Check-for-NULL-before-dereferencing-i.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Fri, 23 Oct 2020 09:49:59 +0000 +Subject: [PATCH] kern/partition: Check for NULL before dereferencing input + string + +There is the possibility that the value of str comes from an external +source and continuing to use it before ever checking its validity is +wrong. So, needs fixing. + +Additionally, drop unneeded part initialization. + +Fixes: CID 292444 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/kern/partition.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/grub-core/kern/partition.c b/grub-core/kern/partition.c +index e499147cbcb..b10a184e3fa 100644 +--- a/grub-core/kern/partition.c ++++ b/grub-core/kern/partition.c +@@ -109,11 +109,14 @@ grub_partition_map_probe (const grub_partition_map_t partmap, + grub_partition_t + grub_partition_probe (struct grub_disk *disk, const char *str) + { +- grub_partition_t part = 0; ++ grub_partition_t part; + grub_partition_t curpart = 0; + grub_partition_t tail; + const char *ptr; + ++ if (str == NULL) ++ return 0; ++ + part = tail = disk->partition; + + for (ptr = str; *ptr;) diff --git a/SOURCES/0363-disk-ldm-Make-sure-comp-data-is-freed-before-exiting.patch b/SOURCES/0363-disk-ldm-Make-sure-comp-data-is-freed-before-exiting.patch new file mode 100644 index 0000000..f3bff82 --- /dev/null +++ b/SOURCES/0363-disk-ldm-Make-sure-comp-data-is-freed-before-exiting.patch @@ -0,0 +1,125 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Marco A Benatto +Date: Mon, 7 Dec 2020 11:53:03 -0300 +Subject: [PATCH] disk/ldm: Make sure comp data is freed before exiting from + make_vg() + +Several error handling paths in make_vg() do not free comp data before +jumping to fail2 label and returning from the function. This will leak +memory. So, let's fix all issues of that kind. + +Fixes: CID 73804 + +Signed-off-by: Marco A Benatto +Reviewed-by: Daniel Kiper +--- + grub-core/disk/ldm.c | 51 ++++++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 44 insertions(+), 7 deletions(-) + +diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c +index b1a57f2d2ad..34e1e4d72ff 100644 +--- a/grub-core/disk/ldm.c ++++ b/grub-core/disk/ldm.c +@@ -554,7 +554,11 @@ make_vg (grub_disk_t disk, + comp->segments = grub_calloc (comp->segment_alloc, + sizeof (*comp->segments)); + if (!comp->segments) +- goto fail2; ++ { ++ grub_free (comp->internal_id); ++ grub_free (comp); ++ goto fail2; ++ } + } + else + { +@@ -562,7 +566,11 @@ make_vg (grub_disk_t disk, + comp->segment_count = 1; + comp->segments = grub_malloc (sizeof (*comp->segments)); + if (!comp->segments) +- goto fail2; ++ { ++ grub_free (comp->internal_id); ++ grub_free (comp); ++ goto fail2; ++ } + comp->segments->start_extent = 0; + comp->segments->extent_count = lv->size; + comp->segments->layout = 0; +@@ -574,15 +582,26 @@ make_vg (grub_disk_t disk, + comp->segments->layout = GRUB_RAID_LAYOUT_SYMMETRIC_MASK; + } + else +- goto fail2; ++ { ++ grub_free (comp->segments); ++ grub_free (comp->internal_id); ++ grub_free (comp); ++ goto fail2; ++ } + ptr += *ptr + 1; + ptr++; + if (!(vblk[i].flags & 0x10)) +- goto fail2; ++ { ++ grub_free (comp->segments); ++ grub_free (comp->internal_id); ++ grub_free (comp); ++ goto fail2; ++ } + if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic) + || ptr + *ptr + 1 >= vblk[i].dynamic + + sizeof (vblk[i].dynamic)) + { ++ grub_free (comp->segments); + grub_free (comp->internal_id); + grub_free (comp); + goto fail2; +@@ -592,6 +611,7 @@ make_vg (grub_disk_t disk, + if (ptr + *ptr + 1 >= vblk[i].dynamic + + sizeof (vblk[i].dynamic)) + { ++ grub_free (comp->segments); + grub_free (comp->internal_id); + grub_free (comp); + goto fail2; +@@ -601,7 +621,12 @@ make_vg (grub_disk_t disk, + comp->segments->nodes = grub_calloc (comp->segments->node_alloc, + sizeof (*comp->segments->nodes)); + if (!lv->segments->nodes) +- goto fail2; ++ { ++ grub_free (comp->segments); ++ grub_free (comp->internal_id); ++ grub_free (comp); ++ goto fail2; ++ } + } + + if (lv->segments->node_alloc == lv->segments->node_count) +@@ -611,11 +636,23 @@ make_vg (grub_disk_t disk, + + if (grub_mul (lv->segments->node_alloc, 2, &lv->segments->node_alloc) || + grub_mul (lv->segments->node_alloc, sizeof (*lv->segments->nodes), &sz)) +- goto fail2; ++ { ++ grub_free (comp->segments->nodes); ++ grub_free (comp->segments); ++ grub_free (comp->internal_id); ++ grub_free (comp); ++ goto fail2; ++ } + + t = grub_realloc (lv->segments->nodes, sz); + if (!t) +- goto fail2; ++ { ++ grub_free (comp->segments->nodes); ++ grub_free (comp->segments); ++ grub_free (comp->internal_id); ++ grub_free (comp); ++ goto fail2; ++ } + lv->segments->nodes = t; + } + lv->segments->nodes[lv->segments->node_count].pv = 0; diff --git a/SOURCES/0363-kern-partition-Check-for-NULL-before-dereferencing-i.patch b/SOURCES/0363-kern-partition-Check-for-NULL-before-dereferencing-i.patch deleted file mode 100644 index 373cae3..0000000 --- a/SOURCES/0363-kern-partition-Check-for-NULL-before-dereferencing-i.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Fri, 23 Oct 2020 09:49:59 +0000 -Subject: [PATCH] kern/partition: Check for NULL before dereferencing input - string - -There is the possibility that the value of str comes from an external -source and continuing to use it before ever checking its validity is -wrong. So, needs fixing. - -Additionally, drop unneeded part initialization. - -Fixes: CID 292444 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/kern/partition.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/grub-core/kern/partition.c b/grub-core/kern/partition.c -index e499147cbcb..b10a184e3fa 100644 ---- a/grub-core/kern/partition.c -+++ b/grub-core/kern/partition.c -@@ -109,11 +109,14 @@ grub_partition_map_probe (const grub_partition_map_t partmap, - grub_partition_t - grub_partition_probe (struct grub_disk *disk, const char *str) - { -- grub_partition_t part = 0; -+ grub_partition_t part; - grub_partition_t curpart = 0; - grub_partition_t tail; - const char *ptr; - -+ if (str == NULL) -+ return 0; -+ - part = tail = disk->partition; - - for (ptr = str; *ptr;) diff --git a/SOURCES/0364-disk-ldm-If-failed-then-free-vg-variable-too.patch b/SOURCES/0364-disk-ldm-If-failed-then-free-vg-variable-too.patch new file mode 100644 index 0000000..de01a6e --- /dev/null +++ b/SOURCES/0364-disk-ldm-If-failed-then-free-vg-variable-too.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paulo Flabiano Smorigo +Date: Mon, 7 Dec 2020 10:07:47 -0300 +Subject: [PATCH] disk/ldm: If failed then free vg variable too + +Fixes: CID 73809 + +Signed-off-by: Paulo Flabiano Smorigo +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 34e1e4d72ff..9c73d2217e9 100644 +--- a/grub-core/disk/ldm.c ++++ b/grub-core/disk/ldm.c +@@ -199,6 +199,7 @@ make_vg (grub_disk_t disk, + { + grub_free (vg->uuid); + grub_free (vg->name); ++ grub_free (vg); + return NULL; + } + grub_memcpy (vg->uuid, label->group_guid, LDM_GUID_STRLEN); diff --git a/SOURCES/0364-disk-ldm-Make-sure-comp-data-is-freed-before-exiting.patch b/SOURCES/0364-disk-ldm-Make-sure-comp-data-is-freed-before-exiting.patch deleted file mode 100644 index f3bff82..0000000 --- a/SOURCES/0364-disk-ldm-Make-sure-comp-data-is-freed-before-exiting.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Marco A Benatto -Date: Mon, 7 Dec 2020 11:53:03 -0300 -Subject: [PATCH] disk/ldm: Make sure comp data is freed before exiting from - make_vg() - -Several error handling paths in make_vg() do not free comp data before -jumping to fail2 label and returning from the function. This will leak -memory. So, let's fix all issues of that kind. - -Fixes: CID 73804 - -Signed-off-by: Marco A Benatto -Reviewed-by: Daniel Kiper ---- - grub-core/disk/ldm.c | 51 ++++++++++++++++++++++++++++++++++++++++++++------- - 1 file changed, 44 insertions(+), 7 deletions(-) - -diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c -index b1a57f2d2ad..34e1e4d72ff 100644 ---- a/grub-core/disk/ldm.c -+++ b/grub-core/disk/ldm.c -@@ -554,7 +554,11 @@ make_vg (grub_disk_t disk, - comp->segments = grub_calloc (comp->segment_alloc, - sizeof (*comp->segments)); - if (!comp->segments) -- goto fail2; -+ { -+ grub_free (comp->internal_id); -+ grub_free (comp); -+ goto fail2; -+ } - } - else - { -@@ -562,7 +566,11 @@ make_vg (grub_disk_t disk, - comp->segment_count = 1; - comp->segments = grub_malloc (sizeof (*comp->segments)); - if (!comp->segments) -- goto fail2; -+ { -+ grub_free (comp->internal_id); -+ grub_free (comp); -+ goto fail2; -+ } - comp->segments->start_extent = 0; - comp->segments->extent_count = lv->size; - comp->segments->layout = 0; -@@ -574,15 +582,26 @@ make_vg (grub_disk_t disk, - comp->segments->layout = GRUB_RAID_LAYOUT_SYMMETRIC_MASK; - } - else -- goto fail2; -+ { -+ grub_free (comp->segments); -+ grub_free (comp->internal_id); -+ grub_free (comp); -+ goto fail2; -+ } - ptr += *ptr + 1; - ptr++; - if (!(vblk[i].flags & 0x10)) -- goto fail2; -+ { -+ grub_free (comp->segments); -+ grub_free (comp->internal_id); -+ grub_free (comp); -+ goto fail2; -+ } - if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic) - || ptr + *ptr + 1 >= vblk[i].dynamic - + sizeof (vblk[i].dynamic)) - { -+ grub_free (comp->segments); - grub_free (comp->internal_id); - grub_free (comp); - goto fail2; -@@ -592,6 +611,7 @@ make_vg (grub_disk_t disk, - if (ptr + *ptr + 1 >= vblk[i].dynamic - + sizeof (vblk[i].dynamic)) - { -+ grub_free (comp->segments); - grub_free (comp->internal_id); - grub_free (comp); - goto fail2; -@@ -601,7 +621,12 @@ make_vg (grub_disk_t disk, - comp->segments->nodes = grub_calloc (comp->segments->node_alloc, - sizeof (*comp->segments->nodes)); - if (!lv->segments->nodes) -- goto fail2; -+ { -+ grub_free (comp->segments); -+ grub_free (comp->internal_id); -+ grub_free (comp); -+ goto fail2; -+ } - } - - if (lv->segments->node_alloc == lv->segments->node_count) -@@ -611,11 +636,23 @@ make_vg (grub_disk_t disk, - - if (grub_mul (lv->segments->node_alloc, 2, &lv->segments->node_alloc) || - grub_mul (lv->segments->node_alloc, sizeof (*lv->segments->nodes), &sz)) -- goto fail2; -+ { -+ grub_free (comp->segments->nodes); -+ grub_free (comp->segments); -+ grub_free (comp->internal_id); -+ grub_free (comp); -+ goto fail2; -+ } - - t = grub_realloc (lv->segments->nodes, sz); - if (!t) -- goto fail2; -+ { -+ grub_free (comp->segments->nodes); -+ grub_free (comp->segments); -+ grub_free (comp->internal_id); -+ grub_free (comp); -+ goto fail2; -+ } - lv->segments->nodes = t; - } - lv->segments->nodes[lv->segments->node_count].pv = 0; diff --git a/SOURCES/0365-disk-ldm-Fix-memory-leak-on-uninserted-lv-references.patch b/SOURCES/0365-disk-ldm-Fix-memory-leak-on-uninserted-lv-references.patch new file mode 100644 index 0000000..771411c --- /dev/null +++ b/SOURCES/0365-disk-ldm-Fix-memory-leak-on-uninserted-lv-references.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Tue, 8 Dec 2020 10:00:51 +0000 +Subject: [PATCH] disk/ldm: Fix memory leak on uninserted lv references + +The problem here is that the memory allocated to the variable lv is not +yet inserted into the list that is being processed at the label fail2. + +As we can already see at line 342, which correctly frees lv before going +to fail2, we should also be doing that at these earlier jumps to fail2. + +Fixes: CID 73824 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/disk/ldm.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c +index 9c73d2217e9..2a953667986 100644 +--- a/grub-core/disk/ldm.c ++++ b/grub-core/disk/ldm.c +@@ -321,7 +321,10 @@ make_vg (grub_disk_t disk, + lv->visible = 1; + lv->segments = grub_zalloc (sizeof (*lv->segments)); + if (!lv->segments) +- goto fail2; ++ { ++ grub_free (lv); ++ goto fail2; ++ } + lv->segments->start_extent = 0; + lv->segments->type = GRUB_DISKFILTER_MIRROR; + lv->segments->node_count = 0; +@@ -329,7 +332,10 @@ make_vg (grub_disk_t disk, + lv->segments->nodes = grub_calloc (lv->segments->node_alloc, + sizeof (*lv->segments->nodes)); + if (!lv->segments->nodes) +- goto fail2; ++ { ++ grub_free (lv); ++ goto fail2; ++ } + ptr = vblk[i].dynamic; + if (ptr + *ptr + 1 >= vblk[i].dynamic + + sizeof (vblk[i].dynamic)) diff --git a/SOURCES/0365-disk-ldm-If-failed-then-free-vg-variable-too.patch b/SOURCES/0365-disk-ldm-If-failed-then-free-vg-variable-too.patch deleted file mode 100644 index de01a6e..0000000 --- a/SOURCES/0365-disk-ldm-If-failed-then-free-vg-variable-too.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Mon, 7 Dec 2020 10:07:47 -0300 -Subject: [PATCH] disk/ldm: If failed then free vg variable too - -Fixes: CID 73809 - -Signed-off-by: Paulo Flabiano Smorigo -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 34e1e4d72ff..9c73d2217e9 100644 ---- a/grub-core/disk/ldm.c -+++ b/grub-core/disk/ldm.c -@@ -199,6 +199,7 @@ make_vg (grub_disk_t disk, - { - grub_free (vg->uuid); - grub_free (vg->name); -+ grub_free (vg); - return NULL; - } - grub_memcpy (vg->uuid, label->group_guid, LDM_GUID_STRLEN); diff --git a/SOURCES/0366-disk-cryptodisk-Fix-potential-integer-overflow.patch b/SOURCES/0366-disk-cryptodisk-Fix-potential-integer-overflow.patch new file mode 100644 index 0000000..ebe6687 --- /dev/null +++ b/SOURCES/0366-disk-cryptodisk-Fix-potential-integer-overflow.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Thu, 21 Jan 2021 11:38:31 +0000 +Subject: [PATCH] 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 +--- + 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 f0e3a900ae3..9289acfc611 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -303,10 +303,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; +@@ -314,10 +314,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; diff --git a/SOURCES/0366-disk-ldm-Fix-memory-leak-on-uninserted-lv-references.patch b/SOURCES/0366-disk-ldm-Fix-memory-leak-on-uninserted-lv-references.patch deleted file mode 100644 index 771411c..0000000 --- a/SOURCES/0366-disk-ldm-Fix-memory-leak-on-uninserted-lv-references.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Tue, 8 Dec 2020 10:00:51 +0000 -Subject: [PATCH] disk/ldm: Fix memory leak on uninserted lv references - -The problem here is that the memory allocated to the variable lv is not -yet inserted into the list that is being processed at the label fail2. - -As we can already see at line 342, which correctly frees lv before going -to fail2, we should also be doing that at these earlier jumps to fail2. - -Fixes: CID 73824 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/disk/ldm.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c -index 9c73d2217e9..2a953667986 100644 ---- a/grub-core/disk/ldm.c -+++ b/grub-core/disk/ldm.c -@@ -321,7 +321,10 @@ make_vg (grub_disk_t disk, - lv->visible = 1; - lv->segments = grub_zalloc (sizeof (*lv->segments)); - if (!lv->segments) -- goto fail2; -+ { -+ grub_free (lv); -+ goto fail2; -+ } - lv->segments->start_extent = 0; - lv->segments->type = GRUB_DISKFILTER_MIRROR; - lv->segments->node_count = 0; -@@ -329,7 +332,10 @@ make_vg (grub_disk_t disk, - lv->segments->nodes = grub_calloc (lv->segments->node_alloc, - sizeof (*lv->segments->nodes)); - if (!lv->segments->nodes) -- goto fail2; -+ { -+ grub_free (lv); -+ goto fail2; -+ } - ptr = vblk[i].dynamic; - if (ptr + *ptr + 1 >= vblk[i].dynamic - + sizeof (vblk[i].dynamic)) diff --git a/SOURCES/0367-disk-cryptodisk-Fix-potential-integer-overflow.patch b/SOURCES/0367-disk-cryptodisk-Fix-potential-integer-overflow.patch deleted file mode 100644 index ebe6687..0000000 --- a/SOURCES/0367-disk-cryptodisk-Fix-potential-integer-overflow.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Thu, 21 Jan 2021 11:38:31 +0000 -Subject: [PATCH] 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 ---- - 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 f0e3a900ae3..9289acfc611 100644 ---- a/grub-core/disk/cryptodisk.c -+++ b/grub-core/disk/cryptodisk.c -@@ -303,10 +303,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; -@@ -314,10 +314,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; diff --git a/SOURCES/0367-hfsplus-Check-that-the-volume-name-length-is-valid.patch b/SOURCES/0367-hfsplus-Check-that-the-volume-name-length-is-valid.patch new file mode 100644 index 0000000..055f927 --- /dev/null +++ b/SOURCES/0367-hfsplus-Check-that-the-volume-name-length-is-valid.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Fri, 23 Oct 2020 17:09:31 +0000 +Subject: [PATCH] hfsplus: Check that the volume name length is valid + +HFS+ documentation suggests that the maximum filename and volume name is +255 Unicode characters in length. + +So, when converting from big-endian to little-endian, we should ensure +that the name of the volume has a length that is between 0 and 255, +inclusive. + +Fixes: CID 73641 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/fs/hfsplus.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c +index d9833f94414..7ae66967b3a 100644 +--- a/grub-core/fs/hfsplus.c ++++ b/grub-core/fs/hfsplus.c +@@ -1002,6 +1002,15 @@ grub_hfsplus_label (grub_device_t device, char **label) + grub_hfsplus_btree_recptr (&data->catalog_tree, node, ptr); + + label_len = grub_be_to_cpu16 (catkey->namelen); ++ ++ /* Ensure that the length is >= 0. */ ++ if (label_len < 0) ++ label_len = 0; ++ ++ /* Ensure label length is at most 255 Unicode characters. */ ++ if (label_len > 255) ++ label_len = 255; ++ + label_name = grub_calloc (label_len, sizeof (*label_name)); + if (!label_name) + { diff --git a/SOURCES/0368-hfsplus-Check-that-the-volume-name-length-is-valid.patch b/SOURCES/0368-hfsplus-Check-that-the-volume-name-length-is-valid.patch deleted file mode 100644 index 055f927..0000000 --- a/SOURCES/0368-hfsplus-Check-that-the-volume-name-length-is-valid.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Fri, 23 Oct 2020 17:09:31 +0000 -Subject: [PATCH] hfsplus: Check that the volume name length is valid - -HFS+ documentation suggests that the maximum filename and volume name is -255 Unicode characters in length. - -So, when converting from big-endian to little-endian, we should ensure -that the name of the volume has a length that is between 0 and 255, -inclusive. - -Fixes: CID 73641 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/fs/hfsplus.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c -index d9833f94414..7ae66967b3a 100644 ---- a/grub-core/fs/hfsplus.c -+++ b/grub-core/fs/hfsplus.c -@@ -1002,6 +1002,15 @@ grub_hfsplus_label (grub_device_t device, char **label) - grub_hfsplus_btree_recptr (&data->catalog_tree, node, ptr); - - label_len = grub_be_to_cpu16 (catkey->namelen); -+ -+ /* Ensure that the length is >= 0. */ -+ if (label_len < 0) -+ label_len = 0; -+ -+ /* Ensure label length is at most 255 Unicode characters. */ -+ if (label_len > 255) -+ label_len = 255; -+ - label_name = grub_calloc (label_len, sizeof (*label_name)); - if (!label_name) - { diff --git a/SOURCES/0368-zfs-Fix-possible-negative-shift-operation.patch b/SOURCES/0368-zfs-Fix-possible-negative-shift-operation.patch new file mode 100644 index 0000000..bc2b098 --- /dev/null +++ b/SOURCES/0368-zfs-Fix-possible-negative-shift-operation.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Tue, 24 Nov 2020 16:41:49 +0000 +Subject: [PATCH] zfs: Fix possible negative shift operation + +While it is possible for the return value from zfs_log2() to be zero +(0), it is quite unlikely, given that the previous assignment to blksz +is shifted up by SPA_MINBLOCKSHIFT (9) before 9 is subtracted at the +assignment to epbs. + +But, while unlikely during a normal operation, it may be that a carefully +crafted ZFS filesystem could result in a zero (0) value to the +dn_datalbkszsec field, which means that the shift left does nothing +and assigns zero (0) to blksz, resulting in a negative epbs value. + +Fixes: CID 73608 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/fs/zfs/zfs.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c +index 6fd21f975f5..f607b9b56b9 100644 +--- a/grub-core/fs/zfs/zfs.c ++++ b/grub-core/fs/zfs/zfs.c +@@ -2602,6 +2602,11 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type, + blksz = grub_zfs_to_cpu16 (mdn->dn.dn_datablkszsec, + mdn->endian) << SPA_MINBLOCKSHIFT; + epbs = zfs_log2 (blksz) - DNODE_SHIFT; ++ ++ /* While this should never happen, we should check that epbs is not negative. */ ++ if (epbs < 0) ++ epbs = 0; ++ + blkid = objnum >> epbs; + idx = objnum & ((1 << epbs) - 1); + diff --git a/SOURCES/0369-zfs-Fix-possible-negative-shift-operation.patch b/SOURCES/0369-zfs-Fix-possible-negative-shift-operation.patch deleted file mode 100644 index bc2b098..0000000 --- a/SOURCES/0369-zfs-Fix-possible-negative-shift-operation.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Tue, 24 Nov 2020 16:41:49 +0000 -Subject: [PATCH] zfs: Fix possible negative shift operation - -While it is possible for the return value from zfs_log2() to be zero -(0), it is quite unlikely, given that the previous assignment to blksz -is shifted up by SPA_MINBLOCKSHIFT (9) before 9 is subtracted at the -assignment to epbs. - -But, while unlikely during a normal operation, it may be that a carefully -crafted ZFS filesystem could result in a zero (0) value to the -dn_datalbkszsec field, which means that the shift left does nothing -and assigns zero (0) to blksz, resulting in a negative epbs value. - -Fixes: CID 73608 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/fs/zfs/zfs.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c -index 6fd21f975f5..f607b9b56b9 100644 ---- a/grub-core/fs/zfs/zfs.c -+++ b/grub-core/fs/zfs/zfs.c -@@ -2602,6 +2602,11 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type, - blksz = grub_zfs_to_cpu16 (mdn->dn.dn_datablkszsec, - mdn->endian) << SPA_MINBLOCKSHIFT; - epbs = zfs_log2 (blksz) - DNODE_SHIFT; -+ -+ /* While this should never happen, we should check that epbs is not negative. */ -+ if (epbs < 0) -+ epbs = 0; -+ - blkid = objnum >> epbs; - idx = objnum & ((1 << epbs) - 1); - diff --git a/SOURCES/0369-zfs-Fix-resource-leaks-while-constructing-path.patch b/SOURCES/0369-zfs-Fix-resource-leaks-while-constructing-path.patch new file mode 100644 index 0000000..3cfef11 --- /dev/null +++ b/SOURCES/0369-zfs-Fix-resource-leaks-while-constructing-path.patch @@ -0,0 +1,114 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paulo Flabiano Smorigo +Date: Mon, 14 Dec 2020 18:54:49 -0300 +Subject: [PATCH] zfs: Fix resource leaks while constructing path + +There are several exit points in dnode_get_path() that are causing possible +memory leaks. + +In the while(1) the correct exit mechanism should not be to do a direct return, +but to instead break out of the loop, setting err first if it is not already set. + +The reason behind this is that the dnode_path is a linked list, and while doing +through this loop, it is being allocated and built up - the only way to +correctly unravel it is to traverse it, which is what is being done at the end +of the function outside of the loop. + +Several of the existing exit points correctly did a break, but not all so this +change makes that more consistent and should resolve the leaking of memory as +found by Coverity. + +Fixes: CID 73741 + +Signed-off-by: Paulo Flabiano Smorigo +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/fs/zfs/zfs.c | 30 ++++++++++++++++++++++-------- + 1 file changed, 22 insertions(+), 8 deletions(-) + +diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c +index f607b9b56b9..467fa7ee9ea 100644 +--- a/grub-core/fs/zfs/zfs.c ++++ b/grub-core/fs/zfs/zfs.c +@@ -2771,8 +2771,8 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, + + if (dnode_path->dn.dn.dn_type != DMU_OT_DIRECTORY_CONTENTS) + { +- grub_free (path_buf); +- return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); ++ err = grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); ++ break; + } + err = zap_lookup (&(dnode_path->dn), cname, &objnum, + data, subvol->case_insensitive); +@@ -2815,7 +2815,11 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, + + sym_value = grub_malloc (sym_sz); + if (!sym_value) +- return grub_errno; ++ { ++ err = grub_errno; ++ break; ++ } ++ + for (block = 0; block < (sym_sz + blksz - 1) / blksz; block++) + { + void *t; +@@ -2823,7 +2827,10 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, + + err = dmu_read (&(dnode_path->dn), block, &t, 0, data); + if (err) +- return err; ++ { ++ grub_free (sym_value); ++ break; ++ } + + movesize = sym_sz - block * blksz; + if (movesize > blksz) +@@ -2832,13 +2839,18 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, + grub_memcpy (sym_value + block * blksz, t, movesize); + grub_free (t); + } ++ if (err) ++ break; + free_symval = 1; + } + path = path_buf = grub_malloc (sym_sz + grub_strlen (oldpath) + 1); + if (!path_buf) + { + grub_free (oldpathbuf); +- return grub_errno; ++ if (free_symval) ++ grub_free (sym_value); ++ err = grub_errno; ++ break; + } + grub_memcpy (path, sym_value, sym_sz); + if (free_symval) +@@ -2876,11 +2888,12 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, + + err = zio_read (bp, dnode_path->dn.endian, &sahdrp, NULL, data); + if (err) +- return err; ++ break; + } + else + { +- return grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); ++ err = grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); ++ break; + } + + hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); +@@ -2901,7 +2914,8 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, + if (!path_buf) + { + grub_free (oldpathbuf); +- return grub_errno; ++ err = grub_errno; ++ break; + } + grub_memcpy (path, sym_value, sym_sz); + path [sym_sz] = 0; diff --git a/SOURCES/0370-zfs-Fix-possible-integer-overflows.patch b/SOURCES/0370-zfs-Fix-possible-integer-overflows.patch new file mode 100644 index 0000000..0038019 --- /dev/null +++ b/SOURCES/0370-zfs-Fix-possible-integer-overflows.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Tue, 8 Dec 2020 22:17:04 +0000 +Subject: [PATCH] zfs: Fix possible integer overflows + +In all cases the problem is that the value being acted upon by +a left-shift is a 32-bit number which is then being used in the +context of a 64-bit number. + +To avoid overflow we ensure that the number being shifted is 64-bit +before the shift is done. + +Fixes: CID 73684, CID 73695, CID 73764 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/fs/zfs/zfs.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c +index 467fa7ee9ea..4fe09b4c10c 100644 +--- a/grub-core/fs/zfs/zfs.c ++++ b/grub-core/fs/zfs/zfs.c +@@ -560,7 +560,7 @@ find_bestub (uberblock_phys_t * ub_array, + ubptr = (uberblock_phys_t *) ((grub_properly_aligned_t *) ub_array + + ((i << ub_shift) + / sizeof (grub_properly_aligned_t))); +- err = uberblock_verify (ubptr, offset, 1 << ub_shift); ++ err = uberblock_verify (ubptr, offset, (grub_size_t) 1 << ub_shift); + if (err) + { + grub_errno = GRUB_ERR_NONE; +@@ -1535,7 +1535,7 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, + + high = grub_divmod64 ((offset >> desc->ashift) + c, + desc->n_children, &devn); +- csize = bsize << desc->ashift; ++ csize = (grub_size_t) bsize << desc->ashift; + if (csize > len) + csize = len; + +@@ -1627,8 +1627,8 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, + + while (len > 0) + { +- grub_size_t csize; +- csize = ((s / (desc->n_children - desc->nparity)) ++ grub_size_t csize = s; ++ csize = ((csize / (desc->n_children - desc->nparity)) + << desc->ashift); + if (csize > len) + csize = len; diff --git a/SOURCES/0370-zfs-Fix-resource-leaks-while-constructing-path.patch b/SOURCES/0370-zfs-Fix-resource-leaks-while-constructing-path.patch deleted file mode 100644 index 3cfef11..0000000 --- a/SOURCES/0370-zfs-Fix-resource-leaks-while-constructing-path.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Mon, 14 Dec 2020 18:54:49 -0300 -Subject: [PATCH] zfs: Fix resource leaks while constructing path - -There are several exit points in dnode_get_path() that are causing possible -memory leaks. - -In the while(1) the correct exit mechanism should not be to do a direct return, -but to instead break out of the loop, setting err first if it is not already set. - -The reason behind this is that the dnode_path is a linked list, and while doing -through this loop, it is being allocated and built up - the only way to -correctly unravel it is to traverse it, which is what is being done at the end -of the function outside of the loop. - -Several of the existing exit points correctly did a break, but not all so this -change makes that more consistent and should resolve the leaking of memory as -found by Coverity. - -Fixes: CID 73741 - -Signed-off-by: Paulo Flabiano Smorigo -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/fs/zfs/zfs.c | 30 ++++++++++++++++++++++-------- - 1 file changed, 22 insertions(+), 8 deletions(-) - -diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c -index f607b9b56b9..467fa7ee9ea 100644 ---- a/grub-core/fs/zfs/zfs.c -+++ b/grub-core/fs/zfs/zfs.c -@@ -2771,8 +2771,8 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, - - if (dnode_path->dn.dn.dn_type != DMU_OT_DIRECTORY_CONTENTS) - { -- grub_free (path_buf); -- return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); -+ err = grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); -+ break; - } - err = zap_lookup (&(dnode_path->dn), cname, &objnum, - data, subvol->case_insensitive); -@@ -2815,7 +2815,11 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, - - sym_value = grub_malloc (sym_sz); - if (!sym_value) -- return grub_errno; -+ { -+ err = grub_errno; -+ break; -+ } -+ - for (block = 0; block < (sym_sz + blksz - 1) / blksz; block++) - { - void *t; -@@ -2823,7 +2827,10 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, - - err = dmu_read (&(dnode_path->dn), block, &t, 0, data); - if (err) -- return err; -+ { -+ grub_free (sym_value); -+ break; -+ } - - movesize = sym_sz - block * blksz; - if (movesize > blksz) -@@ -2832,13 +2839,18 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, - grub_memcpy (sym_value + block * blksz, t, movesize); - grub_free (t); - } -+ if (err) -+ break; - free_symval = 1; - } - path = path_buf = grub_malloc (sym_sz + grub_strlen (oldpath) + 1); - if (!path_buf) - { - grub_free (oldpathbuf); -- return grub_errno; -+ if (free_symval) -+ grub_free (sym_value); -+ err = grub_errno; -+ break; - } - grub_memcpy (path, sym_value, sym_sz); - if (free_symval) -@@ -2876,11 +2888,12 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, - - err = zio_read (bp, dnode_path->dn.endian, &sahdrp, NULL, data); - if (err) -- return err; -+ break; - } - else - { -- return grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); -+ err = grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); -+ break; - } - - hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); -@@ -2901,7 +2914,8 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, - if (!path_buf) - { - grub_free (oldpathbuf); -- return grub_errno; -+ err = grub_errno; -+ break; - } - grub_memcpy (path, sym_value, sym_sz); - path [sym_sz] = 0; diff --git a/SOURCES/0371-zfs-Fix-possible-integer-overflows.patch b/SOURCES/0371-zfs-Fix-possible-integer-overflows.patch deleted file mode 100644 index 0038019..0000000 --- a/SOURCES/0371-zfs-Fix-possible-integer-overflows.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Tue, 8 Dec 2020 22:17:04 +0000 -Subject: [PATCH] zfs: Fix possible integer overflows - -In all cases the problem is that the value being acted upon by -a left-shift is a 32-bit number which is then being used in the -context of a 64-bit number. - -To avoid overflow we ensure that the number being shifted is 64-bit -before the shift is done. - -Fixes: CID 73684, CID 73695, CID 73764 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/fs/zfs/zfs.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c -index 467fa7ee9ea..4fe09b4c10c 100644 ---- a/grub-core/fs/zfs/zfs.c -+++ b/grub-core/fs/zfs/zfs.c -@@ -560,7 +560,7 @@ find_bestub (uberblock_phys_t * ub_array, - ubptr = (uberblock_phys_t *) ((grub_properly_aligned_t *) ub_array - + ((i << ub_shift) - / sizeof (grub_properly_aligned_t))); -- err = uberblock_verify (ubptr, offset, 1 << ub_shift); -+ err = uberblock_verify (ubptr, offset, (grub_size_t) 1 << ub_shift); - if (err) - { - grub_errno = GRUB_ERR_NONE; -@@ -1535,7 +1535,7 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, - - high = grub_divmod64 ((offset >> desc->ashift) + c, - desc->n_children, &devn); -- csize = bsize << desc->ashift; -+ csize = (grub_size_t) bsize << desc->ashift; - if (csize > len) - csize = len; - -@@ -1627,8 +1627,8 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, - - while (len > 0) - { -- grub_size_t csize; -- csize = ((s / (desc->n_children - desc->nparity)) -+ grub_size_t csize = s; -+ csize = ((csize / (desc->n_children - desc->nparity)) - << desc->ashift); - if (csize > len) - csize = len; diff --git a/SOURCES/0371-zfsinfo-Correct-a-check-for-error-allocating-memory.patch b/SOURCES/0371-zfsinfo-Correct-a-check-for-error-allocating-memory.patch new file mode 100644 index 0000000..7c40c48 --- /dev/null +++ b/SOURCES/0371-zfsinfo-Correct-a-check-for-error-allocating-memory.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Thu, 26 Nov 2020 10:56:45 +0000 +Subject: [PATCH] zfsinfo: Correct a check for error allocating memory + +While arguably the check for grub_errno is correct, we should really be +checking the return value from the function since it is always possible +that grub_errno was set elsewhere, making this code behave incorrectly. + +Fixes: CID 73668 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/fs/zfs/zfsinfo.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/grub-core/fs/zfs/zfsinfo.c b/grub-core/fs/zfs/zfsinfo.c +index c96bf2183c0..19562cf4720 100644 +--- a/grub-core/fs/zfs/zfsinfo.c ++++ b/grub-core/fs/zfs/zfsinfo.c +@@ -356,8 +356,8 @@ grub_cmd_zfs_bootfs (grub_command_t cmd __attribute__ ((unused)), int argc, + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + + devname = grub_file_get_device_name (args[0]); +- if (grub_errno) +- return grub_errno; ++ if (devname == NULL) ++ return GRUB_ERR_OUT_OF_MEMORY; + + dev = grub_device_open (devname); + grub_free (devname); diff --git a/SOURCES/0372-affs-Fix-memory-leaks.patch b/SOURCES/0372-affs-Fix-memory-leaks.patch new file mode 100644 index 0000000..57c42a0 --- /dev/null +++ b/SOURCES/0372-affs-Fix-memory-leaks.patch @@ -0,0 +1,79 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Thu, 26 Nov 2020 12:48:07 +0000 +Subject: [PATCH] affs: Fix memory leaks + +The node structure reference is being allocated but not freed if it +reaches the end of the function. If any of the hooks had returned +a non-zero value, then node would have been copied in to the context +reference, but otherwise node is not stored and should be freed. + +Similarly, the call to grub_affs_create_node() replaces the allocated +memory in node with a newly allocated structure, leaking the existing +memory pointed by node. + +Finally, when dir->parent is set, then we again replace node with newly +allocated memory, which seems unnecessary when we copy in the values +from dir->parent immediately after. + +Fixes: CID 73759 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/fs/affs.c | 18 ++++++++---------- + 1 file changed, 8 insertions(+), 10 deletions(-) + +diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c +index 91073795f90..e4615c74381 100644 +--- a/grub-core/fs/affs.c ++++ b/grub-core/fs/affs.c +@@ -400,12 +400,12 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, + { + unsigned int i; + struct grub_affs_file file; +- struct grub_fshelp_node *node = 0; ++ struct grub_fshelp_node *node, *orig_node; + struct grub_affs_data *data = dir->data; + grub_uint32_t *hashtable; + + /* Create the directory entries for `.' and `..'. */ +- node = grub_zalloc (sizeof (*node)); ++ node = orig_node = grub_zalloc (sizeof (*node)); + if (!node) + return 1; + +@@ -414,9 +414,6 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, + return 1; + if (dir->parent) + { +- node = grub_zalloc (sizeof (*node)); +- if (!node) +- return 1; + *node = *dir->parent; + if (hook ("..", GRUB_FSHELP_DIR, node, hook_data)) + return 1; +@@ -456,17 +453,18 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, + + if (grub_affs_create_node (dir, hook, hook_data, &node, &hashtable, + next, &file)) +- return 1; ++ { ++ /* Node has been replaced in function. */ ++ grub_free (orig_node); ++ return 1; ++ } + + next = grub_be_to_cpu32 (file.next); + } + } + +- grub_free (hashtable); +- return 0; +- + fail: +- grub_free (node); ++ grub_free (orig_node); + grub_free (hashtable); + return 0; + } diff --git a/SOURCES/0372-zfsinfo-Correct-a-check-for-error-allocating-memory.patch b/SOURCES/0372-zfsinfo-Correct-a-check-for-error-allocating-memory.patch deleted file mode 100644 index 7c40c48..0000000 --- a/SOURCES/0372-zfsinfo-Correct-a-check-for-error-allocating-memory.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Thu, 26 Nov 2020 10:56:45 +0000 -Subject: [PATCH] zfsinfo: Correct a check for error allocating memory - -While arguably the check for grub_errno is correct, we should really be -checking the return value from the function since it is always possible -that grub_errno was set elsewhere, making this code behave incorrectly. - -Fixes: CID 73668 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/fs/zfs/zfsinfo.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/grub-core/fs/zfs/zfsinfo.c b/grub-core/fs/zfs/zfsinfo.c -index c96bf2183c0..19562cf4720 100644 ---- a/grub-core/fs/zfs/zfsinfo.c -+++ b/grub-core/fs/zfs/zfsinfo.c -@@ -356,8 +356,8 @@ grub_cmd_zfs_bootfs (grub_command_t cmd __attribute__ ((unused)), int argc, - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - - devname = grub_file_get_device_name (args[0]); -- if (grub_errno) -- return grub_errno; -+ if (devname == NULL) -+ return GRUB_ERR_OUT_OF_MEMORY; - - dev = grub_device_open (devname); - grub_free (devname); diff --git a/SOURCES/0373-affs-Fix-memory-leaks.patch b/SOURCES/0373-affs-Fix-memory-leaks.patch deleted file mode 100644 index 57c42a0..0000000 --- a/SOURCES/0373-affs-Fix-memory-leaks.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Thu, 26 Nov 2020 12:48:07 +0000 -Subject: [PATCH] affs: Fix memory leaks - -The node structure reference is being allocated but not freed if it -reaches the end of the function. If any of the hooks had returned -a non-zero value, then node would have been copied in to the context -reference, but otherwise node is not stored and should be freed. - -Similarly, the call to grub_affs_create_node() replaces the allocated -memory in node with a newly allocated structure, leaking the existing -memory pointed by node. - -Finally, when dir->parent is set, then we again replace node with newly -allocated memory, which seems unnecessary when we copy in the values -from dir->parent immediately after. - -Fixes: CID 73759 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/fs/affs.c | 18 ++++++++---------- - 1 file changed, 8 insertions(+), 10 deletions(-) - -diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c -index 91073795f90..e4615c74381 100644 ---- a/grub-core/fs/affs.c -+++ b/grub-core/fs/affs.c -@@ -400,12 +400,12 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, - { - unsigned int i; - struct grub_affs_file file; -- struct grub_fshelp_node *node = 0; -+ struct grub_fshelp_node *node, *orig_node; - struct grub_affs_data *data = dir->data; - grub_uint32_t *hashtable; - - /* Create the directory entries for `.' and `..'. */ -- node = grub_zalloc (sizeof (*node)); -+ node = orig_node = grub_zalloc (sizeof (*node)); - if (!node) - return 1; - -@@ -414,9 +414,6 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, - return 1; - if (dir->parent) - { -- node = grub_zalloc (sizeof (*node)); -- if (!node) -- return 1; - *node = *dir->parent; - if (hook ("..", GRUB_FSHELP_DIR, node, hook_data)) - return 1; -@@ -456,17 +453,18 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, - - if (grub_affs_create_node (dir, hook, hook_data, &node, &hashtable, - next, &file)) -- return 1; -+ { -+ /* Node has been replaced in function. */ -+ grub_free (orig_node); -+ return 1; -+ } - - next = grub_be_to_cpu32 (file.next); - } - } - -- grub_free (hashtable); -- return 0; -- - fail: -- grub_free (node); -+ grub_free (orig_node); - grub_free (hashtable); - return 0; - } diff --git a/SOURCES/0373-libgcrypt-mpi-Fix-possible-unintended-sign-extension.patch b/SOURCES/0373-libgcrypt-mpi-Fix-possible-unintended-sign-extension.patch new file mode 100644 index 0000000..c9f3a35 --- /dev/null +++ b/SOURCES/0373-libgcrypt-mpi-Fix-possible-unintended-sign-extension.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Tue, 3 Nov 2020 16:43:37 +0000 +Subject: [PATCH] libgcrypt/mpi: Fix possible unintended sign extension + +The array of unsigned char gets promoted to a signed 32-bit int before +it is finally promoted to a size_t. There is the possibility that this +may result in the signed-bit being set for the intermediate signed +32-bit int. We should ensure that the promotion is to the correct type +before we bitwise-OR the values. + +Fixes: CID 96697 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/lib/libgcrypt/mpi/mpicoder.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/lib/libgcrypt/mpi/mpicoder.c b/grub-core/lib/libgcrypt/mpi/mpicoder.c +index a3435ed142a..7ecad27b23a 100644 +--- a/grub-core/lib/libgcrypt/mpi/mpicoder.c ++++ b/grub-core/lib/libgcrypt/mpi/mpicoder.c +@@ -458,7 +458,7 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format, + if (len && len < 4) + return gcry_error (GPG_ERR_TOO_SHORT); + +- n = (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]); ++ n = ((size_t)s[0] << 24 | (size_t)s[1] << 16 | (size_t)s[2] << 8 | (size_t)s[3]); + s += 4; + if (len) + len -= 4; diff --git a/SOURCES/0374-libgcrypt-mpi-Fix-possible-NULL-dereference.patch b/SOURCES/0374-libgcrypt-mpi-Fix-possible-NULL-dereference.patch new file mode 100644 index 0000000..89257f5 --- /dev/null +++ b/SOURCES/0374-libgcrypt-mpi-Fix-possible-NULL-dereference.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Thu, 26 Nov 2020 10:41:54 +0000 +Subject: [PATCH] libgcrypt/mpi: Fix possible NULL dereference + +The code in gcry_mpi_scan() assumes that buffer is not NULL, but there +is no explicit check for that, so we add one. + +Fixes: CID 73757 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/lib/libgcrypt/mpi/mpicoder.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/grub-core/lib/libgcrypt/mpi/mpicoder.c b/grub-core/lib/libgcrypt/mpi/mpicoder.c +index 7ecad27b23a..6fe38916532 100644 +--- a/grub-core/lib/libgcrypt/mpi/mpicoder.c ++++ b/grub-core/lib/libgcrypt/mpi/mpicoder.c +@@ -379,6 +379,9 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format, + unsigned int len; + int secure = (buffer && gcry_is_secure (buffer)); + ++ if (!buffer) ++ return gcry_error (GPG_ERR_INV_ARG); ++ + if (format == GCRYMPI_FMT_SSH) + len = 0; + else diff --git a/SOURCES/0374-libgcrypt-mpi-Fix-possible-unintended-sign-extension.patch b/SOURCES/0374-libgcrypt-mpi-Fix-possible-unintended-sign-extension.patch deleted file mode 100644 index c9f3a35..0000000 --- a/SOURCES/0374-libgcrypt-mpi-Fix-possible-unintended-sign-extension.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Tue, 3 Nov 2020 16:43:37 +0000 -Subject: [PATCH] libgcrypt/mpi: Fix possible unintended sign extension - -The array of unsigned char gets promoted to a signed 32-bit int before -it is finally promoted to a size_t. There is the possibility that this -may result in the signed-bit being set for the intermediate signed -32-bit int. We should ensure that the promotion is to the correct type -before we bitwise-OR the values. - -Fixes: CID 96697 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/lib/libgcrypt/mpi/mpicoder.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/lib/libgcrypt/mpi/mpicoder.c b/grub-core/lib/libgcrypt/mpi/mpicoder.c -index a3435ed142a..7ecad27b23a 100644 ---- a/grub-core/lib/libgcrypt/mpi/mpicoder.c -+++ b/grub-core/lib/libgcrypt/mpi/mpicoder.c -@@ -458,7 +458,7 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format, - if (len && len < 4) - return gcry_error (GPG_ERR_TOO_SHORT); - -- n = (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]); -+ n = ((size_t)s[0] << 24 | (size_t)s[1] << 16 | (size_t)s[2] << 8 | (size_t)s[3]); - s += 4; - if (len) - len -= 4; diff --git a/SOURCES/0375-libgcrypt-mpi-Fix-possible-NULL-dereference.patch b/SOURCES/0375-libgcrypt-mpi-Fix-possible-NULL-dereference.patch deleted file mode 100644 index 89257f5..0000000 --- a/SOURCES/0375-libgcrypt-mpi-Fix-possible-NULL-dereference.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Thu, 26 Nov 2020 10:41:54 +0000 -Subject: [PATCH] libgcrypt/mpi: Fix possible NULL dereference - -The code in gcry_mpi_scan() assumes that buffer is not NULL, but there -is no explicit check for that, so we add one. - -Fixes: CID 73757 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/lib/libgcrypt/mpi/mpicoder.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/grub-core/lib/libgcrypt/mpi/mpicoder.c b/grub-core/lib/libgcrypt/mpi/mpicoder.c -index 7ecad27b23a..6fe38916532 100644 ---- a/grub-core/lib/libgcrypt/mpi/mpicoder.c -+++ b/grub-core/lib/libgcrypt/mpi/mpicoder.c -@@ -379,6 +379,9 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format, - unsigned int len; - int secure = (buffer && gcry_is_secure (buffer)); - -+ if (!buffer) -+ return gcry_error (GPG_ERR_INV_ARG); -+ - if (format == GCRYMPI_FMT_SSH) - len = 0; - else diff --git a/SOURCES/0375-syslinux-Fix-memory-leak-while-parsing.patch b/SOURCES/0375-syslinux-Fix-memory-leak-while-parsing.patch new file mode 100644 index 0000000..f987429 --- /dev/null +++ b/SOURCES/0375-syslinux-Fix-memory-leak-while-parsing.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Thu, 26 Nov 2020 15:31:53 +0000 +Subject: [PATCH] syslinux: Fix memory leak while parsing + +In syslinux_parse_real() the 2 points where return is being called +didn't release the memory stored in buf which is no longer required. + +Fixes: CID 176634 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/lib/syslinux_parse.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/grub-core/lib/syslinux_parse.c b/grub-core/lib/syslinux_parse.c +index 6bc504b7c58..1cc99619ac8 100644 +--- a/grub-core/lib/syslinux_parse.c ++++ b/grub-core/lib/syslinux_parse.c +@@ -734,7 +734,10 @@ syslinux_parse_real (struct syslinux_menu *menu) + && grub_strncasecmp ("help", ptr3, ptr4 - ptr3) == 0)) + { + if (helptext (ptr5, file, menu)) +- return 1; ++ { ++ grub_free (buf); ++ return 1; ++ } + continue; + } + +@@ -754,6 +757,7 @@ syslinux_parse_real (struct syslinux_menu *menu) + } + fail: + grub_file_close (file); ++ grub_free (buf); + return err; + } + diff --git a/SOURCES/0376-normal-completion-Fix-leaking-of-memory-when-process.patch b/SOURCES/0376-normal-completion-Fix-leaking-of-memory-when-process.patch new file mode 100644 index 0000000..984c608 --- /dev/null +++ b/SOURCES/0376-normal-completion-Fix-leaking-of-memory-when-process.patch @@ -0,0 +1,49 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Fri, 4 Dec 2020 18:56:48 +0000 +Subject: [PATCH] normal/completion: Fix leaking of memory when processing a + completion + +It is possible for the code to reach the end of the function without +freeing the memory allocated to argv and argc still to be 0. + +We should always call grub_free(argv). The grub_free() will handle +a NULL argument correctly if it reaches that code without the memory +being allocated. + +Fixes: CID 96672 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/normal/completion.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c +index 93aa0d8eda8..5036bcf2d98 100644 +--- a/grub-core/normal/completion.c ++++ b/grub-core/normal/completion.c +@@ -401,8 +401,8 @@ char * + grub_normal_do_completion (char *buf, int *restore, + void (*hook) (const char *, grub_completion_type_t, int)) + { +- int argc; +- char **argv; ++ int argc = 0; ++ char **argv = NULL; + + /* Initialize variables. */ + match = 0; +@@ -517,10 +517,8 @@ grub_normal_do_completion (char *buf, int *restore, + + fail: + if (argc != 0) +- { +- grub_free (argv[0]); +- grub_free (argv); +- } ++ grub_free (argv[0]); ++ grub_free (argv); + grub_free (match); + grub_errno = GRUB_ERR_NONE; + diff --git a/SOURCES/0376-syslinux-Fix-memory-leak-while-parsing.patch b/SOURCES/0376-syslinux-Fix-memory-leak-while-parsing.patch deleted file mode 100644 index f987429..0000000 --- a/SOURCES/0376-syslinux-Fix-memory-leak-while-parsing.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Thu, 26 Nov 2020 15:31:53 +0000 -Subject: [PATCH] syslinux: Fix memory leak while parsing - -In syslinux_parse_real() the 2 points where return is being called -didn't release the memory stored in buf which is no longer required. - -Fixes: CID 176634 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/lib/syslinux_parse.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/grub-core/lib/syslinux_parse.c b/grub-core/lib/syslinux_parse.c -index 6bc504b7c58..1cc99619ac8 100644 ---- a/grub-core/lib/syslinux_parse.c -+++ b/grub-core/lib/syslinux_parse.c -@@ -734,7 +734,10 @@ syslinux_parse_real (struct syslinux_menu *menu) - && grub_strncasecmp ("help", ptr3, ptr4 - ptr3) == 0)) - { - if (helptext (ptr5, file, menu)) -- return 1; -+ { -+ grub_free (buf); -+ return 1; -+ } - continue; - } - -@@ -754,6 +757,7 @@ syslinux_parse_real (struct syslinux_menu *menu) - } - fail: - grub_file_close (file); -+ grub_free (buf); - return err; - } - diff --git a/SOURCES/0377-commands-hashsum-Fix-a-memory-leak.patch b/SOURCES/0377-commands-hashsum-Fix-a-memory-leak.patch new file mode 100644 index 0000000..5fe9eb6 --- /dev/null +++ b/SOURCES/0377-commands-hashsum-Fix-a-memory-leak.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chris Coulson +Date: Tue, 1 Dec 2020 23:41:24 +0000 +Subject: [PATCH] commands/hashsum: Fix a memory leak + +check_list() uses grub_file_getline(), which allocates a buffer. +If the hash list file contains invalid lines, the function leaks +this buffer when it returns an error. + +Fixes: CID 176635 + +Signed-off-by: Chris Coulson +Reviewed-by: Daniel Kiper +--- + grub-core/commands/hashsum.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/grub-core/commands/hashsum.c b/grub-core/commands/hashsum.c +index d18687351a5..282922bba1e 100644 +--- a/grub-core/commands/hashsum.c ++++ b/grub-core/commands/hashsum.c +@@ -128,11 +128,17 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, + high = hextoval (*p++); + low = hextoval (*p++); + if (high < 0 || low < 0) +- return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list"); ++ { ++ grub_free (buf); ++ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list"); ++ } + expected[i] = (high << 4) | low; + } + if ((p[0] != ' ' && p[0] != '\t') || (p[1] != ' ' && p[1] != '\t')) +- return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list"); ++ { ++ grub_free (buf); ++ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list"); ++ } + p += 2; + if (prefix) + { +@@ -140,7 +146,10 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, + + filename = grub_xasprintf ("%s/%s", prefix, p); + if (!filename) +- return grub_errno; ++ { ++ grub_free (buf); ++ return grub_errno; ++ } + if (!uncompress) + grub_file_filter_disable_compression (); + file = grub_file_open (filename); diff --git a/SOURCES/0377-normal-completion-Fix-leaking-of-memory-when-process.patch b/SOURCES/0377-normal-completion-Fix-leaking-of-memory-when-process.patch deleted file mode 100644 index 984c608..0000000 --- a/SOURCES/0377-normal-completion-Fix-leaking-of-memory-when-process.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Fri, 4 Dec 2020 18:56:48 +0000 -Subject: [PATCH] normal/completion: Fix leaking of memory when processing a - completion - -It is possible for the code to reach the end of the function without -freeing the memory allocated to argv and argc still to be 0. - -We should always call grub_free(argv). The grub_free() will handle -a NULL argument correctly if it reaches that code without the memory -being allocated. - -Fixes: CID 96672 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/normal/completion.c | 10 ++++------ - 1 file changed, 4 insertions(+), 6 deletions(-) - -diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c -index 93aa0d8eda8..5036bcf2d98 100644 ---- a/grub-core/normal/completion.c -+++ b/grub-core/normal/completion.c -@@ -401,8 +401,8 @@ char * - grub_normal_do_completion (char *buf, int *restore, - void (*hook) (const char *, grub_completion_type_t, int)) - { -- int argc; -- char **argv; -+ int argc = 0; -+ char **argv = NULL; - - /* Initialize variables. */ - match = 0; -@@ -517,10 +517,8 @@ grub_normal_do_completion (char *buf, int *restore, - - fail: - if (argc != 0) -- { -- grub_free (argv[0]); -- grub_free (argv); -- } -+ grub_free (argv[0]); -+ grub_free (argv); - grub_free (match); - grub_errno = GRUB_ERR_NONE; - diff --git a/SOURCES/0378-commands-hashsum-Fix-a-memory-leak.patch b/SOURCES/0378-commands-hashsum-Fix-a-memory-leak.patch deleted file mode 100644 index 5fe9eb6..0000000 --- a/SOURCES/0378-commands-hashsum-Fix-a-memory-leak.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Coulson -Date: Tue, 1 Dec 2020 23:41:24 +0000 -Subject: [PATCH] commands/hashsum: Fix a memory leak - -check_list() uses grub_file_getline(), which allocates a buffer. -If the hash list file contains invalid lines, the function leaks -this buffer when it returns an error. - -Fixes: CID 176635 - -Signed-off-by: Chris Coulson -Reviewed-by: Daniel Kiper ---- - grub-core/commands/hashsum.c | 15 ++++++++++++--- - 1 file changed, 12 insertions(+), 3 deletions(-) - -diff --git a/grub-core/commands/hashsum.c b/grub-core/commands/hashsum.c -index d18687351a5..282922bba1e 100644 ---- a/grub-core/commands/hashsum.c -+++ b/grub-core/commands/hashsum.c -@@ -128,11 +128,17 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, - high = hextoval (*p++); - low = hextoval (*p++); - if (high < 0 || low < 0) -- return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list"); -+ { -+ grub_free (buf); -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list"); -+ } - expected[i] = (high << 4) | low; - } - if ((p[0] != ' ' && p[0] != '\t') || (p[1] != ' ' && p[1] != '\t')) -- return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list"); -+ { -+ grub_free (buf); -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list"); -+ } - p += 2; - if (prefix) - { -@@ -140,7 +146,10 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, - - filename = grub_xasprintf ("%s/%s", prefix, p); - if (!filename) -- return grub_errno; -+ { -+ grub_free (buf); -+ return grub_errno; -+ } - if (!uncompress) - grub_file_filter_disable_compression (); - file = grub_file_open (filename); diff --git a/SOURCES/0378-video-efi_gop-Remove-unnecessary-return-value-of-gru.patch b/SOURCES/0378-video-efi_gop-Remove-unnecessary-return-value-of-gru.patch new file mode 100644 index 0000000..fce5f99 --- /dev/null +++ b/SOURCES/0378-video-efi_gop-Remove-unnecessary-return-value-of-gru.patch @@ -0,0 +1,91 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Tue, 8 Dec 2020 21:14:31 +0000 +Subject: [PATCH] video/efi_gop: Remove unnecessary return value of + grub_video_gop_fill_mode_info() + +The return value of grub_video_gop_fill_mode_info() is never able to be +anything other than GRUB_ERR_NONE. So, rather than continue to return +a value and checking it each time, it is more correct to redefine the +function to not return anything and remove checks of its return value +altogether. + +Fixes: CID 96701 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/video/efi_gop.c | 25 ++++++------------------- + 1 file changed, 6 insertions(+), 19 deletions(-) + +diff --git a/grub-core/video/efi_gop.c b/grub-core/video/efi_gop.c +index c9e40e8d4e9..9fcc41ac03c 100644 +--- a/grub-core/video/efi_gop.c ++++ b/grub-core/video/efi_gop.c +@@ -229,7 +229,7 @@ grub_video_gop_fill_real_mode_info (unsigned mode, + return GRUB_ERR_NONE; + } + +-static grub_err_t ++static void + grub_video_gop_fill_mode_info (unsigned mode, + struct grub_efi_gop_mode_info *in, + struct grub_video_mode_info *out) +@@ -254,8 +254,6 @@ grub_video_gop_fill_mode_info (unsigned mode, + out->blit_format = GRUB_VIDEO_BLIT_FORMAT_BGRA_8888; + out->mode_type |= (GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED + | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); +- +- return GRUB_ERR_NONE; + } + + static int +@@ -268,7 +266,6 @@ grub_video_gop_iterate (int (*hook) (const struct grub_video_mode_info *info, vo + grub_efi_uintn_t size; + grub_efi_status_t status; + struct grub_efi_gop_mode_info *info = NULL; +- grub_err_t err; + struct grub_video_mode_info mode_info; + + status = efi_call_4 (gop->query_mode, gop, mode, &size, &info); +@@ -279,12 +276,7 @@ grub_video_gop_iterate (int (*hook) (const struct grub_video_mode_info *info, vo + continue; + } + +- err = grub_video_gop_fill_mode_info (mode, info, &mode_info); +- if (err) +- { +- grub_errno = GRUB_ERR_NONE; +- continue; +- } ++ grub_video_gop_fill_mode_info (mode, info, &mode_info); + if (hook (&mode_info, hook_arg)) + return 1; + } +@@ -468,13 +460,8 @@ grub_video_gop_setup (unsigned int width, unsigned int height, + + info = gop->mode->info; + +- err = grub_video_gop_fill_mode_info (gop->mode->mode, info, +- &framebuffer.mode_info); +- if (err) +- { +- grub_dprintf ("video", "GOP: couldn't fill mode info\n"); +- return err; +- } ++ grub_video_gop_fill_mode_info (gop->mode->mode, info, ++ &framebuffer.mode_info); + + framebuffer.ptr = (void *) (grub_addr_t) gop->mode->fb_base; + framebuffer.offscreen +@@ -488,8 +475,8 @@ grub_video_gop_setup (unsigned int width, unsigned int height, + { + grub_dprintf ("video", "GOP: couldn't allocate shadow\n"); + grub_errno = 0; +- err = grub_video_gop_fill_mode_info (gop->mode->mode, info, +- &framebuffer.mode_info); ++ grub_video_gop_fill_mode_info (gop->mode->mode, info, ++ &framebuffer.mode_info); + buffer = framebuffer.ptr; + } + diff --git a/SOURCES/0379-video-efi_gop-Remove-unnecessary-return-value-of-gru.patch b/SOURCES/0379-video-efi_gop-Remove-unnecessary-return-value-of-gru.patch deleted file mode 100644 index fce5f99..0000000 --- a/SOURCES/0379-video-efi_gop-Remove-unnecessary-return-value-of-gru.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Tue, 8 Dec 2020 21:14:31 +0000 -Subject: [PATCH] video/efi_gop: Remove unnecessary return value of - grub_video_gop_fill_mode_info() - -The return value of grub_video_gop_fill_mode_info() is never able to be -anything other than GRUB_ERR_NONE. So, rather than continue to return -a value and checking it each time, it is more correct to redefine the -function to not return anything and remove checks of its return value -altogether. - -Fixes: CID 96701 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/video/efi_gop.c | 25 ++++++------------------- - 1 file changed, 6 insertions(+), 19 deletions(-) - -diff --git a/grub-core/video/efi_gop.c b/grub-core/video/efi_gop.c -index c9e40e8d4e9..9fcc41ac03c 100644 ---- a/grub-core/video/efi_gop.c -+++ b/grub-core/video/efi_gop.c -@@ -229,7 +229,7 @@ grub_video_gop_fill_real_mode_info (unsigned mode, - return GRUB_ERR_NONE; - } - --static grub_err_t -+static void - grub_video_gop_fill_mode_info (unsigned mode, - struct grub_efi_gop_mode_info *in, - struct grub_video_mode_info *out) -@@ -254,8 +254,6 @@ grub_video_gop_fill_mode_info (unsigned mode, - out->blit_format = GRUB_VIDEO_BLIT_FORMAT_BGRA_8888; - out->mode_type |= (GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED - | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); -- -- return GRUB_ERR_NONE; - } - - static int -@@ -268,7 +266,6 @@ grub_video_gop_iterate (int (*hook) (const struct grub_video_mode_info *info, vo - grub_efi_uintn_t size; - grub_efi_status_t status; - struct grub_efi_gop_mode_info *info = NULL; -- grub_err_t err; - struct grub_video_mode_info mode_info; - - status = efi_call_4 (gop->query_mode, gop, mode, &size, &info); -@@ -279,12 +276,7 @@ grub_video_gop_iterate (int (*hook) (const struct grub_video_mode_info *info, vo - continue; - } - -- err = grub_video_gop_fill_mode_info (mode, info, &mode_info); -- if (err) -- { -- grub_errno = GRUB_ERR_NONE; -- continue; -- } -+ grub_video_gop_fill_mode_info (mode, info, &mode_info); - if (hook (&mode_info, hook_arg)) - return 1; - } -@@ -468,13 +460,8 @@ grub_video_gop_setup (unsigned int width, unsigned int height, - - info = gop->mode->info; - -- err = grub_video_gop_fill_mode_info (gop->mode->mode, info, -- &framebuffer.mode_info); -- if (err) -- { -- grub_dprintf ("video", "GOP: couldn't fill mode info\n"); -- return err; -- } -+ grub_video_gop_fill_mode_info (gop->mode->mode, info, -+ &framebuffer.mode_info); - - framebuffer.ptr = (void *) (grub_addr_t) gop->mode->fb_base; - framebuffer.offscreen -@@ -488,8 +475,8 @@ grub_video_gop_setup (unsigned int width, unsigned int height, - { - grub_dprintf ("video", "GOP: couldn't allocate shadow\n"); - grub_errno = 0; -- err = grub_video_gop_fill_mode_info (gop->mode->mode, info, -- &framebuffer.mode_info); -+ grub_video_gop_fill_mode_info (gop->mode->mode, info, -+ &framebuffer.mode_info); - buffer = framebuffer.ptr; - } - diff --git a/SOURCES/0379-video-fb-fbfill-Fix-potential-integer-overflow.patch b/SOURCES/0379-video-fb-fbfill-Fix-potential-integer-overflow.patch new file mode 100644 index 0000000..895fd9d --- /dev/null +++ b/SOURCES/0379-video-fb-fbfill-Fix-potential-integer-overflow.patch @@ -0,0 +1,75 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Wed, 4 Nov 2020 15:10:51 +0000 +Subject: [PATCH] video/fb/fbfill: Fix potential integer overflow + +The multiplication of 2 unsigned 32-bit integers may overflow before +promotion to unsigned 64-bit. We should ensure that the multiplication +is done with overflow detection. Additionally, use grub_sub() for +subtraction. + +Fixes: CID 73640, CID 73697, CID 73702, CID 73823 + +Signed-off-by: Darren Kenny +Signed-off-by: Marco A Benatto +Reviewed-by: Daniel Kiper +--- + grub-core/video/fb/fbfill.c | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +diff --git a/grub-core/video/fb/fbfill.c b/grub-core/video/fb/fbfill.c +index 11816d07a0b..a37acd1e293 100644 +--- a/grub-core/video/fb/fbfill.c ++++ b/grub-core/video/fb/fbfill.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + #include + + /* Generic filler that works for every supported mode. */ +@@ -61,7 +62,9 @@ grub_video_fbfill_direct32 (struct grub_video_fbblit_info *dst, + + /* Calculate the number of bytes to advance from the end of one line + to the beginning of the next line. */ +- rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; ++ if (grub_mul (dst->mode_info->bytes_per_pixel, width, &rowskip) || ++ grub_sub (dst->mode_info->pitch, rowskip, &rowskip)) ++ return; + + /* Get the start address. */ + dstptr = grub_video_fb_get_video_ptr (dst, x, y); +@@ -98,7 +101,9 @@ grub_video_fbfill_direct24 (struct grub_video_fbblit_info *dst, + #endif + /* Calculate the number of bytes to advance from the end of one line + to the beginning of the next line. */ +- rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; ++ if (grub_mul (dst->mode_info->bytes_per_pixel, width, &rowskip) || ++ grub_sub (dst->mode_info->pitch, rowskip, &rowskip)) ++ return; + + /* Get the start address. */ + dstptr = grub_video_fb_get_video_ptr (dst, x, y); +@@ -131,7 +136,9 @@ grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst, + + /* Calculate the number of bytes to advance from the end of one line + to the beginning of the next line. */ +- rowskip = (dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width); ++ if (grub_mul (dst->mode_info->bytes_per_pixel, width, &rowskip) || ++ grub_sub (dst->mode_info->pitch, rowskip, &rowskip)) ++ return; + + /* Get the start address. */ + dstptr = grub_video_fb_get_video_ptr (dst, x, y); +@@ -161,7 +168,9 @@ grub_video_fbfill_direct8 (struct grub_video_fbblit_info *dst, + + /* Calculate the number of bytes to advance from the end of one line + to the beginning of the next line. */ +- rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; ++ if (grub_mul (dst->mode_info->bytes_per_pixel, width, &rowskip) || ++ grub_sub (dst->mode_info->pitch, rowskip, &rowskip)) ++ return; + + /* Get the start address. */ + dstptr = grub_video_fb_get_video_ptr (dst, x, y); diff --git a/SOURCES/0380-video-fb-fbfill-Fix-potential-integer-overflow.patch b/SOURCES/0380-video-fb-fbfill-Fix-potential-integer-overflow.patch deleted file mode 100644 index 895fd9d..0000000 --- a/SOURCES/0380-video-fb-fbfill-Fix-potential-integer-overflow.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Wed, 4 Nov 2020 15:10:51 +0000 -Subject: [PATCH] video/fb/fbfill: Fix potential integer overflow - -The multiplication of 2 unsigned 32-bit integers may overflow before -promotion to unsigned 64-bit. We should ensure that the multiplication -is done with overflow detection. Additionally, use grub_sub() for -subtraction. - -Fixes: CID 73640, CID 73697, CID 73702, CID 73823 - -Signed-off-by: Darren Kenny -Signed-off-by: Marco A Benatto -Reviewed-by: Daniel Kiper ---- - grub-core/video/fb/fbfill.c | 17 +++++++++++++---- - 1 file changed, 13 insertions(+), 4 deletions(-) - -diff --git a/grub-core/video/fb/fbfill.c b/grub-core/video/fb/fbfill.c -index 11816d07a0b..a37acd1e293 100644 ---- a/grub-core/video/fb/fbfill.c -+++ b/grub-core/video/fb/fbfill.c -@@ -31,6 +31,7 @@ - #include - #include - #include -+#include - #include - - /* Generic filler that works for every supported mode. */ -@@ -61,7 +62,9 @@ grub_video_fbfill_direct32 (struct grub_video_fbblit_info *dst, - - /* Calculate the number of bytes to advance from the end of one line - to the beginning of the next line. */ -- rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; -+ if (grub_mul (dst->mode_info->bytes_per_pixel, width, &rowskip) || -+ grub_sub (dst->mode_info->pitch, rowskip, &rowskip)) -+ return; - - /* Get the start address. */ - dstptr = grub_video_fb_get_video_ptr (dst, x, y); -@@ -98,7 +101,9 @@ grub_video_fbfill_direct24 (struct grub_video_fbblit_info *dst, - #endif - /* Calculate the number of bytes to advance from the end of one line - to the beginning of the next line. */ -- rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; -+ if (grub_mul (dst->mode_info->bytes_per_pixel, width, &rowskip) || -+ grub_sub (dst->mode_info->pitch, rowskip, &rowskip)) -+ return; - - /* Get the start address. */ - dstptr = grub_video_fb_get_video_ptr (dst, x, y); -@@ -131,7 +136,9 @@ grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst, - - /* Calculate the number of bytes to advance from the end of one line - to the beginning of the next line. */ -- rowskip = (dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width); -+ if (grub_mul (dst->mode_info->bytes_per_pixel, width, &rowskip) || -+ grub_sub (dst->mode_info->pitch, rowskip, &rowskip)) -+ return; - - /* Get the start address. */ - dstptr = grub_video_fb_get_video_ptr (dst, x, y); -@@ -161,7 +168,9 @@ grub_video_fbfill_direct8 (struct grub_video_fbblit_info *dst, - - /* Calculate the number of bytes to advance from the end of one line - to the beginning of the next line. */ -- rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; -+ if (grub_mul (dst->mode_info->bytes_per_pixel, width, &rowskip) || -+ grub_sub (dst->mode_info->pitch, rowskip, &rowskip)) -+ return; - - /* Get the start address. */ - dstptr = grub_video_fb_get_video_ptr (dst, x, y); diff --git a/SOURCES/0380-video-fb-video_fb-Fix-multiple-integer-overflows.patch b/SOURCES/0380-video-fb-video_fb-Fix-multiple-integer-overflows.patch new file mode 100644 index 0000000..95bc962 --- /dev/null +++ b/SOURCES/0380-video-fb-video_fb-Fix-multiple-integer-overflows.patch @@ -0,0 +1,101 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Wed, 4 Nov 2020 14:43:44 +0000 +Subject: [PATCH] video/fb/video_fb: Fix multiple integer overflows + +The calculation of the unsigned 64-bit value is being generated by +multiplying 2, signed or unsigned, 32-bit integers which may overflow +before promotion to unsigned 64-bit. Fix all of them. + +Fixes: CID 73703, CID 73767, CID 73833 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/video/fb/video_fb.c | 52 ++++++++++++++++++++++++++++++------------- + 1 file changed, 36 insertions(+), 16 deletions(-) + +diff --git a/grub-core/video/fb/video_fb.c b/grub-core/video/fb/video_fb.c +index 722bb3bb436..eae87bab1ea 100644 +--- a/grub-core/video/fb/video_fb.c ++++ b/grub-core/video/fb/video_fb.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -1417,15 +1418,23 @@ doublebuf_blit_update_screen (void) + { + if (framebuffer.current_dirty.first_line + <= framebuffer.current_dirty.last_line) +- grub_memcpy ((char *) framebuffer.pages[0] +- + framebuffer.current_dirty.first_line +- * framebuffer.back_target->mode_info.pitch, +- (char *) framebuffer.back_target->data +- + framebuffer.current_dirty.first_line +- * framebuffer.back_target->mode_info.pitch, +- framebuffer.back_target->mode_info.pitch +- * (framebuffer.current_dirty.last_line +- - framebuffer.current_dirty.first_line)); ++ { ++ grub_size_t copy_size; ++ ++ if (grub_sub (framebuffer.current_dirty.last_line, ++ framebuffer.current_dirty.first_line, ©_size) || ++ grub_mul (framebuffer.back_target->mode_info.pitch, copy_size, ©_size)) ++ { ++ /* Shouldn't happen, but if it does we've a bug. */ ++ return GRUB_ERR_BUG; ++ } ++ ++ grub_memcpy ((char *) framebuffer.pages[0] + framebuffer.current_dirty.first_line * ++ framebuffer.back_target->mode_info.pitch, ++ (char *) framebuffer.back_target->data + framebuffer.current_dirty.first_line * ++ framebuffer.back_target->mode_info.pitch, ++ copy_size); ++ } + framebuffer.current_dirty.first_line + = framebuffer.back_target->mode_info.height; + framebuffer.current_dirty.last_line = 0; +@@ -1439,7 +1448,7 @@ grub_video_fb_doublebuf_blit_init (struct grub_video_fbrender_target **back, + volatile void *framebuf) + { + grub_err_t err; +- grub_size_t page_size = mode_info.pitch * mode_info.height; ++ grub_size_t page_size = (grub_size_t) mode_info.pitch * mode_info.height; + + framebuffer.offscreen_buffer = grub_zalloc (page_size); + if (! framebuffer.offscreen_buffer) +@@ -1482,12 +1491,23 @@ doublebuf_pageflipping_update_screen (void) + last_line = framebuffer.previous_dirty.last_line; + + if (first_line <= last_line) +- grub_memcpy ((char *) framebuffer.pages[framebuffer.render_page] +- + first_line * framebuffer.back_target->mode_info.pitch, +- (char *) framebuffer.back_target->data +- + first_line * framebuffer.back_target->mode_info.pitch, +- framebuffer.back_target->mode_info.pitch +- * (last_line - first_line)); ++ { ++ grub_size_t copy_size; ++ ++ if (grub_sub (last_line, first_line, ©_size) || ++ grub_mul (framebuffer.back_target->mode_info.pitch, copy_size, ©_size)) ++ { ++ /* Shouldn't happen, but if it does we've a bug. */ ++ return GRUB_ERR_BUG; ++ } ++ ++ grub_memcpy ((char *) framebuffer.pages[framebuffer.render_page] + first_line * ++ framebuffer.back_target->mode_info.pitch, ++ (char *) framebuffer.back_target->data + first_line * ++ framebuffer.back_target->mode_info.pitch, ++ copy_size); ++ } ++ + framebuffer.previous_dirty = framebuffer.current_dirty; + framebuffer.current_dirty.first_line + = framebuffer.back_target->mode_info.height; diff --git a/SOURCES/0381-video-fb-video_fb-Fix-multiple-integer-overflows.patch b/SOURCES/0381-video-fb-video_fb-Fix-multiple-integer-overflows.patch deleted file mode 100644 index 95bc962..0000000 --- a/SOURCES/0381-video-fb-video_fb-Fix-multiple-integer-overflows.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Wed, 4 Nov 2020 14:43:44 +0000 -Subject: [PATCH] video/fb/video_fb: Fix multiple integer overflows - -The calculation of the unsigned 64-bit value is being generated by -multiplying 2, signed or unsigned, 32-bit integers which may overflow -before promotion to unsigned 64-bit. Fix all of them. - -Fixes: CID 73703, CID 73767, CID 73833 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/video/fb/video_fb.c | 52 ++++++++++++++++++++++++++++++------------- - 1 file changed, 36 insertions(+), 16 deletions(-) - -diff --git a/grub-core/video/fb/video_fb.c b/grub-core/video/fb/video_fb.c -index 722bb3bb436..eae87bab1ea 100644 ---- a/grub-core/video/fb/video_fb.c -+++ b/grub-core/video/fb/video_fb.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -1417,15 +1418,23 @@ doublebuf_blit_update_screen (void) - { - if (framebuffer.current_dirty.first_line - <= framebuffer.current_dirty.last_line) -- grub_memcpy ((char *) framebuffer.pages[0] -- + framebuffer.current_dirty.first_line -- * framebuffer.back_target->mode_info.pitch, -- (char *) framebuffer.back_target->data -- + framebuffer.current_dirty.first_line -- * framebuffer.back_target->mode_info.pitch, -- framebuffer.back_target->mode_info.pitch -- * (framebuffer.current_dirty.last_line -- - framebuffer.current_dirty.first_line)); -+ { -+ grub_size_t copy_size; -+ -+ if (grub_sub (framebuffer.current_dirty.last_line, -+ framebuffer.current_dirty.first_line, ©_size) || -+ grub_mul (framebuffer.back_target->mode_info.pitch, copy_size, ©_size)) -+ { -+ /* Shouldn't happen, but if it does we've a bug. */ -+ return GRUB_ERR_BUG; -+ } -+ -+ grub_memcpy ((char *) framebuffer.pages[0] + framebuffer.current_dirty.first_line * -+ framebuffer.back_target->mode_info.pitch, -+ (char *) framebuffer.back_target->data + framebuffer.current_dirty.first_line * -+ framebuffer.back_target->mode_info.pitch, -+ copy_size); -+ } - framebuffer.current_dirty.first_line - = framebuffer.back_target->mode_info.height; - framebuffer.current_dirty.last_line = 0; -@@ -1439,7 +1448,7 @@ grub_video_fb_doublebuf_blit_init (struct grub_video_fbrender_target **back, - volatile void *framebuf) - { - grub_err_t err; -- grub_size_t page_size = mode_info.pitch * mode_info.height; -+ grub_size_t page_size = (grub_size_t) mode_info.pitch * mode_info.height; - - framebuffer.offscreen_buffer = grub_zalloc (page_size); - if (! framebuffer.offscreen_buffer) -@@ -1482,12 +1491,23 @@ doublebuf_pageflipping_update_screen (void) - last_line = framebuffer.previous_dirty.last_line; - - if (first_line <= last_line) -- grub_memcpy ((char *) framebuffer.pages[framebuffer.render_page] -- + first_line * framebuffer.back_target->mode_info.pitch, -- (char *) framebuffer.back_target->data -- + first_line * framebuffer.back_target->mode_info.pitch, -- framebuffer.back_target->mode_info.pitch -- * (last_line - first_line)); -+ { -+ grub_size_t copy_size; -+ -+ if (grub_sub (last_line, first_line, ©_size) || -+ grub_mul (framebuffer.back_target->mode_info.pitch, copy_size, ©_size)) -+ { -+ /* Shouldn't happen, but if it does we've a bug. */ -+ return GRUB_ERR_BUG; -+ } -+ -+ grub_memcpy ((char *) framebuffer.pages[framebuffer.render_page] + first_line * -+ framebuffer.back_target->mode_info.pitch, -+ (char *) framebuffer.back_target->data + first_line * -+ framebuffer.back_target->mode_info.pitch, -+ copy_size); -+ } -+ - framebuffer.previous_dirty = framebuffer.current_dirty; - framebuffer.current_dirty.first_line - = framebuffer.back_target->mode_info.height; diff --git a/SOURCES/0381-video-fb-video_fb-Fix-possible-integer-overflow.patch b/SOURCES/0381-video-fb-video_fb-Fix-possible-integer-overflow.patch new file mode 100644 index 0000000..164b926 --- /dev/null +++ b/SOURCES/0381-video-fb-video_fb-Fix-possible-integer-overflow.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Fri, 4 Dec 2020 14:51:30 +0000 +Subject: [PATCH] video/fb/video_fb: Fix possible integer overflow + +It is minimal possibility that the values being used here will overflow. +So, change the code to use the safemath function grub_mul() to ensure +that doesn't happen. + +Fixes: CID 73761 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/video/fb/video_fb.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/grub-core/video/fb/video_fb.c b/grub-core/video/fb/video_fb.c +index eae87bab1ea..33cf98f655b 100644 +--- a/grub-core/video/fb/video_fb.c ++++ b/grub-core/video/fb/video_fb.c +@@ -1537,7 +1537,13 @@ doublebuf_pageflipping_init (struct grub_video_mode_info *mode_info, + volatile void *page1_ptr) + { + grub_err_t err; +- grub_size_t page_size = mode_info->pitch * mode_info->height; ++ grub_size_t page_size = 0; ++ ++ if (grub_mul (mode_info->pitch, mode_info->height, &page_size)) ++ { ++ /* Shouldn't happen, but if it does we've a bug. */ ++ return GRUB_ERR_BUG; ++ } + + framebuffer.offscreen_buffer = grub_malloc (page_size); + if (! framebuffer.offscreen_buffer) diff --git a/SOURCES/0382-video-fb-video_fb-Fix-possible-integer-overflow.patch b/SOURCES/0382-video-fb-video_fb-Fix-possible-integer-overflow.patch deleted file mode 100644 index 164b926..0000000 --- a/SOURCES/0382-video-fb-video_fb-Fix-possible-integer-overflow.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Fri, 4 Dec 2020 14:51:30 +0000 -Subject: [PATCH] video/fb/video_fb: Fix possible integer overflow - -It is minimal possibility that the values being used here will overflow. -So, change the code to use the safemath function grub_mul() to ensure -that doesn't happen. - -Fixes: CID 73761 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/video/fb/video_fb.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/grub-core/video/fb/video_fb.c b/grub-core/video/fb/video_fb.c -index eae87bab1ea..33cf98f655b 100644 ---- a/grub-core/video/fb/video_fb.c -+++ b/grub-core/video/fb/video_fb.c -@@ -1537,7 +1537,13 @@ doublebuf_pageflipping_init (struct grub_video_mode_info *mode_info, - volatile void *page1_ptr) - { - grub_err_t err; -- grub_size_t page_size = mode_info->pitch * mode_info->height; -+ grub_size_t page_size = 0; -+ -+ if (grub_mul (mode_info->pitch, mode_info->height, &page_size)) -+ { -+ /* Shouldn't happen, but if it does we've a bug. */ -+ return GRUB_ERR_BUG; -+ } - - framebuffer.offscreen_buffer = grub_malloc (page_size); - if (! framebuffer.offscreen_buffer) diff --git a/SOURCES/0382-video-readers-jpeg-Test-for-an-invalid-next-marker-r.patch b/SOURCES/0382-video-readers-jpeg-Test-for-an-invalid-next-marker-r.patch new file mode 100644 index 0000000..3394852 --- /dev/null +++ b/SOURCES/0382-video-readers-jpeg-Test-for-an-invalid-next-marker-r.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Fri, 4 Dec 2020 15:39:00 +0000 +Subject: [PATCH] video/readers/jpeg: Test for an invalid next marker reference + from a jpeg file + +While it may never happen, and potentially could be caught at the end of +the function, it is worth checking up front for a bad reference to the +next marker just in case of a maliciously crafted file being provided. + +Fixes: CID 73694 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/video/readers/jpeg.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c +index 2dc2ee10e54..ed6d9bfd160 100644 +--- a/grub-core/video/readers/jpeg.c ++++ b/grub-core/video/readers/jpeg.c +@@ -253,6 +253,12 @@ grub_jpeg_decode_quan_table (struct grub_jpeg_data *data) + next_marker = data->file->offset; + next_marker += grub_jpeg_get_word (data); + ++ if (next_marker > data->file->size) ++ { ++ /* Should never be set beyond the size of the file. */ ++ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid next reference"); ++ } ++ + while (data->file->offset + sizeof (data->quan_table[id]) + 1 + <= next_marker) + { diff --git a/SOURCES/0383-gfxmenu-gui_list-Remove-code-that-coverity-is-flaggi.patch b/SOURCES/0383-gfxmenu-gui_list-Remove-code-that-coverity-is-flaggi.patch new file mode 100644 index 0000000..4e1d94a --- /dev/null +++ b/SOURCES/0383-gfxmenu-gui_list-Remove-code-that-coverity-is-flaggi.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Mon, 7 Dec 2020 14:44:47 +0000 +Subject: [PATCH] gfxmenu/gui_list: Remove code that coverity is flagging as + dead + +The test of value for NULL before calling grub_strdup() is not required, +since the if condition prior to this has already tested for value being +NULL and cannot reach this code if it is. + +Fixes: CID 73659 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/gfxmenu/gui_list.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/gfxmenu/gui_list.c b/grub-core/gfxmenu/gui_list.c +index 5d26811f9d2..2a52a529247 100644 +--- a/grub-core/gfxmenu/gui_list.c ++++ b/grub-core/gfxmenu/gui_list.c +@@ -768,7 +768,7 @@ list_set_property (void *vself, const char *name, const char *value) + { + self->need_to_recreate_boxes = 1; + grub_free (self->selected_item_box_pattern); +- self->selected_item_box_pattern = value ? grub_strdup (value) : 0; ++ self->selected_item_box_pattern = grub_strdup (value); + self->selected_item_box_pattern_inherit = 0; + } + } diff --git a/SOURCES/0383-video-readers-jpeg-Test-for-an-invalid-next-marker-r.patch b/SOURCES/0383-video-readers-jpeg-Test-for-an-invalid-next-marker-r.patch deleted file mode 100644 index 3394852..0000000 --- a/SOURCES/0383-video-readers-jpeg-Test-for-an-invalid-next-marker-r.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Fri, 4 Dec 2020 15:39:00 +0000 -Subject: [PATCH] video/readers/jpeg: Test for an invalid next marker reference - from a jpeg file - -While it may never happen, and potentially could be caught at the end of -the function, it is worth checking up front for a bad reference to the -next marker just in case of a maliciously crafted file being provided. - -Fixes: CID 73694 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/video/readers/jpeg.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c -index 2dc2ee10e54..ed6d9bfd160 100644 ---- a/grub-core/video/readers/jpeg.c -+++ b/grub-core/video/readers/jpeg.c -@@ -253,6 +253,12 @@ grub_jpeg_decode_quan_table (struct grub_jpeg_data *data) - next_marker = data->file->offset; - next_marker += grub_jpeg_get_word (data); - -+ if (next_marker > data->file->size) -+ { -+ /* Should never be set beyond the size of the file. */ -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid next reference"); -+ } -+ - while (data->file->offset + sizeof (data->quan_table[id]) + 1 - <= next_marker) - { diff --git a/SOURCES/0384-gfxmenu-gui_list-Remove-code-that-coverity-is-flaggi.patch b/SOURCES/0384-gfxmenu-gui_list-Remove-code-that-coverity-is-flaggi.patch deleted file mode 100644 index 4e1d94a..0000000 --- a/SOURCES/0384-gfxmenu-gui_list-Remove-code-that-coverity-is-flaggi.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Mon, 7 Dec 2020 14:44:47 +0000 -Subject: [PATCH] gfxmenu/gui_list: Remove code that coverity is flagging as - dead - -The test of value for NULL before calling grub_strdup() is not required, -since the if condition prior to this has already tested for value being -NULL and cannot reach this code if it is. - -Fixes: CID 73659 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/gfxmenu/gui_list.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/gfxmenu/gui_list.c b/grub-core/gfxmenu/gui_list.c -index 5d26811f9d2..2a52a529247 100644 ---- a/grub-core/gfxmenu/gui_list.c -+++ b/grub-core/gfxmenu/gui_list.c -@@ -768,7 +768,7 @@ list_set_property (void *vself, const char *name, const char *value) - { - self->need_to_recreate_boxes = 1; - grub_free (self->selected_item_box_pattern); -- self->selected_item_box_pattern = value ? grub_strdup (value) : 0; -+ self->selected_item_box_pattern = grub_strdup (value); - self->selected_item_box_pattern_inherit = 0; - } - } diff --git a/SOURCES/0384-loader-bsd-Check-for-NULL-arg-up-front.patch b/SOURCES/0384-loader-bsd-Check-for-NULL-arg-up-front.patch new file mode 100644 index 0000000..f38c592 --- /dev/null +++ b/SOURCES/0384-loader-bsd-Check-for-NULL-arg-up-front.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Tue, 8 Dec 2020 21:47:13 +0000 +Subject: [PATCH] loader/bsd: Check for NULL arg up-front + +The code in the next block suggests that it is possible for .set to be +true but .arg may still be NULL. + +This code assumes that it is never NULL, yet later is testing if it is +NULL - that is inconsistent. + +So we should check first if .arg is not NULL, and remove this check that +is being flagged by Coverity since it is no longer required. + +Fixes: CID 292471 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/loader/i386/bsd.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c +index dc62800df45..220fcb93033 100644 +--- a/grub-core/loader/i386/bsd.c ++++ b/grub-core/loader/i386/bsd.c +@@ -1599,7 +1599,7 @@ grub_cmd_openbsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) + kernel_type = KERNEL_TYPE_OPENBSD; + bootflags = grub_bsd_parse_flags (ctxt->state, openbsd_flags); + +- if (ctxt->state[OPENBSD_ROOT_ARG].set) ++ if (ctxt->state[OPENBSD_ROOT_ARG].set && ctxt->state[OPENBSD_ROOT_ARG].arg != NULL) + { + const char *arg = ctxt->state[OPENBSD_ROOT_ARG].arg; + unsigned type, unit, part; +@@ -1616,7 +1616,7 @@ grub_cmd_openbsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) + "unknown disk type name"); + + unit = grub_strtoul (arg, (char **) &arg, 10); +- if (! (arg && *arg >= 'a' && *arg <= 'z')) ++ if (! (*arg >= 'a' && *arg <= 'z')) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "only device specifications of form " + " are supported"); diff --git a/SOURCES/0385-loader-bsd-Check-for-NULL-arg-up-front.patch b/SOURCES/0385-loader-bsd-Check-for-NULL-arg-up-front.patch deleted file mode 100644 index f38c592..0000000 --- a/SOURCES/0385-loader-bsd-Check-for-NULL-arg-up-front.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Tue, 8 Dec 2020 21:47:13 +0000 -Subject: [PATCH] loader/bsd: Check for NULL arg up-front - -The code in the next block suggests that it is possible for .set to be -true but .arg may still be NULL. - -This code assumes that it is never NULL, yet later is testing if it is -NULL - that is inconsistent. - -So we should check first if .arg is not NULL, and remove this check that -is being flagged by Coverity since it is no longer required. - -Fixes: CID 292471 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/loader/i386/bsd.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c -index dc62800df45..220fcb93033 100644 ---- a/grub-core/loader/i386/bsd.c -+++ b/grub-core/loader/i386/bsd.c -@@ -1599,7 +1599,7 @@ grub_cmd_openbsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) - kernel_type = KERNEL_TYPE_OPENBSD; - bootflags = grub_bsd_parse_flags (ctxt->state, openbsd_flags); - -- if (ctxt->state[OPENBSD_ROOT_ARG].set) -+ if (ctxt->state[OPENBSD_ROOT_ARG].set && ctxt->state[OPENBSD_ROOT_ARG].arg != NULL) - { - const char *arg = ctxt->state[OPENBSD_ROOT_ARG].arg; - unsigned type, unit, part; -@@ -1616,7 +1616,7 @@ grub_cmd_openbsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) - "unknown disk type name"); - - unit = grub_strtoul (arg, (char **) &arg, 10); -- if (! (arg && *arg >= 'a' && *arg <= 'z')) -+ if (! (*arg >= 'a' && *arg <= 'z')) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "only device specifications of form " - " are supported"); diff --git a/SOURCES/0385-loader-xnu-Free-driverkey-data-when-an-error-is-dete.patch b/SOURCES/0385-loader-xnu-Free-driverkey-data-when-an-error-is-dete.patch new file mode 100644 index 0000000..26f822c --- /dev/null +++ b/SOURCES/0385-loader-xnu-Free-driverkey-data-when-an-error-is-dete.patch @@ -0,0 +1,74 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Marco A Benatto +Date: Mon, 30 Nov 2020 12:18:24 -0300 +Subject: [PATCH] loader/xnu: Free driverkey data when an error is detected in + grub_xnu_writetree_toheap() + +... to avoid memory leaks. + +Fixes: CID 96640 + +Signed-off-by: Marco A Benatto +Reviewed-by: Daniel Kiper +--- + grub-core/loader/xnu.c | 24 ++++++++++++++++++++---- + 1 file changed, 20 insertions(+), 4 deletions(-) + +diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c +index 14e0d65cd27..f7f3a9d45c8 100644 +--- a/grub-core/loader/xnu.c ++++ b/grub-core/loader/xnu.c +@@ -227,26 +227,33 @@ grub_xnu_writetree_toheap (grub_addr_t *target, grub_size_t *size) + if (! memorymap) + return grub_errno; + +- driverkey = (struct grub_xnu_devtree_key *) grub_malloc (sizeof (*driverkey)); ++ driverkey = (struct grub_xnu_devtree_key *) grub_zalloc (sizeof (*driverkey)); + if (! driverkey) + return grub_errno; + driverkey->name = grub_strdup ("DeviceTree"); + if (! driverkey->name) +- return grub_errno; ++ { ++ err = grub_errno; ++ goto fail; ++ } ++ + driverkey->datasize = sizeof (*extdesc); + driverkey->next = memorymap->first_child; + memorymap->first_child = driverkey; + driverkey->data = extdesc + = (struct grub_xnu_extdesc *) grub_malloc (sizeof (*extdesc)); + if (! driverkey->data) +- return grub_errno; ++ { ++ err = grub_errno; ++ goto fail; ++ } + + /* Allocate the space based on the size with dummy value. */ + *size = grub_xnu_writetree_get_size (grub_xnu_devtree_root, "/"); + err = grub_xnu_heap_malloc (ALIGN_UP (*size + 1, GRUB_XNU_PAGESIZE), + &src, target); + if (err) +- return err; ++ goto fail; + + /* Put real data in the dummy. */ + extdesc->addr = *target; +@@ -255,6 +262,15 @@ grub_xnu_writetree_toheap (grub_addr_t *target, grub_size_t *size) + /* Write the tree to heap. */ + grub_xnu_writetree_toheap_real (src, grub_xnu_devtree_root, "/"); + return GRUB_ERR_NONE; ++ ++ fail: ++ memorymap->first_child = NULL; ++ ++ grub_free (driverkey->data); ++ grub_free (driverkey->name); ++ grub_free (driverkey); ++ ++ return err; + } + + /* Find a key or value in parent key. */ diff --git a/SOURCES/0386-loader-xnu-Check-if-pointer-is-NULL-before-using-it.patch b/SOURCES/0386-loader-xnu-Check-if-pointer-is-NULL-before-using-it.patch new file mode 100644 index 0000000..abbcea7 --- /dev/null +++ b/SOURCES/0386-loader-xnu-Check-if-pointer-is-NULL-before-using-it.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paulo Flabiano Smorigo +Date: Mon, 30 Nov 2020 10:36:00 -0300 +Subject: [PATCH] loader/xnu: Check if pointer is NULL before using it + +Fixes: CID 73654 + +Signed-off-by: Paulo Flabiano Smorigo +Reviewed-by: Daniel Kiper +--- + grub-core/loader/xnu.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c +index f7f3a9d45c8..804a097907f 100644 +--- a/grub-core/loader/xnu.c ++++ b/grub-core/loader/xnu.c +@@ -662,6 +662,9 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile, + char *name, *nameend; + int namelen; + ++ if (infoplistname == NULL) ++ return grub_error (GRUB_ERR_BAD_FILENAME, N_("missing p-list filename")); ++ + name = get_name_ptr (infoplistname); + nameend = grub_strchr (name, '/'); + +@@ -693,10 +696,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile, + else + macho = 0; + +- if (infoplistname) +- infoplist = grub_file_open (infoplistname); +- else +- infoplist = 0; ++ infoplist = grub_file_open (infoplistname); + grub_errno = GRUB_ERR_NONE; + if (infoplist) + { diff --git a/SOURCES/0386-loader-xnu-Free-driverkey-data-when-an-error-is-dete.patch b/SOURCES/0386-loader-xnu-Free-driverkey-data-when-an-error-is-dete.patch deleted file mode 100644 index 26f822c..0000000 --- a/SOURCES/0386-loader-xnu-Free-driverkey-data-when-an-error-is-dete.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Marco A Benatto -Date: Mon, 30 Nov 2020 12:18:24 -0300 -Subject: [PATCH] loader/xnu: Free driverkey data when an error is detected in - grub_xnu_writetree_toheap() - -... to avoid memory leaks. - -Fixes: CID 96640 - -Signed-off-by: Marco A Benatto -Reviewed-by: Daniel Kiper ---- - grub-core/loader/xnu.c | 24 ++++++++++++++++++++---- - 1 file changed, 20 insertions(+), 4 deletions(-) - -diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c -index 14e0d65cd27..f7f3a9d45c8 100644 ---- a/grub-core/loader/xnu.c -+++ b/grub-core/loader/xnu.c -@@ -227,26 +227,33 @@ grub_xnu_writetree_toheap (grub_addr_t *target, grub_size_t *size) - if (! memorymap) - return grub_errno; - -- driverkey = (struct grub_xnu_devtree_key *) grub_malloc (sizeof (*driverkey)); -+ driverkey = (struct grub_xnu_devtree_key *) grub_zalloc (sizeof (*driverkey)); - if (! driverkey) - return grub_errno; - driverkey->name = grub_strdup ("DeviceTree"); - if (! driverkey->name) -- return grub_errno; -+ { -+ err = grub_errno; -+ goto fail; -+ } -+ - driverkey->datasize = sizeof (*extdesc); - driverkey->next = memorymap->first_child; - memorymap->first_child = driverkey; - driverkey->data = extdesc - = (struct grub_xnu_extdesc *) grub_malloc (sizeof (*extdesc)); - if (! driverkey->data) -- return grub_errno; -+ { -+ err = grub_errno; -+ goto fail; -+ } - - /* Allocate the space based on the size with dummy value. */ - *size = grub_xnu_writetree_get_size (grub_xnu_devtree_root, "/"); - err = grub_xnu_heap_malloc (ALIGN_UP (*size + 1, GRUB_XNU_PAGESIZE), - &src, target); - if (err) -- return err; -+ goto fail; - - /* Put real data in the dummy. */ - extdesc->addr = *target; -@@ -255,6 +262,15 @@ grub_xnu_writetree_toheap (grub_addr_t *target, grub_size_t *size) - /* Write the tree to heap. */ - grub_xnu_writetree_toheap_real (src, grub_xnu_devtree_root, "/"); - return GRUB_ERR_NONE; -+ -+ fail: -+ memorymap->first_child = NULL; -+ -+ grub_free (driverkey->data); -+ grub_free (driverkey->name); -+ grub_free (driverkey); -+ -+ return err; - } - - /* Find a key or value in parent key. */ diff --git a/SOURCES/0387-loader-xnu-Check-if-pointer-is-NULL-before-using-it.patch b/SOURCES/0387-loader-xnu-Check-if-pointer-is-NULL-before-using-it.patch deleted file mode 100644 index abbcea7..0000000 --- a/SOURCES/0387-loader-xnu-Check-if-pointer-is-NULL-before-using-it.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Mon, 30 Nov 2020 10:36:00 -0300 -Subject: [PATCH] loader/xnu: Check if pointer is NULL before using it - -Fixes: CID 73654 - -Signed-off-by: Paulo Flabiano Smorigo -Reviewed-by: Daniel Kiper ---- - grub-core/loader/xnu.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c -index f7f3a9d45c8..804a097907f 100644 ---- a/grub-core/loader/xnu.c -+++ b/grub-core/loader/xnu.c -@@ -662,6 +662,9 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile, - char *name, *nameend; - int namelen; - -+ if (infoplistname == NULL) -+ return grub_error (GRUB_ERR_BAD_FILENAME, N_("missing p-list filename")); -+ - name = get_name_ptr (infoplistname); - nameend = grub_strchr (name, '/'); - -@@ -693,10 +696,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile, - else - macho = 0; - -- if (infoplistname) -- infoplist = grub_file_open (infoplistname); -- else -- infoplist = 0; -+ infoplist = grub_file_open (infoplistname); - grub_errno = GRUB_ERR_NONE; - if (infoplist) - { diff --git a/SOURCES/0387-util-grub-editenv-Fix-incorrect-casting-of-a-signed-.patch b/SOURCES/0387-util-grub-editenv-Fix-incorrect-casting-of-a-signed-.patch new file mode 100644 index 0000000..d351038 --- /dev/null +++ b/SOURCES/0387-util-grub-editenv-Fix-incorrect-casting-of-a-signed-.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Thu, 5 Nov 2020 14:33:50 +0000 +Subject: [PATCH] util/grub-editenv: Fix incorrect casting of a signed value + +The return value of ftell() may be negative (-1) on error. While it is +probably unlikely to occur, we should not blindly cast to an unsigned +value without first testing that it is not negative. + +Fixes: CID 73856 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + util/grub-editenv.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/util/grub-editenv.c b/util/grub-editenv.c +index 118e89fe57f..9fff221b181 100644 +--- a/util/grub-editenv.c ++++ b/util/grub-editenv.c +@@ -125,6 +125,7 @@ open_envblk_file (const char *name) + { + FILE *fp; + char *buf; ++ long loc; + size_t size; + grub_envblk_t envblk; + +@@ -143,7 +144,12 @@ open_envblk_file (const char *name) + grub_util_error (_("cannot seek `%s': %s"), name, + strerror (errno)); + +- size = (size_t) ftell (fp); ++ loc = ftell (fp); ++ if (loc < 0) ++ grub_util_error (_("cannot get file location `%s': %s"), name, ++ strerror (errno)); ++ ++ size = (size_t) loc; + + if (fseek (fp, 0, SEEK_SET) < 0) + grub_util_error (_("cannot seek `%s': %s"), name, diff --git a/SOURCES/0388-util-glue-efi-Fix-incorrect-use-of-a-possibly-negati.patch b/SOURCES/0388-util-glue-efi-Fix-incorrect-use-of-a-possibly-negati.patch new file mode 100644 index 0000000..ad3a0d6 --- /dev/null +++ b/SOURCES/0388-util-glue-efi-Fix-incorrect-use-of-a-possibly-negati.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darren Kenny +Date: Fri, 4 Dec 2020 15:04:28 +0000 +Subject: [PATCH] util/glue-efi: Fix incorrect use of a possibly negative value + +It is possible for the ftell() function to return a negative value, +although it is fairly unlikely here, we should be checking for +a negative value before we assign it to an unsigned value. + +Fixes: CID 73744 + +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + util/glue-efi.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/util/glue-efi.c b/util/glue-efi.c +index 68f53168b58..de0fa6d33d5 100644 +--- a/util/glue-efi.c ++++ b/util/glue-efi.c +@@ -39,13 +39,23 @@ write_fat (FILE *in32, FILE *in64, FILE *out, const char *out_filename, + struct grub_macho_fat_header head; + struct grub_macho_fat_arch arch32, arch64; + grub_uint32_t size32, size64; ++ long size; + char *buf; + + fseek (in32, 0, SEEK_END); +- size32 = ftell (in32); ++ size = ftell (in32); ++ if (size < 0) ++ grub_util_error ("cannot get end of input file '%s': %s", ++ name32, strerror (errno)); ++ size32 = (grub_uint32_t) size; + fseek (in32, 0, SEEK_SET); ++ + fseek (in64, 0, SEEK_END); +- size64 = ftell (in64); ++ size = ftell (in64); ++ if (size < 0) ++ grub_util_error ("cannot get end of input file '%s': %s", ++ name64, strerror (errno)); ++ size64 = (grub_uint64_t) size; + fseek (in64, 0, SEEK_SET); + + head.magic = grub_cpu_to_le32_compile_time (GRUB_MACHO_FAT_EFI_MAGIC); diff --git a/SOURCES/0388-util-grub-editenv-Fix-incorrect-casting-of-a-signed-.patch b/SOURCES/0388-util-grub-editenv-Fix-incorrect-casting-of-a-signed-.patch deleted file mode 100644 index d351038..0000000 --- a/SOURCES/0388-util-grub-editenv-Fix-incorrect-casting-of-a-signed-.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Thu, 5 Nov 2020 14:33:50 +0000 -Subject: [PATCH] util/grub-editenv: Fix incorrect casting of a signed value - -The return value of ftell() may be negative (-1) on error. While it is -probably unlikely to occur, we should not blindly cast to an unsigned -value without first testing that it is not negative. - -Fixes: CID 73856 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - util/grub-editenv.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/util/grub-editenv.c b/util/grub-editenv.c -index 118e89fe57f..9fff221b181 100644 ---- a/util/grub-editenv.c -+++ b/util/grub-editenv.c -@@ -125,6 +125,7 @@ open_envblk_file (const char *name) - { - FILE *fp; - char *buf; -+ long loc; - size_t size; - grub_envblk_t envblk; - -@@ -143,7 +144,12 @@ open_envblk_file (const char *name) - grub_util_error (_("cannot seek `%s': %s"), name, - strerror (errno)); - -- size = (size_t) ftell (fp); -+ loc = ftell (fp); -+ if (loc < 0) -+ grub_util_error (_("cannot get file location `%s': %s"), name, -+ strerror (errno)); -+ -+ size = (size_t) loc; - - if (fseek (fp, 0, SEEK_SET) < 0) - grub_util_error (_("cannot seek `%s': %s"), name, diff --git a/SOURCES/0389-script-execute-Fix-NULL-dereference-in-grub_script_e.patch b/SOURCES/0389-script-execute-Fix-NULL-dereference-in-grub_script_e.patch new file mode 100644 index 0000000..a9642fa --- /dev/null +++ b/SOURCES/0389-script-execute-Fix-NULL-dereference-in-grub_script_e.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Fri, 3 Apr 2020 23:05:13 +1100 +Subject: [PATCH] script/execute: Fix NULL dereference in + grub_script_execute_cmdline() + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/script/execute.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c +index 52ccbd9965b..04ffb9b4740 100644 +--- a/grub-core/script/execute.c ++++ b/grub-core/script/execute.c +@@ -960,7 +960,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) + struct grub_script_argv argv = { 0, 0, 0 }; + + /* Lookup the command. */ +- if (grub_script_arglist_to_argv (cmdline->arglist, &argv) || ! argv.args[0]) ++ if (grub_script_arglist_to_argv (cmdline->arglist, &argv) || ! argv.args || ! argv.args[0]) + return grub_errno; + + invert = 0; diff --git a/SOURCES/0389-util-glue-efi-Fix-incorrect-use-of-a-possibly-negati.patch b/SOURCES/0389-util-glue-efi-Fix-incorrect-use-of-a-possibly-negati.patch deleted file mode 100644 index ad3a0d6..0000000 --- a/SOURCES/0389-util-glue-efi-Fix-incorrect-use-of-a-possibly-negati.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Fri, 4 Dec 2020 15:04:28 +0000 -Subject: [PATCH] util/glue-efi: Fix incorrect use of a possibly negative value - -It is possible for the ftell() function to return a negative value, -although it is fairly unlikely here, we should be checking for -a negative value before we assign it to an unsigned value. - -Fixes: CID 73744 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - util/glue-efi.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/util/glue-efi.c b/util/glue-efi.c -index 68f53168b58..de0fa6d33d5 100644 ---- a/util/glue-efi.c -+++ b/util/glue-efi.c -@@ -39,13 +39,23 @@ write_fat (FILE *in32, FILE *in64, FILE *out, const char *out_filename, - struct grub_macho_fat_header head; - struct grub_macho_fat_arch arch32, arch64; - grub_uint32_t size32, size64; -+ long size; - char *buf; - - fseek (in32, 0, SEEK_END); -- size32 = ftell (in32); -+ size = ftell (in32); -+ if (size < 0) -+ grub_util_error ("cannot get end of input file '%s': %s", -+ name32, strerror (errno)); -+ size32 = (grub_uint32_t) size; - fseek (in32, 0, SEEK_SET); -+ - fseek (in64, 0, SEEK_END); -- size64 = ftell (in64); -+ size = ftell (in64); -+ if (size < 0) -+ grub_util_error ("cannot get end of input file '%s': %s", -+ name64, strerror (errno)); -+ size64 = (grub_uint64_t) size; - fseek (in64, 0, SEEK_SET); - - head.magic = grub_cpu_to_le32_compile_time (GRUB_MACHO_FAT_EFI_MAGIC); diff --git a/SOURCES/0390-commands-ls-Require-device_name-is-not-NULL-before-p.patch b/SOURCES/0390-commands-ls-Require-device_name-is-not-NULL-before-p.patch new file mode 100644 index 0000000..011ee6d --- /dev/null +++ b/SOURCES/0390-commands-ls-Require-device_name-is-not-NULL-before-p.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Mon, 11 Jan 2021 16:57:37 +1100 +Subject: [PATCH] commands/ls: Require device_name is not NULL before printing + +This can be triggered with: + ls -l (0 0*) +and causes a NULL deref in grub_normal_print_device_info(). + +I'm not sure if there's any implication with the IEEE 1275 platform. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/commands/ls.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c +index 0eaf8365279..7df04565561 100644 +--- a/grub-core/commands/ls.c ++++ b/grub-core/commands/ls.c +@@ -196,7 +196,7 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human) + goto fail; + } + +- if (! *path) ++ if (! *path && device_name) + { + if (grub_errno == GRUB_ERR_UNKNOWN_FS) + grub_errno = GRUB_ERR_NONE; diff --git a/SOURCES/0390-script-execute-Fix-NULL-dereference-in-grub_script_e.patch b/SOURCES/0390-script-execute-Fix-NULL-dereference-in-grub_script_e.patch deleted file mode 100644 index a9642fa..0000000 --- a/SOURCES/0390-script-execute-Fix-NULL-dereference-in-grub_script_e.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 3 Apr 2020 23:05:13 +1100 -Subject: [PATCH] script/execute: Fix NULL dereference in - grub_script_execute_cmdline() - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/script/execute.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c -index 52ccbd9965b..04ffb9b4740 100644 ---- a/grub-core/script/execute.c -+++ b/grub-core/script/execute.c -@@ -960,7 +960,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) - struct grub_script_argv argv = { 0, 0, 0 }; - - /* Lookup the command. */ -- if (grub_script_arglist_to_argv (cmdline->arglist, &argv) || ! argv.args[0]) -+ if (grub_script_arglist_to_argv (cmdline->arglist, &argv) || ! argv.args || ! argv.args[0]) - return grub_errno; - - invert = 0; diff --git a/SOURCES/0391-commands-ls-Require-device_name-is-not-NULL-before-p.patch b/SOURCES/0391-commands-ls-Require-device_name-is-not-NULL-before-p.patch deleted file mode 100644 index 011ee6d..0000000 --- a/SOURCES/0391-commands-ls-Require-device_name-is-not-NULL-before-p.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 11 Jan 2021 16:57:37 +1100 -Subject: [PATCH] commands/ls: Require device_name is not NULL before printing - -This can be triggered with: - ls -l (0 0*) -and causes a NULL deref in grub_normal_print_device_info(). - -I'm not sure if there's any implication with the IEEE 1275 platform. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/commands/ls.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c -index 0eaf8365279..7df04565561 100644 ---- a/grub-core/commands/ls.c -+++ b/grub-core/commands/ls.c -@@ -196,7 +196,7 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human) - goto fail; - } - -- if (! *path) -+ if (! *path && device_name) - { - if (grub_errno == GRUB_ERR_UNKNOWN_FS) - grub_errno = GRUB_ERR_NONE; diff --git a/SOURCES/0391-script-execute-Avoid-crash-when-using-outside-a-func.patch b/SOURCES/0391-script-execute-Avoid-crash-when-using-outside-a-func.patch new file mode 100644 index 0000000..7b77dc9 --- /dev/null +++ b/SOURCES/0391-script-execute-Avoid-crash-when-using-outside-a-func.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Mon, 11 Jan 2021 17:30:42 +1100 +Subject: [PATCH] script/execute: Avoid crash when using "$#" outside a + function scope + +"$#" represents the number of arguments to a function. It is only +defined in a function scope, where "scope" is non-NULL. Currently, +if we attempt to evaluate "$#" outside a function scope, "scope" will +be NULL and we will crash with a NULL pointer dereference. + +Do not attempt to count arguments for "$#" if "scope" is NULL. This +will result in "$#" being interpreted as an empty string if evaluated +outside a function scope. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/script/execute.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c +index 04ffb9b4740..7c43f88ac51 100644 +--- a/grub-core/script/execute.c ++++ b/grub-core/script/execute.c +@@ -518,7 +518,7 @@ gettext_putvar (const char *str, grub_size_t len, + return 0; + + /* Enough for any number. */ +- if (len == 1 && str[0] == '#') ++ if (len == 1 && str[0] == '#' && scope != NULL) + { + grub_snprintf (*ptr, 30, "%u", scope->argv.argc); + *ptr += grub_strlen (*ptr); diff --git a/SOURCES/0392-lib-arg-Block-repeated-short-options-that-require-an.patch b/SOURCES/0392-lib-arg-Block-repeated-short-options-that-require-an.patch new file mode 100644 index 0000000..63cf2af --- /dev/null +++ b/SOURCES/0392-lib-arg-Block-repeated-short-options-that-require-an.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Fri, 22 Jan 2021 16:07:29 +1100 +Subject: [PATCH] lib/arg: Block repeated short options that require an + argument + +Fuzzing found the following crash: + + search -hhhhhhhhhhhhhf + +We didn't allocate enough option space for 13 hints because the +allocation code counts the number of discrete arguments (i.e. argc). +However, the shortopt parsing code will happily keep processing +a combination of short options without checking if those short +options require an argument. This means you can easily end writing +past the allocated option space. + +This fixes a OOB write which can cause heap corruption. + +Fixes: CVE-2021-20225 + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/lib/arg.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c +index 3288609a5e1..537c5e94b83 100644 +--- a/grub-core/lib/arg.c ++++ b/grub-core/lib/arg.c +@@ -299,6 +299,19 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv, + it can have an argument value. */ + if (*curshort) + { ++ /* ++ * Only permit further short opts if this one doesn't ++ * require a value. ++ */ ++ if (opt->type != ARG_TYPE_NONE && ++ !(opt->flags & GRUB_ARG_OPTION_OPTIONAL)) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("missing mandatory option for `%s'"), ++ opt->longarg); ++ goto fail; ++ } ++ + if (parse_option (cmd, opt, 0, usr) || grub_errno) + goto fail; + } diff --git a/SOURCES/0392-script-execute-Avoid-crash-when-using-outside-a-func.patch b/SOURCES/0392-script-execute-Avoid-crash-when-using-outside-a-func.patch deleted file mode 100644 index 7b77dc9..0000000 --- a/SOURCES/0392-script-execute-Avoid-crash-when-using-outside-a-func.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 11 Jan 2021 17:30:42 +1100 -Subject: [PATCH] script/execute: Avoid crash when using "$#" outside a - function scope - -"$#" represents the number of arguments to a function. It is only -defined in a function scope, where "scope" is non-NULL. Currently, -if we attempt to evaluate "$#" outside a function scope, "scope" will -be NULL and we will crash with a NULL pointer dereference. - -Do not attempt to count arguments for "$#" if "scope" is NULL. This -will result in "$#" being interpreted as an empty string if evaluated -outside a function scope. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/script/execute.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c -index 04ffb9b4740..7c43f88ac51 100644 ---- a/grub-core/script/execute.c -+++ b/grub-core/script/execute.c -@@ -518,7 +518,7 @@ gettext_putvar (const char *str, grub_size_t len, - return 0; - - /* Enough for any number. */ -- if (len == 1 && str[0] == '#') -+ if (len == 1 && str[0] == '#' && scope != NULL) - { - grub_snprintf (*ptr, 30, "%u", scope->argv.argc); - *ptr += grub_strlen (*ptr); diff --git a/SOURCES/0393-lib-arg-Block-repeated-short-options-that-require-an.patch b/SOURCES/0393-lib-arg-Block-repeated-short-options-that-require-an.patch deleted file mode 100644 index 63cf2af..0000000 --- a/SOURCES/0393-lib-arg-Block-repeated-short-options-that-require-an.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 22 Jan 2021 16:07:29 +1100 -Subject: [PATCH] lib/arg: Block repeated short options that require an - argument - -Fuzzing found the following crash: - - search -hhhhhhhhhhhhhf - -We didn't allocate enough option space for 13 hints because the -allocation code counts the number of discrete arguments (i.e. argc). -However, the shortopt parsing code will happily keep processing -a combination of short options without checking if those short -options require an argument. This means you can easily end writing -past the allocated option space. - -This fixes a OOB write which can cause heap corruption. - -Fixes: CVE-2021-20225 - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/lib/arg.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c -index 3288609a5e1..537c5e94b83 100644 ---- a/grub-core/lib/arg.c -+++ b/grub-core/lib/arg.c -@@ -299,6 +299,19 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv, - it can have an argument value. */ - if (*curshort) - { -+ /* -+ * Only permit further short opts if this one doesn't -+ * require a value. -+ */ -+ if (opt->type != ARG_TYPE_NONE && -+ !(opt->flags & GRUB_ARG_OPTION_OPTIONAL)) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("missing mandatory option for `%s'"), -+ opt->longarg); -+ goto fail; -+ } -+ - if (parse_option (cmd, opt, 0, usr) || grub_errno) - goto fail; - } diff --git a/SOURCES/0393-script-execute-Don-t-crash-on-a-for-loop-with-no-ite.patch b/SOURCES/0393-script-execute-Don-t-crash-on-a-for-loop-with-no-ite.patch new file mode 100644 index 0000000..b7064c7 --- /dev/null +++ b/SOURCES/0393-script-execute-Don-t-crash-on-a-for-loop-with-no-ite.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Fri, 22 Jan 2021 16:18:26 +1100 +Subject: [PATCH] script/execute: Don't crash on a "for" loop with no items + +The following crashes the parser: + + for x in; do + 0 + done + +This is because grub_script_arglist_to_argv() doesn't consider the +possibility that arglist is NULL. Catch that explicitly. + +This avoids a NULL pointer dereference. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/script/execute.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c +index 7c43f88ac51..fa20d32278d 100644 +--- a/grub-core/script/execute.c ++++ b/grub-core/script/execute.c +@@ -657,6 +657,9 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, + struct grub_script_arg *arg = 0; + struct grub_script_argv result = { 0, 0, 0 }; + ++ if (arglist == NULL) ++ return 1; ++ + for (; arglist && arglist->arg; arglist = arglist->next) + { + if (grub_script_argv_next (&result)) diff --git a/SOURCES/0394-commands-menuentry-Fix-quoting-in-setparams_prefix.patch b/SOURCES/0394-commands-menuentry-Fix-quoting-in-setparams_prefix.patch new file mode 100644 index 0000000..45f6fb3 --- /dev/null +++ b/SOURCES/0394-commands-menuentry-Fix-quoting-in-setparams_prefix.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Fri, 22 Jan 2021 17:10:48 +1100 +Subject: [PATCH] commands/menuentry: Fix quoting in setparams_prefix() + +Commit 9acdcbf32542 (use single quotes in menuentry setparams command) +says that expressing a quoted single quote will require 3 characters. It +actually requires (and always did require!) 4 characters: + + str: a'b => a'\''b + len: 3 => 6 (2 for the letters + 4 for the quote) + +This leads to not allocating enough memory and thus out of bounds writes +that have been observed to cause heap corruption. + +Allocate 4 bytes for each single quote. + +Commit 22e7dbb2bb81 (Fix quoting in legacy parser.) does the same +quoting, but it adds 3 as extra overhead on top of the single byte that +the quote already needs. So it's correct. + +Fixes: CVE-2021-20233 +Fixes: 9acdcbf32542 (use single quotes in menuentry setparams command) + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/commands/menuentry.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c +index 16c52ed00e8..4ad524afbc3 100644 +--- a/grub-core/commands/menuentry.c ++++ b/grub-core/commands/menuentry.c +@@ -230,7 +230,7 @@ setparams_prefix (int argc, char **args) + len += 3; /* 3 = 1 space + 2 quotes */ + p = args[i]; + while (*p) +- len += (*p++ == '\'' ? 3 : 1); ++ len += (*p++ == '\'' ? 4 : 1); + } + + result = grub_malloc (len + 2); diff --git a/SOURCES/0394-script-execute-Don-t-crash-on-a-for-loop-with-no-ite.patch b/SOURCES/0394-script-execute-Don-t-crash-on-a-for-loop-with-no-ite.patch deleted file mode 100644 index b7064c7..0000000 --- a/SOURCES/0394-script-execute-Don-t-crash-on-a-for-loop-with-no-ite.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 22 Jan 2021 16:18:26 +1100 -Subject: [PATCH] script/execute: Don't crash on a "for" loop with no items - -The following crashes the parser: - - for x in; do - 0 - done - -This is because grub_script_arglist_to_argv() doesn't consider the -possibility that arglist is NULL. Catch that explicitly. - -This avoids a NULL pointer dereference. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/script/execute.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c -index 7c43f88ac51..fa20d32278d 100644 ---- a/grub-core/script/execute.c -+++ b/grub-core/script/execute.c -@@ -657,6 +657,9 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, - struct grub_script_arg *arg = 0; - struct grub_script_argv result = { 0, 0, 0 }; - -+ if (arglist == NULL) -+ return 1; -+ - for (; arglist && arglist->arg; arglist = arglist->next) - { - if (grub_script_argv_next (&result)) diff --git a/SOURCES/0395-commands-menuentry-Fix-quoting-in-setparams_prefix.patch b/SOURCES/0395-commands-menuentry-Fix-quoting-in-setparams_prefix.patch deleted file mode 100644 index 45f6fb3..0000000 --- a/SOURCES/0395-commands-menuentry-Fix-quoting-in-setparams_prefix.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 22 Jan 2021 17:10:48 +1100 -Subject: [PATCH] commands/menuentry: Fix quoting in setparams_prefix() - -Commit 9acdcbf32542 (use single quotes in menuentry setparams command) -says that expressing a quoted single quote will require 3 characters. It -actually requires (and always did require!) 4 characters: - - str: a'b => a'\''b - len: 3 => 6 (2 for the letters + 4 for the quote) - -This leads to not allocating enough memory and thus out of bounds writes -that have been observed to cause heap corruption. - -Allocate 4 bytes for each single quote. - -Commit 22e7dbb2bb81 (Fix quoting in legacy parser.) does the same -quoting, but it adds 3 as extra overhead on top of the single byte that -the quote already needs. So it's correct. - -Fixes: CVE-2021-20233 -Fixes: 9acdcbf32542 (use single quotes in menuentry setparams command) - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/commands/menuentry.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c -index 16c52ed00e8..4ad524afbc3 100644 ---- a/grub-core/commands/menuentry.c -+++ b/grub-core/commands/menuentry.c -@@ -230,7 +230,7 @@ setparams_prefix (int argc, char **args) - len += 3; /* 3 = 1 space + 2 quotes */ - p = args[i]; - while (*p) -- len += (*p++ == '\'' ? 3 : 1); -+ len += (*p++ == '\'' ? 4 : 1); - } - - result = grub_malloc (len + 2); diff --git a/SOURCES/0395-kern-misc-Always-set-end-in-grub_strtoull.patch b/SOURCES/0395-kern-misc-Always-set-end-in-grub_strtoull.patch new file mode 100644 index 0000000..cbbdb01 --- /dev/null +++ b/SOURCES/0395-kern-misc-Always-set-end-in-grub_strtoull.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Wed, 13 Jan 2021 22:19:01 +1100 +Subject: [PATCH] kern/misc: Always set *end in grub_strtoull() + +Currently, if there is an error in grub_strtoull(), *end is not set. +This differs from the usual behavior of strtoull(), and also means that +some callers may use an uninitialized value for *end. + +Set *end unconditionally. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/kern/misc.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c +index 8b4a78b35be..bd43b0f5f61 100644 +--- a/grub-core/kern/misc.c ++++ b/grub-core/kern/misc.c +@@ -451,6 +451,10 @@ grub_strtoull (const char *str, char **end, int base) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("overflow is detected")); ++ ++ if (end) ++ *end = (char *) str; ++ + return ~0ULL; + } + +@@ -462,6 +466,10 @@ grub_strtoull (const char *str, char **end, int base) + { + grub_error (GRUB_ERR_BAD_NUMBER, + N_("unrecognized number")); ++ ++ if (end) ++ *end = (char *) str; ++ + return 0; + } + diff --git a/SOURCES/0396-kern-misc-Always-set-end-in-grub_strtoull.patch b/SOURCES/0396-kern-misc-Always-set-end-in-grub_strtoull.patch deleted file mode 100644 index cbbdb01..0000000 --- a/SOURCES/0396-kern-misc-Always-set-end-in-grub_strtoull.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Wed, 13 Jan 2021 22:19:01 +1100 -Subject: [PATCH] kern/misc: Always set *end in grub_strtoull() - -Currently, if there is an error in grub_strtoull(), *end is not set. -This differs from the usual behavior of strtoull(), and also means that -some callers may use an uninitialized value for *end. - -Set *end unconditionally. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/kern/misc.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index 8b4a78b35be..bd43b0f5f61 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -451,6 +451,10 @@ grub_strtoull (const char *str, char **end, int base) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("overflow is detected")); -+ -+ if (end) -+ *end = (char *) str; -+ - return ~0ULL; - } - -@@ -462,6 +466,10 @@ grub_strtoull (const char *str, char **end, int base) - { - grub_error (GRUB_ERR_BAD_NUMBER, - N_("unrecognized number")); -+ -+ if (end) -+ *end = (char *) str; -+ - return 0; - } - diff --git a/SOURCES/0396-video-readers-jpeg-Catch-files-with-unsupported-quan.patch b/SOURCES/0396-video-readers-jpeg-Catch-files-with-unsupported-quan.patch new file mode 100644 index 0000000..9aaae14 --- /dev/null +++ b/SOURCES/0396-video-readers-jpeg-Catch-files-with-unsupported-quan.patch @@ -0,0 +1,49 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Fri, 15 Jan 2021 12:57:04 +1100 +Subject: [PATCH] video/readers/jpeg: Catch files with unsupported quantization + or Huffman tables + +Our decoder only supports 2 quantization tables. If a file asks for +a quantization table with index > 1, reject it. + +Similarly, our decoder only supports 4 Huffman tables. If a file asks +for a Huffman table with index > 3, reject it. + +This fixes some out of bounds reads. It's not clear what degree of control +over subsequent execution could be gained by someone who can carefully +set up the contents of memory before loading an invalid JPEG file. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/video/readers/jpeg.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c +index ed6d9bfd160..5d3fa4de37d 100644 +--- a/grub-core/video/readers/jpeg.c ++++ b/grub-core/video/readers/jpeg.c +@@ -330,7 +330,11 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data) + else if (ss != JPEG_SAMPLING_1x1) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: sampling method not supported"); ++ + data->comp_index[id][0] = grub_jpeg_get_byte (data); ++ if (data->comp_index[id][0] > 1) ++ return grub_error (GRUB_ERR_BAD_FILE_TYPE, ++ "jpeg: too many quantization tables"); + } + + if (data->file->offset != next_marker) +@@ -599,6 +603,10 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data) + ht = grub_jpeg_get_byte (data); + data->comp_index[id][1] = (ht >> 4); + data->comp_index[id][2] = (ht & 0xF) + 2; ++ ++ 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"); + } + + grub_jpeg_get_byte (data); /* Skip 3 unused bytes. */ diff --git a/SOURCES/0397-video-readers-jpeg-Catch-OOB-reads-writes-in-grub_jp.patch b/SOURCES/0397-video-readers-jpeg-Catch-OOB-reads-writes-in-grub_jp.patch new file mode 100644 index 0000000..d035c95 --- /dev/null +++ b/SOURCES/0397-video-readers-jpeg-Catch-OOB-reads-writes-in-grub_jp.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Fri, 15 Jan 2021 13:29:53 +1100 +Subject: [PATCH] video/readers/jpeg: Catch OOB reads/writes in + grub_jpeg_decode_du() + +The key line is: + + du[jpeg_zigzag_order[pos]] = val * (int) data->quan_table[qt][pos]; + +jpeg_zigzag_order is grub_uint8_t[64]. + +I don't understand JPEG decoders quite well enough to explain what's +going on here. However, I observe sometimes pos=64, which leads to an +OOB read of the jpeg_zigzag_order global then an OOB write to du. +That leads to various unpleasant memory corruption conditions. + +Catch where pos >= ARRAY_SIZE(jpeg_zigzag_order) and bail. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/video/readers/jpeg.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c +index 5d3fa4de37d..2cbbb467ebb 100644 +--- a/grub-core/video/readers/jpeg.c ++++ b/grub-core/video/readers/jpeg.c +@@ -523,6 +523,14 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du) + val = grub_jpeg_get_number (data, num & 0xF); + num >>= 4; + pos += num; ++ ++ if (pos >= ARRAY_SIZE (jpeg_zigzag_order)) ++ { ++ grub_error (GRUB_ERR_BAD_FILE_TYPE, ++ "jpeg: invalid position in zigzag order!?"); ++ return; ++ } ++ + du[jpeg_zigzag_order[pos]] = val * (int) data->quan_table[qt][pos]; + pos++; + } diff --git a/SOURCES/0397-video-readers-jpeg-Catch-files-with-unsupported-quan.patch b/SOURCES/0397-video-readers-jpeg-Catch-files-with-unsupported-quan.patch deleted file mode 100644 index 9aaae14..0000000 --- a/SOURCES/0397-video-readers-jpeg-Catch-files-with-unsupported-quan.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 15 Jan 2021 12:57:04 +1100 -Subject: [PATCH] video/readers/jpeg: Catch files with unsupported quantization - or Huffman tables - -Our decoder only supports 2 quantization tables. If a file asks for -a quantization table with index > 1, reject it. - -Similarly, our decoder only supports 4 Huffman tables. If a file asks -for a Huffman table with index > 3, reject it. - -This fixes some out of bounds reads. It's not clear what degree of control -over subsequent execution could be gained by someone who can carefully -set up the contents of memory before loading an invalid JPEG file. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/video/readers/jpeg.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c -index ed6d9bfd160..5d3fa4de37d 100644 ---- a/grub-core/video/readers/jpeg.c -+++ b/grub-core/video/readers/jpeg.c -@@ -330,7 +330,11 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data) - else if (ss != JPEG_SAMPLING_1x1) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "jpeg: sampling method not supported"); -+ - data->comp_index[id][0] = grub_jpeg_get_byte (data); -+ if (data->comp_index[id][0] > 1) -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "jpeg: too many quantization tables"); - } - - if (data->file->offset != next_marker) -@@ -599,6 +603,10 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data) - ht = grub_jpeg_get_byte (data); - data->comp_index[id][1] = (ht >> 4); - data->comp_index[id][2] = (ht & 0xF) + 2; -+ -+ 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"); - } - - grub_jpeg_get_byte (data); /* Skip 3 unused bytes. */ diff --git a/SOURCES/0398-video-readers-jpeg-Catch-OOB-reads-writes-in-grub_jp.patch b/SOURCES/0398-video-readers-jpeg-Catch-OOB-reads-writes-in-grub_jp.patch deleted file mode 100644 index d035c95..0000000 --- a/SOURCES/0398-video-readers-jpeg-Catch-OOB-reads-writes-in-grub_jp.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 15 Jan 2021 13:29:53 +1100 -Subject: [PATCH] video/readers/jpeg: Catch OOB reads/writes in - grub_jpeg_decode_du() - -The key line is: - - du[jpeg_zigzag_order[pos]] = val * (int) data->quan_table[qt][pos]; - -jpeg_zigzag_order is grub_uint8_t[64]. - -I don't understand JPEG decoders quite well enough to explain what's -going on here. However, I observe sometimes pos=64, which leads to an -OOB read of the jpeg_zigzag_order global then an OOB write to du. -That leads to various unpleasant memory corruption conditions. - -Catch where pos >= ARRAY_SIZE(jpeg_zigzag_order) and bail. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/video/readers/jpeg.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c -index 5d3fa4de37d..2cbbb467ebb 100644 ---- a/grub-core/video/readers/jpeg.c -+++ b/grub-core/video/readers/jpeg.c -@@ -523,6 +523,14 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du) - val = grub_jpeg_get_number (data, num & 0xF); - num >>= 4; - pos += num; -+ -+ if (pos >= ARRAY_SIZE (jpeg_zigzag_order)) -+ { -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "jpeg: invalid position in zigzag order!?"); -+ return; -+ } -+ - du[jpeg_zigzag_order[pos]] = val * (int) data->quan_table[qt][pos]; - pos++; - } diff --git a/SOURCES/0398-video-readers-jpeg-Don-t-decode-data-before-start-of.patch b/SOURCES/0398-video-readers-jpeg-Don-t-decode-data-before-start-of.patch new file mode 100644 index 0000000..a1429b8 --- /dev/null +++ b/SOURCES/0398-video-readers-jpeg-Don-t-decode-data-before-start-of.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Fri, 15 Jan 2021 14:06:46 +1100 +Subject: [PATCH] video/readers/jpeg: Don't decode data before start of stream + +When a start of stream marker is encountered, we call grub_jpeg_decode_sos() +which allocates space for a bitmap. + +When a restart marker is encountered, we call grub_jpeg_decode_data() which +then fills in that bitmap. + +If we get a restart marker before the start of stream marker, we will +attempt to write to a bitmap_ptr that hasn't been allocated. Catch this +and bail out. This fixes an attempt to write to NULL. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/video/readers/jpeg.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c +index 2cbbb467ebb..a6742a96b13 100644 +--- a/grub-core/video/readers/jpeg.c ++++ b/grub-core/video/readers/jpeg.c +@@ -643,6 +643,10 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data) + nr1 = (data->image_height + vb - 1) / vb; + nc1 = (data->image_width + hb - 1) / hb; + ++ if (data->bitmap_ptr == NULL) ++ 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) + for (c1 = 0; c1 < nc1 && (!data->dri || rst); diff --git a/SOURCES/0399-term-gfxterm-Don-t-set-up-a-font-with-glyphs-that-ar.patch b/SOURCES/0399-term-gfxterm-Don-t-set-up-a-font-with-glyphs-that-ar.patch new file mode 100644 index 0000000..3e4dd09 --- /dev/null +++ b/SOURCES/0399-term-gfxterm-Don-t-set-up-a-font-with-glyphs-that-ar.patch @@ -0,0 +1,48 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Fri, 15 Jan 2021 20:03:20 +1100 +Subject: [PATCH] term/gfxterm: Don't set up a font with glyphs that are too + big + +Catch the case where we have a font so big that it causes the number of +rows or columns to be 0. Currently we continue and allocate a +virtual_screen.text_buffer of size 0. We then try to use that for glpyhs +and things go badly. + +On the emu platform, malloc() may give us a valid pointer, in which case +we'll access heap memory which we shouldn't. Alternatively, it may give us +NULL, in which case we'll crash. For other platforms, if I understand +grub_memalign() correctly, we will receive a valid but small allocation +that we will very likely later overrun. + +Prevent the creation of a virtual screen that isn't at least 40 cols +by 12 rows. This is arbitrary, but it seems that if your width or height +is half a standard 80x24 terminal, you're probably going to struggle to +read anything anyway. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/term/gfxterm.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c +index dc0669b354d..b68cce809d5 100644 +--- a/grub-core/term/gfxterm.c ++++ b/grub-core/term/gfxterm.c +@@ -230,6 +230,15 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y, + virtual_screen.columns = virtual_screen.width / virtual_screen.normal_char_width; + virtual_screen.rows = virtual_screen.height / virtual_screen.normal_char_height; + ++ /* ++ * There must be a minimum number of rows and columns for the screen to ++ * make sense. Arbitrarily pick half of 80x24. If either dimensions is 0 ++ * we would allocate 0 bytes for the text_buffer. ++ */ ++ if (virtual_screen.columns < 40 || virtual_screen.rows < 12) ++ return grub_error (GRUB_ERR_BAD_FONT, ++ "font: glyphs too large to fit on screen"); ++ + /* Allocate memory for text buffer. */ + virtual_screen.text_buffer = + (struct grub_colored_char *) grub_malloc (virtual_screen.columns diff --git a/SOURCES/0399-video-readers-jpeg-Don-t-decode-data-before-start-of.patch b/SOURCES/0399-video-readers-jpeg-Don-t-decode-data-before-start-of.patch deleted file mode 100644 index a1429b8..0000000 --- a/SOURCES/0399-video-readers-jpeg-Don-t-decode-data-before-start-of.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 15 Jan 2021 14:06:46 +1100 -Subject: [PATCH] video/readers/jpeg: Don't decode data before start of stream - -When a start of stream marker is encountered, we call grub_jpeg_decode_sos() -which allocates space for a bitmap. - -When a restart marker is encountered, we call grub_jpeg_decode_data() which -then fills in that bitmap. - -If we get a restart marker before the start of stream marker, we will -attempt to write to a bitmap_ptr that hasn't been allocated. Catch this -and bail out. This fixes an attempt to write to NULL. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/video/readers/jpeg.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c -index 2cbbb467ebb..a6742a96b13 100644 ---- a/grub-core/video/readers/jpeg.c -+++ b/grub-core/video/readers/jpeg.c -@@ -643,6 +643,10 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data) - nr1 = (data->image_height + vb - 1) / vb; - nc1 = (data->image_width + hb - 1) / hb; - -+ if (data->bitmap_ptr == NULL) -+ 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) - for (c1 = 0; c1 < nc1 && (!data->dri || rst); diff --git a/SOURCES/0400-fs-fshelp-Catch-impermissibly-large-block-sizes-in-r.patch b/SOURCES/0400-fs-fshelp-Catch-impermissibly-large-block-sizes-in-r.patch new file mode 100644 index 0000000..c0218af --- /dev/null +++ b/SOURCES/0400-fs-fshelp-Catch-impermissibly-large-block-sizes-in-r.patch @@ -0,0 +1,50 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Mon, 18 Jan 2021 11:46:39 +1100 +Subject: [PATCH] fs/fshelp: Catch impermissibly large block sizes in read + helper + +A fuzzed HFS+ filesystem had log2blocksize = 22. This gave +log2blocksize + GRUB_DISK_SECTOR_BITS = 31. 1 << 31 = 0x80000000, +which is -1 as an int. This caused some wacky behavior later on in +the function, leading to out-of-bounds writes on the destination buffer. + +Catch log2blocksize + GRUB_DISK_SECTOR_BITS >= 31. We could be stricter, +but this is the minimum that will prevent integer size weirdness. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/fs/fshelp.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/grub-core/fs/fshelp.c b/grub-core/fs/fshelp.c +index 42bd542bbc3..7e7387e86e1 100644 +--- a/grub-core/fs/fshelp.c ++++ b/grub-core/fs/fshelp.c +@@ -252,6 +252,25 @@ grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node, + grub_disk_addr_t i, blockcnt; + int blocksize = 1 << (log2blocksize + GRUB_DISK_SECTOR_BITS); + ++ /* ++ * Catch blatantly invalid log2blocksize. We could be a lot stricter, but ++ * this is the most permissive we can be before we start to see integer ++ * overflow/underflow issues. ++ */ ++ if (log2blocksize + GRUB_DISK_SECTOR_BITS >= 31) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("blocksize too large")); ++ return -1; ++ } ++ ++ if (pos > filesize) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("attempt to read past the end of file")); ++ return -1; ++ } ++ + /* Adjust LEN so it we can't read past the end of the file. */ + if (pos + len > filesize) + len = filesize - pos; diff --git a/SOURCES/0400-term-gfxterm-Don-t-set-up-a-font-with-glyphs-that-ar.patch b/SOURCES/0400-term-gfxterm-Don-t-set-up-a-font-with-glyphs-that-ar.patch deleted file mode 100644 index 3e4dd09..0000000 --- a/SOURCES/0400-term-gfxterm-Don-t-set-up-a-font-with-glyphs-that-ar.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 15 Jan 2021 20:03:20 +1100 -Subject: [PATCH] term/gfxterm: Don't set up a font with glyphs that are too - big - -Catch the case where we have a font so big that it causes the number of -rows or columns to be 0. Currently we continue and allocate a -virtual_screen.text_buffer of size 0. We then try to use that for glpyhs -and things go badly. - -On the emu platform, malloc() may give us a valid pointer, in which case -we'll access heap memory which we shouldn't. Alternatively, it may give us -NULL, in which case we'll crash. For other platforms, if I understand -grub_memalign() correctly, we will receive a valid but small allocation -that we will very likely later overrun. - -Prevent the creation of a virtual screen that isn't at least 40 cols -by 12 rows. This is arbitrary, but it seems that if your width or height -is half a standard 80x24 terminal, you're probably going to struggle to -read anything anyway. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/term/gfxterm.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c -index dc0669b354d..b68cce809d5 100644 ---- a/grub-core/term/gfxterm.c -+++ b/grub-core/term/gfxterm.c -@@ -230,6 +230,15 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y, - virtual_screen.columns = virtual_screen.width / virtual_screen.normal_char_width; - virtual_screen.rows = virtual_screen.height / virtual_screen.normal_char_height; - -+ /* -+ * There must be a minimum number of rows and columns for the screen to -+ * make sense. Arbitrarily pick half of 80x24. If either dimensions is 0 -+ * we would allocate 0 bytes for the text_buffer. -+ */ -+ if (virtual_screen.columns < 40 || virtual_screen.rows < 12) -+ return grub_error (GRUB_ERR_BAD_FONT, -+ "font: glyphs too large to fit on screen"); -+ - /* Allocate memory for text buffer. */ - virtual_screen.text_buffer = - (struct grub_colored_char *) grub_malloc (virtual_screen.columns diff --git a/SOURCES/0401-fs-fshelp-Catch-impermissibly-large-block-sizes-in-r.patch b/SOURCES/0401-fs-fshelp-Catch-impermissibly-large-block-sizes-in-r.patch deleted file mode 100644 index c0218af..0000000 --- a/SOURCES/0401-fs-fshelp-Catch-impermissibly-large-block-sizes-in-r.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 18 Jan 2021 11:46:39 +1100 -Subject: [PATCH] fs/fshelp: Catch impermissibly large block sizes in read - helper - -A fuzzed HFS+ filesystem had log2blocksize = 22. This gave -log2blocksize + GRUB_DISK_SECTOR_BITS = 31. 1 << 31 = 0x80000000, -which is -1 as an int. This caused some wacky behavior later on in -the function, leading to out-of-bounds writes on the destination buffer. - -Catch log2blocksize + GRUB_DISK_SECTOR_BITS >= 31. We could be stricter, -but this is the minimum that will prevent integer size weirdness. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/fs/fshelp.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - -diff --git a/grub-core/fs/fshelp.c b/grub-core/fs/fshelp.c -index 42bd542bbc3..7e7387e86e1 100644 ---- a/grub-core/fs/fshelp.c -+++ b/grub-core/fs/fshelp.c -@@ -252,6 +252,25 @@ grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node, - grub_disk_addr_t i, blockcnt; - int blocksize = 1 << (log2blocksize + GRUB_DISK_SECTOR_BITS); - -+ /* -+ * Catch blatantly invalid log2blocksize. We could be a lot stricter, but -+ * this is the most permissive we can be before we start to see integer -+ * overflow/underflow issues. -+ */ -+ if (log2blocksize + GRUB_DISK_SECTOR_BITS >= 31) -+ { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, -+ N_("blocksize too large")); -+ return -1; -+ } -+ -+ if (pos > filesize) -+ { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, -+ N_("attempt to read past the end of file")); -+ return -1; -+ } -+ - /* Adjust LEN so it we can't read past the end of the file. */ - if (pos + len > filesize) - len = filesize - pos; diff --git a/SOURCES/0401-fs-hfsplus-Don-t-fetch-a-key-beyond-the-end-of-the-n.patch b/SOURCES/0401-fs-hfsplus-Don-t-fetch-a-key-beyond-the-end-of-the-n.patch new file mode 100644 index 0000000..1b8ab48 --- /dev/null +++ b/SOURCES/0401-fs-hfsplus-Don-t-fetch-a-key-beyond-the-end-of-the-n.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Fri, 22 Jan 2021 18:13:56 +1100 +Subject: [PATCH] fs/hfsplus: Don't fetch a key beyond the end of the node + +Otherwise you get a wild pointer, leading to a bunch of invalid reads. +Check it falls inside the given node. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/fs/hfsplus.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c +index 7ae66967b3a..d958c457e87 100644 +--- a/grub-core/fs/hfsplus.c ++++ b/grub-core/fs/hfsplus.c +@@ -629,6 +629,10 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, + pointer = ((char *) currkey + + grub_be_to_cpu16 (currkey->keylen) + + 2); ++ ++ if ((char *) pointer > node + btree->nodesize - 2) ++ return grub_error (GRUB_ERR_BAD_FS, "HFS+ key beyond end of node"); ++ + currnode = grub_be_to_cpu32 (grub_get_unaligned32 (pointer)); + match = 1; + } diff --git a/SOURCES/0402-fs-hfsplus-Don-t-fetch-a-key-beyond-the-end-of-the-n.patch b/SOURCES/0402-fs-hfsplus-Don-t-fetch-a-key-beyond-the-end-of-the-n.patch deleted file mode 100644 index 1b8ab48..0000000 --- a/SOURCES/0402-fs-hfsplus-Don-t-fetch-a-key-beyond-the-end-of-the-n.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 22 Jan 2021 18:13:56 +1100 -Subject: [PATCH] fs/hfsplus: Don't fetch a key beyond the end of the node - -Otherwise you get a wild pointer, leading to a bunch of invalid reads. -Check it falls inside the given node. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/fs/hfsplus.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c -index 7ae66967b3a..d958c457e87 100644 ---- a/grub-core/fs/hfsplus.c -+++ b/grub-core/fs/hfsplus.c -@@ -629,6 +629,10 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, - pointer = ((char *) currkey - + grub_be_to_cpu16 (currkey->keylen) - + 2); -+ -+ if ((char *) pointer > node + btree->nodesize - 2) -+ return grub_error (GRUB_ERR_BAD_FS, "HFS+ key beyond end of node"); -+ - currnode = grub_be_to_cpu32 (grub_get_unaligned32 (pointer)); - match = 1; - } diff --git a/SOURCES/0402-fs-hfsplus-Don-t-use-uninitialized-data-on-corrupt-f.patch b/SOURCES/0402-fs-hfsplus-Don-t-use-uninitialized-data-on-corrupt-f.patch new file mode 100644 index 0000000..79afdf4 --- /dev/null +++ b/SOURCES/0402-fs-hfsplus-Don-t-use-uninitialized-data-on-corrupt-f.patch @@ -0,0 +1,104 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Tue, 2 Feb 2021 16:59:35 +1100 +Subject: [PATCH] fs/hfsplus: Don't use uninitialized data on corrupt + filesystems + +Valgrind identified the following use of uninitialized data: + + ==2782220== Conditional jump or move depends on uninitialised value(s) + ==2782220== at 0x42B364: grub_hfsplus_btree_search (hfsplus.c:566) + ==2782220== by 0x42B21D: grub_hfsplus_read_block (hfsplus.c:185) + ==2782220== by 0x42A693: grub_fshelp_read_file (fshelp.c:386) + ==2782220== by 0x42C598: grub_hfsplus_read_file (hfsplus.c:219) + ==2782220== by 0x42C598: grub_hfsplus_mount (hfsplus.c:330) + ==2782220== by 0x42B8C5: grub_hfsplus_dir (hfsplus.c:958) + ==2782220== by 0x4C1AE6: grub_fs_probe (fs.c:73) + ==2782220== by 0x407C94: grub_ls_list_files (ls.c:186) + ==2782220== by 0x407C94: grub_cmd_ls (ls.c:284) + ==2782220== by 0x4D7130: grub_extcmd_dispatcher (extcmd.c:55) + ==2782220== by 0x4045A6: execute_command (grub-fstest.c:59) + ==2782220== by 0x4045A6: fstest (grub-fstest.c:433) + ==2782220== by 0x4045A6: main (grub-fstest.c:772) + ==2782220== Uninitialised value was created by a heap allocation + ==2782220== at 0x483C7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) + ==2782220== by 0x4C0305: grub_malloc (mm.c:42) + ==2782220== by 0x42C21D: grub_hfsplus_mount (hfsplus.c:239) + ==2782220== by 0x42B8C5: grub_hfsplus_dir (hfsplus.c:958) + ==2782220== by 0x4C1AE6: grub_fs_probe (fs.c:73) + ==2782220== by 0x407C94: grub_ls_list_files (ls.c:186) + ==2782220== by 0x407C94: grub_cmd_ls (ls.c:284) + ==2782220== by 0x4D7130: grub_extcmd_dispatcher (extcmd.c:55) + ==2782220== by 0x4045A6: execute_command (grub-fstest.c:59) + ==2782220== by 0x4045A6: fstest (grub-fstest.c:433) + ==2782220== by 0x4045A6: main (grub-fstest.c:772) + +This happens when the process of reading the catalog file goes sufficiently +wrong that there's an attempt to read the extent overflow file, which has +not yet been loaded. Keep track of when the extent overflow file is +fully loaded and refuse to use it before then. + +The load valgrind doesn't like is btree->nodesize, and that's then used +to allocate a data structure. It looks like there are subsequently a lot +of reads based on that pointer so OOB reads are likely, and indeed crashes +(albeit difficult-to-replicate ones) have been observed in fuzzing. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/fs/hfsplus.c | 14 ++++++++++++++ + include/grub/hfsplus.h | 2 ++ + 2 files changed, 16 insertions(+) + +diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c +index d958c457e87..a385182a46c 100644 +--- a/grub-core/fs/hfsplus.c ++++ b/grub-core/fs/hfsplus.c +@@ -177,6 +177,17 @@ grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + break; + } + ++ /* ++ * If the extent overflow tree isn't ready yet, we can't look ++ * in it. This can happen where the catalog file is corrupted. ++ */ ++ if (!node->data->extoverflow_tree_ready) ++ { ++ grub_error (GRUB_ERR_BAD_FS, ++ "attempted to read extent overflow tree before loading"); ++ break; ++ } ++ + /* Set up the key to look for in the extent overflow file. */ + extoverflow.extkey.fileid = node->fileid; + extoverflow.extkey.type = 0; +@@ -241,6 +252,7 @@ grub_hfsplus_mount (grub_disk_t disk) + return 0; + + data->disk = disk; ++ data->extoverflow_tree_ready = 0; + + /* Read the bootblock. */ + grub_disk_read (disk, GRUB_HFSPLUS_SBLOCK, 0, sizeof (volheader), +@@ -351,6 +363,8 @@ grub_hfsplus_mount (grub_disk_t disk) + data->extoverflow_tree.root = grub_be_to_cpu32 (header.root); + data->extoverflow_tree.nodesize = grub_be_to_cpu16 (header.nodesize); + ++ data->extoverflow_tree_ready = 1; ++ + if (grub_hfsplus_read_file (&data->attr_tree.file, 0, 0, + sizeof (struct grub_hfsplus_btnode), + sizeof (header), (char *) &header) <= 0) +diff --git a/include/grub/hfsplus.h b/include/grub/hfsplus.h +index 8ba8f32468b..7277d565bce 100644 +--- a/include/grub/hfsplus.h ++++ b/include/grub/hfsplus.h +@@ -113,6 +113,8 @@ struct grub_hfsplus_data + struct grub_hfsplus_btree extoverflow_tree; + struct grub_hfsplus_btree attr_tree; + ++ int extoverflow_tree_ready; ++ + struct grub_hfsplus_file dirroot; + struct grub_hfsplus_file opened_file; + diff --git a/SOURCES/0403-fs-hfs-Disable-under-lockdown.patch b/SOURCES/0403-fs-hfs-Disable-under-lockdown.patch new file mode 100644 index 0000000..a7f6ae6 --- /dev/null +++ b/SOURCES/0403-fs-hfs-Disable-under-lockdown.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Mon, 18 Jan 2021 12:19:07 +1100 +Subject: [PATCH] fs/hfs: Disable under lockdown + +HFS has issues such as infinite mutual recursion that are simply too +complex to fix for such a legacy format. So simply do not permit +it to be loaded under lockdown. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/fs/hfs.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c +index 79f6845879a..6e9215a22f9 100644 +--- a/grub-core/fs/hfs.c ++++ b/grub-core/fs/hfs.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -1433,11 +1434,13 @@ static struct grub_fs grub_hfs_fs = + + GRUB_MOD_INIT(hfs) + { +- grub_fs_register (&grub_hfs_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_register (&grub_hfs_fs); + my_mod = mod; + } + + GRUB_MOD_FINI(hfs) + { +- grub_fs_unregister (&grub_hfs_fs); ++ if (!grub_is_lockdown()) ++ grub_fs_unregister (&grub_hfs_fs); + } diff --git a/SOURCES/0403-fs-hfsplus-Don-t-use-uninitialized-data-on-corrupt-f.patch b/SOURCES/0403-fs-hfsplus-Don-t-use-uninitialized-data-on-corrupt-f.patch deleted file mode 100644 index 79afdf4..0000000 --- a/SOURCES/0403-fs-hfsplus-Don-t-use-uninitialized-data-on-corrupt-f.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 2 Feb 2021 16:59:35 +1100 -Subject: [PATCH] fs/hfsplus: Don't use uninitialized data on corrupt - filesystems - -Valgrind identified the following use of uninitialized data: - - ==2782220== Conditional jump or move depends on uninitialised value(s) - ==2782220== at 0x42B364: grub_hfsplus_btree_search (hfsplus.c:566) - ==2782220== by 0x42B21D: grub_hfsplus_read_block (hfsplus.c:185) - ==2782220== by 0x42A693: grub_fshelp_read_file (fshelp.c:386) - ==2782220== by 0x42C598: grub_hfsplus_read_file (hfsplus.c:219) - ==2782220== by 0x42C598: grub_hfsplus_mount (hfsplus.c:330) - ==2782220== by 0x42B8C5: grub_hfsplus_dir (hfsplus.c:958) - ==2782220== by 0x4C1AE6: grub_fs_probe (fs.c:73) - ==2782220== by 0x407C94: grub_ls_list_files (ls.c:186) - ==2782220== by 0x407C94: grub_cmd_ls (ls.c:284) - ==2782220== by 0x4D7130: grub_extcmd_dispatcher (extcmd.c:55) - ==2782220== by 0x4045A6: execute_command (grub-fstest.c:59) - ==2782220== by 0x4045A6: fstest (grub-fstest.c:433) - ==2782220== by 0x4045A6: main (grub-fstest.c:772) - ==2782220== Uninitialised value was created by a heap allocation - ==2782220== at 0x483C7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) - ==2782220== by 0x4C0305: grub_malloc (mm.c:42) - ==2782220== by 0x42C21D: grub_hfsplus_mount (hfsplus.c:239) - ==2782220== by 0x42B8C5: grub_hfsplus_dir (hfsplus.c:958) - ==2782220== by 0x4C1AE6: grub_fs_probe (fs.c:73) - ==2782220== by 0x407C94: grub_ls_list_files (ls.c:186) - ==2782220== by 0x407C94: grub_cmd_ls (ls.c:284) - ==2782220== by 0x4D7130: grub_extcmd_dispatcher (extcmd.c:55) - ==2782220== by 0x4045A6: execute_command (grub-fstest.c:59) - ==2782220== by 0x4045A6: fstest (grub-fstest.c:433) - ==2782220== by 0x4045A6: main (grub-fstest.c:772) - -This happens when the process of reading the catalog file goes sufficiently -wrong that there's an attempt to read the extent overflow file, which has -not yet been loaded. Keep track of when the extent overflow file is -fully loaded and refuse to use it before then. - -The load valgrind doesn't like is btree->nodesize, and that's then used -to allocate a data structure. It looks like there are subsequently a lot -of reads based on that pointer so OOB reads are likely, and indeed crashes -(albeit difficult-to-replicate ones) have been observed in fuzzing. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/fs/hfsplus.c | 14 ++++++++++++++ - include/grub/hfsplus.h | 2 ++ - 2 files changed, 16 insertions(+) - -diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c -index d958c457e87..a385182a46c 100644 ---- a/grub-core/fs/hfsplus.c -+++ b/grub-core/fs/hfsplus.c -@@ -177,6 +177,17 @@ grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) - break; - } - -+ /* -+ * If the extent overflow tree isn't ready yet, we can't look -+ * in it. This can happen where the catalog file is corrupted. -+ */ -+ if (!node->data->extoverflow_tree_ready) -+ { -+ grub_error (GRUB_ERR_BAD_FS, -+ "attempted to read extent overflow tree before loading"); -+ break; -+ } -+ - /* Set up the key to look for in the extent overflow file. */ - extoverflow.extkey.fileid = node->fileid; - extoverflow.extkey.type = 0; -@@ -241,6 +252,7 @@ grub_hfsplus_mount (grub_disk_t disk) - return 0; - - data->disk = disk; -+ data->extoverflow_tree_ready = 0; - - /* Read the bootblock. */ - grub_disk_read (disk, GRUB_HFSPLUS_SBLOCK, 0, sizeof (volheader), -@@ -351,6 +363,8 @@ grub_hfsplus_mount (grub_disk_t disk) - data->extoverflow_tree.root = grub_be_to_cpu32 (header.root); - data->extoverflow_tree.nodesize = grub_be_to_cpu16 (header.nodesize); - -+ data->extoverflow_tree_ready = 1; -+ - if (grub_hfsplus_read_file (&data->attr_tree.file, 0, 0, - sizeof (struct grub_hfsplus_btnode), - sizeof (header), (char *) &header) <= 0) -diff --git a/include/grub/hfsplus.h b/include/grub/hfsplus.h -index 8ba8f32468b..7277d565bce 100644 ---- a/include/grub/hfsplus.h -+++ b/include/grub/hfsplus.h -@@ -113,6 +113,8 @@ struct grub_hfsplus_data - struct grub_hfsplus_btree extoverflow_tree; - struct grub_hfsplus_btree attr_tree; - -+ int extoverflow_tree_ready; -+ - struct grub_hfsplus_file dirroot; - struct grub_hfsplus_file opened_file; - diff --git a/SOURCES/0404-fs-hfs-Disable-under-lockdown.patch b/SOURCES/0404-fs-hfs-Disable-under-lockdown.patch deleted file mode 100644 index a7f6ae6..0000000 --- a/SOURCES/0404-fs-hfs-Disable-under-lockdown.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 18 Jan 2021 12:19:07 +1100 -Subject: [PATCH] fs/hfs: Disable under lockdown - -HFS has issues such as infinite mutual recursion that are simply too -complex to fix for such a legacy format. So simply do not permit -it to be loaded under lockdown. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/fs/hfs.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c -index 79f6845879a..6e9215a22f9 100644 ---- a/grub-core/fs/hfs.c -+++ b/grub-core/fs/hfs.c -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -1433,11 +1434,13 @@ static struct grub_fs grub_hfs_fs = - - GRUB_MOD_INIT(hfs) - { -- grub_fs_register (&grub_hfs_fs); -+ if (!grub_is_lockdown ()) -+ grub_fs_register (&grub_hfs_fs); - my_mod = mod; - } - - GRUB_MOD_FINI(hfs) - { -- grub_fs_unregister (&grub_hfs_fs); -+ if (!grub_is_lockdown()) -+ grub_fs_unregister (&grub_hfs_fs); - } diff --git a/SOURCES/0404-fs-sfs-Fix-over-read-of-root-object-name.patch b/SOURCES/0404-fs-sfs-Fix-over-read-of-root-object-name.patch new file mode 100644 index 0000000..068fd80 --- /dev/null +++ b/SOURCES/0404-fs-sfs-Fix-over-read-of-root-object-name.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Mon, 18 Jan 2021 14:34:58 +1100 +Subject: [PATCH] fs/sfs: Fix over-read of root object name + +There's a read of the name of the root object that assumes that the name +is nul-terminated within the root block. This isn't guaranteed - it seems +SFS would require you to read multiple blocks to get a full name in general, +but maybe that doesn't apply to the root object. + +Either way, figure out how much space is left in the root block and don't +over-read it. This fixes some OOB reads. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/fs/sfs.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c +index 4f68808a891..bba600429bb 100644 +--- a/grub-core/fs/sfs.c ++++ b/grub-core/fs/sfs.c +@@ -368,6 +368,7 @@ grub_sfs_mount (grub_disk_t disk) + struct grub_sfs_objc *rootobjc; + char *rootobjc_data = 0; + grub_uint32_t blk; ++ unsigned int max_len; + + data = grub_malloc (sizeof (*data)); + if (!data) +@@ -416,7 +417,13 @@ grub_sfs_mount (grub_disk_t disk) + data->diropen.data = data; + data->diropen.cache = 0; + data->disk = disk; +- data->label = grub_strdup ((char *) (rootobjc->objects[0].filename)); ++ ++ /* We only read 1 block of data, so truncate the name if needed. */ ++ max_len = ((GRUB_DISK_SECTOR_SIZE << data->log_blocksize) ++ - 24 /* offsetof (struct grub_sfs_objc, objects) */ ++ - 25); /* offsetof (struct grub_sfs_obj, filename) */ ++ data->label = grub_zalloc (max_len + 1); ++ grub_strncpy (data->label, (char *) rootobjc->objects[0].filename, max_len); + + grub_free (rootobjc_data); + return data; diff --git a/SOURCES/0405-fs-jfs-Do-not-move-to-leaf-level-if-name-length-is-n.patch b/SOURCES/0405-fs-jfs-Do-not-move-to-leaf-level-if-name-length-is-n.patch new file mode 100644 index 0000000..7c75a3b --- /dev/null +++ b/SOURCES/0405-fs-jfs-Do-not-move-to-leaf-level-if-name-length-is-n.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Mon, 18 Jan 2021 14:51:11 +1100 +Subject: [PATCH] fs/jfs: Do not move to leaf level if name length is negative + +Fuzzing JFS revealed crashes where a negative number would be passed +to le_to_cpu16_copy(). There it would be cast to a large positive number +and the copy would read and write off the end of the respective buffers. + +Catch this at the top as well as the bottom of the loop. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/fs/jfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c +index aab3e8c7b7d..1819899bdec 100644 +--- a/grub-core/fs/jfs.c ++++ b/grub-core/fs/jfs.c +@@ -563,7 +563,7 @@ grub_jfs_getent (struct grub_jfs_diropen *diro) + + /* Move down to the leaf level. */ + nextent = leaf->next; +- if (leaf->next != 255) ++ if (leaf->next != 255 && len > 0) + do + { + next_leaf = &diro->next_leaf[nextent]; diff --git a/SOURCES/0405-fs-sfs-Fix-over-read-of-root-object-name.patch b/SOURCES/0405-fs-sfs-Fix-over-read-of-root-object-name.patch deleted file mode 100644 index 068fd80..0000000 --- a/SOURCES/0405-fs-sfs-Fix-over-read-of-root-object-name.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 18 Jan 2021 14:34:58 +1100 -Subject: [PATCH] fs/sfs: Fix over-read of root object name - -There's a read of the name of the root object that assumes that the name -is nul-terminated within the root block. This isn't guaranteed - it seems -SFS would require you to read multiple blocks to get a full name in general, -but maybe that doesn't apply to the root object. - -Either way, figure out how much space is left in the root block and don't -over-read it. This fixes some OOB reads. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/fs/sfs.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c -index 4f68808a891..bba600429bb 100644 ---- a/grub-core/fs/sfs.c -+++ b/grub-core/fs/sfs.c -@@ -368,6 +368,7 @@ grub_sfs_mount (grub_disk_t disk) - struct grub_sfs_objc *rootobjc; - char *rootobjc_data = 0; - grub_uint32_t blk; -+ unsigned int max_len; - - data = grub_malloc (sizeof (*data)); - if (!data) -@@ -416,7 +417,13 @@ grub_sfs_mount (grub_disk_t disk) - data->diropen.data = data; - data->diropen.cache = 0; - data->disk = disk; -- data->label = grub_strdup ((char *) (rootobjc->objects[0].filename)); -+ -+ /* We only read 1 block of data, so truncate the name if needed. */ -+ max_len = ((GRUB_DISK_SECTOR_SIZE << data->log_blocksize) -+ - 24 /* offsetof (struct grub_sfs_objc, objects) */ -+ - 25); /* offsetof (struct grub_sfs_obj, filename) */ -+ data->label = grub_zalloc (max_len + 1); -+ grub_strncpy (data->label, (char *) rootobjc->objects[0].filename, max_len); - - grub_free (rootobjc_data); - return data; diff --git a/SOURCES/0406-fs-jfs-Do-not-move-to-leaf-level-if-name-length-is-n.patch b/SOURCES/0406-fs-jfs-Do-not-move-to-leaf-level-if-name-length-is-n.patch deleted file mode 100644 index 7c75a3b..0000000 --- a/SOURCES/0406-fs-jfs-Do-not-move-to-leaf-level-if-name-length-is-n.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 18 Jan 2021 14:51:11 +1100 -Subject: [PATCH] fs/jfs: Do not move to leaf level if name length is negative - -Fuzzing JFS revealed crashes where a negative number would be passed -to le_to_cpu16_copy(). There it would be cast to a large positive number -and the copy would read and write off the end of the respective buffers. - -Catch this at the top as well as the bottom of the loop. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/fs/jfs.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c -index aab3e8c7b7d..1819899bdec 100644 ---- a/grub-core/fs/jfs.c -+++ b/grub-core/fs/jfs.c -@@ -563,7 +563,7 @@ grub_jfs_getent (struct grub_jfs_diropen *diro) - - /* Move down to the leaf level. */ - nextent = leaf->next; -- if (leaf->next != 255) -+ if (leaf->next != 255 && len > 0) - do - { - next_leaf = &diro->next_leaf[nextent]; diff --git a/SOURCES/0406-fs-jfs-Limit-the-extents-that-getblk-can-consider.patch b/SOURCES/0406-fs-jfs-Limit-the-extents-that-getblk-can-consider.patch new file mode 100644 index 0000000..91ab8db --- /dev/null +++ b/SOURCES/0406-fs-jfs-Limit-the-extents-that-getblk-can-consider.patch @@ -0,0 +1,58 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Mon, 18 Jan 2021 14:57:17 +1100 +Subject: [PATCH] fs/jfs: Limit the extents that getblk() can consider + +getblk() implicitly trusts that treehead->count is an accurate count of +the number of extents. However, that value is read from disk and is not +trustworthy, leading to OOB reads and crashes. I am not sure to what +extent the data read from OOB can influence subsequent program execution. + +Require callers to pass in the maximum number of extents for which +they have storage. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/fs/jfs.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c +index 1819899bdec..6e81f37da6c 100644 +--- a/grub-core/fs/jfs.c ++++ b/grub-core/fs/jfs.c +@@ -261,13 +261,15 @@ static grub_err_t grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint + static grub_int64_t + getblk (struct grub_jfs_treehead *treehead, + struct grub_jfs_tree_extent *extents, ++ int max_extents, + struct grub_jfs_data *data, + grub_uint64_t blk) + { + int found = -1; + int i; + +- for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2; i++) ++ for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2 && ++ i < max_extents; i++) + { + if (treehead->flags & GRUB_JFS_TREE_LEAF) + { +@@ -302,7 +304,7 @@ getblk (struct grub_jfs_treehead *treehead, + << (grub_le_to_cpu16 (data->sblock.log2_blksz) + - GRUB_DISK_SECTOR_BITS), 0, + sizeof (*tree), (char *) tree)) +- ret = getblk (&tree->treehead, &tree->extents[0], data, blk); ++ ret = getblk (&tree->treehead, &tree->extents[0], 254, data, blk); + grub_free (tree); + return ret; + } +@@ -316,7 +318,7 @@ static grub_int64_t + grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode, + grub_uint64_t blk) + { +- return getblk (&inode->file.tree, &inode->file.extents[0], data, blk); ++ return getblk (&inode->file.tree, &inode->file.extents[0], 16, data, blk); + } + + diff --git a/SOURCES/0407-fs-jfs-Catch-infinite-recursion.patch b/SOURCES/0407-fs-jfs-Catch-infinite-recursion.patch new file mode 100644 index 0000000..dee5914 --- /dev/null +++ b/SOURCES/0407-fs-jfs-Catch-infinite-recursion.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Mon, 18 Jan 2021 15:47:24 +1100 +Subject: [PATCH] fs/jfs: Catch infinite recursion + +It's possible with a fuzzed filesystem for JFS to keep getblk()-ing +the same data over and over again, leading to stack exhaustion. + +Check if we'd be calling the function with exactly the same data as +was passed in, and if so abort. + +I'm not sure what the performance impact of this is and am open to +better ideas. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/fs/jfs.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c +index 6e81f37da6c..20d966abfc0 100644 +--- a/grub-core/fs/jfs.c ++++ b/grub-core/fs/jfs.c +@@ -304,7 +304,16 @@ getblk (struct grub_jfs_treehead *treehead, + << (grub_le_to_cpu16 (data->sblock.log2_blksz) + - GRUB_DISK_SECTOR_BITS), 0, + sizeof (*tree), (char *) tree)) +- ret = getblk (&tree->treehead, &tree->extents[0], 254, data, blk); ++ { ++ if (grub_memcmp (&tree->treehead, treehead, sizeof (struct grub_jfs_treehead)) || ++ grub_memcmp (&tree->extents, extents, 254 * sizeof (struct grub_jfs_tree_extent))) ++ ret = getblk (&tree->treehead, &tree->extents[0], 254, data, blk); ++ else ++ { ++ grub_error (GRUB_ERR_BAD_FS, "jfs: infinite recursion detected"); ++ ret = -1; ++ } ++ } + grub_free (tree); + return ret; + } diff --git a/SOURCES/0407-fs-jfs-Limit-the-extents-that-getblk-can-consider.patch b/SOURCES/0407-fs-jfs-Limit-the-extents-that-getblk-can-consider.patch deleted file mode 100644 index 91ab8db..0000000 --- a/SOURCES/0407-fs-jfs-Limit-the-extents-that-getblk-can-consider.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 18 Jan 2021 14:57:17 +1100 -Subject: [PATCH] fs/jfs: Limit the extents that getblk() can consider - -getblk() implicitly trusts that treehead->count is an accurate count of -the number of extents. However, that value is read from disk and is not -trustworthy, leading to OOB reads and crashes. I am not sure to what -extent the data read from OOB can influence subsequent program execution. - -Require callers to pass in the maximum number of extents for which -they have storage. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/fs/jfs.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c -index 1819899bdec..6e81f37da6c 100644 ---- a/grub-core/fs/jfs.c -+++ b/grub-core/fs/jfs.c -@@ -261,13 +261,15 @@ static grub_err_t grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint - static grub_int64_t - getblk (struct grub_jfs_treehead *treehead, - struct grub_jfs_tree_extent *extents, -+ int max_extents, - struct grub_jfs_data *data, - grub_uint64_t blk) - { - int found = -1; - int i; - -- for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2; i++) -+ for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2 && -+ i < max_extents; i++) - { - if (treehead->flags & GRUB_JFS_TREE_LEAF) - { -@@ -302,7 +304,7 @@ getblk (struct grub_jfs_treehead *treehead, - << (grub_le_to_cpu16 (data->sblock.log2_blksz) - - GRUB_DISK_SECTOR_BITS), 0, - sizeof (*tree), (char *) tree)) -- ret = getblk (&tree->treehead, &tree->extents[0], data, blk); -+ ret = getblk (&tree->treehead, &tree->extents[0], 254, data, blk); - grub_free (tree); - return ret; - } -@@ -316,7 +318,7 @@ static grub_int64_t - grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode, - grub_uint64_t blk) - { -- return getblk (&inode->file.tree, &inode->file.extents[0], data, blk); -+ return getblk (&inode->file.tree, &inode->file.extents[0], 16, data, blk); - } - - diff --git a/SOURCES/0408-fs-jfs-Catch-infinite-recursion.patch b/SOURCES/0408-fs-jfs-Catch-infinite-recursion.patch deleted file mode 100644 index dee5914..0000000 --- a/SOURCES/0408-fs-jfs-Catch-infinite-recursion.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 18 Jan 2021 15:47:24 +1100 -Subject: [PATCH] fs/jfs: Catch infinite recursion - -It's possible with a fuzzed filesystem for JFS to keep getblk()-ing -the same data over and over again, leading to stack exhaustion. - -Check if we'd be calling the function with exactly the same data as -was passed in, and if so abort. - -I'm not sure what the performance impact of this is and am open to -better ideas. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/fs/jfs.c | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c -index 6e81f37da6c..20d966abfc0 100644 ---- a/grub-core/fs/jfs.c -+++ b/grub-core/fs/jfs.c -@@ -304,7 +304,16 @@ getblk (struct grub_jfs_treehead *treehead, - << (grub_le_to_cpu16 (data->sblock.log2_blksz) - - GRUB_DISK_SECTOR_BITS), 0, - sizeof (*tree), (char *) tree)) -- ret = getblk (&tree->treehead, &tree->extents[0], 254, data, blk); -+ { -+ if (grub_memcmp (&tree->treehead, treehead, sizeof (struct grub_jfs_treehead)) || -+ grub_memcmp (&tree->extents, extents, 254 * sizeof (struct grub_jfs_tree_extent))) -+ ret = getblk (&tree->treehead, &tree->extents[0], 254, data, blk); -+ else -+ { -+ grub_error (GRUB_ERR_BAD_FS, "jfs: infinite recursion detected"); -+ ret = -1; -+ } -+ } - grub_free (tree); - return ret; - } diff --git a/SOURCES/0408-fs-nilfs2-Reject-too-large-keys.patch b/SOURCES/0408-fs-nilfs2-Reject-too-large-keys.patch new file mode 100644 index 0000000..f55029d --- /dev/null +++ b/SOURCES/0408-fs-nilfs2-Reject-too-large-keys.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Mon, 18 Jan 2021 16:49:09 +1100 +Subject: [PATCH] fs/nilfs2: Reject too-large keys + +NILFS2 has up to 7 keys, per the data structure. Do not permit array +indices in excess of that. + +This catches some OOB reads. I don't know how controllable the invalidly +read data is or if that could be used later in the program. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/fs/nilfs2.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c +index 388ee188edc..09e89f615bc 100644 +--- a/grub-core/fs/nilfs2.c ++++ b/grub-core/fs/nilfs2.c +@@ -569,6 +569,11 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data, + static inline grub_uint64_t + grub_nilfs2_direct_lookup (struct grub_nilfs2_inode *inode, grub_uint64_t key) + { ++ if (1 + key > 6) ++ { ++ grub_error (GRUB_ERR_BAD_FS, "key is too large"); ++ return 0xffffffffffffffff; ++ } + return grub_le_to_cpu64 (inode->i_bmap[1 + key]); + } + +@@ -584,7 +589,7 @@ grub_nilfs2_bmap_lookup (struct grub_nilfs2_data *data, + { + grub_uint64_t ptr; + ptr = grub_nilfs2_direct_lookup (inode, key); +- if (need_translate) ++ if (ptr != ((grub_uint64_t) 0xffffffffffffffff) && need_translate) + ptr = grub_nilfs2_dat_translate (data, ptr); + return ptr; + } diff --git a/SOURCES/0409-fs-nilfs2-Don-t-search-children-if-provided-number-i.patch b/SOURCES/0409-fs-nilfs2-Don-t-search-children-if-provided-number-i.patch new file mode 100644 index 0000000..b24c2d0 --- /dev/null +++ b/SOURCES/0409-fs-nilfs2-Don-t-search-children-if-provided-number-i.patch @@ -0,0 +1,96 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Mon, 18 Jan 2021 16:49:44 +1100 +Subject: [PATCH] fs/nilfs2: Don't search children if provided number is too + large + +NILFS2 reads the number of children a node has from the node. Unfortunately, +that's not trustworthy. Check if it's beyond what the filesystem permits and +reject it if so. + +This blocks some OOB reads. I'm not sure how controllable the read is and what +could be done with invalidly read data later on. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/fs/nilfs2.c | 38 +++++++++++++++++++++++--------------- + 1 file changed, 23 insertions(+), 15 deletions(-) + +diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c +index 09e89f615bc..896d2c22c81 100644 +--- a/grub-core/fs/nilfs2.c ++++ b/grub-core/fs/nilfs2.c +@@ -416,14 +416,34 @@ grub_nilfs2_btree_node_get_key (struct grub_nilfs2_btree_node *node, + } + + static inline int +-grub_nilfs2_btree_node_lookup (struct grub_nilfs2_btree_node *node, ++grub_nilfs2_btree_node_nchildren_max (struct grub_nilfs2_data *data, ++ struct grub_nilfs2_btree_node *node) ++{ ++ int node_children_max = ((NILFS2_BLOCK_SIZE (data) - ++ sizeof (struct grub_nilfs2_btree_node) - ++ NILFS_BTREE_NODE_EXTRA_PAD_SIZE) / ++ (sizeof (grub_uint64_t) + sizeof (grub_uint64_t))); ++ ++ return (node->bn_flags & NILFS_BTREE_NODE_ROOT) ? 3 : node_children_max; ++} ++ ++static inline int ++grub_nilfs2_btree_node_lookup (struct grub_nilfs2_data *data, ++ struct grub_nilfs2_btree_node *node, + grub_uint64_t key, int *indexp) + { + grub_uint64_t nkey; + int index, low, high, s; + + low = 0; ++ + high = grub_le_to_cpu16 (node->bn_nchildren) - 1; ++ if (high >= grub_nilfs2_btree_node_nchildren_max (data, node)) ++ { ++ grub_error (GRUB_ERR_BAD_FS, "too many children"); ++ return 0; ++ } ++ + index = 0; + s = 0; + while (low <= high) +@@ -459,18 +479,6 @@ grub_nilfs2_btree_node_lookup (struct grub_nilfs2_btree_node *node, + return s == 0; + } + +-static inline int +-grub_nilfs2_btree_node_nchildren_max (struct grub_nilfs2_data *data, +- struct grub_nilfs2_btree_node *node) +-{ +- int node_children_max = ((NILFS2_BLOCK_SIZE (data) - +- sizeof (struct grub_nilfs2_btree_node) - +- NILFS_BTREE_NODE_EXTRA_PAD_SIZE) / +- (sizeof (grub_uint64_t) + sizeof (grub_uint64_t))); +- +- return (node->bn_flags & NILFS_BTREE_NODE_ROOT) ? 3 : node_children_max; +-} +- + static inline grub_uint64_t * + grub_nilfs2_btree_node_dptrs (struct grub_nilfs2_data *data, + struct grub_nilfs2_btree_node *node) +@@ -517,7 +525,7 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data, + node = grub_nilfs2_btree_get_root (inode); + level = grub_nilfs2_btree_get_level (node); + +- found = grub_nilfs2_btree_node_lookup (node, key, &index); ++ found = grub_nilfs2_btree_node_lookup (data, node, key, &index); + ptr = grub_nilfs2_btree_node_get_ptr (data, node, index); + if (need_translate) + ptr = grub_nilfs2_dat_translate (data, ptr); +@@ -538,7 +546,7 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data, + } + + if (!found) +- found = grub_nilfs2_btree_node_lookup (node, key, &index); ++ found = grub_nilfs2_btree_node_lookup (data, node, key, &index); + else + index = 0; + diff --git a/SOURCES/0409-fs-nilfs2-Reject-too-large-keys.patch b/SOURCES/0409-fs-nilfs2-Reject-too-large-keys.patch deleted file mode 100644 index f55029d..0000000 --- a/SOURCES/0409-fs-nilfs2-Reject-too-large-keys.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 18 Jan 2021 16:49:09 +1100 -Subject: [PATCH] fs/nilfs2: Reject too-large keys - -NILFS2 has up to 7 keys, per the data structure. Do not permit array -indices in excess of that. - -This catches some OOB reads. I don't know how controllable the invalidly -read data is or if that could be used later in the program. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/fs/nilfs2.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c -index 388ee188edc..09e89f615bc 100644 ---- a/grub-core/fs/nilfs2.c -+++ b/grub-core/fs/nilfs2.c -@@ -569,6 +569,11 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data, - static inline grub_uint64_t - grub_nilfs2_direct_lookup (struct grub_nilfs2_inode *inode, grub_uint64_t key) - { -+ if (1 + key > 6) -+ { -+ grub_error (GRUB_ERR_BAD_FS, "key is too large"); -+ return 0xffffffffffffffff; -+ } - return grub_le_to_cpu64 (inode->i_bmap[1 + key]); - } - -@@ -584,7 +589,7 @@ grub_nilfs2_bmap_lookup (struct grub_nilfs2_data *data, - { - grub_uint64_t ptr; - ptr = grub_nilfs2_direct_lookup (inode, key); -- if (need_translate) -+ if (ptr != ((grub_uint64_t) 0xffffffffffffffff) && need_translate) - ptr = grub_nilfs2_dat_translate (data, ptr); - return ptr; - } diff --git a/SOURCES/0410-fs-nilfs2-Don-t-search-children-if-provided-number-i.patch b/SOURCES/0410-fs-nilfs2-Don-t-search-children-if-provided-number-i.patch deleted file mode 100644 index b24c2d0..0000000 --- a/SOURCES/0410-fs-nilfs2-Don-t-search-children-if-provided-number-i.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 18 Jan 2021 16:49:44 +1100 -Subject: [PATCH] fs/nilfs2: Don't search children if provided number is too - large - -NILFS2 reads the number of children a node has from the node. Unfortunately, -that's not trustworthy. Check if it's beyond what the filesystem permits and -reject it if so. - -This blocks some OOB reads. I'm not sure how controllable the read is and what -could be done with invalidly read data later on. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/fs/nilfs2.c | 38 +++++++++++++++++++++++--------------- - 1 file changed, 23 insertions(+), 15 deletions(-) - -diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c -index 09e89f615bc..896d2c22c81 100644 ---- a/grub-core/fs/nilfs2.c -+++ b/grub-core/fs/nilfs2.c -@@ -416,14 +416,34 @@ grub_nilfs2_btree_node_get_key (struct grub_nilfs2_btree_node *node, - } - - static inline int --grub_nilfs2_btree_node_lookup (struct grub_nilfs2_btree_node *node, -+grub_nilfs2_btree_node_nchildren_max (struct grub_nilfs2_data *data, -+ struct grub_nilfs2_btree_node *node) -+{ -+ int node_children_max = ((NILFS2_BLOCK_SIZE (data) - -+ sizeof (struct grub_nilfs2_btree_node) - -+ NILFS_BTREE_NODE_EXTRA_PAD_SIZE) / -+ (sizeof (grub_uint64_t) + sizeof (grub_uint64_t))); -+ -+ return (node->bn_flags & NILFS_BTREE_NODE_ROOT) ? 3 : node_children_max; -+} -+ -+static inline int -+grub_nilfs2_btree_node_lookup (struct grub_nilfs2_data *data, -+ struct grub_nilfs2_btree_node *node, - grub_uint64_t key, int *indexp) - { - grub_uint64_t nkey; - int index, low, high, s; - - low = 0; -+ - high = grub_le_to_cpu16 (node->bn_nchildren) - 1; -+ if (high >= grub_nilfs2_btree_node_nchildren_max (data, node)) -+ { -+ grub_error (GRUB_ERR_BAD_FS, "too many children"); -+ return 0; -+ } -+ - index = 0; - s = 0; - while (low <= high) -@@ -459,18 +479,6 @@ grub_nilfs2_btree_node_lookup (struct grub_nilfs2_btree_node *node, - return s == 0; - } - --static inline int --grub_nilfs2_btree_node_nchildren_max (struct grub_nilfs2_data *data, -- struct grub_nilfs2_btree_node *node) --{ -- int node_children_max = ((NILFS2_BLOCK_SIZE (data) - -- sizeof (struct grub_nilfs2_btree_node) - -- NILFS_BTREE_NODE_EXTRA_PAD_SIZE) / -- (sizeof (grub_uint64_t) + sizeof (grub_uint64_t))); -- -- return (node->bn_flags & NILFS_BTREE_NODE_ROOT) ? 3 : node_children_max; --} -- - static inline grub_uint64_t * - grub_nilfs2_btree_node_dptrs (struct grub_nilfs2_data *data, - struct grub_nilfs2_btree_node *node) -@@ -517,7 +525,7 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data, - node = grub_nilfs2_btree_get_root (inode); - level = grub_nilfs2_btree_get_level (node); - -- found = grub_nilfs2_btree_node_lookup (node, key, &index); -+ found = grub_nilfs2_btree_node_lookup (data, node, key, &index); - ptr = grub_nilfs2_btree_node_get_ptr (data, node, index); - if (need_translate) - ptr = grub_nilfs2_dat_translate (data, ptr); -@@ -538,7 +546,7 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data, - } - - if (!found) -- found = grub_nilfs2_btree_node_lookup (node, key, &index); -+ found = grub_nilfs2_btree_node_lookup (data, node, key, &index); - else - index = 0; - diff --git a/SOURCES/0410-fs-nilfs2-Properly-bail-on-errors-in-grub_nilfs2_btr.patch b/SOURCES/0410-fs-nilfs2-Properly-bail-on-errors-in-grub_nilfs2_btr.patch new file mode 100644 index 0000000..de0fc8b --- /dev/null +++ b/SOURCES/0410-fs-nilfs2-Properly-bail-on-errors-in-grub_nilfs2_btr.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Mon, 18 Jan 2021 17:06:19 +1100 +Subject: [PATCH] fs/nilfs2: Properly bail on errors in + grub_nilfs2_btree_node_lookup() + +We just introduced an error return in grub_nilfs2_btree_node_lookup(). +Make sure the callers catch it. + +At the same time, make sure that grub_nilfs2_btree_node_lookup() always +inits the index pointer passed to it. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/fs/nilfs2.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c +index 896d2c22c81..bdf395a093a 100644 +--- a/grub-core/fs/nilfs2.c ++++ b/grub-core/fs/nilfs2.c +@@ -433,7 +433,7 @@ grub_nilfs2_btree_node_lookup (struct grub_nilfs2_data *data, + grub_uint64_t key, int *indexp) + { + grub_uint64_t nkey; +- int index, low, high, s; ++ int index = 0, low, high, s; + + low = 0; + +@@ -441,10 +441,10 @@ grub_nilfs2_btree_node_lookup (struct grub_nilfs2_data *data, + if (high >= grub_nilfs2_btree_node_nchildren_max (data, node)) + { + grub_error (GRUB_ERR_BAD_FS, "too many children"); ++ *indexp = index; + return 0; + } + +- index = 0; + s = 0; + while (low <= high) + { +@@ -526,6 +526,10 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data, + level = grub_nilfs2_btree_get_level (node); + + found = grub_nilfs2_btree_node_lookup (data, node, key, &index); ++ ++ if (grub_errno != GRUB_ERR_NONE) ++ goto fail; ++ + ptr = grub_nilfs2_btree_node_get_ptr (data, node, index); + if (need_translate) + ptr = grub_nilfs2_dat_translate (data, ptr); +@@ -550,7 +554,8 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data, + else + index = 0; + +- if (index < grub_nilfs2_btree_node_nchildren_max (data, node)) ++ if (index < grub_nilfs2_btree_node_nchildren_max (data, node) && ++ grub_errno == GRUB_ERR_NONE) + { + ptr = grub_nilfs2_btree_node_get_ptr (data, node, index); + if (need_translate) diff --git a/SOURCES/0411-fs-nilfs2-Properly-bail-on-errors-in-grub_nilfs2_btr.patch b/SOURCES/0411-fs-nilfs2-Properly-bail-on-errors-in-grub_nilfs2_btr.patch deleted file mode 100644 index de0fc8b..0000000 --- a/SOURCES/0411-fs-nilfs2-Properly-bail-on-errors-in-grub_nilfs2_btr.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 18 Jan 2021 17:06:19 +1100 -Subject: [PATCH] fs/nilfs2: Properly bail on errors in - grub_nilfs2_btree_node_lookup() - -We just introduced an error return in grub_nilfs2_btree_node_lookup(). -Make sure the callers catch it. - -At the same time, make sure that grub_nilfs2_btree_node_lookup() always -inits the index pointer passed to it. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/fs/nilfs2.c | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - -diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c -index 896d2c22c81..bdf395a093a 100644 ---- a/grub-core/fs/nilfs2.c -+++ b/grub-core/fs/nilfs2.c -@@ -433,7 +433,7 @@ grub_nilfs2_btree_node_lookup (struct grub_nilfs2_data *data, - grub_uint64_t key, int *indexp) - { - grub_uint64_t nkey; -- int index, low, high, s; -+ int index = 0, low, high, s; - - low = 0; - -@@ -441,10 +441,10 @@ grub_nilfs2_btree_node_lookup (struct grub_nilfs2_data *data, - if (high >= grub_nilfs2_btree_node_nchildren_max (data, node)) - { - grub_error (GRUB_ERR_BAD_FS, "too many children"); -+ *indexp = index; - return 0; - } - -- index = 0; - s = 0; - while (low <= high) - { -@@ -526,6 +526,10 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data, - level = grub_nilfs2_btree_get_level (node); - - found = grub_nilfs2_btree_node_lookup (data, node, key, &index); -+ -+ if (grub_errno != GRUB_ERR_NONE) -+ goto fail; -+ - ptr = grub_nilfs2_btree_node_get_ptr (data, node, index); - if (need_translate) - ptr = grub_nilfs2_dat_translate (data, ptr); -@@ -550,7 +554,8 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data, - else - index = 0; - -- if (index < grub_nilfs2_btree_node_nchildren_max (data, node)) -+ if (index < grub_nilfs2_btree_node_nchildren_max (data, node) && -+ grub_errno == GRUB_ERR_NONE) - { - ptr = grub_nilfs2_btree_node_get_ptr (data, node, index); - if (need_translate) diff --git a/SOURCES/0411-io-gzio-Bail-if-gzio-tl-td-is-NULL.patch b/SOURCES/0411-io-gzio-Bail-if-gzio-tl-td-is-NULL.patch new file mode 100644 index 0000000..3bd30c5 --- /dev/null +++ b/SOURCES/0411-io-gzio-Bail-if-gzio-tl-td-is-NULL.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Wed, 13 Jan 2021 20:59:09 +1100 +Subject: [PATCH] io/gzio: Bail if gzio->tl/td is NULL + +This is an ugly fix that doesn't address why gzio->tl comes to be NULL. +However, it seems to be sufficient to patch up a bunch of NULL derefs. + +It would be good to revisit this in future and see if we can have +a cleaner solution that addresses some of the causes of the unexpected +NULL pointers. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/io/gzio.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c +index daf514bc482..09e0e2842f2 100644 +--- a/grub-core/io/gzio.c ++++ b/grub-core/io/gzio.c +@@ -657,6 +657,13 @@ inflate_codes_in_window (grub_gzio_t gzio) + { + if (! gzio->code_state) + { ++ ++ if (gzio->tl == NULL) ++ { ++ grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "NULL gzio->tl"); ++ return 1; ++ } ++ + NEEDBITS ((unsigned) gzio->bl); + if ((e = (t = gzio->tl + ((unsigned) b & ml))->e) > 16) + do +@@ -695,6 +702,12 @@ inflate_codes_in_window (grub_gzio_t gzio) + n = t->v.n + ((unsigned) b & mask_bits[e]); + DUMPBITS (e); + ++ if (gzio->td == NULL) ++ { ++ grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "NULL gzio->td"); ++ return 1; ++ } ++ + /* decode distance of block to copy */ + NEEDBITS ((unsigned) gzio->bd); + if ((e = (t = gzio->td + ((unsigned) b & md))->e) > 16) +@@ -905,6 +918,13 @@ init_dynamic_block (grub_gzio_t gzio) + n = nl + nd; + m = mask_bits[gzio->bl]; + i = l = 0; ++ ++ if (gzio->tl == NULL) ++ { ++ grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "NULL gzio->tl"); ++ return; ++ } ++ + while ((unsigned) i < n) + { + NEEDBITS ((unsigned) gzio->bl); diff --git a/SOURCES/0412-io-gzio-Add-init_dynamic_block-clean-up-if-unpacking.patch b/SOURCES/0412-io-gzio-Add-init_dynamic_block-clean-up-if-unpacking.patch new file mode 100644 index 0000000..0fd1fc1 --- /dev/null +++ b/SOURCES/0412-io-gzio-Add-init_dynamic_block-clean-up-if-unpacking.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Thu, 21 Jan 2021 00:05:58 +1100 +Subject: [PATCH] io/gzio: Add init_dynamic_block() clean up if unpacking codes + fails + +init_dynamic_block() didn't clean up gzio->tl and td in some error +paths. This left td pointing to part of tl. Then in grub_gzio_close(), +when tl was freed the storage for td would also be freed. The code then +attempts to free td explicitly, performing a UAF and then a double free. + +Explicitly clean up tl and td in the error paths. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/io/gzio.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c +index 09e0e2842f2..d3b12a61e61 100644 +--- a/grub-core/io/gzio.c ++++ b/grub-core/io/gzio.c +@@ -941,7 +941,7 @@ init_dynamic_block (grub_gzio_t gzio) + if ((unsigned) i + j > n) + { + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found"); +- return; ++ goto fail; + } + while (j--) + ll[i++] = l; +@@ -954,7 +954,7 @@ init_dynamic_block (grub_gzio_t gzio) + if ((unsigned) i + j > n) + { + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found"); +- return; ++ goto fail; + } + while (j--) + ll[i++] = 0; +@@ -969,7 +969,7 @@ init_dynamic_block (grub_gzio_t gzio) + if ((unsigned) i + j > n) + { + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found"); +- return; ++ goto fail; + } + while (j--) + ll[i++] = 0; +@@ -1007,6 +1007,12 @@ init_dynamic_block (grub_gzio_t gzio) + /* indicate we're now working on a block */ + gzio->code_state = 0; + gzio->block_len++; ++ return; ++ ++ fail: ++ huft_free (gzio->tl); ++ gzio->td = NULL; ++ gzio->tl = NULL; + } + + diff --git a/SOURCES/0412-io-gzio-Bail-if-gzio-tl-td-is-NULL.patch b/SOURCES/0412-io-gzio-Bail-if-gzio-tl-td-is-NULL.patch deleted file mode 100644 index 3bd30c5..0000000 --- a/SOURCES/0412-io-gzio-Bail-if-gzio-tl-td-is-NULL.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Wed, 13 Jan 2021 20:59:09 +1100 -Subject: [PATCH] io/gzio: Bail if gzio->tl/td is NULL - -This is an ugly fix that doesn't address why gzio->tl comes to be NULL. -However, it seems to be sufficient to patch up a bunch of NULL derefs. - -It would be good to revisit this in future and see if we can have -a cleaner solution that addresses some of the causes of the unexpected -NULL pointers. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/io/gzio.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c -index daf514bc482..09e0e2842f2 100644 ---- a/grub-core/io/gzio.c -+++ b/grub-core/io/gzio.c -@@ -657,6 +657,13 @@ inflate_codes_in_window (grub_gzio_t gzio) - { - if (! gzio->code_state) - { -+ -+ if (gzio->tl == NULL) -+ { -+ grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "NULL gzio->tl"); -+ return 1; -+ } -+ - NEEDBITS ((unsigned) gzio->bl); - if ((e = (t = gzio->tl + ((unsigned) b & ml))->e) > 16) - do -@@ -695,6 +702,12 @@ inflate_codes_in_window (grub_gzio_t gzio) - n = t->v.n + ((unsigned) b & mask_bits[e]); - DUMPBITS (e); - -+ if (gzio->td == NULL) -+ { -+ grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "NULL gzio->td"); -+ return 1; -+ } -+ - /* decode distance of block to copy */ - NEEDBITS ((unsigned) gzio->bd); - if ((e = (t = gzio->td + ((unsigned) b & md))->e) > 16) -@@ -905,6 +918,13 @@ init_dynamic_block (grub_gzio_t gzio) - n = nl + nd; - m = mask_bits[gzio->bl]; - i = l = 0; -+ -+ if (gzio->tl == NULL) -+ { -+ grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "NULL gzio->tl"); -+ return; -+ } -+ - while ((unsigned) i < n) - { - NEEDBITS ((unsigned) gzio->bl); diff --git a/SOURCES/0413-io-gzio-Add-init_dynamic_block-clean-up-if-unpacking.patch b/SOURCES/0413-io-gzio-Add-init_dynamic_block-clean-up-if-unpacking.patch deleted file mode 100644 index 0fd1fc1..0000000 --- a/SOURCES/0413-io-gzio-Add-init_dynamic_block-clean-up-if-unpacking.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Thu, 21 Jan 2021 00:05:58 +1100 -Subject: [PATCH] io/gzio: Add init_dynamic_block() clean up if unpacking codes - fails - -init_dynamic_block() didn't clean up gzio->tl and td in some error -paths. This left td pointing to part of tl. Then in grub_gzio_close(), -when tl was freed the storage for td would also be freed. The code then -attempts to free td explicitly, performing a UAF and then a double free. - -Explicitly clean up tl and td in the error paths. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/io/gzio.c | 12 +++++++++--- - 1 file changed, 9 insertions(+), 3 deletions(-) - -diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c -index 09e0e2842f2..d3b12a61e61 100644 ---- a/grub-core/io/gzio.c -+++ b/grub-core/io/gzio.c -@@ -941,7 +941,7 @@ init_dynamic_block (grub_gzio_t gzio) - if ((unsigned) i + j > n) - { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found"); -- return; -+ goto fail; - } - while (j--) - ll[i++] = l; -@@ -954,7 +954,7 @@ init_dynamic_block (grub_gzio_t gzio) - if ((unsigned) i + j > n) - { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found"); -- return; -+ goto fail; - } - while (j--) - ll[i++] = 0; -@@ -969,7 +969,7 @@ init_dynamic_block (grub_gzio_t gzio) - if ((unsigned) i + j > n) - { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found"); -- return; -+ goto fail; - } - while (j--) - ll[i++] = 0; -@@ -1007,6 +1007,12 @@ init_dynamic_block (grub_gzio_t gzio) - /* indicate we're now working on a block */ - gzio->code_state = 0; - gzio->block_len++; -+ return; -+ -+ fail: -+ huft_free (gzio->tl); -+ gzio->td = NULL; -+ gzio->tl = NULL; - } - - diff --git a/SOURCES/0413-io-gzio-Catch-missing-values-in-huft_build-and-bail.patch b/SOURCES/0413-io-gzio-Catch-missing-values-in-huft_build-and-bail.patch new file mode 100644 index 0000000..4302771 --- /dev/null +++ b/SOURCES/0413-io-gzio-Catch-missing-values-in-huft_build-and-bail.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Thu, 21 Jan 2021 12:20:49 +1100 +Subject: [PATCH] io/gzio: Catch missing values in huft_build() and bail + +In huft_build(), "v" is a table of values in order of bit length. +The code later (when setting up table entries in "r") assumes that all +elements of this array corresponding to a code are initialized and less +than N_MAX. However, it doesn't enforce this. + +With sufficiently manipulated inputs (e.g. from fuzzing), there can be +elements of "v" that are not filled. Therefore a lookup into "e" or "d" +will use an uninitialized value. This can lead to an invalid/OOB read on +those values, often leading to a crash. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/io/gzio.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c +index d3b12a61e61..3e14347827b 100644 +--- a/grub-core/io/gzio.c ++++ b/grub-core/io/gzio.c +@@ -495,6 +495,7 @@ huft_build (unsigned *b, /* code lengths in bits (all assumed <= BMAX) */ + } + + /* Make a table of values in order of bit lengths */ ++ grub_memset (v, N_MAX, ARRAY_SIZE (v)); + p = b; + i = 0; + do +@@ -576,11 +577,18 @@ huft_build (unsigned *b, /* code lengths in bits (all assumed <= BMAX) */ + r.v.n = (ush) (*p); /* simple code is just the value */ + p++; /* one compiler does not like *p++ */ + } +- else ++ else if (*p < N_MAX) + { + r.e = (uch) e[*p - s]; /* non-simple--look up in lists */ + r.v.n = d[*p++ - s]; + } ++ else ++ { ++ /* Detected an uninitialised value, abort. */ ++ if (h) ++ huft_free (u[0]); ++ return 2; ++ } + + /* fill code-like entries with r */ + f = 1 << (k - w); diff --git a/SOURCES/0414-io-gzio-Catch-missing-values-in-huft_build-and-bail.patch b/SOURCES/0414-io-gzio-Catch-missing-values-in-huft_build-and-bail.patch deleted file mode 100644 index 4302771..0000000 --- a/SOURCES/0414-io-gzio-Catch-missing-values-in-huft_build-and-bail.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Thu, 21 Jan 2021 12:20:49 +1100 -Subject: [PATCH] io/gzio: Catch missing values in huft_build() and bail - -In huft_build(), "v" is a table of values in order of bit length. -The code later (when setting up table entries in "r") assumes that all -elements of this array corresponding to a code are initialized and less -than N_MAX. However, it doesn't enforce this. - -With sufficiently manipulated inputs (e.g. from fuzzing), there can be -elements of "v" that are not filled. Therefore a lookup into "e" or "d" -will use an uninitialized value. This can lead to an invalid/OOB read on -those values, often leading to a crash. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/io/gzio.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c -index d3b12a61e61..3e14347827b 100644 ---- a/grub-core/io/gzio.c -+++ b/grub-core/io/gzio.c -@@ -495,6 +495,7 @@ huft_build (unsigned *b, /* code lengths in bits (all assumed <= BMAX) */ - } - - /* Make a table of values in order of bit lengths */ -+ grub_memset (v, N_MAX, ARRAY_SIZE (v)); - p = b; - i = 0; - do -@@ -576,11 +577,18 @@ huft_build (unsigned *b, /* code lengths in bits (all assumed <= BMAX) */ - r.v.n = (ush) (*p); /* simple code is just the value */ - p++; /* one compiler does not like *p++ */ - } -- else -+ else if (*p < N_MAX) - { - r.e = (uch) e[*p - s]; /* non-simple--look up in lists */ - r.v.n = d[*p++ - s]; - } -+ else -+ { -+ /* Detected an uninitialised value, abort. */ -+ if (h) -+ huft_free (u[0]); -+ return 2; -+ } - - /* fill code-like entries with r */ - f = 1 << (k - w); diff --git a/SOURCES/0414-io-gzio-Zero-gzio-tl-td-in-init_dynamic_block-if-huf.patch b/SOURCES/0414-io-gzio-Zero-gzio-tl-td-in-init_dynamic_block-if-huf.patch new file mode 100644 index 0000000..e9bb063 --- /dev/null +++ b/SOURCES/0414-io-gzio-Zero-gzio-tl-td-in-init_dynamic_block-if-huf.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Thu, 21 Jan 2021 12:22:28 +1100 +Subject: [PATCH] io/gzio: Zero gzio->tl/td in init_dynamic_block() if + huft_build() fails + +If huft_build() fails, gzio->tl or gzio->td could contain pointers that +are no longer valid. Zero them out. + +This prevents a double free when grub_gzio_close() comes through and +attempts to free them again. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/io/gzio.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c +index 3e14347827b..070e8727698 100644 +--- a/grub-core/io/gzio.c ++++ b/grub-core/io/gzio.c +@@ -998,6 +998,7 @@ init_dynamic_block (grub_gzio_t gzio) + gzio->bl = lbits; + if (huft_build (ll, nl, 257, cplens, cplext, &gzio->tl, &gzio->bl) != 0) + { ++ gzio->tl = 0; + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + "failed in building a Huffman code table"); + return; +@@ -1007,6 +1008,7 @@ init_dynamic_block (grub_gzio_t gzio) + { + huft_free (gzio->tl); + gzio->tl = 0; ++ gzio->td = 0; + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + "failed in building a Huffman code table"); + return; diff --git a/SOURCES/0415-disk-lvm-Don-t-go-beyond-the-end-of-the-data-we-read.patch b/SOURCES/0415-disk-lvm-Don-t-go-beyond-the-end-of-the-data-we-read.patch new file mode 100644 index 0000000..95c426e --- /dev/null +++ b/SOURCES/0415-disk-lvm-Don-t-go-beyond-the-end-of-the-data-we-read.patch @@ -0,0 +1,45 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Thu, 21 Jan 2021 17:59:14 +1100 +Subject: [PATCH] disk/lvm: Don't go beyond the end of the data we read from + disk + +We unconditionally trusted offset_xl from the LVM label header, even if +it told us that the PV header/disk locations were way off past the end +of the data we read from disk. + +Require that the offset be sane, fixing an OOB read and crash. + +Fixes: CID 314367, CID 314371 + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/disk/lvm.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c +index 5fa9f562e4f..43e2f6ddf3c 100644 +--- a/grub-core/disk/lvm.c ++++ b/grub-core/disk/lvm.c +@@ -142,6 +142,20 @@ grub_lvm_detect (grub_disk_t disk, + goto fail; + } + ++ /* ++ * We read a grub_lvm_pv_header and then 2 grub_lvm_disk_locns that ++ * immediately follow the PV header. Make sure we have space for both. ++ */ ++ if (grub_le_to_cpu32 (lh->offset_xl) >= ++ GRUB_LVM_LABEL_SIZE - sizeof (struct grub_lvm_pv_header) - ++ 2 * sizeof (struct grub_lvm_disk_locn)) ++ { ++#ifdef GRUB_UTIL ++ grub_util_info ("LVM PV header/disk locations are beyond the end of the block"); ++#endif ++ goto fail; ++ } ++ + pvh = (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl)); + + for (i = 0, j = 0; i < GRUB_LVM_ID_LEN; i++) diff --git a/SOURCES/0415-io-gzio-Zero-gzio-tl-td-in-init_dynamic_block-if-huf.patch b/SOURCES/0415-io-gzio-Zero-gzio-tl-td-in-init_dynamic_block-if-huf.patch deleted file mode 100644 index e9bb063..0000000 --- a/SOURCES/0415-io-gzio-Zero-gzio-tl-td-in-init_dynamic_block-if-huf.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Thu, 21 Jan 2021 12:22:28 +1100 -Subject: [PATCH] io/gzio: Zero gzio->tl/td in init_dynamic_block() if - huft_build() fails - -If huft_build() fails, gzio->tl or gzio->td could contain pointers that -are no longer valid. Zero them out. - -This prevents a double free when grub_gzio_close() comes through and -attempts to free them again. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/io/gzio.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c -index 3e14347827b..070e8727698 100644 ---- a/grub-core/io/gzio.c -+++ b/grub-core/io/gzio.c -@@ -998,6 +998,7 @@ init_dynamic_block (grub_gzio_t gzio) - gzio->bl = lbits; - if (huft_build (ll, nl, 257, cplens, cplext, &gzio->tl, &gzio->bl) != 0) - { -+ gzio->tl = 0; - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, - "failed in building a Huffman code table"); - return; -@@ -1007,6 +1008,7 @@ init_dynamic_block (grub_gzio_t gzio) - { - huft_free (gzio->tl); - gzio->tl = 0; -+ gzio->td = 0; - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, - "failed in building a Huffman code table"); - return; diff --git a/SOURCES/0416-disk-lvm-Don-t-blast-past-the-end-of-the-circular-me.patch b/SOURCES/0416-disk-lvm-Don-t-blast-past-the-end-of-the-circular-me.patch new file mode 100644 index 0000000..525de2b --- /dev/null +++ b/SOURCES/0416-disk-lvm-Don-t-blast-past-the-end-of-the-circular-me.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Thu, 21 Jan 2021 18:19:51 +1100 +Subject: [PATCH] disk/lvm: Don't blast past the end of the circular metadata + buffer + +This catches at least some OOB reads, and it's possible I suppose that +if 2 * mda_size is less than GRUB_LVM_MDA_HEADER_SIZE it might catch some +OOB writes too (although that hasn't showed up as a crash in fuzzing yet). + +It's a bit ugly and I'd appreciate better suggestions. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/disk/lvm.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c +index 43e2f6ddf3c..7a8d61ffb20 100644 +--- a/grub-core/disk/lvm.c ++++ b/grub-core/disk/lvm.c +@@ -215,6 +215,16 @@ grub_lvm_detect (grub_disk_t disk, + if (grub_le_to_cpu64 (rlocn->offset) + grub_le_to_cpu64 (rlocn->size) > + grub_le_to_cpu64 (mdah->size)) + { ++ if (2 * mda_size < GRUB_LVM_MDA_HEADER_SIZE || ++ (grub_le_to_cpu64 (rlocn->offset) + grub_le_to_cpu64 (rlocn->size) - ++ grub_le_to_cpu64 (mdah->size) > mda_size - GRUB_LVM_MDA_HEADER_SIZE)) ++ { ++#ifdef GRUB_UTIL ++ grub_util_info ("cannot copy metadata wrap in circular buffer"); ++#endif ++ goto fail2; ++ } ++ + /* Metadata is circular. Copy the wrap in place. */ + grub_memcpy (metadatabuf + mda_size, + metadatabuf + GRUB_LVM_MDA_HEADER_SIZE, diff --git a/SOURCES/0416-disk-lvm-Don-t-go-beyond-the-end-of-the-data-we-read.patch b/SOURCES/0416-disk-lvm-Don-t-go-beyond-the-end-of-the-data-we-read.patch deleted file mode 100644 index 95c426e..0000000 --- a/SOURCES/0416-disk-lvm-Don-t-go-beyond-the-end-of-the-data-we-read.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Thu, 21 Jan 2021 17:59:14 +1100 -Subject: [PATCH] disk/lvm: Don't go beyond the end of the data we read from - disk - -We unconditionally trusted offset_xl from the LVM label header, even if -it told us that the PV header/disk locations were way off past the end -of the data we read from disk. - -Require that the offset be sane, fixing an OOB read and crash. - -Fixes: CID 314367, CID 314371 - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/disk/lvm.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c -index 5fa9f562e4f..43e2f6ddf3c 100644 ---- a/grub-core/disk/lvm.c -+++ b/grub-core/disk/lvm.c -@@ -142,6 +142,20 @@ grub_lvm_detect (grub_disk_t disk, - goto fail; - } - -+ /* -+ * We read a grub_lvm_pv_header and then 2 grub_lvm_disk_locns that -+ * immediately follow the PV header. Make sure we have space for both. -+ */ -+ if (grub_le_to_cpu32 (lh->offset_xl) >= -+ GRUB_LVM_LABEL_SIZE - sizeof (struct grub_lvm_pv_header) - -+ 2 * sizeof (struct grub_lvm_disk_locn)) -+ { -+#ifdef GRUB_UTIL -+ grub_util_info ("LVM PV header/disk locations are beyond the end of the block"); -+#endif -+ goto fail; -+ } -+ - pvh = (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl)); - - for (i = 0, j = 0; i < GRUB_LVM_ID_LEN; i++) diff --git a/SOURCES/0417-disk-lvm-Bail-on-missing-PV-list.patch b/SOURCES/0417-disk-lvm-Bail-on-missing-PV-list.patch new file mode 100644 index 0000000..e2d947c --- /dev/null +++ b/SOURCES/0417-disk-lvm-Bail-on-missing-PV-list.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Thu, 21 Jan 2021 18:54:29 +1100 +Subject: [PATCH] disk/lvm: Bail on missing PV list + +There's an if block for the presence of "physical_volumes {", but if +that block is absent, then p remains NULL and a NULL-deref will result +when looking for logical volumes. + +It doesn't seem like LVM makes sense without physical volumes, so error +out rather than crashing. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/disk/lvm.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c +index 7a8d61ffb20..939afa17d28 100644 +--- a/grub-core/disk/lvm.c ++++ b/grub-core/disk/lvm.c +@@ -371,6 +371,8 @@ error_parsing_metadata: + goto fail4; + } + } ++ else ++ goto fail4; + + p = grub_strstr (p, "logical_volumes {"); + if (p) diff --git a/SOURCES/0417-disk-lvm-Don-t-blast-past-the-end-of-the-circular-me.patch b/SOURCES/0417-disk-lvm-Don-t-blast-past-the-end-of-the-circular-me.patch deleted file mode 100644 index 525de2b..0000000 --- a/SOURCES/0417-disk-lvm-Don-t-blast-past-the-end-of-the-circular-me.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Thu, 21 Jan 2021 18:19:51 +1100 -Subject: [PATCH] disk/lvm: Don't blast past the end of the circular metadata - buffer - -This catches at least some OOB reads, and it's possible I suppose that -if 2 * mda_size is less than GRUB_LVM_MDA_HEADER_SIZE it might catch some -OOB writes too (although that hasn't showed up as a crash in fuzzing yet). - -It's a bit ugly and I'd appreciate better suggestions. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/disk/lvm.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c -index 43e2f6ddf3c..7a8d61ffb20 100644 ---- a/grub-core/disk/lvm.c -+++ b/grub-core/disk/lvm.c -@@ -215,6 +215,16 @@ grub_lvm_detect (grub_disk_t disk, - if (grub_le_to_cpu64 (rlocn->offset) + grub_le_to_cpu64 (rlocn->size) > - grub_le_to_cpu64 (mdah->size)) - { -+ if (2 * mda_size < GRUB_LVM_MDA_HEADER_SIZE || -+ (grub_le_to_cpu64 (rlocn->offset) + grub_le_to_cpu64 (rlocn->size) - -+ grub_le_to_cpu64 (mdah->size) > mda_size - GRUB_LVM_MDA_HEADER_SIZE)) -+ { -+#ifdef GRUB_UTIL -+ grub_util_info ("cannot copy metadata wrap in circular buffer"); -+#endif -+ goto fail2; -+ } -+ - /* Metadata is circular. Copy the wrap in place. */ - grub_memcpy (metadatabuf + mda_size, - metadatabuf + GRUB_LVM_MDA_HEADER_SIZE, diff --git a/SOURCES/0418-disk-lvm-Bail-on-missing-PV-list.patch b/SOURCES/0418-disk-lvm-Bail-on-missing-PV-list.patch deleted file mode 100644 index e2d947c..0000000 --- a/SOURCES/0418-disk-lvm-Bail-on-missing-PV-list.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Thu, 21 Jan 2021 18:54:29 +1100 -Subject: [PATCH] disk/lvm: Bail on missing PV list - -There's an if block for the presence of "physical_volumes {", but if -that block is absent, then p remains NULL and a NULL-deref will result -when looking for logical volumes. - -It doesn't seem like LVM makes sense without physical volumes, so error -out rather than crashing. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/disk/lvm.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c -index 7a8d61ffb20..939afa17d28 100644 ---- a/grub-core/disk/lvm.c -+++ b/grub-core/disk/lvm.c -@@ -371,6 +371,8 @@ error_parsing_metadata: - goto fail4; - } - } -+ else -+ goto fail4; - - p = grub_strstr (p, "logical_volumes {"); - if (p) diff --git a/SOURCES/0418-disk-lvm-Do-not-crash-if-an-expected-string-is-not-f.patch b/SOURCES/0418-disk-lvm-Do-not-crash-if-an-expected-string-is-not-f.patch new file mode 100644 index 0000000..b21f2ba --- /dev/null +++ b/SOURCES/0418-disk-lvm-Do-not-crash-if-an-expected-string-is-not-f.patch @@ -0,0 +1,79 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Thu, 21 Jan 2021 18:35:22 +1100 +Subject: [PATCH] disk/lvm: Do not crash if an expected string is not found + +Clean up a bunch of cases where we could have strstr() fail and lead to +us dereferencing NULL. + +We'll still leak memory in some cases (loops don't clean up allocations +from earlier iterations if a later iteration fails) but at least we're +not crashing. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/disk/lvm.c | 22 +++++++++++++++++----- + 1 file changed, 17 insertions(+), 5 deletions(-) + +diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c +index 939afa17d28..7776a0a0a07 100644 +--- a/grub-core/disk/lvm.c ++++ b/grub-core/disk/lvm.c +@@ -541,7 +541,16 @@ error_parsing_metadata: + } + + if (seg->node_count != 1) +- seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = "); ++ { ++ seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = "); ++ if (p == NULL) ++ { ++#ifdef GRUB_UTIL ++ grub_util_info ("unknown stripe_size"); ++#endif ++ goto lvs_segment_fail; ++ } ++ } + + seg->nodes = grub_calloc (seg->node_count, + sizeof (*stripe)); +@@ -561,7 +570,7 @@ error_parsing_metadata: + { + p = grub_strchr (p, '"'); + if (p == NULL) +- continue; ++ goto lvs_segment_fail2; + q = ++p; + while (*q != '"') + q++; +@@ -580,7 +589,10 @@ error_parsing_metadata: + stripe->start = grub_lvm_getvalue (&p, ",") + * vg->extent_size; + if (p == NULL) +- continue; ++ { ++ grub_free (stripe->name); ++ goto lvs_segment_fail2; ++ } + + stripe++; + } +@@ -617,7 +629,7 @@ error_parsing_metadata: + + p = grub_strchr (p, '"'); + if (p == NULL) +- continue; ++ goto lvs_segment_fail2; + q = ++p; + while (*q != '"') + q++; +@@ -699,7 +711,7 @@ error_parsing_metadata: + p = p ? grub_strchr (p + 1, '"') : 0; + p = p ? grub_strchr (p + 1, '"') : 0; + if (p == NULL) +- continue; ++ goto lvs_segment_fail2; + q = ++p; + while (*q != '"') + q++; diff --git a/SOURCES/0419-disk-lvm-Do-not-crash-if-an-expected-string-is-not-f.patch b/SOURCES/0419-disk-lvm-Do-not-crash-if-an-expected-string-is-not-f.patch deleted file mode 100644 index b21f2ba..0000000 --- a/SOURCES/0419-disk-lvm-Do-not-crash-if-an-expected-string-is-not-f.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Thu, 21 Jan 2021 18:35:22 +1100 -Subject: [PATCH] disk/lvm: Do not crash if an expected string is not found - -Clean up a bunch of cases where we could have strstr() fail and lead to -us dereferencing NULL. - -We'll still leak memory in some cases (loops don't clean up allocations -from earlier iterations if a later iteration fails) but at least we're -not crashing. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/disk/lvm.c | 22 +++++++++++++++++----- - 1 file changed, 17 insertions(+), 5 deletions(-) - -diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c -index 939afa17d28..7776a0a0a07 100644 ---- a/grub-core/disk/lvm.c -+++ b/grub-core/disk/lvm.c -@@ -541,7 +541,16 @@ error_parsing_metadata: - } - - if (seg->node_count != 1) -- seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = "); -+ { -+ seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = "); -+ if (p == NULL) -+ { -+#ifdef GRUB_UTIL -+ grub_util_info ("unknown stripe_size"); -+#endif -+ goto lvs_segment_fail; -+ } -+ } - - seg->nodes = grub_calloc (seg->node_count, - sizeof (*stripe)); -@@ -561,7 +570,7 @@ error_parsing_metadata: - { - p = grub_strchr (p, '"'); - if (p == NULL) -- continue; -+ goto lvs_segment_fail2; - q = ++p; - while (*q != '"') - q++; -@@ -580,7 +589,10 @@ error_parsing_metadata: - stripe->start = grub_lvm_getvalue (&p, ",") - * vg->extent_size; - if (p == NULL) -- continue; -+ { -+ grub_free (stripe->name); -+ goto lvs_segment_fail2; -+ } - - stripe++; - } -@@ -617,7 +629,7 @@ error_parsing_metadata: - - p = grub_strchr (p, '"'); - if (p == NULL) -- continue; -+ goto lvs_segment_fail2; - q = ++p; - while (*q != '"') - q++; -@@ -699,7 +711,7 @@ error_parsing_metadata: - p = p ? grub_strchr (p + 1, '"') : 0; - p = p ? grub_strchr (p + 1, '"') : 0; - if (p == NULL) -- continue; -+ goto lvs_segment_fail2; - q = ++p; - while (*q != '"') - q++; diff --git a/SOURCES/0419-disk-lvm-Do-not-overread-metadata.patch b/SOURCES/0419-disk-lvm-Do-not-overread-metadata.patch new file mode 100644 index 0000000..be71eed --- /dev/null +++ b/SOURCES/0419-disk-lvm-Do-not-overread-metadata.patch @@ -0,0 +1,107 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Thu, 21 Jan 2021 18:35:22 +1100 +Subject: [PATCH] disk/lvm: Do not overread metadata + +We could reach the end of valid metadata and not realize, leading to +some buffer overreads. Check if we have reached the end and bail. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/disk/lvm.c | 31 +++++++++++++++++++++++++------ + 1 file changed, 25 insertions(+), 6 deletions(-) + +diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c +index 7776a0a0a07..5fb1b69091c 100644 +--- a/grub-core/disk/lvm.c ++++ b/grub-core/disk/lvm.c +@@ -314,17 +314,23 @@ error_parsing_metadata: + while (1) + { + grub_ssize_t s; +- while (grub_isspace (*p)) ++ while (grub_isspace (*p) && p < mda_end) + p++; + ++ if (p == mda_end) ++ goto fail4; ++ + if (*p == '}') + break; + + pv = grub_zalloc (sizeof (*pv)); + q = p; +- while (*q != ' ') ++ while (*q != ' ' && q < mda_end) + q++; + ++ if (q == mda_end) ++ goto pvs_fail_noname; ++ + s = q - p; + pv->name = grub_malloc (s + 1); + grub_memcpy (pv->name, p, s); +@@ -367,6 +373,7 @@ error_parsing_metadata: + continue; + pvs_fail: + grub_free (pv->name); ++ pvs_fail_noname: + grub_free (pv); + goto fail4; + } +@@ -388,18 +395,24 @@ error_parsing_metadata: + struct grub_diskfilter_segment *seg; + int is_pvmove; + +- while (grub_isspace (*p)) ++ while (grub_isspace (*p) && p < mda_end) + p++; + ++ if (p == mda_end) ++ goto fail4; ++ + if (*p == '}') + break; + + lv = grub_zalloc (sizeof (*lv)); + + q = p; +- while (*q != ' ') ++ while (*q != ' ' && q < mda_end) + q++; + ++ if (q == mda_end) ++ goto lvs_fail; ++ + s = q - p; + lv->name = grub_strndup (p, s); + if (!lv->name) +@@ -572,9 +585,12 @@ error_parsing_metadata: + if (p == NULL) + goto lvs_segment_fail2; + q = ++p; +- while (*q != '"') ++ while (q < mda_end && *q != '"') + q++; + ++ if (q == mda_end) ++ goto lvs_segment_fail2; ++ + s = q - p; + + stripe->name = grub_malloc (s + 1); +@@ -631,9 +647,12 @@ error_parsing_metadata: + if (p == NULL) + goto lvs_segment_fail2; + q = ++p; +- while (*q != '"') ++ while (q < mda_end && *q != '"') + q++; + ++ if (q == mda_end) ++ goto lvs_segment_fail2; ++ + s = q - p; + + lvname = grub_malloc (s + 1); diff --git a/SOURCES/0420-disk-lvm-Do-not-overread-metadata.patch b/SOURCES/0420-disk-lvm-Do-not-overread-metadata.patch deleted file mode 100644 index be71eed..0000000 --- a/SOURCES/0420-disk-lvm-Do-not-overread-metadata.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Thu, 21 Jan 2021 18:35:22 +1100 -Subject: [PATCH] disk/lvm: Do not overread metadata - -We could reach the end of valid metadata and not realize, leading to -some buffer overreads. Check if we have reached the end and bail. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/disk/lvm.c | 31 +++++++++++++++++++++++++------ - 1 file changed, 25 insertions(+), 6 deletions(-) - -diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c -index 7776a0a0a07..5fb1b69091c 100644 ---- a/grub-core/disk/lvm.c -+++ b/grub-core/disk/lvm.c -@@ -314,17 +314,23 @@ error_parsing_metadata: - while (1) - { - grub_ssize_t s; -- while (grub_isspace (*p)) -+ while (grub_isspace (*p) && p < mda_end) - p++; - -+ if (p == mda_end) -+ goto fail4; -+ - if (*p == '}') - break; - - pv = grub_zalloc (sizeof (*pv)); - q = p; -- while (*q != ' ') -+ while (*q != ' ' && q < mda_end) - q++; - -+ if (q == mda_end) -+ goto pvs_fail_noname; -+ - s = q - p; - pv->name = grub_malloc (s + 1); - grub_memcpy (pv->name, p, s); -@@ -367,6 +373,7 @@ error_parsing_metadata: - continue; - pvs_fail: - grub_free (pv->name); -+ pvs_fail_noname: - grub_free (pv); - goto fail4; - } -@@ -388,18 +395,24 @@ error_parsing_metadata: - struct grub_diskfilter_segment *seg; - int is_pvmove; - -- while (grub_isspace (*p)) -+ while (grub_isspace (*p) && p < mda_end) - p++; - -+ if (p == mda_end) -+ goto fail4; -+ - if (*p == '}') - break; - - lv = grub_zalloc (sizeof (*lv)); - - q = p; -- while (*q != ' ') -+ while (*q != ' ' && q < mda_end) - q++; - -+ if (q == mda_end) -+ goto lvs_fail; -+ - s = q - p; - lv->name = grub_strndup (p, s); - if (!lv->name) -@@ -572,9 +585,12 @@ error_parsing_metadata: - if (p == NULL) - goto lvs_segment_fail2; - q = ++p; -- while (*q != '"') -+ while (q < mda_end && *q != '"') - q++; - -+ if (q == mda_end) -+ goto lvs_segment_fail2; -+ - s = q - p; - - stripe->name = grub_malloc (s + 1); -@@ -631,9 +647,12 @@ error_parsing_metadata: - if (p == NULL) - goto lvs_segment_fail2; - q = ++p; -- while (*q != '"') -+ while (q < mda_end && *q != '"') - q++; - -+ if (q == mda_end) -+ goto lvs_segment_fail2; -+ - s = q - p; - - lvname = grub_malloc (s + 1); diff --git a/SOURCES/0420-disk-lvm-Sanitize-rlocn-offset-to-prevent-wild-read.patch b/SOURCES/0420-disk-lvm-Sanitize-rlocn-offset-to-prevent-wild-read.patch new file mode 100644 index 0000000..bee39f6 --- /dev/null +++ b/SOURCES/0420-disk-lvm-Sanitize-rlocn-offset-to-prevent-wild-read.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Fri, 22 Jan 2021 14:43:58 +1100 +Subject: [PATCH] disk/lvm: Sanitize rlocn->offset to prevent wild read + +rlocn->offset is read directly from disk and added to the metadatabuf +pointer to create a pointer to a block of metadata. It's a 64-bit +quantity so as long as you don't overflow you can set subsequent +pointers to point anywhere in memory. + +Require that rlocn->offset fits within the metadata buffer size. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/disk/lvm.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c +index 5fb1b69091c..7356ee83935 100644 +--- a/grub-core/disk/lvm.c ++++ b/grub-core/disk/lvm.c +@@ -212,6 +212,14 @@ grub_lvm_detect (grub_disk_t disk, + } + + rlocn = mdah->raw_locns; ++ if (grub_le_to_cpu64 (rlocn->offset) >= grub_le_to_cpu64 (mda_size)) ++ { ++#ifdef GRUB_UTIL ++ grub_util_info ("metadata offset is beyond end of metadata area"); ++#endif ++ goto fail2; ++ } ++ + if (grub_le_to_cpu64 (rlocn->offset) + grub_le_to_cpu64 (rlocn->size) > + grub_le_to_cpu64 (mdah->size)) + { diff --git a/SOURCES/0421-disk-lvm-Do-not-allow-a-LV-to-be-it-s-own-segment-s-.patch b/SOURCES/0421-disk-lvm-Do-not-allow-a-LV-to-be-it-s-own-segment-s-.patch new file mode 100644 index 0000000..33a6501 --- /dev/null +++ b/SOURCES/0421-disk-lvm-Do-not-allow-a-LV-to-be-it-s-own-segment-s-.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Fri, 22 Jan 2021 14:42:21 +1100 +Subject: [PATCH] disk/lvm: Do not allow a LV to be it's own segment's node's + LV + +This prevents infinite recursion in the diskfilter verification code. + +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/disk/lvm.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c +index 7356ee83935..937af0a48be 100644 +--- a/grub-core/disk/lvm.c ++++ b/grub-core/disk/lvm.c +@@ -834,9 +834,13 @@ error_parsing_metadata: + } + if (lv1->segments[i].nodes[j].pv == NULL) + for (lv2 = vg->lvs; lv2; lv2 = lv2->next) +- if (grub_strcmp (lv2->name, +- lv1->segments[i].nodes[j].name) == 0) +- lv1->segments[i].nodes[j].lv = lv2; ++ { ++ if (lv1 == lv2) ++ continue; ++ if (grub_strcmp (lv2->name, ++ lv1->segments[i].nodes[j].name) == 0) ++ lv1->segments[i].nodes[j].lv = lv2; ++ } + } + + } diff --git a/SOURCES/0421-disk-lvm-Sanitize-rlocn-offset-to-prevent-wild-read.patch b/SOURCES/0421-disk-lvm-Sanitize-rlocn-offset-to-prevent-wild-read.patch deleted file mode 100644 index bee39f6..0000000 --- a/SOURCES/0421-disk-lvm-Sanitize-rlocn-offset-to-prevent-wild-read.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 22 Jan 2021 14:43:58 +1100 -Subject: [PATCH] disk/lvm: Sanitize rlocn->offset to prevent wild read - -rlocn->offset is read directly from disk and added to the metadatabuf -pointer to create a pointer to a block of metadata. It's a 64-bit -quantity so as long as you don't overflow you can set subsequent -pointers to point anywhere in memory. - -Require that rlocn->offset fits within the metadata buffer size. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/disk/lvm.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c -index 5fb1b69091c..7356ee83935 100644 ---- a/grub-core/disk/lvm.c -+++ b/grub-core/disk/lvm.c -@@ -212,6 +212,14 @@ grub_lvm_detect (grub_disk_t disk, - } - - rlocn = mdah->raw_locns; -+ if (grub_le_to_cpu64 (rlocn->offset) >= grub_le_to_cpu64 (mda_size)) -+ { -+#ifdef GRUB_UTIL -+ grub_util_info ("metadata offset is beyond end of metadata area"); -+#endif -+ goto fail2; -+ } -+ - if (grub_le_to_cpu64 (rlocn->offset) + grub_le_to_cpu64 (rlocn->size) > - grub_le_to_cpu64 (mdah->size)) - { diff --git a/SOURCES/0422-disk-lvm-Do-not-allow-a-LV-to-be-it-s-own-segment-s-.patch b/SOURCES/0422-disk-lvm-Do-not-allow-a-LV-to-be-it-s-own-segment-s-.patch deleted file mode 100644 index 33a6501..0000000 --- a/SOURCES/0422-disk-lvm-Do-not-allow-a-LV-to-be-it-s-own-segment-s-.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 22 Jan 2021 14:42:21 +1100 -Subject: [PATCH] disk/lvm: Do not allow a LV to be it's own segment's node's - LV - -This prevents infinite recursion in the diskfilter verification code. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/disk/lvm.c | 10 +++++++--- - 1 file changed, 7 insertions(+), 3 deletions(-) - -diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c -index 7356ee83935..937af0a48be 100644 ---- a/grub-core/disk/lvm.c -+++ b/grub-core/disk/lvm.c -@@ -834,9 +834,13 @@ error_parsing_metadata: - } - if (lv1->segments[i].nodes[j].pv == NULL) - for (lv2 = vg->lvs; lv2; lv2 = lv2->next) -- if (grub_strcmp (lv2->name, -- lv1->segments[i].nodes[j].name) == 0) -- lv1->segments[i].nodes[j].lv = lv2; -+ { -+ if (lv1 == lv2) -+ continue; -+ if (grub_strcmp (lv2->name, -+ lv1->segments[i].nodes[j].name) == 0) -+ lv1->segments[i].nodes[j].lv = lv2; -+ } - } - - } diff --git a/SOURCES/0422-kern-parser-Fix-a-memory-leak.patch b/SOURCES/0422-kern-parser-Fix-a-memory-leak.patch new file mode 100644 index 0000000..66171e9 --- /dev/null +++ b/SOURCES/0422-kern-parser-Fix-a-memory-leak.patch @@ -0,0 +1,73 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chris Coulson +Date: Wed, 18 Nov 2020 00:59:24 +0000 +Subject: [PATCH] kern/parser: Fix a memory leak + +The getline() function supplied to grub_parser_split_cmdline() returns +a newly allocated buffer and can be called multiple times, but the +returned buffer is never freed. + +Signed-off-by: Chris Coulson +Reviewed-by: Daniel Kiper +--- + grub-core/kern/parser.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c +index 94e8728d59a..23ebebf5ffa 100644 +--- a/grub-core/kern/parser.c ++++ b/grub-core/kern/parser.c +@@ -140,6 +140,7 @@ grub_parser_split_cmdline (const char *cmdline, + char buffer[1024]; + char *bp = buffer; + char *rd = (char *) cmdline; ++ char *rp = rd; + char varname[200]; + char *vp = varname; + char *args; +@@ -149,10 +150,18 @@ grub_parser_split_cmdline (const char *cmdline, + *argv = NULL; + do + { +- if (!rd || !*rd) ++ if (rp == NULL || *rp == '\0') + { ++ if (rd != cmdline) ++ { ++ grub_free (rd); ++ rd = rp = NULL; ++ } + if (getline) +- getline (&rd, 1, getline_data); ++ { ++ getline (&rd, 1, getline_data); ++ rp = rd; ++ } + else + break; + } +@@ -160,12 +169,12 @@ grub_parser_split_cmdline (const char *cmdline, + if (!rd) + break; + +- for (; *rd; rd++) ++ for (; *rp != '\0'; rp++) + { + grub_parser_state_t newstate; + char use; + +- newstate = grub_parser_cmdline_state (state, *rd, &use); ++ newstate = grub_parser_cmdline_state (state, *rp, &use); + + /* If a variable was being processed and this character does + not describe the variable anymore, write the variable to +@@ -198,6 +207,9 @@ grub_parser_split_cmdline (const char *cmdline, + } + while (state != GRUB_PARSER_STATE_TEXT && !check_varstate (state)); + ++ if (rd != cmdline) ++ grub_free (rd); ++ + /* A special case for when the last character was part of a + variable. */ + add_var (varname, &bp, &vp, state, GRUB_PARSER_STATE_TEXT); diff --git a/SOURCES/0423-kern-parser-Fix-a-memory-leak.patch b/SOURCES/0423-kern-parser-Fix-a-memory-leak.patch deleted file mode 100644 index 66171e9..0000000 --- a/SOURCES/0423-kern-parser-Fix-a-memory-leak.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Coulson -Date: Wed, 18 Nov 2020 00:59:24 +0000 -Subject: [PATCH] kern/parser: Fix a memory leak - -The getline() function supplied to grub_parser_split_cmdline() returns -a newly allocated buffer and can be called multiple times, but the -returned buffer is never freed. - -Signed-off-by: Chris Coulson -Reviewed-by: Daniel Kiper ---- - grub-core/kern/parser.c | 20 ++++++++++++++++---- - 1 file changed, 16 insertions(+), 4 deletions(-) - -diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c -index 94e8728d59a..23ebebf5ffa 100644 ---- a/grub-core/kern/parser.c -+++ b/grub-core/kern/parser.c -@@ -140,6 +140,7 @@ grub_parser_split_cmdline (const char *cmdline, - char buffer[1024]; - char *bp = buffer; - char *rd = (char *) cmdline; -+ char *rp = rd; - char varname[200]; - char *vp = varname; - char *args; -@@ -149,10 +150,18 @@ grub_parser_split_cmdline (const char *cmdline, - *argv = NULL; - do - { -- if (!rd || !*rd) -+ if (rp == NULL || *rp == '\0') - { -+ if (rd != cmdline) -+ { -+ grub_free (rd); -+ rd = rp = NULL; -+ } - if (getline) -- getline (&rd, 1, getline_data); -+ { -+ getline (&rd, 1, getline_data); -+ rp = rd; -+ } - else - break; - } -@@ -160,12 +169,12 @@ grub_parser_split_cmdline (const char *cmdline, - if (!rd) - break; - -- for (; *rd; rd++) -+ for (; *rp != '\0'; rp++) - { - grub_parser_state_t newstate; - char use; - -- newstate = grub_parser_cmdline_state (state, *rd, &use); -+ newstate = grub_parser_cmdline_state (state, *rp, &use); - - /* If a variable was being processed and this character does - not describe the variable anymore, write the variable to -@@ -198,6 +207,9 @@ grub_parser_split_cmdline (const char *cmdline, - } - while (state != GRUB_PARSER_STATE_TEXT && !check_varstate (state)); - -+ if (rd != cmdline) -+ grub_free (rd); -+ - /* A special case for when the last character was part of a - variable. */ - add_var (varname, &bp, &vp, state, GRUB_PARSER_STATE_TEXT); diff --git a/SOURCES/0423-kern-parser-Introduce-process_char-helper.patch b/SOURCES/0423-kern-parser-Introduce-process_char-helper.patch new file mode 100644 index 0000000..3c59281 --- /dev/null +++ b/SOURCES/0423-kern-parser-Introduce-process_char-helper.patch @@ -0,0 +1,116 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chris Coulson +Date: Tue, 5 Jan 2021 22:17:28 +0000 +Subject: [PATCH] kern/parser: Introduce process_char() helper + +grub_parser_split_cmdline() iterates over each command line character. +In order to add error checking and to simplify the subsequent error +handling, split the character processing in to a separate function. + +Signed-off-by: Chris Coulson +Reviewed-by: Daniel Kiper +--- + grub-core/kern/parser.c | 74 ++++++++++++++++++++++++++++++------------------- + 1 file changed, 46 insertions(+), 28 deletions(-) + +diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c +index 23ebebf5ffa..db6e255834f 100644 +--- a/grub-core/kern/parser.c ++++ b/grub-core/kern/parser.c +@@ -1,7 +1,7 @@ + /* parser.c - the part of the parser that can return partial tokens */ + /* + * GRUB -- GRand Unified Bootloader +- * Copyright (C) 2005,2007,2009 Free Software Foundation, Inc. ++ * Copyright (C) 2005,2007,2009,2021 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -129,6 +129,46 @@ add_var (char *varname, char **bp, char **vp, + *((*bp)++) = *val; + } + ++static grub_err_t ++process_char (char c, char *buffer, char **bp, char *varname, char **vp, ++ grub_parser_state_t state, int *argc, ++ grub_parser_state_t *newstate) ++{ ++ char use; ++ ++ *newstate = grub_parser_cmdline_state (state, c, &use); ++ ++ /* ++ * If a variable was being processed and this character does ++ * not describe the variable anymore, write the variable to ++ * the buffer. ++ */ ++ add_var (varname, bp, vp, state, *newstate); ++ ++ if (check_varstate (*newstate)) ++ { ++ if (use) ++ *((*vp)++) = use; ++ } ++ else if (*newstate == GRUB_PARSER_STATE_TEXT && ++ state != GRUB_PARSER_STATE_ESC && grub_isspace (use)) ++ { ++ /* ++ * Don't add more than one argument if multiple ++ * spaces are used. ++ */ ++ if (*bp != buffer && *((*bp) - 1) != '\0') ++ { ++ *((*bp)++) = '\0'; ++ (*argc)++; ++ } ++ } ++ else if (use) ++ *((*bp)++) = use; ++ ++ return GRUB_ERR_NONE; ++} ++ + grub_err_t + grub_parser_split_cmdline (const char *cmdline, + grub_reader_getline_t getline, void *getline_data, +@@ -172,35 +212,13 @@ grub_parser_split_cmdline (const char *cmdline, + for (; *rp != '\0'; rp++) + { + grub_parser_state_t newstate; +- char use; + +- newstate = grub_parser_cmdline_state (state, *rp, &use); +- +- /* If a variable was being processed and this character does +- not describe the variable anymore, write the variable to +- the buffer. */ +- add_var (varname, &bp, &vp, state, newstate); +- +- if (check_varstate (newstate)) +- { +- if (use) +- *(vp++) = use; +- } +- else ++ if (process_char (*rp, buffer, &bp, varname, &vp, state, argc, ++ &newstate) != GRUB_ERR_NONE) + { +- if (newstate == GRUB_PARSER_STATE_TEXT +- && state != GRUB_PARSER_STATE_ESC && grub_isspace (use)) +- { +- /* Don't add more than one argument if multiple +- spaces are used. */ +- if (bp != buffer && *(bp - 1)) +- { +- *(bp++) = '\0'; +- (*argc)++; +- } +- } +- else if (use) +- *(bp++) = use; ++ if (rd != cmdline) ++ grub_free (rd); ++ return grub_errno; + } + state = newstate; + } diff --git a/SOURCES/0424-kern-parser-Introduce-process_char-helper.patch b/SOURCES/0424-kern-parser-Introduce-process_char-helper.patch deleted file mode 100644 index 3c59281..0000000 --- a/SOURCES/0424-kern-parser-Introduce-process_char-helper.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Coulson -Date: Tue, 5 Jan 2021 22:17:28 +0000 -Subject: [PATCH] kern/parser: Introduce process_char() helper - -grub_parser_split_cmdline() iterates over each command line character. -In order to add error checking and to simplify the subsequent error -handling, split the character processing in to a separate function. - -Signed-off-by: Chris Coulson -Reviewed-by: Daniel Kiper ---- - grub-core/kern/parser.c | 74 ++++++++++++++++++++++++++++++------------------- - 1 file changed, 46 insertions(+), 28 deletions(-) - -diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c -index 23ebebf5ffa..db6e255834f 100644 ---- a/grub-core/kern/parser.c -+++ b/grub-core/kern/parser.c -@@ -1,7 +1,7 @@ - /* parser.c - the part of the parser that can return partial tokens */ - /* - * GRUB -- GRand Unified Bootloader -- * Copyright (C) 2005,2007,2009 Free Software Foundation, Inc. -+ * Copyright (C) 2005,2007,2009,2021 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -129,6 +129,46 @@ add_var (char *varname, char **bp, char **vp, - *((*bp)++) = *val; - } - -+static grub_err_t -+process_char (char c, char *buffer, char **bp, char *varname, char **vp, -+ grub_parser_state_t state, int *argc, -+ grub_parser_state_t *newstate) -+{ -+ char use; -+ -+ *newstate = grub_parser_cmdline_state (state, c, &use); -+ -+ /* -+ * If a variable was being processed and this character does -+ * not describe the variable anymore, write the variable to -+ * the buffer. -+ */ -+ add_var (varname, bp, vp, state, *newstate); -+ -+ if (check_varstate (*newstate)) -+ { -+ if (use) -+ *((*vp)++) = use; -+ } -+ else if (*newstate == GRUB_PARSER_STATE_TEXT && -+ state != GRUB_PARSER_STATE_ESC && grub_isspace (use)) -+ { -+ /* -+ * Don't add more than one argument if multiple -+ * spaces are used. -+ */ -+ if (*bp != buffer && *((*bp) - 1) != '\0') -+ { -+ *((*bp)++) = '\0'; -+ (*argc)++; -+ } -+ } -+ else if (use) -+ *((*bp)++) = use; -+ -+ return GRUB_ERR_NONE; -+} -+ - grub_err_t - grub_parser_split_cmdline (const char *cmdline, - grub_reader_getline_t getline, void *getline_data, -@@ -172,35 +212,13 @@ grub_parser_split_cmdline (const char *cmdline, - for (; *rp != '\0'; rp++) - { - grub_parser_state_t newstate; -- char use; - -- newstate = grub_parser_cmdline_state (state, *rp, &use); -- -- /* If a variable was being processed and this character does -- not describe the variable anymore, write the variable to -- the buffer. */ -- add_var (varname, &bp, &vp, state, newstate); -- -- if (check_varstate (newstate)) -- { -- if (use) -- *(vp++) = use; -- } -- else -+ if (process_char (*rp, buffer, &bp, varname, &vp, state, argc, -+ &newstate) != GRUB_ERR_NONE) - { -- if (newstate == GRUB_PARSER_STATE_TEXT -- && state != GRUB_PARSER_STATE_ESC && grub_isspace (use)) -- { -- /* Don't add more than one argument if multiple -- spaces are used. */ -- if (bp != buffer && *(bp - 1)) -- { -- *(bp++) = '\0'; -- (*argc)++; -- } -- } -- else if (use) -- *(bp++) = use; -+ if (rd != cmdline) -+ grub_free (rd); -+ return grub_errno; - } - state = newstate; - } diff --git a/SOURCES/0424-kern-parser-Introduce-terminate_arg-helper.patch b/SOURCES/0424-kern-parser-Introduce-terminate_arg-helper.patch new file mode 100644 index 0000000..df7dbd6 --- /dev/null +++ b/SOURCES/0424-kern-parser-Introduce-terminate_arg-helper.patch @@ -0,0 +1,62 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chris Coulson +Date: Thu, 7 Jan 2021 19:53:55 +0000 +Subject: [PATCH] kern/parser: Introduce terminate_arg() helper + +process_char() and grub_parser_split_cmdline() use similar code for +terminating the most recent argument. Add a helper function for this. + +Signed-off-by: Chris Coulson +Reviewed-by: Daniel Kiper +--- + grub-core/kern/parser.c | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c +index db6e255834f..6ef90c82938 100644 +--- a/grub-core/kern/parser.c ++++ b/grub-core/kern/parser.c +@@ -129,6 +129,16 @@ add_var (char *varname, char **bp, char **vp, + *((*bp)++) = *val; + } + ++static void ++terminate_arg (char *buffer, char **bp, int *argc) ++{ ++ if (*bp != buffer && *((*bp) - 1) != '\0') ++ { ++ *((*bp)++) = '\0'; ++ (*argc)++; ++ } ++} ++ + static grub_err_t + process_char (char c, char *buffer, char **bp, char *varname, char **vp, + grub_parser_state_t state, int *argc, +@@ -157,11 +167,7 @@ process_char (char c, char *buffer, char **bp, char *varname, char **vp, + * Don't add more than one argument if multiple + * spaces are used. + */ +- if (*bp != buffer && *((*bp) - 1) != '\0') +- { +- *((*bp)++) = '\0'; +- (*argc)++; +- } ++ terminate_arg (buffer, bp, argc); + } + else if (use) + *((*bp)++) = use; +@@ -232,11 +238,8 @@ grub_parser_split_cmdline (const char *cmdline, + variable. */ + add_var (varname, &bp, &vp, state, GRUB_PARSER_STATE_TEXT); + +- if (bp != buffer && *(bp - 1)) +- { +- *(bp++) = '\0'; +- (*argc)++; +- } ++ /* Ensure that the last argument is terminated. */ ++ terminate_arg (buffer, &bp, argc); + + /* If there are no args, then we're done. */ + if (!*argc) diff --git a/SOURCES/0425-kern-parser-Introduce-terminate_arg-helper.patch b/SOURCES/0425-kern-parser-Introduce-terminate_arg-helper.patch deleted file mode 100644 index df7dbd6..0000000 --- a/SOURCES/0425-kern-parser-Introduce-terminate_arg-helper.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Coulson -Date: Thu, 7 Jan 2021 19:53:55 +0000 -Subject: [PATCH] kern/parser: Introduce terminate_arg() helper - -process_char() and grub_parser_split_cmdline() use similar code for -terminating the most recent argument. Add a helper function for this. - -Signed-off-by: Chris Coulson -Reviewed-by: Daniel Kiper ---- - grub-core/kern/parser.c | 23 +++++++++++++---------- - 1 file changed, 13 insertions(+), 10 deletions(-) - -diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c -index db6e255834f..6ef90c82938 100644 ---- a/grub-core/kern/parser.c -+++ b/grub-core/kern/parser.c -@@ -129,6 +129,16 @@ add_var (char *varname, char **bp, char **vp, - *((*bp)++) = *val; - } - -+static void -+terminate_arg (char *buffer, char **bp, int *argc) -+{ -+ if (*bp != buffer && *((*bp) - 1) != '\0') -+ { -+ *((*bp)++) = '\0'; -+ (*argc)++; -+ } -+} -+ - static grub_err_t - process_char (char c, char *buffer, char **bp, char *varname, char **vp, - grub_parser_state_t state, int *argc, -@@ -157,11 +167,7 @@ process_char (char c, char *buffer, char **bp, char *varname, char **vp, - * Don't add more than one argument if multiple - * spaces are used. - */ -- if (*bp != buffer && *((*bp) - 1) != '\0') -- { -- *((*bp)++) = '\0'; -- (*argc)++; -- } -+ terminate_arg (buffer, bp, argc); - } - else if (use) - *((*bp)++) = use; -@@ -232,11 +238,8 @@ grub_parser_split_cmdline (const char *cmdline, - variable. */ - add_var (varname, &bp, &vp, state, GRUB_PARSER_STATE_TEXT); - -- if (bp != buffer && *(bp - 1)) -- { -- *(bp++) = '\0'; -- (*argc)++; -- } -+ /* Ensure that the last argument is terminated. */ -+ terminate_arg (buffer, &bp, argc); - - /* If there are no args, then we're done. */ - if (!*argc) diff --git a/SOURCES/0425-kern-parser-Refactor-grub_parser_split_cmdline-clean.patch b/SOURCES/0425-kern-parser-Refactor-grub_parser_split_cmdline-clean.patch new file mode 100644 index 0000000..1f9cd6d --- /dev/null +++ b/SOURCES/0425-kern-parser-Refactor-grub_parser_split_cmdline-clean.patch @@ -0,0 +1,88 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chris Coulson +Date: Wed, 6 Jan 2021 13:54:26 +0000 +Subject: [PATCH] kern/parser: Refactor grub_parser_split_cmdline() cleanup + +Introduce a common function epilogue used for cleaning up on all +return paths, which will simplify additional error handling to be +introduced in a subsequent commit. + +Signed-off-by: Chris Coulson +Reviewed-by: Daniel Kiper +--- + grub-core/kern/parser.c | 35 ++++++++++++++++++++--------------- + 1 file changed, 20 insertions(+), 15 deletions(-) + +diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c +index 6ef90c82938..16879f072fe 100644 +--- a/grub-core/kern/parser.c ++++ b/grub-core/kern/parser.c +@@ -221,19 +221,13 @@ grub_parser_split_cmdline (const char *cmdline, + + if (process_char (*rp, buffer, &bp, varname, &vp, state, argc, + &newstate) != GRUB_ERR_NONE) +- { +- if (rd != cmdline) +- grub_free (rd); +- return grub_errno; +- } ++ goto fail; ++ + state = newstate; + } + } + while (state != GRUB_PARSER_STATE_TEXT && !check_varstate (state)); + +- if (rd != cmdline) +- grub_free (rd); +- + /* A special case for when the last character was part of a + variable. */ + add_var (varname, &bp, &vp, state, GRUB_PARSER_STATE_TEXT); +@@ -243,20 +237,20 @@ grub_parser_split_cmdline (const char *cmdline, + + /* If there are no args, then we're done. */ + if (!*argc) +- return 0; ++ { ++ grub_errno = GRUB_ERR_NONE; ++ goto out; ++ } + + /* Reserve memory for the return values. */ + args = grub_malloc (bp - buffer); + if (!args) +- return grub_errno; ++ goto fail; + grub_memcpy (args, buffer, bp - buffer); + + *argv = grub_calloc (*argc + 1, sizeof (char *)); + if (!*argv) +- { +- grub_free (args); +- return grub_errno; +- } ++ goto fail; + + /* The arguments are separated with 0's, setup argv so it points to + the right values. */ +@@ -269,7 +263,18 @@ grub_parser_split_cmdline (const char *cmdline, + bp++; + } + +- return 0; ++ grub_errno = GRUB_ERR_NONE; ++ ++ out: ++ if (rd != cmdline) ++ grub_free (rd); ++ ++ return grub_errno; ++ ++ fail: ++ grub_free (*argv); ++ grub_free (args); ++ goto out; + } + + /* Helper for grub_parser_execute. */ diff --git a/SOURCES/0426-kern-buffer-Add-variable-sized-heap-buffer.patch b/SOURCES/0426-kern-buffer-Add-variable-sized-heap-buffer.patch new file mode 100644 index 0000000..b9ffa09 --- /dev/null +++ b/SOURCES/0426-kern-buffer-Add-variable-sized-heap-buffer.patch @@ -0,0 +1,304 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chris Coulson +Date: Thu, 7 Jan 2021 15:15:43 +0000 +Subject: [PATCH] kern/buffer: Add variable sized heap buffer + +Add a new variable sized heap buffer type (grub_buffer_t) with simple +operations for appending data, accessing the data and maintaining +a read cursor. + +Signed-off-by: Chris Coulson +Reviewed-by: Daniel Kiper +--- + grub-core/Makefile.core.def | 1 + + grub-core/kern/buffer.c | 117 +++++++++++++++++++++++++++++++++++ + include/grub/buffer.h | 144 ++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 262 insertions(+) + create mode 100644 grub-core/kern/buffer.c + create mode 100644 include/grub/buffer.h + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 2beb1d83a63..5228d3d530d 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -114,6 +114,7 @@ kernel = { + arm_efi_startup = kern/arm/efi/startup.S; + arm64_efi_startup = kern/arm64/efi/startup.S; + ++ common = kern/buffer.c; + common = kern/command.c; + common = kern/corecmd.c; + common = kern/device.c; +diff --git a/grub-core/kern/buffer.c b/grub-core/kern/buffer.c +new file mode 100644 +index 00000000000..9f5f8b86705 +--- /dev/null ++++ b/grub-core/kern/buffer.c +@@ -0,0 +1,117 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2021 Free Software Foundation, Inc. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++grub_buffer_t ++grub_buffer_new (grub_size_t sz) ++{ ++ struct grub_buffer *ret; ++ ++ ret = (struct grub_buffer *) grub_malloc (sizeof (*ret)); ++ if (ret == NULL) ++ return NULL; ++ ++ ret->data = (grub_uint8_t *) grub_malloc (sz); ++ if (ret->data == NULL) ++ { ++ grub_free (ret); ++ return NULL; ++ } ++ ++ ret->sz = sz; ++ ret->pos = 0; ++ ret->used = 0; ++ ++ return ret; ++} ++ ++void ++grub_buffer_free (grub_buffer_t buf) ++{ ++ grub_free (buf->data); ++ grub_free (buf); ++} ++ ++grub_err_t ++grub_buffer_ensure_space (grub_buffer_t buf, grub_size_t req) ++{ ++ grub_uint8_t *d; ++ grub_size_t newsz = 1; ++ ++ /* Is the current buffer size adequate? */ ++ if (buf->sz >= req) ++ return GRUB_ERR_NONE; ++ ++ /* Find the smallest power-of-2 size that satisfies the request. */ ++ while (newsz < req) ++ { ++ if (newsz == 0) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("requested buffer size is too large")); ++ newsz <<= 1; ++ } ++ ++ d = (grub_uint8_t *) grub_realloc (buf->data, newsz); ++ if (d == NULL) ++ return grub_errno; ++ ++ buf->data = d; ++ buf->sz = newsz; ++ ++ return GRUB_ERR_NONE; ++} ++ ++void * ++grub_buffer_take_data (grub_buffer_t buf) ++{ ++ void *data = buf->data; ++ ++ buf->data = NULL; ++ buf->sz = buf->pos = buf->used = 0; ++ ++ return data; ++} ++ ++void ++grub_buffer_reset (grub_buffer_t buf) ++{ ++ buf->pos = buf->used = 0; ++} ++ ++grub_err_t ++grub_buffer_advance_read_pos (grub_buffer_t buf, grub_size_t n) ++{ ++ grub_size_t newpos; ++ ++ if (grub_add (buf->pos, n, &newpos)) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ ++ if (newpos > buf->used) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("new read is position beyond the end of the written data")); ++ ++ buf->pos = newpos; ++ ++ return GRUB_ERR_NONE; ++} +diff --git a/include/grub/buffer.h b/include/grub/buffer.h +new file mode 100644 +index 00000000000..f4b10cf2810 +--- /dev/null ++++ b/include/grub/buffer.h +@@ -0,0 +1,144 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2021 Free Software Foundation, Inc. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#ifndef GRUB_BUFFER_H ++#define GRUB_BUFFER_H 1 ++ ++#include ++#include ++#include ++#include ++#include ++ ++struct grub_buffer ++{ ++ grub_uint8_t *data; ++ grub_size_t sz; ++ grub_size_t pos; ++ grub_size_t used; ++}; ++ ++/* ++ * grub_buffer_t represents a simple variable sized byte buffer with ++ * read and write cursors. It currently only implements ++ * functionality required by the only user in GRUB (append byte[s], ++ * peeking data at a specified position and updating the read cursor. ++ * Some things that this doesn't do yet are: ++ * - Reading a portion of the buffer by copying data from the current ++ * read position in to a caller supplied destination buffer and then ++ * automatically updating the read cursor. ++ * - Dropping the read part at the start of the buffer when an append ++ * requires more space. ++ */ ++typedef struct grub_buffer *grub_buffer_t; ++ ++/* Allocate a new buffer with the specified initial size. */ ++extern grub_buffer_t grub_buffer_new (grub_size_t sz); ++ ++/* Free the buffer and its resources. */ ++extern void grub_buffer_free (grub_buffer_t buf); ++ ++/* Return the number of unread bytes in this buffer. */ ++static inline grub_size_t ++grub_buffer_get_unread_bytes (grub_buffer_t buf) ++{ ++ return buf->used - buf->pos; ++} ++ ++/* ++ * Ensure that the buffer size is at least the requested ++ * number of bytes. ++ */ ++extern grub_err_t grub_buffer_ensure_space (grub_buffer_t buf, grub_size_t req); ++ ++/* ++ * Append the specified number of bytes from the supplied ++ * data to the buffer. ++ */ ++static inline grub_err_t ++grub_buffer_append_data (grub_buffer_t buf, const void *data, grub_size_t len) ++{ ++ grub_size_t req; ++ ++ if (grub_add (buf->used, len, &req)) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ ++ if (grub_buffer_ensure_space (buf, req) != GRUB_ERR_NONE) ++ return grub_errno; ++ ++ grub_memcpy (&buf->data[buf->used], data, len); ++ buf->used = req; ++ ++ return GRUB_ERR_NONE; ++} ++ ++/* Append the supplied character to the buffer. */ ++static inline grub_err_t ++grub_buffer_append_char (grub_buffer_t buf, char c) ++{ ++ return grub_buffer_append_data (buf, &c, 1); ++} ++ ++/* ++ * Forget and return the underlying data buffer. The caller ++ * becomes the owner of this buffer, and must free it when it ++ * is no longer required. ++ */ ++extern void *grub_buffer_take_data (grub_buffer_t buf); ++ ++/* Reset this buffer. Note that this does not deallocate any resources. */ ++void grub_buffer_reset (grub_buffer_t buf); ++ ++/* ++ * Return a pointer to the underlying data buffer at the specified ++ * offset from the current read position. Note that this pointer may ++ * become invalid if the buffer is mutated further. ++ */ ++static inline void * ++grub_buffer_peek_data_at (grub_buffer_t buf, grub_size_t off) ++{ ++ if (grub_add (buf->pos, off, &off)) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected.")); ++ return NULL; ++ } ++ ++ if (off >= buf->used) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("peek out of range")); ++ return NULL; ++ } ++ ++ return &buf->data[off]; ++} ++ ++/* ++ * Return a pointer to the underlying data buffer at the current ++ * read position. Note that this pointer may become invalid if the ++ * buffer is mutated further. ++ */ ++static inline void * ++grub_buffer_peek_data (grub_buffer_t buf) ++{ ++ return grub_buffer_peek_data_at (buf, 0); ++} ++ ++/* Advance the read position by the specified number of bytes. */ ++extern grub_err_t grub_buffer_advance_read_pos (grub_buffer_t buf, grub_size_t n); ++ ++#endif /* GRUB_BUFFER_H */ diff --git a/SOURCES/0426-kern-parser-Refactor-grub_parser_split_cmdline-clean.patch b/SOURCES/0426-kern-parser-Refactor-grub_parser_split_cmdline-clean.patch deleted file mode 100644 index 1f9cd6d..0000000 --- a/SOURCES/0426-kern-parser-Refactor-grub_parser_split_cmdline-clean.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Coulson -Date: Wed, 6 Jan 2021 13:54:26 +0000 -Subject: [PATCH] kern/parser: Refactor grub_parser_split_cmdline() cleanup - -Introduce a common function epilogue used for cleaning up on all -return paths, which will simplify additional error handling to be -introduced in a subsequent commit. - -Signed-off-by: Chris Coulson -Reviewed-by: Daniel Kiper ---- - grub-core/kern/parser.c | 35 ++++++++++++++++++++--------------- - 1 file changed, 20 insertions(+), 15 deletions(-) - -diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c -index 6ef90c82938..16879f072fe 100644 ---- a/grub-core/kern/parser.c -+++ b/grub-core/kern/parser.c -@@ -221,19 +221,13 @@ grub_parser_split_cmdline (const char *cmdline, - - if (process_char (*rp, buffer, &bp, varname, &vp, state, argc, - &newstate) != GRUB_ERR_NONE) -- { -- if (rd != cmdline) -- grub_free (rd); -- return grub_errno; -- } -+ goto fail; -+ - state = newstate; - } - } - while (state != GRUB_PARSER_STATE_TEXT && !check_varstate (state)); - -- if (rd != cmdline) -- grub_free (rd); -- - /* A special case for when the last character was part of a - variable. */ - add_var (varname, &bp, &vp, state, GRUB_PARSER_STATE_TEXT); -@@ -243,20 +237,20 @@ grub_parser_split_cmdline (const char *cmdline, - - /* If there are no args, then we're done. */ - if (!*argc) -- return 0; -+ { -+ grub_errno = GRUB_ERR_NONE; -+ goto out; -+ } - - /* Reserve memory for the return values. */ - args = grub_malloc (bp - buffer); - if (!args) -- return grub_errno; -+ goto fail; - grub_memcpy (args, buffer, bp - buffer); - - *argv = grub_calloc (*argc + 1, sizeof (char *)); - if (!*argv) -- { -- grub_free (args); -- return grub_errno; -- } -+ goto fail; - - /* The arguments are separated with 0's, setup argv so it points to - the right values. */ -@@ -269,7 +263,18 @@ grub_parser_split_cmdline (const char *cmdline, - bp++; - } - -- return 0; -+ grub_errno = GRUB_ERR_NONE; -+ -+ out: -+ if (rd != cmdline) -+ grub_free (rd); -+ -+ return grub_errno; -+ -+ fail: -+ grub_free (*argv); -+ grub_free (args); -+ goto out; - } - - /* Helper for grub_parser_execute. */ diff --git a/SOURCES/0427-kern-buffer-Add-variable-sized-heap-buffer.patch b/SOURCES/0427-kern-buffer-Add-variable-sized-heap-buffer.patch deleted file mode 100644 index b9ffa09..0000000 --- a/SOURCES/0427-kern-buffer-Add-variable-sized-heap-buffer.patch +++ /dev/null @@ -1,304 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Coulson -Date: Thu, 7 Jan 2021 15:15:43 +0000 -Subject: [PATCH] kern/buffer: Add variable sized heap buffer - -Add a new variable sized heap buffer type (grub_buffer_t) with simple -operations for appending data, accessing the data and maintaining -a read cursor. - -Signed-off-by: Chris Coulson -Reviewed-by: Daniel Kiper ---- - grub-core/Makefile.core.def | 1 + - grub-core/kern/buffer.c | 117 +++++++++++++++++++++++++++++++++++ - include/grub/buffer.h | 144 ++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 262 insertions(+) - create mode 100644 grub-core/kern/buffer.c - create mode 100644 include/grub/buffer.h - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 2beb1d83a63..5228d3d530d 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -114,6 +114,7 @@ kernel = { - arm_efi_startup = kern/arm/efi/startup.S; - arm64_efi_startup = kern/arm64/efi/startup.S; - -+ common = kern/buffer.c; - common = kern/command.c; - common = kern/corecmd.c; - common = kern/device.c; -diff --git a/grub-core/kern/buffer.c b/grub-core/kern/buffer.c -new file mode 100644 -index 00000000000..9f5f8b86705 ---- /dev/null -+++ b/grub-core/kern/buffer.c -@@ -0,0 +1,117 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2021 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+grub_buffer_t -+grub_buffer_new (grub_size_t sz) -+{ -+ struct grub_buffer *ret; -+ -+ ret = (struct grub_buffer *) grub_malloc (sizeof (*ret)); -+ if (ret == NULL) -+ return NULL; -+ -+ ret->data = (grub_uint8_t *) grub_malloc (sz); -+ if (ret->data == NULL) -+ { -+ grub_free (ret); -+ return NULL; -+ } -+ -+ ret->sz = sz; -+ ret->pos = 0; -+ ret->used = 0; -+ -+ return ret; -+} -+ -+void -+grub_buffer_free (grub_buffer_t buf) -+{ -+ grub_free (buf->data); -+ grub_free (buf); -+} -+ -+grub_err_t -+grub_buffer_ensure_space (grub_buffer_t buf, grub_size_t req) -+{ -+ grub_uint8_t *d; -+ grub_size_t newsz = 1; -+ -+ /* Is the current buffer size adequate? */ -+ if (buf->sz >= req) -+ return GRUB_ERR_NONE; -+ -+ /* Find the smallest power-of-2 size that satisfies the request. */ -+ while (newsz < req) -+ { -+ if (newsz == 0) -+ return grub_error (GRUB_ERR_OUT_OF_RANGE, -+ N_("requested buffer size is too large")); -+ newsz <<= 1; -+ } -+ -+ d = (grub_uint8_t *) grub_realloc (buf->data, newsz); -+ if (d == NULL) -+ return grub_errno; -+ -+ buf->data = d; -+ buf->sz = newsz; -+ -+ return GRUB_ERR_NONE; -+} -+ -+void * -+grub_buffer_take_data (grub_buffer_t buf) -+{ -+ void *data = buf->data; -+ -+ buf->data = NULL; -+ buf->sz = buf->pos = buf->used = 0; -+ -+ return data; -+} -+ -+void -+grub_buffer_reset (grub_buffer_t buf) -+{ -+ buf->pos = buf->used = 0; -+} -+ -+grub_err_t -+grub_buffer_advance_read_pos (grub_buffer_t buf, grub_size_t n) -+{ -+ grub_size_t newpos; -+ -+ if (grub_add (buf->pos, n, &newpos)) -+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); -+ -+ if (newpos > buf->used) -+ return grub_error (GRUB_ERR_OUT_OF_RANGE, -+ N_("new read is position beyond the end of the written data")); -+ -+ buf->pos = newpos; -+ -+ return GRUB_ERR_NONE; -+} -diff --git a/include/grub/buffer.h b/include/grub/buffer.h -new file mode 100644 -index 00000000000..f4b10cf2810 ---- /dev/null -+++ b/include/grub/buffer.h -@@ -0,0 +1,144 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2021 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_BUFFER_H -+#define GRUB_BUFFER_H 1 -+ -+#include -+#include -+#include -+#include -+#include -+ -+struct grub_buffer -+{ -+ grub_uint8_t *data; -+ grub_size_t sz; -+ grub_size_t pos; -+ grub_size_t used; -+}; -+ -+/* -+ * grub_buffer_t represents a simple variable sized byte buffer with -+ * read and write cursors. It currently only implements -+ * functionality required by the only user in GRUB (append byte[s], -+ * peeking data at a specified position and updating the read cursor. -+ * Some things that this doesn't do yet are: -+ * - Reading a portion of the buffer by copying data from the current -+ * read position in to a caller supplied destination buffer and then -+ * automatically updating the read cursor. -+ * - Dropping the read part at the start of the buffer when an append -+ * requires more space. -+ */ -+typedef struct grub_buffer *grub_buffer_t; -+ -+/* Allocate a new buffer with the specified initial size. */ -+extern grub_buffer_t grub_buffer_new (grub_size_t sz); -+ -+/* Free the buffer and its resources. */ -+extern void grub_buffer_free (grub_buffer_t buf); -+ -+/* Return the number of unread bytes in this buffer. */ -+static inline grub_size_t -+grub_buffer_get_unread_bytes (grub_buffer_t buf) -+{ -+ return buf->used - buf->pos; -+} -+ -+/* -+ * Ensure that the buffer size is at least the requested -+ * number of bytes. -+ */ -+extern grub_err_t grub_buffer_ensure_space (grub_buffer_t buf, grub_size_t req); -+ -+/* -+ * Append the specified number of bytes from the supplied -+ * data to the buffer. -+ */ -+static inline grub_err_t -+grub_buffer_append_data (grub_buffer_t buf, const void *data, grub_size_t len) -+{ -+ grub_size_t req; -+ -+ if (grub_add (buf->used, len, &req)) -+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); -+ -+ if (grub_buffer_ensure_space (buf, req) != GRUB_ERR_NONE) -+ return grub_errno; -+ -+ grub_memcpy (&buf->data[buf->used], data, len); -+ buf->used = req; -+ -+ return GRUB_ERR_NONE; -+} -+ -+/* Append the supplied character to the buffer. */ -+static inline grub_err_t -+grub_buffer_append_char (grub_buffer_t buf, char c) -+{ -+ return grub_buffer_append_data (buf, &c, 1); -+} -+ -+/* -+ * Forget and return the underlying data buffer. The caller -+ * becomes the owner of this buffer, and must free it when it -+ * is no longer required. -+ */ -+extern void *grub_buffer_take_data (grub_buffer_t buf); -+ -+/* Reset this buffer. Note that this does not deallocate any resources. */ -+void grub_buffer_reset (grub_buffer_t buf); -+ -+/* -+ * Return a pointer to the underlying data buffer at the specified -+ * offset from the current read position. Note that this pointer may -+ * become invalid if the buffer is mutated further. -+ */ -+static inline void * -+grub_buffer_peek_data_at (grub_buffer_t buf, grub_size_t off) -+{ -+ if (grub_add (buf->pos, off, &off)) -+ { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected.")); -+ return NULL; -+ } -+ -+ if (off >= buf->used) -+ { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("peek out of range")); -+ return NULL; -+ } -+ -+ return &buf->data[off]; -+} -+ -+/* -+ * Return a pointer to the underlying data buffer at the current -+ * read position. Note that this pointer may become invalid if the -+ * buffer is mutated further. -+ */ -+static inline void * -+grub_buffer_peek_data (grub_buffer_t buf) -+{ -+ return grub_buffer_peek_data_at (buf, 0); -+} -+ -+/* Advance the read position by the specified number of bytes. */ -+extern grub_err_t grub_buffer_advance_read_pos (grub_buffer_t buf, grub_size_t n); -+ -+#endif /* GRUB_BUFFER_H */ diff --git a/SOURCES/0427-kern-parser-Fix-a-stack-buffer-overflow.patch b/SOURCES/0427-kern-parser-Fix-a-stack-buffer-overflow.patch new file mode 100644 index 0000000..40c1c37 --- /dev/null +++ b/SOURCES/0427-kern-parser-Fix-a-stack-buffer-overflow.patch @@ -0,0 +1,244 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chris Coulson +Date: Thu, 7 Jan 2021 19:21:03 +0000 +Subject: [PATCH] kern/parser: Fix a stack buffer overflow + +grub_parser_split_cmdline() expands variable names present in the supplied +command line in to their corresponding variable contents and uses a 1 kiB +stack buffer for temporary storage without sufficient bounds checking. If +the function is called with a command line that references a variable with +a sufficiently large payload, it is possible to overflow the stack +buffer via tab completion, corrupt the stack frame and potentially +control execution. + +Fixes: CVE-2020-27749 + +Reported-by: Chris Coulson +Signed-off-by: Chris Coulson +Signed-off-by: Darren Kenny +Reviewed-by: Daniel Kiper +--- + grub-core/kern/parser.c | 110 +++++++++++++++++++++++++++++------------------- + 1 file changed, 67 insertions(+), 43 deletions(-) + +diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c +index 16879f072fe..068b6d0fe57 100644 +--- a/grub-core/kern/parser.c ++++ b/grub-core/kern/parser.c +@@ -18,6 +18,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -107,8 +108,8 @@ check_varstate (grub_parser_state_t s) + } + + +-static void +-add_var (char *varname, char **bp, char **vp, ++static grub_err_t ++add_var (grub_buffer_t varname, grub_buffer_t buf, + grub_parser_state_t state, grub_parser_state_t newstate) + { + const char *val; +@@ -116,31 +117,41 @@ add_var (char *varname, char **bp, char **vp, + /* Check if a variable was being read in and the end of the name + was reached. */ + if (!(check_varstate (state) && !check_varstate (newstate))) +- return; ++ return GRUB_ERR_NONE; + +- *((*vp)++) = '\0'; +- val = grub_env_get (varname); +- *vp = varname; ++ if (grub_buffer_append_char (varname, '\0') != GRUB_ERR_NONE) ++ return grub_errno; ++ ++ val = grub_env_get ((const char *) grub_buffer_peek_data (varname)); ++ grub_buffer_reset (varname); + if (!val) +- return; ++ return GRUB_ERR_NONE; + + /* Insert the contents of the variable in the buffer. */ +- for (; *val; val++) +- *((*bp)++) = *val; ++ return grub_buffer_append_data (buf, val, grub_strlen (val)); + } + +-static void +-terminate_arg (char *buffer, char **bp, int *argc) ++static grub_err_t ++terminate_arg (grub_buffer_t buffer, int *argc) + { +- if (*bp != buffer && *((*bp) - 1) != '\0') +- { +- *((*bp)++) = '\0'; +- (*argc)++; +- } ++ grub_size_t unread = grub_buffer_get_unread_bytes (buffer); ++ ++ if (unread == 0) ++ return GRUB_ERR_NONE; ++ ++ if (*(const char *) grub_buffer_peek_data_at (buffer, unread - 1) == '\0') ++ return GRUB_ERR_NONE; ++ ++ if (grub_buffer_append_char (buffer, '\0') != GRUB_ERR_NONE) ++ return grub_errno; ++ ++ (*argc)++; ++ ++ return GRUB_ERR_NONE; + } + + static grub_err_t +-process_char (char c, char *buffer, char **bp, char *varname, char **vp, ++process_char (char c, grub_buffer_t buffer, grub_buffer_t varname, + grub_parser_state_t state, int *argc, + grub_parser_state_t *newstate) + { +@@ -153,12 +164,13 @@ process_char (char c, char *buffer, char **bp, char *varname, char **vp, + * not describe the variable anymore, write the variable to + * the buffer. + */ +- add_var (varname, bp, vp, state, *newstate); ++ if (add_var (varname, buffer, state, *newstate) != GRUB_ERR_NONE) ++ return grub_errno; + + if (check_varstate (*newstate)) + { + if (use) +- *((*vp)++) = use; ++ return grub_buffer_append_char (varname, use); + } + else if (*newstate == GRUB_PARSER_STATE_TEXT && + state != GRUB_PARSER_STATE_ESC && grub_isspace (use)) +@@ -167,10 +179,10 @@ process_char (char c, char *buffer, char **bp, char *varname, char **vp, + * Don't add more than one argument if multiple + * spaces are used. + */ +- terminate_arg (buffer, bp, argc); ++ return terminate_arg (buffer, argc); + } + else if (use) +- *((*bp)++) = use; ++ return grub_buffer_append_char (buffer, use); + + return GRUB_ERR_NONE; + } +@@ -181,19 +193,22 @@ grub_parser_split_cmdline (const char *cmdline, + int *argc, char ***argv) + { + grub_parser_state_t state = GRUB_PARSER_STATE_TEXT; +- /* XXX: Fixed size buffer, perhaps this buffer should be dynamically +- allocated. */ +- char buffer[1024]; +- char *bp = buffer; ++ grub_buffer_t buffer, varname; + char *rd = (char *) cmdline; + char *rp = rd; +- char varname[200]; +- char *vp = varname; +- char *args; + int i; + + *argc = 0; + *argv = NULL; ++ ++ buffer = grub_buffer_new (1024); ++ if (buffer == NULL) ++ return grub_errno; ++ ++ varname = grub_buffer_new (200); ++ if (varname == NULL) ++ goto fail; ++ + do + { + if (rp == NULL || *rp == '\0') +@@ -219,7 +234,7 @@ grub_parser_split_cmdline (const char *cmdline, + { + grub_parser_state_t newstate; + +- if (process_char (*rp, buffer, &bp, varname, &vp, state, argc, ++ if (process_char (*rp, buffer, varname, state, argc, + &newstate) != GRUB_ERR_NONE) + goto fail; + +@@ -230,10 +245,12 @@ grub_parser_split_cmdline (const char *cmdline, + + /* A special case for when the last character was part of a + variable. */ +- add_var (varname, &bp, &vp, state, GRUB_PARSER_STATE_TEXT); ++ if (add_var (varname, buffer, state, GRUB_PARSER_STATE_TEXT) != GRUB_ERR_NONE) ++ goto fail; + + /* Ensure that the last argument is terminated. */ +- terminate_arg (buffer, &bp, argc); ++ if (terminate_arg (buffer, argc) != GRUB_ERR_NONE) ++ goto fail; + + /* If there are no args, then we're done. */ + if (!*argc) +@@ -242,38 +259,45 @@ grub_parser_split_cmdline (const char *cmdline, + goto out; + } + +- /* Reserve memory for the return values. */ +- args = grub_malloc (bp - buffer); +- if (!args) +- goto fail; +- grub_memcpy (args, buffer, bp - buffer); +- + *argv = grub_calloc (*argc + 1, sizeof (char *)); + if (!*argv) + goto fail; + + /* The arguments are separated with 0's, setup argv so it points to + the right values. */ +- bp = args; + for (i = 0; i < *argc; i++) + { +- (*argv)[i] = bp; +- while (*bp) +- bp++; +- bp++; ++ char *arg; ++ ++ if (i > 0) ++ { ++ if (grub_buffer_advance_read_pos (buffer, 1) != GRUB_ERR_NONE) ++ goto fail; ++ } ++ ++ arg = (char *) grub_buffer_peek_data (buffer); ++ if (arg == NULL || ++ grub_buffer_advance_read_pos (buffer, grub_strlen (arg)) != GRUB_ERR_NONE) ++ goto fail; ++ ++ (*argv)[i] = arg; + } + ++ /* Keep memory for the return values. */ ++ grub_buffer_take_data (buffer); ++ + grub_errno = GRUB_ERR_NONE; + + out: + if (rd != cmdline) + grub_free (rd); ++ grub_buffer_free (buffer); ++ grub_buffer_free (varname); + + return grub_errno; + + fail: + grub_free (*argv); +- grub_free (args); + goto out; + } + diff --git a/SOURCES/0428-kern-efi-Add-initial-stack-protector-implementation.patch b/SOURCES/0428-kern-efi-Add-initial-stack-protector-implementation.patch new file mode 100644 index 0000000..4814e96 --- /dev/null +++ b/SOURCES/0428-kern-efi-Add-initial-stack-protector-implementation.patch @@ -0,0 +1,298 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chris Coulson +Date: Fri, 19 Feb 2021 13:53:45 +0100 +Subject: [PATCH] kern/efi: Add initial stack protector implementation + +It works only on UEFI platforms but can be quite easily extended to +others architectures and platforms if needed. + +Signed-off-by: Chris Coulson +Signed-off-by: Daniel Kiper +Reviewed-by: Marco A Benatto +Reviewed-by: Javier Martinez Canillas +--- + configure.ac | 44 ++++++++++++++++++++++++++++++---- + grub-core/kern/efi/init.c | 54 ++++++++++++++++++++++++++++++++++++++++++ + include/grub/efi/api.h | 19 +++++++++++++++ + include/grub/stack_protector.h | 30 +++++++++++++++++++++++ + acinclude.m4 | 38 +++++++++++++++++++++++++++-- + grub-core/Makefile.am | 1 + + 6 files changed, 179 insertions(+), 7 deletions(-) + create mode 100644 include/grub/stack_protector.h + +diff --git a/configure.ac b/configure.ac +index 936cfa0ce5a..0edae0f5926 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1006,12 +1006,41 @@ fi] + + CFLAGS="$TARGET_CFLAGS" + +-# Smashing stack protector. ++# Stack smashing protector. + grub_CHECK_STACK_PROTECTOR +-# Need that, because some distributions ship compilers that include +-# `-fstack-protector' in the default specs. +-if test "x$ssp_possible" = xyes; then +- TARGET_CFLAGS="$TARGET_CFLAGS -fno-stack-protector" ++AC_ARG_ENABLE([stack-protector], ++ AS_HELP_STRING([--enable-stack-protector], ++ [enable the stack protector]), ++ [], ++ [enable_stack_protector=no]) ++if test "x$enable_stack_protector" = xno; then ++ if test "x$ssp_possible" = xyes; then ++ # Need that, because some distributions ship compilers that include ++ # `-fstack-protector' in the default specs. ++ TARGET_CFLAGS="$TARGET_CFLAGS -fno-stack-protector" ++ fi ++elif test "x$platform" != xefi; then ++ AC_MSG_ERROR([--enable-stack-protector is only supported on EFI platforms]) ++elif test "x$ssp_global_possible" != xyes; then ++ AC_MSG_ERROR([--enable-stack-protector is not supported (compiler doesn't support -mstack-protector-guard=global)]) ++else ++ TARGET_CFLAGS="$TARGET_CFLAGS -mstack-protector-guard=global" ++ if test "x$enable_stack_protector" = xyes; then ++ if test "x$ssp_possible" != xyes; then ++ AC_MSG_ERROR([--enable-stack-protector is not supported (compiler doesn't support -fstack-protector)]) ++ fi ++ TARGET_CFLAGS="$TARGET_CFLAGS -fstack-protector" ++ elif test "x$enable_stack_protector" = xstrong; then ++ if test "x$ssp_strong_possible" != xyes; then ++ AC_MSG_ERROR([--enable-stack-protector=strong is not supported (compiler doesn't support -fstack-protector-strong)]) ++ fi ++ TARGET_CFLAGS="$TARGET_CFLAGS -fstack-protector-strong" ++ else ++ # Note, -fstack-protector-all requires that the protector is disabled for ++ # functions that appear in the call stack when the canary is initialized. ++ AC_MSG_ERROR([invalid value $enable_stack_protector for --enable-stack-protector]) ++ fi ++ TARGET_CPPFLAGS="$TARGET_CPPFLAGS -DGRUB_STACK_PROTECTOR=1" + fi + + CFLAGS="$TARGET_CFLAGS" +@@ -1912,5 +1941,10 @@ echo "Without liblzma (no support for XZ-compressed mips images) ($liblzma_excus + else + echo "With liblzma from $LIBLZMA (support for XZ-compressed mips images)" + fi ++if test "x$enable_stack_protector" != xno; then ++echo "With stack smashing protector: Yes" ++else ++echo "With stack smashing protector: No" ++fi + echo "*******************************************************" + ] +diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c +index ed33201f12a..2071eaa9997 100644 +--- a/grub-core/kern/efi/init.c ++++ b/grub-core/kern/efi/init.c +@@ -28,6 +28,58 @@ + #include + #include + #include ++#include ++ ++#ifdef GRUB_STACK_PROTECTOR ++ ++static grub_efi_guid_t rng_protocol_guid = GRUB_EFI_RNG_PROTOCOL_GUID; ++ ++/* ++ * Don't put this on grub_efi_init()'s local stack to avoid it ++ * getting a stack check. ++ */ ++static grub_efi_uint8_t stack_chk_guard_buf[32]; ++ ++grub_addr_t __stack_chk_guard; ++ ++void __attribute__ ((noreturn)) ++__stack_chk_fail (void) ++{ ++ /* ++ * Assume it's not safe to call into EFI Boot Services. Sorry, that ++ * means no console message here. ++ */ ++ do ++ { ++ /* Do not optimize out the loop. */ ++ asm volatile (""); ++ } ++ while (1); ++} ++ ++static void ++stack_protector_init (void) ++{ ++ grub_efi_rng_protocol_t *rng; ++ ++ /* Set up the stack canary. Make errors here non-fatal for now. */ ++ rng = grub_efi_locate_protocol (&rng_protocol_guid, NULL); ++ if (rng != NULL) ++ { ++ grub_efi_status_t status; ++ ++ status = efi_call_4 (rng->get_rng, rng, NULL, sizeof (stack_chk_guard_buf), ++ stack_chk_guard_buf); ++ if (status == GRUB_EFI_SUCCESS) ++ grub_memcpy (&__stack_chk_guard, stack_chk_guard_buf, sizeof (__stack_chk_guard)); ++ } ++} ++#else ++static void ++stack_protector_init (void) ++{ ++} ++#endif + + grub_addr_t grub_modbase; + +@@ -69,6 +121,8 @@ grub_efi_init (void) + messages. */ + grub_console_init (); + ++ stack_protector_init (); ++ + /* Initialize the memory management system. */ + grub_efi_mm_init (); + +diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h +index 9860fd16189..4a8d7031b70 100644 +--- a/include/grub/efi/api.h ++++ b/include/grub/efi/api.h +@@ -299,6 +299,11 @@ + { 0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a } \ + } + ++#define GRUB_EFI_RNG_PROTOCOL_GUID \ ++ { 0x3152bca5, 0xeade, 0x433d, \ ++ { 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 } \ ++ } ++ + struct grub_efi_sal_system_table + { + grub_uint32_t signature; +@@ -2009,6 +2014,20 @@ struct grub_efi_ip6_config_manual_address { + }; + typedef struct grub_efi_ip6_config_manual_address grub_efi_ip6_config_manual_address_t; + ++typedef grub_efi_guid_t grub_efi_rng_algorithm_t; ++ ++struct grub_efi_rng_protocol ++{ ++ grub_efi_status_t (*get_info) (struct grub_efi_rng_protocol *this, ++ grub_efi_uintn_t *rng_algorithm_list_size, ++ grub_efi_rng_algorithm_t *rng_algorithm_list); ++ grub_efi_status_t (*get_rng) (struct grub_efi_rng_protocol *this, ++ grub_efi_rng_algorithm_t *rng_algorithm, ++ grub_efi_uintn_t rng_value_length, ++ grub_efi_uint8_t *rng_value); ++}; ++typedef struct grub_efi_rng_protocol grub_efi_rng_protocol_t; ++ + #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \ + || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) + +diff --git a/include/grub/stack_protector.h b/include/grub/stack_protector.h +new file mode 100644 +index 00000000000..c88dc00b5f9 +--- /dev/null ++++ b/include/grub/stack_protector.h +@@ -0,0 +1,30 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2021 Free Software Foundation, Inc. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#ifndef GRUB_STACK_PROTECTOR_H ++#define GRUB_STACK_PROTECTOR_H 1 ++ ++#include ++#include ++ ++#ifdef GRUB_STACK_PROTECTOR ++extern grub_addr_t EXPORT_VAR (__stack_chk_guard); ++extern void __attribute__ ((noreturn)) EXPORT_FUNC (__stack_chk_fail) (void); ++#endif ++ ++#endif /* GRUB_STACK_PROTECTOR_H */ +diff --git a/acinclude.m4 b/acinclude.m4 +index b2bb88d838e..ca720b0c453 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -379,9 +379,9 @@ fi + ]) + + +-dnl Check if the C compiler supports `-fstack-protector'. ++dnl Check if the C compiler supports the stack protector + AC_DEFUN([grub_CHECK_STACK_PROTECTOR],[ +-[# Smashing stack protector. ++[# Stack smashing protector. + ssp_possible=yes] + AC_MSG_CHECKING([whether `$CC' accepts `-fstack-protector']) + # Is this a reliable test case? +@@ -398,6 +398,40 @@ else + ssp_possible=no] + AC_MSG_RESULT([no]) + [fi] ++[# Strong stack smashing protector. ++ssp_strong_possible=yes] ++AC_MSG_CHECKING([whether `$CC' accepts `-fstack-protector-strong']) ++# Is this a reliable test case? ++AC_LANG_CONFTEST([AC_LANG_SOURCE([[ ++void foo (void) { volatile char a[8]; a[3]; } ++]])]) ++[# `$CC -c -o ...' might not be portable. But, oh, well... Is calling ++# `ac_compile' like this correct, after all? ++if eval "$ac_compile -S -fstack-protector-strong -o conftest.s" 2> /dev/null; then] ++ AC_MSG_RESULT([yes]) ++ [# Should we clear up other files as well, having called `AC_LANG_CONFTEST'? ++ rm -f conftest.s ++else ++ ssp_strong_possible=no] ++ AC_MSG_RESULT([no]) ++[fi] ++[# Global stack smashing protector. ++ssp_global_possible=yes] ++AC_MSG_CHECKING([whether `$CC' accepts `-mstack-protector-guard=global']) ++# Is this a reliable test case? ++AC_LANG_CONFTEST([AC_LANG_SOURCE([[ ++void foo (void) { volatile char a[8]; a[3]; } ++]])]) ++[# `$CC -c -o ...' might not be portable. But, oh, well... Is calling ++# `ac_compile' like this correct, after all? ++if eval "$ac_compile -S -fstack-protector -mstack-protector-guard=global -o conftest.s" 2> /dev/null; then] ++ AC_MSG_RESULT([yes]) ++ [# Should we clear up other files as well, having called `AC_LANG_CONFTEST'? ++ rm -f conftest.s ++else ++ ssp_global_possible=no] ++ AC_MSG_RESULT([no]) ++[fi] + ]) + + dnl Check if the C compiler supports `-mstack-arg-probe' (Cygwin). +diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am +index e15846ba75b..2acd02cd188 100644 +--- a/grub-core/Makefile.am ++++ b/grub-core/Makefile.am +@@ -85,6 +85,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/misc.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/stack_protector.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h diff --git a/SOURCES/0428-kern-parser-Fix-a-stack-buffer-overflow.patch b/SOURCES/0428-kern-parser-Fix-a-stack-buffer-overflow.patch deleted file mode 100644 index 40c1c37..0000000 --- a/SOURCES/0428-kern-parser-Fix-a-stack-buffer-overflow.patch +++ /dev/null @@ -1,244 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Coulson -Date: Thu, 7 Jan 2021 19:21:03 +0000 -Subject: [PATCH] kern/parser: Fix a stack buffer overflow - -grub_parser_split_cmdline() expands variable names present in the supplied -command line in to their corresponding variable contents and uses a 1 kiB -stack buffer for temporary storage without sufficient bounds checking. If -the function is called with a command line that references a variable with -a sufficiently large payload, it is possible to overflow the stack -buffer via tab completion, corrupt the stack frame and potentially -control execution. - -Fixes: CVE-2020-27749 - -Reported-by: Chris Coulson -Signed-off-by: Chris Coulson -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/kern/parser.c | 110 +++++++++++++++++++++++++++++------------------- - 1 file changed, 67 insertions(+), 43 deletions(-) - -diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c -index 16879f072fe..068b6d0fe57 100644 ---- a/grub-core/kern/parser.c -+++ b/grub-core/kern/parser.c -@@ -18,6 +18,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -107,8 +108,8 @@ check_varstate (grub_parser_state_t s) - } - - --static void --add_var (char *varname, char **bp, char **vp, -+static grub_err_t -+add_var (grub_buffer_t varname, grub_buffer_t buf, - grub_parser_state_t state, grub_parser_state_t newstate) - { - const char *val; -@@ -116,31 +117,41 @@ add_var (char *varname, char **bp, char **vp, - /* Check if a variable was being read in and the end of the name - was reached. */ - if (!(check_varstate (state) && !check_varstate (newstate))) -- return; -+ return GRUB_ERR_NONE; - -- *((*vp)++) = '\0'; -- val = grub_env_get (varname); -- *vp = varname; -+ if (grub_buffer_append_char (varname, '\0') != GRUB_ERR_NONE) -+ return grub_errno; -+ -+ val = grub_env_get ((const char *) grub_buffer_peek_data (varname)); -+ grub_buffer_reset (varname); - if (!val) -- return; -+ return GRUB_ERR_NONE; - - /* Insert the contents of the variable in the buffer. */ -- for (; *val; val++) -- *((*bp)++) = *val; -+ return grub_buffer_append_data (buf, val, grub_strlen (val)); - } - --static void --terminate_arg (char *buffer, char **bp, int *argc) -+static grub_err_t -+terminate_arg (grub_buffer_t buffer, int *argc) - { -- if (*bp != buffer && *((*bp) - 1) != '\0') -- { -- *((*bp)++) = '\0'; -- (*argc)++; -- } -+ grub_size_t unread = grub_buffer_get_unread_bytes (buffer); -+ -+ if (unread == 0) -+ return GRUB_ERR_NONE; -+ -+ if (*(const char *) grub_buffer_peek_data_at (buffer, unread - 1) == '\0') -+ return GRUB_ERR_NONE; -+ -+ if (grub_buffer_append_char (buffer, '\0') != GRUB_ERR_NONE) -+ return grub_errno; -+ -+ (*argc)++; -+ -+ return GRUB_ERR_NONE; - } - - static grub_err_t --process_char (char c, char *buffer, char **bp, char *varname, char **vp, -+process_char (char c, grub_buffer_t buffer, grub_buffer_t varname, - grub_parser_state_t state, int *argc, - grub_parser_state_t *newstate) - { -@@ -153,12 +164,13 @@ process_char (char c, char *buffer, char **bp, char *varname, char **vp, - * not describe the variable anymore, write the variable to - * the buffer. - */ -- add_var (varname, bp, vp, state, *newstate); -+ if (add_var (varname, buffer, state, *newstate) != GRUB_ERR_NONE) -+ return grub_errno; - - if (check_varstate (*newstate)) - { - if (use) -- *((*vp)++) = use; -+ return grub_buffer_append_char (varname, use); - } - else if (*newstate == GRUB_PARSER_STATE_TEXT && - state != GRUB_PARSER_STATE_ESC && grub_isspace (use)) -@@ -167,10 +179,10 @@ process_char (char c, char *buffer, char **bp, char *varname, char **vp, - * Don't add more than one argument if multiple - * spaces are used. - */ -- terminate_arg (buffer, bp, argc); -+ return terminate_arg (buffer, argc); - } - else if (use) -- *((*bp)++) = use; -+ return grub_buffer_append_char (buffer, use); - - return GRUB_ERR_NONE; - } -@@ -181,19 +193,22 @@ grub_parser_split_cmdline (const char *cmdline, - int *argc, char ***argv) - { - grub_parser_state_t state = GRUB_PARSER_STATE_TEXT; -- /* XXX: Fixed size buffer, perhaps this buffer should be dynamically -- allocated. */ -- char buffer[1024]; -- char *bp = buffer; -+ grub_buffer_t buffer, varname; - char *rd = (char *) cmdline; - char *rp = rd; -- char varname[200]; -- char *vp = varname; -- char *args; - int i; - - *argc = 0; - *argv = NULL; -+ -+ buffer = grub_buffer_new (1024); -+ if (buffer == NULL) -+ return grub_errno; -+ -+ varname = grub_buffer_new (200); -+ if (varname == NULL) -+ goto fail; -+ - do - { - if (rp == NULL || *rp == '\0') -@@ -219,7 +234,7 @@ grub_parser_split_cmdline (const char *cmdline, - { - grub_parser_state_t newstate; - -- if (process_char (*rp, buffer, &bp, varname, &vp, state, argc, -+ if (process_char (*rp, buffer, varname, state, argc, - &newstate) != GRUB_ERR_NONE) - goto fail; - -@@ -230,10 +245,12 @@ grub_parser_split_cmdline (const char *cmdline, - - /* A special case for when the last character was part of a - variable. */ -- add_var (varname, &bp, &vp, state, GRUB_PARSER_STATE_TEXT); -+ if (add_var (varname, buffer, state, GRUB_PARSER_STATE_TEXT) != GRUB_ERR_NONE) -+ goto fail; - - /* Ensure that the last argument is terminated. */ -- terminate_arg (buffer, &bp, argc); -+ if (terminate_arg (buffer, argc) != GRUB_ERR_NONE) -+ goto fail; - - /* If there are no args, then we're done. */ - if (!*argc) -@@ -242,38 +259,45 @@ grub_parser_split_cmdline (const char *cmdline, - goto out; - } - -- /* Reserve memory for the return values. */ -- args = grub_malloc (bp - buffer); -- if (!args) -- goto fail; -- grub_memcpy (args, buffer, bp - buffer); -- - *argv = grub_calloc (*argc + 1, sizeof (char *)); - if (!*argv) - goto fail; - - /* The arguments are separated with 0's, setup argv so it points to - the right values. */ -- bp = args; - for (i = 0; i < *argc; i++) - { -- (*argv)[i] = bp; -- while (*bp) -- bp++; -- bp++; -+ char *arg; -+ -+ if (i > 0) -+ { -+ if (grub_buffer_advance_read_pos (buffer, 1) != GRUB_ERR_NONE) -+ goto fail; -+ } -+ -+ arg = (char *) grub_buffer_peek_data (buffer); -+ if (arg == NULL || -+ grub_buffer_advance_read_pos (buffer, grub_strlen (arg)) != GRUB_ERR_NONE) -+ goto fail; -+ -+ (*argv)[i] = arg; - } - -+ /* Keep memory for the return values. */ -+ grub_buffer_take_data (buffer); -+ - grub_errno = GRUB_ERR_NONE; - - out: - if (rd != cmdline) - grub_free (rd); -+ grub_buffer_free (buffer); -+ grub_buffer_free (varname); - - return grub_errno; - - fail: - grub_free (*argv); -- grub_free (args); - goto out; - } - diff --git a/SOURCES/0429-kern-efi-Add-initial-stack-protector-implementation.patch b/SOURCES/0429-kern-efi-Add-initial-stack-protector-implementation.patch deleted file mode 100644 index 4814e96..0000000 --- a/SOURCES/0429-kern-efi-Add-initial-stack-protector-implementation.patch +++ /dev/null @@ -1,298 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Coulson -Date: Fri, 19 Feb 2021 13:53:45 +0100 -Subject: [PATCH] kern/efi: Add initial stack protector implementation - -It works only on UEFI platforms but can be quite easily extended to -others architectures and platforms if needed. - -Signed-off-by: Chris Coulson -Signed-off-by: Daniel Kiper -Reviewed-by: Marco A Benatto -Reviewed-by: Javier Martinez Canillas ---- - configure.ac | 44 ++++++++++++++++++++++++++++++---- - grub-core/kern/efi/init.c | 54 ++++++++++++++++++++++++++++++++++++++++++ - include/grub/efi/api.h | 19 +++++++++++++++ - include/grub/stack_protector.h | 30 +++++++++++++++++++++++ - acinclude.m4 | 38 +++++++++++++++++++++++++++-- - grub-core/Makefile.am | 1 + - 6 files changed, 179 insertions(+), 7 deletions(-) - create mode 100644 include/grub/stack_protector.h - -diff --git a/configure.ac b/configure.ac -index 936cfa0ce5a..0edae0f5926 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1006,12 +1006,41 @@ fi] - - CFLAGS="$TARGET_CFLAGS" - --# Smashing stack protector. -+# Stack smashing protector. - grub_CHECK_STACK_PROTECTOR --# Need that, because some distributions ship compilers that include --# `-fstack-protector' in the default specs. --if test "x$ssp_possible" = xyes; then -- TARGET_CFLAGS="$TARGET_CFLAGS -fno-stack-protector" -+AC_ARG_ENABLE([stack-protector], -+ AS_HELP_STRING([--enable-stack-protector], -+ [enable the stack protector]), -+ [], -+ [enable_stack_protector=no]) -+if test "x$enable_stack_protector" = xno; then -+ if test "x$ssp_possible" = xyes; then -+ # Need that, because some distributions ship compilers that include -+ # `-fstack-protector' in the default specs. -+ TARGET_CFLAGS="$TARGET_CFLAGS -fno-stack-protector" -+ fi -+elif test "x$platform" != xefi; then -+ AC_MSG_ERROR([--enable-stack-protector is only supported on EFI platforms]) -+elif test "x$ssp_global_possible" != xyes; then -+ AC_MSG_ERROR([--enable-stack-protector is not supported (compiler doesn't support -mstack-protector-guard=global)]) -+else -+ TARGET_CFLAGS="$TARGET_CFLAGS -mstack-protector-guard=global" -+ if test "x$enable_stack_protector" = xyes; then -+ if test "x$ssp_possible" != xyes; then -+ AC_MSG_ERROR([--enable-stack-protector is not supported (compiler doesn't support -fstack-protector)]) -+ fi -+ TARGET_CFLAGS="$TARGET_CFLAGS -fstack-protector" -+ elif test "x$enable_stack_protector" = xstrong; then -+ if test "x$ssp_strong_possible" != xyes; then -+ AC_MSG_ERROR([--enable-stack-protector=strong is not supported (compiler doesn't support -fstack-protector-strong)]) -+ fi -+ TARGET_CFLAGS="$TARGET_CFLAGS -fstack-protector-strong" -+ else -+ # Note, -fstack-protector-all requires that the protector is disabled for -+ # functions that appear in the call stack when the canary is initialized. -+ AC_MSG_ERROR([invalid value $enable_stack_protector for --enable-stack-protector]) -+ fi -+ TARGET_CPPFLAGS="$TARGET_CPPFLAGS -DGRUB_STACK_PROTECTOR=1" - fi - - CFLAGS="$TARGET_CFLAGS" -@@ -1912,5 +1941,10 @@ echo "Without liblzma (no support for XZ-compressed mips images) ($liblzma_excus - else - echo "With liblzma from $LIBLZMA (support for XZ-compressed mips images)" - fi -+if test "x$enable_stack_protector" != xno; then -+echo "With stack smashing protector: Yes" -+else -+echo "With stack smashing protector: No" -+fi - echo "*******************************************************" - ] -diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c -index ed33201f12a..2071eaa9997 100644 ---- a/grub-core/kern/efi/init.c -+++ b/grub-core/kern/efi/init.c -@@ -28,6 +28,58 @@ - #include - #include - #include -+#include -+ -+#ifdef GRUB_STACK_PROTECTOR -+ -+static grub_efi_guid_t rng_protocol_guid = GRUB_EFI_RNG_PROTOCOL_GUID; -+ -+/* -+ * Don't put this on grub_efi_init()'s local stack to avoid it -+ * getting a stack check. -+ */ -+static grub_efi_uint8_t stack_chk_guard_buf[32]; -+ -+grub_addr_t __stack_chk_guard; -+ -+void __attribute__ ((noreturn)) -+__stack_chk_fail (void) -+{ -+ /* -+ * Assume it's not safe to call into EFI Boot Services. Sorry, that -+ * means no console message here. -+ */ -+ do -+ { -+ /* Do not optimize out the loop. */ -+ asm volatile (""); -+ } -+ while (1); -+} -+ -+static void -+stack_protector_init (void) -+{ -+ grub_efi_rng_protocol_t *rng; -+ -+ /* Set up the stack canary. Make errors here non-fatal for now. */ -+ rng = grub_efi_locate_protocol (&rng_protocol_guid, NULL); -+ if (rng != NULL) -+ { -+ grub_efi_status_t status; -+ -+ status = efi_call_4 (rng->get_rng, rng, NULL, sizeof (stack_chk_guard_buf), -+ stack_chk_guard_buf); -+ if (status == GRUB_EFI_SUCCESS) -+ grub_memcpy (&__stack_chk_guard, stack_chk_guard_buf, sizeof (__stack_chk_guard)); -+ } -+} -+#else -+static void -+stack_protector_init (void) -+{ -+} -+#endif - - grub_addr_t grub_modbase; - -@@ -69,6 +121,8 @@ grub_efi_init (void) - messages. */ - grub_console_init (); - -+ stack_protector_init (); -+ - /* Initialize the memory management system. */ - grub_efi_mm_init (); - -diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index 9860fd16189..4a8d7031b70 100644 ---- a/include/grub/efi/api.h -+++ b/include/grub/efi/api.h -@@ -299,6 +299,11 @@ - { 0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a } \ - } - -+#define GRUB_EFI_RNG_PROTOCOL_GUID \ -+ { 0x3152bca5, 0xeade, 0x433d, \ -+ { 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 } \ -+ } -+ - struct grub_efi_sal_system_table - { - grub_uint32_t signature; -@@ -2009,6 +2014,20 @@ struct grub_efi_ip6_config_manual_address { - }; - typedef struct grub_efi_ip6_config_manual_address grub_efi_ip6_config_manual_address_t; - -+typedef grub_efi_guid_t grub_efi_rng_algorithm_t; -+ -+struct grub_efi_rng_protocol -+{ -+ grub_efi_status_t (*get_info) (struct grub_efi_rng_protocol *this, -+ grub_efi_uintn_t *rng_algorithm_list_size, -+ grub_efi_rng_algorithm_t *rng_algorithm_list); -+ grub_efi_status_t (*get_rng) (struct grub_efi_rng_protocol *this, -+ grub_efi_rng_algorithm_t *rng_algorithm, -+ grub_efi_uintn_t rng_value_length, -+ grub_efi_uint8_t *rng_value); -+}; -+typedef struct grub_efi_rng_protocol grub_efi_rng_protocol_t; -+ - #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \ - || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) - -diff --git a/include/grub/stack_protector.h b/include/grub/stack_protector.h -new file mode 100644 -index 00000000000..c88dc00b5f9 ---- /dev/null -+++ b/include/grub/stack_protector.h -@@ -0,0 +1,30 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2021 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_STACK_PROTECTOR_H -+#define GRUB_STACK_PROTECTOR_H 1 -+ -+#include -+#include -+ -+#ifdef GRUB_STACK_PROTECTOR -+extern grub_addr_t EXPORT_VAR (__stack_chk_guard); -+extern void __attribute__ ((noreturn)) EXPORT_FUNC (__stack_chk_fail) (void); -+#endif -+ -+#endif /* GRUB_STACK_PROTECTOR_H */ -diff --git a/acinclude.m4 b/acinclude.m4 -index b2bb88d838e..ca720b0c453 100644 ---- a/acinclude.m4 -+++ b/acinclude.m4 -@@ -379,9 +379,9 @@ fi - ]) - - --dnl Check if the C compiler supports `-fstack-protector'. -+dnl Check if the C compiler supports the stack protector - AC_DEFUN([grub_CHECK_STACK_PROTECTOR],[ --[# Smashing stack protector. -+[# Stack smashing protector. - ssp_possible=yes] - AC_MSG_CHECKING([whether `$CC' accepts `-fstack-protector']) - # Is this a reliable test case? -@@ -398,6 +398,40 @@ else - ssp_possible=no] - AC_MSG_RESULT([no]) - [fi] -+[# Strong stack smashing protector. -+ssp_strong_possible=yes] -+AC_MSG_CHECKING([whether `$CC' accepts `-fstack-protector-strong']) -+# Is this a reliable test case? -+AC_LANG_CONFTEST([AC_LANG_SOURCE([[ -+void foo (void) { volatile char a[8]; a[3]; } -+]])]) -+[# `$CC -c -o ...' might not be portable. But, oh, well... Is calling -+# `ac_compile' like this correct, after all? -+if eval "$ac_compile -S -fstack-protector-strong -o conftest.s" 2> /dev/null; then] -+ AC_MSG_RESULT([yes]) -+ [# Should we clear up other files as well, having called `AC_LANG_CONFTEST'? -+ rm -f conftest.s -+else -+ ssp_strong_possible=no] -+ AC_MSG_RESULT([no]) -+[fi] -+[# Global stack smashing protector. -+ssp_global_possible=yes] -+AC_MSG_CHECKING([whether `$CC' accepts `-mstack-protector-guard=global']) -+# Is this a reliable test case? -+AC_LANG_CONFTEST([AC_LANG_SOURCE([[ -+void foo (void) { volatile char a[8]; a[3]; } -+]])]) -+[# `$CC -c -o ...' might not be portable. But, oh, well... Is calling -+# `ac_compile' like this correct, after all? -+if eval "$ac_compile -S -fstack-protector -mstack-protector-guard=global -o conftest.s" 2> /dev/null; then] -+ AC_MSG_RESULT([yes]) -+ [# Should we clear up other files as well, having called `AC_LANG_CONFTEST'? -+ rm -f conftest.s -+else -+ ssp_global_possible=no] -+ AC_MSG_RESULT([no]) -+[fi] - ]) - - dnl Check if the C compiler supports `-mstack-arg-probe' (Cygwin). -diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am -index e15846ba75b..2acd02cd188 100644 ---- a/grub-core/Makefile.am -+++ b/grub-core/Makefile.am -@@ -85,6 +85,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/misc.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h -+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/stack_protector.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h diff --git a/SOURCES/0429-util-mkimage-Remove-unused-code-to-add-BSS-section.patch b/SOURCES/0429-util-mkimage-Remove-unused-code-to-add-BSS-section.patch new file mode 100644 index 0000000..25d1d50 --- /dev/null +++ b/SOURCES/0429-util-mkimage-Remove-unused-code-to-add-BSS-section.patch @@ -0,0 +1,57 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Thu, 11 Feb 2021 17:06:49 +0100 +Subject: [PATCH] util/mkimage: Remove unused code to add BSS section + +The code is compiled out so there is no reason to keep it. + +Additionally, don't set bss_size field since we do not add a BSS section. + +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + util/mkimage.c | 17 ----------------- + 1 file changed, 17 deletions(-) + +diff --git a/util/mkimage.c b/util/mkimage.c +index e6b799fd73c..55bfd1d8b9e 100644 +--- a/util/mkimage.c ++++ b/util/mkimage.c +@@ -1460,7 +1460,6 @@ grub_install_generate_image (const char *dir, const char *prefix, + o->code_size = grub_host_to_target32 (exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size + - header_size); +- o->bss_size = grub_cpu_to_le32 (bss_size); + o->entry_addr = grub_cpu_to_le32 (start_address); + o->code_base = grub_cpu_to_le32 (header_size); + +@@ -1498,7 +1497,6 @@ grub_install_generate_image (const char *dir, const char *prefix, + o->code_size = grub_host_to_target32 (exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size + - header_size); +- o->bss_size = grub_cpu_to_le32 (bss_size); + o->entry_addr = grub_cpu_to_le32 (start_address); + o->code_base = grub_cpu_to_le32 (header_size); + o->image_base = 0; +@@ -1543,21 +1541,6 @@ grub_install_generate_image (const char *dir, const char *prefix, + = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE); +- +-#if 0 +- bss_section = data_section + 1; +- strcpy (bss_section->name, ".bss"); +- bss_section->virtual_size = grub_cpu_to_le32 (bss_size); +- bss_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size); +- bss_section->raw_data_size = 0; +- bss_section->raw_data_offset = 0; +- bss_section->characteristics +- = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_MEM_READ +- | GRUB_PE32_SCN_MEM_WRITE +- | GRUB_PE32_SCN_ALIGN_64BYTES +- | GRUB_PE32_SCN_CNT_INITIALIZED_DATA +- | 0x80); +-#endif + + mods_section = data_section + 1; + strcpy (mods_section->name, "mods"); diff --git a/SOURCES/0430-util-mkimage-Remove-unused-code-to-add-BSS-section.patch b/SOURCES/0430-util-mkimage-Remove-unused-code-to-add-BSS-section.patch deleted file mode 100644 index 25d1d50..0000000 --- a/SOURCES/0430-util-mkimage-Remove-unused-code-to-add-BSS-section.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Thu, 11 Feb 2021 17:06:49 +0100 -Subject: [PATCH] util/mkimage: Remove unused code to add BSS section - -The code is compiled out so there is no reason to keep it. - -Additionally, don't set bss_size field since we do not add a BSS section. - -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - util/mkimage.c | 17 ----------------- - 1 file changed, 17 deletions(-) - -diff --git a/util/mkimage.c b/util/mkimage.c -index e6b799fd73c..55bfd1d8b9e 100644 ---- a/util/mkimage.c -+++ b/util/mkimage.c -@@ -1460,7 +1460,6 @@ grub_install_generate_image (const char *dir, const char *prefix, - o->code_size = grub_host_to_target32 (exec_size); - o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size - - header_size); -- o->bss_size = grub_cpu_to_le32 (bss_size); - o->entry_addr = grub_cpu_to_le32 (start_address); - o->code_base = grub_cpu_to_le32 (header_size); - -@@ -1498,7 +1497,6 @@ grub_install_generate_image (const char *dir, const char *prefix, - o->code_size = grub_host_to_target32 (exec_size); - o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size - - header_size); -- o->bss_size = grub_cpu_to_le32 (bss_size); - o->entry_addr = grub_cpu_to_le32 (start_address); - o->code_base = grub_cpu_to_le32 (header_size); - o->image_base = 0; -@@ -1543,21 +1541,6 @@ grub_install_generate_image (const char *dir, const char *prefix, - = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE); -- --#if 0 -- bss_section = data_section + 1; -- strcpy (bss_section->name, ".bss"); -- bss_section->virtual_size = grub_cpu_to_le32 (bss_size); -- bss_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size); -- bss_section->raw_data_size = 0; -- bss_section->raw_data_offset = 0; -- bss_section->characteristics -- = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_MEM_READ -- | GRUB_PE32_SCN_MEM_WRITE -- | GRUB_PE32_SCN_ALIGN_64BYTES -- | GRUB_PE32_SCN_CNT_INITIALIZED_DATA -- | 0x80); --#endif - - mods_section = data_section + 1; - strcpy (mods_section->name, "mods"); diff --git a/SOURCES/0430-util-mkimage-Use-grub_host_to_target32-instead-of-gr.patch b/SOURCES/0430-util-mkimage-Use-grub_host_to_target32-instead-of-gr.patch new file mode 100644 index 0000000..93d2b70 --- /dev/null +++ b/SOURCES/0430-util-mkimage-Use-grub_host_to_target32-instead-of-gr.patch @@ -0,0 +1,109 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 15 Feb 2021 13:59:21 +0100 +Subject: [PATCH] util/mkimage: Use grub_host_to_target32() instead of + grub_cpu_to_le32() + +The latter doesn't take into account the target image endianness. There is +a grub_cpu_to_le32_compile_time() but no compile time variant for function +grub_host_to_target32(). So, let's keep using the other one for this case. + +Signed-off-by: Peter Jones +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + util/mkimage.c | 44 ++++++++++++++++++++++---------------------- + 1 file changed, 22 insertions(+), 22 deletions(-) + +diff --git a/util/mkimage.c b/util/mkimage.c +index 55bfd1d8b9e..f4f84dbecd0 100644 +--- a/util/mkimage.c ++++ b/util/mkimage.c +@@ -1458,10 +1458,10 @@ grub_install_generate_image (const char *dir, const char *prefix, + + sizeof (struct grub_pe32_coff_header)); + o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->code_size = grub_host_to_target32 (exec_size); +- o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size ++ o->data_size = grub_host_to_target32 (reloc_addr - exec_size + - header_size); +- o->entry_addr = grub_cpu_to_le32 (start_address); +- o->code_base = grub_cpu_to_le32 (header_size); ++ o->entry_addr = grub_host_to_target32 (start_address); ++ o->code_base = grub_host_to_target32 (header_size); + + o->data_base = grub_host_to_target32 (header_size + exec_size); + +@@ -1495,10 +1495,10 @@ grub_install_generate_image (const char *dir, const char *prefix, + + sizeof (struct grub_pe32_coff_header)); + o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); + o->code_size = grub_host_to_target32 (exec_size); +- o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size ++ o->data_size = grub_host_to_target32 (reloc_addr - exec_size + - header_size); +- o->entry_addr = grub_cpu_to_le32 (start_address); +- o->code_base = grub_cpu_to_le32 (header_size); ++ o->entry_addr = grub_host_to_target32 (start_address); ++ o->code_base = grub_host_to_target32 (header_size); + o->image_base = 0; + o->section_alignment = grub_host_to_target32 (image_target->section_align); + o->file_alignment = grub_host_to_target32 (image_target->section_align); +@@ -1522,10 +1522,10 @@ grub_install_generate_image (const char *dir, const char *prefix, + /* The sections. */ + text_section = sections; + strcpy (text_section->name, ".text"); +- text_section->virtual_size = grub_cpu_to_le32 (exec_size); +- text_section->virtual_address = grub_cpu_to_le32 (header_size); +- text_section->raw_data_size = grub_cpu_to_le32 (exec_size); +- text_section->raw_data_offset = grub_cpu_to_le32 (header_size); ++ text_section->virtual_size = grub_host_to_target32 (exec_size); ++ text_section->virtual_address = grub_host_to_target32 (header_size); ++ text_section->raw_data_size = grub_host_to_target32 (exec_size); ++ text_section->raw_data_offset = grub_host_to_target32 (header_size); + text_section->characteristics = grub_cpu_to_le32_compile_time ( + GRUB_PE32_SCN_CNT_CODE + | GRUB_PE32_SCN_MEM_EXECUTE +@@ -1533,10 +1533,10 @@ grub_install_generate_image (const char *dir, const char *prefix, + + data_section = text_section + 1; + strcpy (data_section->name, ".data"); +- data_section->virtual_size = grub_cpu_to_le32 (kernel_size - exec_size); +- data_section->virtual_address = grub_cpu_to_le32 (header_size + exec_size); +- data_section->raw_data_size = grub_cpu_to_le32 (kernel_size - exec_size); +- data_section->raw_data_offset = grub_cpu_to_le32 (header_size + exec_size); ++ data_section->virtual_size = grub_host_to_target32 (kernel_size - exec_size); ++ data_section->virtual_address = grub_host_to_target32 (header_size + exec_size); ++ data_section->raw_data_size = grub_host_to_target32 (kernel_size - exec_size); ++ data_section->raw_data_offset = grub_host_to_target32 (header_size + exec_size); + data_section->characteristics + = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ +@@ -1544,10 +1544,10 @@ grub_install_generate_image (const char *dir, const char *prefix, + + mods_section = data_section + 1; + strcpy (mods_section->name, "mods"); +- mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); +- mods_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size + bss_size); +- mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); +- mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + kernel_size); ++ mods_section->virtual_size = grub_host_to_target32 (reloc_addr - kernel_size - header_size); ++ mods_section->virtual_address = grub_host_to_target32 (header_size + kernel_size + bss_size); ++ mods_section->raw_data_size = grub_host_to_target32 (reloc_addr - kernel_size - header_size); ++ mods_section->raw_data_offset = grub_host_to_target32 (header_size + kernel_size); + mods_section->characteristics + = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ +@@ -1555,10 +1555,10 @@ grub_install_generate_image (const char *dir, const char *prefix, + + reloc_section = mods_section + 1; + strcpy (reloc_section->name, ".reloc"); +- reloc_section->virtual_size = grub_cpu_to_le32 (reloc_size); +- reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + bss_size); +- reloc_section->raw_data_size = grub_cpu_to_le32 (reloc_size); +- reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr); ++ reloc_section->virtual_size = grub_host_to_target32 (reloc_size); ++ reloc_section->virtual_address = grub_host_to_target32 (reloc_addr + bss_size); ++ reloc_section->raw_data_size = grub_host_to_target32 (reloc_size); ++ reloc_section->raw_data_offset = grub_host_to_target32 (reloc_addr); + reloc_section->characteristics + = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_DISCARDABLE diff --git a/SOURCES/0431-util-mkimage-Always-use-grub_host_to_target32-to-ini.patch b/SOURCES/0431-util-mkimage-Always-use-grub_host_to_target32-to-ini.patch new file mode 100644 index 0000000..b6f5f06 --- /dev/null +++ b/SOURCES/0431-util-mkimage-Always-use-grub_host_to_target32-to-ini.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 15 Feb 2021 14:14:24 +0100 +Subject: [PATCH] util/mkimage: Always use grub_host_to_target32() to + initialize PE stack and heap stuff + +This change does not impact final result of initialization itself. +However, it eases PE code unification in subsequent patches. + +Signed-off-by: Peter Jones +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + util/mkimage.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/util/mkimage.c b/util/mkimage.c +index f4f84dbecd0..f44675e867b 100644 +--- a/util/mkimage.c ++++ b/util/mkimage.c +@@ -1507,10 +1507,10 @@ grub_install_generate_image (const char *dir, const char *prefix, + o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ +- o->stack_reserve_size = grub_host_to_target64 (0x10000); +- o->stack_commit_size = grub_host_to_target64 (0x10000); +- o->heap_reserve_size = grub_host_to_target64 (0x10000); +- o->heap_commit_size = grub_host_to_target64 (0x10000); ++ o->stack_reserve_size = grub_host_to_target32 (0x10000); ++ o->stack_commit_size = grub_host_to_target32 (0x10000); ++ o->heap_reserve_size = grub_host_to_target32 (0x10000); ++ o->heap_commit_size = grub_host_to_target32 (0x10000); + + o->num_data_directories + = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); diff --git a/SOURCES/0431-util-mkimage-Use-grub_host_to_target32-instead-of-gr.patch b/SOURCES/0431-util-mkimage-Use-grub_host_to_target32-instead-of-gr.patch deleted file mode 100644 index 93d2b70..0000000 --- a/SOURCES/0431-util-mkimage-Use-grub_host_to_target32-instead-of-gr.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 15 Feb 2021 13:59:21 +0100 -Subject: [PATCH] util/mkimage: Use grub_host_to_target32() instead of - grub_cpu_to_le32() - -The latter doesn't take into account the target image endianness. There is -a grub_cpu_to_le32_compile_time() but no compile time variant for function -grub_host_to_target32(). So, let's keep using the other one for this case. - -Signed-off-by: Peter Jones -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - util/mkimage.c | 44 ++++++++++++++++++++++---------------------- - 1 file changed, 22 insertions(+), 22 deletions(-) - -diff --git a/util/mkimage.c b/util/mkimage.c -index 55bfd1d8b9e..f4f84dbecd0 100644 ---- a/util/mkimage.c -+++ b/util/mkimage.c -@@ -1458,10 +1458,10 @@ grub_install_generate_image (const char *dir, const char *prefix, - + sizeof (struct grub_pe32_coff_header)); - o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); - o->code_size = grub_host_to_target32 (exec_size); -- o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size -+ o->data_size = grub_host_to_target32 (reloc_addr - exec_size - - header_size); -- o->entry_addr = grub_cpu_to_le32 (start_address); -- o->code_base = grub_cpu_to_le32 (header_size); -+ o->entry_addr = grub_host_to_target32 (start_address); -+ o->code_base = grub_host_to_target32 (header_size); - - o->data_base = grub_host_to_target32 (header_size + exec_size); - -@@ -1495,10 +1495,10 @@ grub_install_generate_image (const char *dir, const char *prefix, - + sizeof (struct grub_pe32_coff_header)); - o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); - o->code_size = grub_host_to_target32 (exec_size); -- o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size -+ o->data_size = grub_host_to_target32 (reloc_addr - exec_size - - header_size); -- o->entry_addr = grub_cpu_to_le32 (start_address); -- o->code_base = grub_cpu_to_le32 (header_size); -+ o->entry_addr = grub_host_to_target32 (start_address); -+ o->code_base = grub_host_to_target32 (header_size); - o->image_base = 0; - o->section_alignment = grub_host_to_target32 (image_target->section_align); - o->file_alignment = grub_host_to_target32 (image_target->section_align); -@@ -1522,10 +1522,10 @@ grub_install_generate_image (const char *dir, const char *prefix, - /* The sections. */ - text_section = sections; - strcpy (text_section->name, ".text"); -- text_section->virtual_size = grub_cpu_to_le32 (exec_size); -- text_section->virtual_address = grub_cpu_to_le32 (header_size); -- text_section->raw_data_size = grub_cpu_to_le32 (exec_size); -- text_section->raw_data_offset = grub_cpu_to_le32 (header_size); -+ text_section->virtual_size = grub_host_to_target32 (exec_size); -+ text_section->virtual_address = grub_host_to_target32 (header_size); -+ text_section->raw_data_size = grub_host_to_target32 (exec_size); -+ text_section->raw_data_offset = grub_host_to_target32 (header_size); - text_section->characteristics = grub_cpu_to_le32_compile_time ( - GRUB_PE32_SCN_CNT_CODE - | GRUB_PE32_SCN_MEM_EXECUTE -@@ -1533,10 +1533,10 @@ grub_install_generate_image (const char *dir, const char *prefix, - - data_section = text_section + 1; - strcpy (data_section->name, ".data"); -- data_section->virtual_size = grub_cpu_to_le32 (kernel_size - exec_size); -- data_section->virtual_address = grub_cpu_to_le32 (header_size + exec_size); -- data_section->raw_data_size = grub_cpu_to_le32 (kernel_size - exec_size); -- data_section->raw_data_offset = grub_cpu_to_le32 (header_size + exec_size); -+ data_section->virtual_size = grub_host_to_target32 (kernel_size - exec_size); -+ data_section->virtual_address = grub_host_to_target32 (header_size + exec_size); -+ data_section->raw_data_size = grub_host_to_target32 (kernel_size - exec_size); -+ data_section->raw_data_offset = grub_host_to_target32 (header_size + exec_size); - data_section->characteristics - = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ -@@ -1544,10 +1544,10 @@ grub_install_generate_image (const char *dir, const char *prefix, - - mods_section = data_section + 1; - strcpy (mods_section->name, "mods"); -- mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); -- mods_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size + bss_size); -- mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); -- mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + kernel_size); -+ mods_section->virtual_size = grub_host_to_target32 (reloc_addr - kernel_size - header_size); -+ mods_section->virtual_address = grub_host_to_target32 (header_size + kernel_size + bss_size); -+ mods_section->raw_data_size = grub_host_to_target32 (reloc_addr - kernel_size - header_size); -+ mods_section->raw_data_offset = grub_host_to_target32 (header_size + kernel_size); - mods_section->characteristics - = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ -@@ -1555,10 +1555,10 @@ grub_install_generate_image (const char *dir, const char *prefix, - - reloc_section = mods_section + 1; - strcpy (reloc_section->name, ".reloc"); -- reloc_section->virtual_size = grub_cpu_to_le32 (reloc_size); -- reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + bss_size); -- reloc_section->raw_data_size = grub_cpu_to_le32 (reloc_size); -- reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr); -+ reloc_section->virtual_size = grub_host_to_target32 (reloc_size); -+ reloc_section->virtual_address = grub_host_to_target32 (reloc_addr + bss_size); -+ reloc_section->raw_data_size = grub_host_to_target32 (reloc_size); -+ reloc_section->raw_data_offset = grub_host_to_target32 (reloc_addr); - reloc_section->characteristics - = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_DISCARDABLE diff --git a/SOURCES/0432-util-mkimage-Always-use-grub_host_to_target32-to-ini.patch b/SOURCES/0432-util-mkimage-Always-use-grub_host_to_target32-to-ini.patch deleted file mode 100644 index b6f5f06..0000000 --- a/SOURCES/0432-util-mkimage-Always-use-grub_host_to_target32-to-ini.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 15 Feb 2021 14:14:24 +0100 -Subject: [PATCH] util/mkimage: Always use grub_host_to_target32() to - initialize PE stack and heap stuff - -This change does not impact final result of initialization itself. -However, it eases PE code unification in subsequent patches. - -Signed-off-by: Peter Jones -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - util/mkimage.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/util/mkimage.c b/util/mkimage.c -index f4f84dbecd0..f44675e867b 100644 ---- a/util/mkimage.c -+++ b/util/mkimage.c -@@ -1507,10 +1507,10 @@ grub_install_generate_image (const char *dir, const char *prefix, - o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); - - /* Do these really matter? */ -- o->stack_reserve_size = grub_host_to_target64 (0x10000); -- o->stack_commit_size = grub_host_to_target64 (0x10000); -- o->heap_reserve_size = grub_host_to_target64 (0x10000); -- o->heap_commit_size = grub_host_to_target64 (0x10000); -+ o->stack_reserve_size = grub_host_to_target32 (0x10000); -+ o->stack_commit_size = grub_host_to_target32 (0x10000); -+ o->heap_reserve_size = grub_host_to_target32 (0x10000); -+ o->heap_commit_size = grub_host_to_target32 (0x10000); - - o->num_data_directories - = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); diff --git a/SOURCES/0432-util-mkimage-Unify-more-of-the-PE32-and-PE32-header-.patch b/SOURCES/0432-util-mkimage-Unify-more-of-the-PE32-and-PE32-header-.patch new file mode 100644 index 0000000..689b94e --- /dev/null +++ b/SOURCES/0432-util-mkimage-Unify-more-of-the-PE32-and-PE32-header-.patch @@ -0,0 +1,165 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Fri, 19 Feb 2021 14:22:13 +0100 +Subject: [PATCH] util/mkimage: Unify more of the PE32 and PE32+ header set-up + +There's quite a bit of code duplication in the code that sets the optional +header for PE32 and PE32+. The two are very similar with the exception of +a few fields that have type grub_uint64_t instead of grub_uint32_t. + +Factor out the common code and add a PE_OHDR() macro that simplifies the +set-up and make the code more readable. + +Signed-off-by: Peter Jones +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + util/mkimage.c | 111 ++++++++++++++++++++++++++------------------------------- + 1 file changed, 51 insertions(+), 60 deletions(-) + +diff --git a/util/mkimage.c b/util/mkimage.c +index f44675e867b..47ff76fb14b 100644 +--- a/util/mkimage.c ++++ b/util/mkimage.c +@@ -978,6 +978,21 @@ grub_install_get_image_targets_string (void) + return formats; + } + ++/* ++ * tmp_ is just here so the compiler knows we'll never derefernce a NULL. ++ * It should get fully optimized away. ++ */ ++#define PE_OHDR(o32, o64, field) (*( \ ++{ \ ++ __typeof__((o64)->field) tmp_; \ ++ __typeof__((o64)->field) *ret_ = &tmp_; \ ++ if (o32) \ ++ ret_ = (void *)(&((o32)->field)); \ ++ else if (o64) \ ++ ret_ = (void *)(&((o64)->field)); \ ++ ret_; \ ++})) ++ + void + grub_install_generate_image (const char *dir, const char *prefix, + FILE *out, const char *outname, char *mods[], +@@ -1409,6 +1424,8 @@ grub_install_generate_image (const char *dir, const char *prefix, + static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; + int header_size; + int reloc_addr; ++ struct grub_pe32_optional_header *o32 = NULL; ++ struct grub_pe64_optional_header *o64 = NULL; + + if (image_target->voidp_sizeof == 4) + header_size = EFI32_HEADER_SIZE; +@@ -1449,76 +1466,50 @@ grub_install_generate_image (const char *dir, const char *prefix, + /* The PE Optional header. */ + if (image_target->voidp_sizeof == 4) + { +- struct grub_pe32_optional_header *o; +- + c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header)); + +- o = (struct grub_pe32_optional_header *) +- (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE +- + sizeof (struct grub_pe32_coff_header)); +- o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); +- o->code_size = grub_host_to_target32 (exec_size); +- o->data_size = grub_host_to_target32 (reloc_addr - exec_size +- - header_size); +- o->entry_addr = grub_host_to_target32 (start_address); +- o->code_base = grub_host_to_target32 (header_size); ++ o32 = (struct grub_pe32_optional_header *) ++ (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + ++ sizeof (struct grub_pe32_coff_header)); ++ o32->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); ++ o32->data_base = grub_host_to_target32 (header_size + exec_size); + +- o->data_base = grub_host_to_target32 (header_size + exec_size); +- +- o->image_base = 0; +- o->section_alignment = grub_host_to_target32 (image_target->section_align); +- o->file_alignment = grub_host_to_target32 (image_target->section_align); +- o->image_size = grub_host_to_target32 (pe_size); +- o->header_size = grub_host_to_target32 (header_size); +- o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); +- +- /* Do these really matter? */ +- o->stack_reserve_size = grub_host_to_target32 (0x10000); +- o->stack_commit_size = grub_host_to_target32 (0x10000); +- o->heap_reserve_size = grub_host_to_target32 (0x10000); +- o->heap_commit_size = grub_host_to_target32 (0x10000); +- +- o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); +- +- o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); +- o->base_relocation_table.size = grub_host_to_target32 (reloc_size); +- sections = o + 1; ++ sections = o32 + 1; + } + else + { +- struct grub_pe64_optional_header *o; +- + c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe64_optional_header)); + +- o = (struct grub_pe64_optional_header *) +- (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE +- + sizeof (struct grub_pe32_coff_header)); +- o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); +- o->code_size = grub_host_to_target32 (exec_size); +- o->data_size = grub_host_to_target32 (reloc_addr - exec_size +- - header_size); +- o->entry_addr = grub_host_to_target32 (start_address); +- o->code_base = grub_host_to_target32 (header_size); +- o->image_base = 0; +- o->section_alignment = grub_host_to_target32 (image_target->section_align); +- o->file_alignment = grub_host_to_target32 (image_target->section_align); +- o->image_size = grub_host_to_target32 (pe_size); +- o->header_size = grub_host_to_target32 (header_size); +- o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); ++ o64 = (struct grub_pe64_optional_header *) ++ (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + ++ sizeof (struct grub_pe32_coff_header)); ++ o64->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); + +- /* Do these really matter? */ +- o->stack_reserve_size = grub_host_to_target32 (0x10000); +- o->stack_commit_size = grub_host_to_target32 (0x10000); +- o->heap_reserve_size = grub_host_to_target32 (0x10000); +- o->heap_commit_size = grub_host_to_target32 (0x10000); +- +- o->num_data_directories +- = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); +- +- o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); +- o->base_relocation_table.size = grub_host_to_target32 (reloc_size); +- sections = o + 1; ++ sections = o64 + 1; + } ++ ++ PE_OHDR (o32, o64, code_size) = grub_host_to_target32 (exec_size); ++ PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (reloc_addr - exec_size - header_size); ++ PE_OHDR (o32, o64, entry_addr) = grub_host_to_target32 (start_address); ++ PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (header_size); ++ ++ PE_OHDR (o32, o64, image_base) = 0; ++ PE_OHDR (o32, o64, section_alignment) = grub_host_to_target32 (image_target->section_align); ++ PE_OHDR (o32, o64, file_alignment) = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT); ++ PE_OHDR (o32, o64, image_size) = grub_host_to_target32 (pe_size); ++ PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size); ++ PE_OHDR (o32, o64, subsystem) = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); ++ ++ /* Do these really matter? */ ++ PE_OHDR (o32, o64, stack_reserve_size) = grub_host_to_target32 (0x10000); ++ PE_OHDR (o32, o64, stack_commit_size) = grub_host_to_target32 (0x10000); ++ PE_OHDR (o32, o64, heap_reserve_size) = grub_host_to_target32 (0x10000); ++ PE_OHDR (o32, o64, heap_commit_size) = grub_host_to_target32 (0x10000); ++ ++ PE_OHDR (o32, o64, num_data_directories) = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); ++ PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (reloc_addr); ++ PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (reloc_size); ++ + /* The sections. */ + text_section = sections; + strcpy (text_section->name, ".text"); diff --git a/SOURCES/0433-util-mkimage-Reorder-PE-optional-header-fields-set-u.patch b/SOURCES/0433-util-mkimage-Reorder-PE-optional-header-fields-set-u.patch new file mode 100644 index 0000000..318152e --- /dev/null +++ b/SOURCES/0433-util-mkimage-Reorder-PE-optional-header-fields-set-u.patch @@ -0,0 +1,69 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 15 Feb 2021 14:21:48 +0100 +Subject: [PATCH] util/mkimage: Reorder PE optional header fields set-up + +This makes the PE32 and PE32+ header fields set-up easier to follow by +setting them closer to the initialization of their related sections. + +Signed-off-by: Peter Jones +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + util/mkimage.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/util/mkimage.c b/util/mkimage.c +index 47ff76fb14b..ca88b0ff96a 100644 +--- a/util/mkimage.c ++++ b/util/mkimage.c +@@ -1488,16 +1488,13 @@ grub_install_generate_image (const char *dir, const char *prefix, + sections = o64 + 1; + } + +- PE_OHDR (o32, o64, code_size) = grub_host_to_target32 (exec_size); +- PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (reloc_addr - exec_size - header_size); ++ PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size); + PE_OHDR (o32, o64, entry_addr) = grub_host_to_target32 (start_address); +- PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (header_size); + + PE_OHDR (o32, o64, image_base) = 0; ++ PE_OHDR (o32, o64, image_size) = grub_host_to_target32 (pe_size); + PE_OHDR (o32, o64, section_alignment) = grub_host_to_target32 (image_target->section_align); + PE_OHDR (o32, o64, file_alignment) = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT); +- PE_OHDR (o32, o64, image_size) = grub_host_to_target32 (pe_size); +- PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size); + PE_OHDR (o32, o64, subsystem) = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ +@@ -1507,10 +1504,10 @@ grub_install_generate_image (const char *dir, const char *prefix, + PE_OHDR (o32, o64, heap_commit_size) = grub_host_to_target32 (0x10000); + + PE_OHDR (o32, o64, num_data_directories) = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); +- PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (reloc_addr); +- PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (reloc_size); + + /* The sections. */ ++ PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (header_size); ++ PE_OHDR (o32, o64, code_size) = grub_host_to_target32 (exec_size); + text_section = sections; + strcpy (text_section->name, ".text"); + text_section->virtual_size = grub_host_to_target32 (exec_size); +@@ -1522,6 +1519,8 @@ grub_install_generate_image (const char *dir, const char *prefix, + | GRUB_PE32_SCN_MEM_EXECUTE + | GRUB_PE32_SCN_MEM_READ); + ++ PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (reloc_addr - exec_size - header_size); ++ + data_section = text_section + 1; + strcpy (data_section->name, ".data"); + data_section->virtual_size = grub_host_to_target32 (kernel_size - exec_size); +@@ -1544,6 +1543,8 @@ grub_install_generate_image (const char *dir, const char *prefix, + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE); + ++ PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (reloc_addr); ++ PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (reloc_size); + reloc_section = mods_section + 1; + strcpy (reloc_section->name, ".reloc"); + reloc_section->virtual_size = grub_host_to_target32 (reloc_size); diff --git a/SOURCES/0433-util-mkimage-Unify-more-of-the-PE32-and-PE32-header-.patch b/SOURCES/0433-util-mkimage-Unify-more-of-the-PE32-and-PE32-header-.patch deleted file mode 100644 index 689b94e..0000000 --- a/SOURCES/0433-util-mkimage-Unify-more-of-the-PE32-and-PE32-header-.patch +++ /dev/null @@ -1,165 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 19 Feb 2021 14:22:13 +0100 -Subject: [PATCH] util/mkimage: Unify more of the PE32 and PE32+ header set-up - -There's quite a bit of code duplication in the code that sets the optional -header for PE32 and PE32+. The two are very similar with the exception of -a few fields that have type grub_uint64_t instead of grub_uint32_t. - -Factor out the common code and add a PE_OHDR() macro that simplifies the -set-up and make the code more readable. - -Signed-off-by: Peter Jones -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - util/mkimage.c | 111 ++++++++++++++++++++++++++------------------------------- - 1 file changed, 51 insertions(+), 60 deletions(-) - -diff --git a/util/mkimage.c b/util/mkimage.c -index f44675e867b..47ff76fb14b 100644 ---- a/util/mkimage.c -+++ b/util/mkimage.c -@@ -978,6 +978,21 @@ grub_install_get_image_targets_string (void) - return formats; - } - -+/* -+ * tmp_ is just here so the compiler knows we'll never derefernce a NULL. -+ * It should get fully optimized away. -+ */ -+#define PE_OHDR(o32, o64, field) (*( \ -+{ \ -+ __typeof__((o64)->field) tmp_; \ -+ __typeof__((o64)->field) *ret_ = &tmp_; \ -+ if (o32) \ -+ ret_ = (void *)(&((o32)->field)); \ -+ else if (o64) \ -+ ret_ = (void *)(&((o64)->field)); \ -+ ret_; \ -+})) -+ - void - grub_install_generate_image (const char *dir, const char *prefix, - FILE *out, const char *outname, char *mods[], -@@ -1409,6 +1424,8 @@ grub_install_generate_image (const char *dir, const char *prefix, - static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; - int header_size; - int reloc_addr; -+ struct grub_pe32_optional_header *o32 = NULL; -+ struct grub_pe64_optional_header *o64 = NULL; - - if (image_target->voidp_sizeof == 4) - header_size = EFI32_HEADER_SIZE; -@@ -1449,76 +1466,50 @@ grub_install_generate_image (const char *dir, const char *prefix, - /* The PE Optional header. */ - if (image_target->voidp_sizeof == 4) - { -- struct grub_pe32_optional_header *o; -- - c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header)); - -- o = (struct grub_pe32_optional_header *) -- (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE -- + sizeof (struct grub_pe32_coff_header)); -- o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); -- o->code_size = grub_host_to_target32 (exec_size); -- o->data_size = grub_host_to_target32 (reloc_addr - exec_size -- - header_size); -- o->entry_addr = grub_host_to_target32 (start_address); -- o->code_base = grub_host_to_target32 (header_size); -+ o32 = (struct grub_pe32_optional_header *) -+ (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + -+ sizeof (struct grub_pe32_coff_header)); -+ o32->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); -+ o32->data_base = grub_host_to_target32 (header_size + exec_size); - -- o->data_base = grub_host_to_target32 (header_size + exec_size); -- -- o->image_base = 0; -- o->section_alignment = grub_host_to_target32 (image_target->section_align); -- o->file_alignment = grub_host_to_target32 (image_target->section_align); -- o->image_size = grub_host_to_target32 (pe_size); -- o->header_size = grub_host_to_target32 (header_size); -- o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); -- -- /* Do these really matter? */ -- o->stack_reserve_size = grub_host_to_target32 (0x10000); -- o->stack_commit_size = grub_host_to_target32 (0x10000); -- o->heap_reserve_size = grub_host_to_target32 (0x10000); -- o->heap_commit_size = grub_host_to_target32 (0x10000); -- -- o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); -- -- o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); -- o->base_relocation_table.size = grub_host_to_target32 (reloc_size); -- sections = o + 1; -+ sections = o32 + 1; - } - else - { -- struct grub_pe64_optional_header *o; -- - c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe64_optional_header)); - -- o = (struct grub_pe64_optional_header *) -- (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE -- + sizeof (struct grub_pe32_coff_header)); -- o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); -- o->code_size = grub_host_to_target32 (exec_size); -- o->data_size = grub_host_to_target32 (reloc_addr - exec_size -- - header_size); -- o->entry_addr = grub_host_to_target32 (start_address); -- o->code_base = grub_host_to_target32 (header_size); -- o->image_base = 0; -- o->section_alignment = grub_host_to_target32 (image_target->section_align); -- o->file_alignment = grub_host_to_target32 (image_target->section_align); -- o->image_size = grub_host_to_target32 (pe_size); -- o->header_size = grub_host_to_target32 (header_size); -- o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); -+ o64 = (struct grub_pe64_optional_header *) -+ (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + -+ sizeof (struct grub_pe32_coff_header)); -+ o64->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); - -- /* Do these really matter? */ -- o->stack_reserve_size = grub_host_to_target32 (0x10000); -- o->stack_commit_size = grub_host_to_target32 (0x10000); -- o->heap_reserve_size = grub_host_to_target32 (0x10000); -- o->heap_commit_size = grub_host_to_target32 (0x10000); -- -- o->num_data_directories -- = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); -- -- o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); -- o->base_relocation_table.size = grub_host_to_target32 (reloc_size); -- sections = o + 1; -+ sections = o64 + 1; - } -+ -+ PE_OHDR (o32, o64, code_size) = grub_host_to_target32 (exec_size); -+ PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (reloc_addr - exec_size - header_size); -+ PE_OHDR (o32, o64, entry_addr) = grub_host_to_target32 (start_address); -+ PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (header_size); -+ -+ PE_OHDR (o32, o64, image_base) = 0; -+ PE_OHDR (o32, o64, section_alignment) = grub_host_to_target32 (image_target->section_align); -+ PE_OHDR (o32, o64, file_alignment) = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT); -+ PE_OHDR (o32, o64, image_size) = grub_host_to_target32 (pe_size); -+ PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size); -+ PE_OHDR (o32, o64, subsystem) = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); -+ -+ /* Do these really matter? */ -+ PE_OHDR (o32, o64, stack_reserve_size) = grub_host_to_target32 (0x10000); -+ PE_OHDR (o32, o64, stack_commit_size) = grub_host_to_target32 (0x10000); -+ PE_OHDR (o32, o64, heap_reserve_size) = grub_host_to_target32 (0x10000); -+ PE_OHDR (o32, o64, heap_commit_size) = grub_host_to_target32 (0x10000); -+ -+ PE_OHDR (o32, o64, num_data_directories) = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); -+ PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (reloc_addr); -+ PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (reloc_size); -+ - /* The sections. */ - text_section = sections; - strcpy (text_section->name, ".text"); diff --git a/SOURCES/0434-util-mkimage-Improve-data_size-value-calculation.patch b/SOURCES/0434-util-mkimage-Improve-data_size-value-calculation.patch new file mode 100644 index 0000000..3e8e459 --- /dev/null +++ b/SOURCES/0434-util-mkimage-Improve-data_size-value-calculation.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Fri, 26 Feb 2021 01:27:42 +0100 +Subject: [PATCH] util/mkimage: Improve data_size value calculation + +According to "Microsoft Portable Executable and Common Object File Format +Specification", the Optional Header SizeOfInitializedData field contains: + + Size of the initialized data section, or the sum of all such sections if + there are multiple data sections. + +Make this explicit by adding the GRUB kernel data size to the sum of all +the modules sizes. The ALIGN_UP() is not required by the PE spec but do +it to avoid alignment issues. + +Signed-off-by: Peter Jones +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + util/mkimage.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/util/mkimage.c b/util/mkimage.c +index ca88b0ff96a..f23fceef8f7 100644 +--- a/util/mkimage.c ++++ b/util/mkimage.c +@@ -1417,6 +1417,7 @@ grub_install_generate_image (const char *dir, const char *prefix, + void *pe_img; + grub_uint8_t *header; + void *sections; ++ size_t scn_size; + size_t pe_size; + struct grub_pe32_coff_header *c; + struct grub_pe32_section_table *text_section, *data_section; +@@ -1519,7 +1520,10 @@ grub_install_generate_image (const char *dir, const char *prefix, + | GRUB_PE32_SCN_MEM_EXECUTE + | GRUB_PE32_SCN_MEM_READ); + +- PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (reloc_addr - exec_size - header_size); ++ scn_size = ALIGN_UP (kernel_size - exec_size, GRUB_PE32_FILE_ALIGNMENT); ++ PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size + ++ ALIGN_UP (total_module_size, ++ + + data_section = text_section + 1; + strcpy (data_section->name, ".data"); diff --git a/SOURCES/0434-util-mkimage-Reorder-PE-optional-header-fields-set-u.patch b/SOURCES/0434-util-mkimage-Reorder-PE-optional-header-fields-set-u.patch deleted file mode 100644 index 318152e..0000000 --- a/SOURCES/0434-util-mkimage-Reorder-PE-optional-header-fields-set-u.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 15 Feb 2021 14:21:48 +0100 -Subject: [PATCH] util/mkimage: Reorder PE optional header fields set-up - -This makes the PE32 and PE32+ header fields set-up easier to follow by -setting them closer to the initialization of their related sections. - -Signed-off-by: Peter Jones -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - util/mkimage.c | 15 ++++++++------- - 1 file changed, 8 insertions(+), 7 deletions(-) - -diff --git a/util/mkimage.c b/util/mkimage.c -index 47ff76fb14b..ca88b0ff96a 100644 ---- a/util/mkimage.c -+++ b/util/mkimage.c -@@ -1488,16 +1488,13 @@ grub_install_generate_image (const char *dir, const char *prefix, - sections = o64 + 1; - } - -- PE_OHDR (o32, o64, code_size) = grub_host_to_target32 (exec_size); -- PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (reloc_addr - exec_size - header_size); -+ PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size); - PE_OHDR (o32, o64, entry_addr) = grub_host_to_target32 (start_address); -- PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (header_size); - - PE_OHDR (o32, o64, image_base) = 0; -+ PE_OHDR (o32, o64, image_size) = grub_host_to_target32 (pe_size); - PE_OHDR (o32, o64, section_alignment) = grub_host_to_target32 (image_target->section_align); - PE_OHDR (o32, o64, file_alignment) = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT); -- PE_OHDR (o32, o64, image_size) = grub_host_to_target32 (pe_size); -- PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size); - PE_OHDR (o32, o64, subsystem) = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); - - /* Do these really matter? */ -@@ -1507,10 +1504,10 @@ grub_install_generate_image (const char *dir, const char *prefix, - PE_OHDR (o32, o64, heap_commit_size) = grub_host_to_target32 (0x10000); - - PE_OHDR (o32, o64, num_data_directories) = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); -- PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (reloc_addr); -- PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (reloc_size); - - /* The sections. */ -+ PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (header_size); -+ PE_OHDR (o32, o64, code_size) = grub_host_to_target32 (exec_size); - text_section = sections; - strcpy (text_section->name, ".text"); - text_section->virtual_size = grub_host_to_target32 (exec_size); -@@ -1522,6 +1519,8 @@ grub_install_generate_image (const char *dir, const char *prefix, - | GRUB_PE32_SCN_MEM_EXECUTE - | GRUB_PE32_SCN_MEM_READ); - -+ PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (reloc_addr - exec_size - header_size); -+ - data_section = text_section + 1; - strcpy (data_section->name, ".data"); - data_section->virtual_size = grub_host_to_target32 (kernel_size - exec_size); -@@ -1544,6 +1543,8 @@ grub_install_generate_image (const char *dir, const char *prefix, - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE); - -+ PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (reloc_addr); -+ PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (reloc_size); - reloc_section = mods_section + 1; - strcpy (reloc_section->name, ".reloc"); - reloc_section->virtual_size = grub_host_to_target32 (reloc_size); diff --git a/SOURCES/0435-util-mkimage-Improve-data_size-value-calculation.patch b/SOURCES/0435-util-mkimage-Improve-data_size-value-calculation.patch deleted file mode 100644 index 3e8e459..0000000 --- a/SOURCES/0435-util-mkimage-Improve-data_size-value-calculation.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 26 Feb 2021 01:27:42 +0100 -Subject: [PATCH] util/mkimage: Improve data_size value calculation - -According to "Microsoft Portable Executable and Common Object File Format -Specification", the Optional Header SizeOfInitializedData field contains: - - Size of the initialized data section, or the sum of all such sections if - there are multiple data sections. - -Make this explicit by adding the GRUB kernel data size to the sum of all -the modules sizes. The ALIGN_UP() is not required by the PE spec but do -it to avoid alignment issues. - -Signed-off-by: Peter Jones -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - util/mkimage.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/util/mkimage.c b/util/mkimage.c -index ca88b0ff96a..f23fceef8f7 100644 ---- a/util/mkimage.c -+++ b/util/mkimage.c -@@ -1417,6 +1417,7 @@ grub_install_generate_image (const char *dir, const char *prefix, - void *pe_img; - grub_uint8_t *header; - void *sections; -+ size_t scn_size; - size_t pe_size; - struct grub_pe32_coff_header *c; - struct grub_pe32_section_table *text_section, *data_section; -@@ -1519,7 +1520,10 @@ grub_install_generate_image (const char *dir, const char *prefix, - | GRUB_PE32_SCN_MEM_EXECUTE - | GRUB_PE32_SCN_MEM_READ); - -- PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (reloc_addr - exec_size - header_size); -+ scn_size = ALIGN_UP (kernel_size - exec_size, GRUB_PE32_FILE_ALIGNMENT); -+ PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size + -+ ALIGN_UP (total_module_size, -+ - - data_section = text_section + 1; - strcpy (data_section->name, ".data"); diff --git a/SOURCES/0435-util-mkimage-Refactor-section-setup-to-use-a-helper.patch b/SOURCES/0435-util-mkimage-Refactor-section-setup-to-use-a-helper.patch new file mode 100644 index 0000000..b575a25 --- /dev/null +++ b/SOURCES/0435-util-mkimage-Refactor-section-setup-to-use-a-helper.patch @@ -0,0 +1,216 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Fri, 26 Feb 2021 01:30:37 +0100 +Subject: [PATCH] util/mkimage: Refactor section setup to use a helper + +Add a init_pe_section() helper function to setup PE sections. This makes +the code simpler and easier to read. + +Signed-off-by: Peter Jones +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + util/mkimage.c | 141 +++++++++++++++++++++++++++++++-------------------------- + 1 file changed, 77 insertions(+), 64 deletions(-) + +diff --git a/util/mkimage.c b/util/mkimage.c +index f23fceef8f7..938a06a2d3f 100644 +--- a/util/mkimage.c ++++ b/util/mkimage.c +@@ -978,6 +978,38 @@ grub_install_get_image_targets_string (void) + return formats; + } + ++/* ++ * The image_target parameter is used by the grub_host_to_target32() macro. ++ */ ++static struct grub_pe32_section_table * ++init_pe_section(const struct grub_install_image_target_desc *image_target, ++ struct grub_pe32_section_table *section, ++ const char * const name, ++ grub_uint32_t *vma, grub_uint32_t vsz, grub_uint32_t valign, ++ grub_uint32_t *rda, grub_uint32_t rsz, ++ grub_uint32_t characteristics) ++{ ++ size_t len = strlen (name); ++ ++ if (len > sizeof (section->name)) ++ grub_util_error (_("section name %s length is bigger than %lu"), ++ name, (unsigned long) sizeof (section->name)); ++ ++ memcpy (section->name, name, len); ++ ++ section->virtual_address = grub_host_to_target32 (*vma); ++ section->virtual_size = grub_host_to_target32 (vsz); ++ (*vma) = ALIGN_UP (*vma + vsz, valign); ++ ++ section->raw_data_offset = grub_host_to_target32 (*rda); ++ section->raw_data_size = grub_host_to_target32 (rsz); ++ (*rda) = ALIGN_UP (*rda + rsz, GRUB_PE32_FILE_ALIGNMENT); ++ ++ section->characteristics = grub_host_to_target32 (characteristics); ++ ++ return section + 1; ++} ++ + /* + * tmp_ is just here so the compiler knows we'll never derefernce a NULL. + * It should get fully optimized away. +@@ -1414,17 +1446,13 @@ grub_install_generate_image (const char *dir, const char *prefix, + break; + case IMAGE_EFI: + { +- void *pe_img; +- grub_uint8_t *header; +- void *sections; ++ char *pe_img, *header; ++ struct grub_pe32_section_table *section; + size_t scn_size; +- size_t pe_size; ++ grub_uint32_t vma, raw_data; ++ size_t pe_size, header_size; + struct grub_pe32_coff_header *c; +- struct grub_pe32_section_table *text_section, *data_section; +- struct grub_pe32_section_table *mods_section, *reloc_section; + static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; +- int header_size; +- int reloc_addr; + struct grub_pe32_optional_header *o32 = NULL; + struct grub_pe64_optional_header *o64 = NULL; + +@@ -1433,16 +1461,12 @@ grub_install_generate_image (const char *dir, const char *prefix, + else + header_size = EFI64_HEADER_SIZE; + +- reloc_addr = ALIGN_UP (header_size + core_size, +- image_target->section_align); ++ vma = raw_data = header_size; ++ pe_size = ALIGN_UP (header_size + core_size, GRUB_PE32_FILE_ALIGNMENT) + ++ ALIGN_UP (layout.reloc_size, GRUB_PE32_FILE_ALIGNMENT); ++ header = pe_img = xcalloc (1, pe_size); + +- pe_size = ALIGN_UP (reloc_addr + reloc_size, +- image_target->section_align); +- pe_img = xmalloc (reloc_addr + reloc_size); +- memset (pe_img, 0, header_size); +- memcpy ((char *) pe_img + header_size, core_img, core_size); +- memcpy ((char *) pe_img + reloc_addr, rel_section, reloc_size); +- header = pe_img; ++ memcpy (pe_img + raw_data, core_img, core_size); + + /* The magic. */ + memcpy (header, stub, GRUB_PE32_MSDOS_STUB_SIZE); +@@ -1475,18 +1499,17 @@ grub_install_generate_image (const char *dir, const char *prefix, + o32->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o32->data_base = grub_host_to_target32 (header_size + exec_size); + +- sections = o32 + 1; ++ section = (struct grub_pe32_section_table *)(o32 + 1); + } + else + { + c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe64_optional_header)); +- + o64 = (struct grub_pe64_optional_header *) + (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header)); + o64->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); + +- sections = o64 + 1; ++ section = (struct grub_pe32_section_table *)(o64 + 1); + } + + PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size); +@@ -1507,58 +1530,48 @@ grub_install_generate_image (const char *dir, const char *prefix, + PE_OHDR (o32, o64, num_data_directories) = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + + /* The sections. */ +- PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (header_size); ++ PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (vma); + PE_OHDR (o32, o64, code_size) = grub_host_to_target32 (exec_size); +- text_section = sections; +- strcpy (text_section->name, ".text"); +- text_section->virtual_size = grub_host_to_target32 (exec_size); +- text_section->virtual_address = grub_host_to_target32 (header_size); +- text_section->raw_data_size = grub_host_to_target32 (exec_size); +- text_section->raw_data_offset = grub_host_to_target32 (header_size); +- text_section->characteristics = grub_cpu_to_le32_compile_time ( +- GRUB_PE32_SCN_CNT_CODE +- | GRUB_PE32_SCN_MEM_EXECUTE +- | GRUB_PE32_SCN_MEM_READ); ++ ++ section = init_pe_section (image_target, section, ".text", ++ &vma, exec_size, ++ image_target->section_align, ++ &raw_data, exec_size, ++ GRUB_PE32_SCN_CNT_CODE | ++ GRUB_PE32_SCN_MEM_EXECUTE | ++ GRUB_PE32_SCN_MEM_READ); + + scn_size = ALIGN_UP (kernel_size - exec_size, GRUB_PE32_FILE_ALIGNMENT); + PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size + + ALIGN_UP (total_module_size, + + +- data_section = text_section + 1; +- strcpy (data_section->name, ".data"); +- data_section->virtual_size = grub_host_to_target32 (kernel_size - exec_size); +- data_section->virtual_address = grub_host_to_target32 (header_size + exec_size); +- data_section->raw_data_size = grub_host_to_target32 (kernel_size - exec_size); +- data_section->raw_data_offset = grub_host_to_target32 (header_size + exec_size); +- data_section->characteristics +- = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA +- | GRUB_PE32_SCN_MEM_READ +- | GRUB_PE32_SCN_MEM_WRITE); +- +- mods_section = data_section + 1; +- strcpy (mods_section->name, "mods"); +- mods_section->virtual_size = grub_host_to_target32 (reloc_addr - kernel_size - header_size); +- mods_section->virtual_address = grub_host_to_target32 (header_size + kernel_size + bss_size); +- mods_section->raw_data_size = grub_host_to_target32 (reloc_addr - kernel_size - header_size); +- mods_section->raw_data_offset = grub_host_to_target32 (header_size + kernel_size); +- mods_section->characteristics +- = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA +- | GRUB_PE32_SCN_MEM_READ +- | GRUB_PE32_SCN_MEM_WRITE); ++ section = init_pe_section (image_target, section, ".data", ++ &vma, scn_size, image_target->section_align, ++ &raw_data, scn_size, ++ GRUB_PE32_SCN_CNT_INITIALIZED_DATA | ++ GRUB_PE32_SCN_MEM_READ | ++ GRUB_PE32_SCN_MEM_WRITE); ++ ++ scn_size = pe_size - reloc_size - raw_data; ++ section = init_pe_section (image_target, section, "mods", ++ &vma, scn_size, image_target->section_align, ++ &raw_data, scn_size, ++ GRUB_PE32_SCN_CNT_INITIALIZED_DATA | ++ GRUB_PE32_SCN_MEM_READ | ++ GRUB_PE32_SCN_MEM_WRITE); ++ ++ scn_size = reloc_size; ++ PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (vma); ++ PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (scn_size); ++ memcpy (pe_img + raw_data, rel_section, scn_size); ++ init_pe_section (image_target, section, ".reloc", ++ &vma, scn_size, image_target->section_align, ++ &raw_data, scn_size, ++ GRUB_PE32_SCN_CNT_INITIALIZED_DATA | ++ GRUB_PE32_SCN_MEM_DISCARDABLE | ++ GRUB_PE32_SCN_MEM_READ); + +- PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (reloc_addr); +- PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (reloc_size); +- reloc_section = mods_section + 1; +- strcpy (reloc_section->name, ".reloc"); +- reloc_section->virtual_size = grub_host_to_target32 (reloc_size); +- reloc_section->virtual_address = grub_host_to_target32 (reloc_addr + bss_size); +- reloc_section->raw_data_size = grub_host_to_target32 (reloc_size); +- reloc_section->raw_data_offset = grub_host_to_target32 (reloc_addr); +- reloc_section->characteristics +- = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA +- | GRUB_PE32_SCN_MEM_DISCARDABLE +- | GRUB_PE32_SCN_MEM_READ); + free (core_img); + core_img = pe_img; + core_size = pe_size; diff --git a/SOURCES/0436-util-mkimage-Add-an-option-to-import-SBAT-metadata-i.patch b/SOURCES/0436-util-mkimage-Add-an-option-to-import-SBAT-metadata-i.patch new file mode 100644 index 0000000..b06f33b --- /dev/null +++ b/SOURCES/0436-util-mkimage-Add-an-option-to-import-SBAT-metadata-i.patch @@ -0,0 +1,252 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Fri, 26 Feb 2021 01:43:30 +0100 +Subject: [PATCH] util/mkimage: Add an option to import SBAT metadata into a + .sbat section + +Add a --sbat option to the grub-mkimage tool which allows us to import +an SBAT metadata formatted as a CSV file into a .sbat section of the +EFI binary. + +Signed-off-by: Peter Jones +Signed-off-by: Javier Martinez Canillas +Reviewed-by: Daniel Kiper +--- + util/grub-install-common.c | 2 +- + util/grub-mkimage.c | 15 ++++++++++++++- + util/mkimage.c | 44 +++++++++++++++++++++++++++++++++++++------- + include/grub/util/install.h | 3 ++- + docs/grub.texi | 21 +++++++++++++++++++++ + 5 files changed, 75 insertions(+), 10 deletions(-) + +diff --git a/util/grub-install-common.c b/util/grub-install-common.c +index d49a93d4740..b4192cf47a3 100644 +--- a/util/grub-install-common.c ++++ b/util/grub-install-common.c +@@ -498,7 +498,7 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, + grub_install_generate_image (dir, prefix, fp, outname, + modules.entries, memdisk_path, + pubkeys, npubkeys, config_path, tgt, +- note, compression); ++ note, compression, NULL); + while (dc--) + grub_install_pop_module (); + } +diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c +index 1e0bcf1bf4f..c674f76c42a 100644 +--- a/util/grub-mkimage.c ++++ b/util/grub-mkimage.c +@@ -80,6 +80,7 @@ static struct argp_option options[] = { + {"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0}, + {"format", 'O', N_("FORMAT"), 0, 0, 0}, + {"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use for core image"), 0}, ++ {"sbat", 's', N_("FILE"), 0, N_("SBAT metadata"), 0}, + {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, + { 0, 0, 0, 0, 0, 0 } + }; +@@ -121,6 +122,7 @@ struct arguments + size_t npubkeys; + char *font; + char *config; ++ char *sbat; + int note; + const struct grub_install_image_target_desc *image_target; + grub_compression_t comp; +@@ -215,6 +217,13 @@ argp_parser (int key, char *arg, struct argp_state *state) + arguments->prefix = xstrdup (arg); + break; + ++ case 's': ++ if (arguments->sbat) ++ free (arguments->sbat); ++ ++ arguments->sbat = xstrdup (arg); ++ break; ++ + case 'v': + verbosity++; + break; +@@ -299,7 +308,8 @@ main (int argc, char *argv[]) + arguments.memdisk, arguments.pubkeys, + arguments.npubkeys, arguments.config, + arguments.image_target, arguments.note, +- arguments.comp); ++ arguments.comp, ++ arguments.sbat); + + grub_util_file_sync (fp); + fclose (fp); +@@ -310,5 +320,8 @@ main (int argc, char *argv[]) + if (arguments.output) + free (arguments.output); + ++ if (arguments.sbat) ++ free (arguments.sbat); ++ + return 0; + } +diff --git a/util/mkimage.c b/util/mkimage.c +index 938a06a2d3f..44e2b8adfd8 100644 +--- a/util/mkimage.c ++++ b/util/mkimage.c +@@ -1032,12 +1032,14 @@ grub_install_generate_image (const char *dir, const char *prefix, + size_t npubkeys, char *config_path, + const struct grub_install_image_target_desc *image_target, + int note, +- grub_compression_t comp) ++ grub_compression_t comp, ++ const char *sbat_path) + { + char *kernel_img, *core_img; + size_t kernel_size, total_module_size, core_size, exec_size; + size_t memdisk_size = 0, config_size = 0, config_size_pure = 0; + size_t prefix_size = 0; ++ size_t sbat_size = 0; + char *kernel_path; + size_t offset; + struct grub_util_path_list *path_list, *p, *next; +@@ -1085,6 +1087,9 @@ grub_install_generate_image (const char *dir, const char *prefix, + total_module_size += memdisk_size + sizeof (struct grub_module_header); + } + ++ if (sbat_path != NULL && image_target->id != IMAGE_EFI) ++ grub_util_error (_(".sbat section can be embedded into EFI images only")); ++ + if (config_path) + { + config_size_pure = grub_util_get_image_size (config_path) + 1; +@@ -1446,8 +1451,9 @@ grub_install_generate_image (const char *dir, const char *prefix, + break; + case IMAGE_EFI: + { +- char *pe_img, *header; ++ char *pe_img, *pe_sbat, *header; + struct grub_pe32_section_table *section; ++ size_t n_sections = 4; + size_t scn_size; + grub_uint32_t vma, raw_data; + size_t pe_size, header_size; +@@ -1462,8 +1468,15 @@ grub_install_generate_image (const char *dir, const char *prefix, + header_size = EFI64_HEADER_SIZE; + + vma = raw_data = header_size; ++ ++ if (sbat_path != NULL) ++ { ++ sbat_size = ALIGN_ADDR (grub_util_get_image_size (sbat_path)); ++ sbat_size = ALIGN_UP (sbat_size, GRUB_PE32_FILE_ALIGNMENT); ++ } ++ + pe_size = ALIGN_UP (header_size + core_size, GRUB_PE32_FILE_ALIGNMENT) + +- ALIGN_UP (layout.reloc_size, GRUB_PE32_FILE_ALIGNMENT); ++ ALIGN_UP (reloc_size, GRUB_PE32_FILE_ALIGNMENT) + sbat_size; + header = pe_img = xcalloc (1, pe_size); + + memcpy (pe_img + raw_data, core_img, core_size); +@@ -1478,7 +1491,10 @@ grub_install_generate_image (const char *dir, const char *prefix, + + GRUB_PE32_SIGNATURE_SIZE); + c->machine = grub_host_to_target16 (image_target->pe_target); + +- c->num_sections = grub_host_to_target16 (4); ++ if (sbat_path != NULL) ++ n_sections++; ++ ++ c->num_sections = grub_host_to_target16 (n_sections); + c->time = grub_host_to_target32 (time (0)); + c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE + | GRUB_PE32_LINE_NUMS_STRIPPED +@@ -1542,9 +1558,10 @@ grub_install_generate_image (const char *dir, const char *prefix, + GRUB_PE32_SCN_MEM_READ); + + scn_size = ALIGN_UP (kernel_size - exec_size, GRUB_PE32_FILE_ALIGNMENT); +- PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size + ++ /* ALIGN_UP (sbat_size, GRUB_PE32_FILE_ALIGNMENT) is done earlier. */ ++ PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size + sbat_size + + ALIGN_UP (total_module_size, +- ++ GRUB_PE32_FILE_ALIGNMENT)); + + section = init_pe_section (image_target, section, ".data", + &vma, scn_size, image_target->section_align, +@@ -1553,7 +1570,7 @@ grub_install_generate_image (const char *dir, const char *prefix, + GRUB_PE32_SCN_MEM_READ | + GRUB_PE32_SCN_MEM_WRITE); + +- scn_size = pe_size - reloc_size - raw_data; ++ scn_size = pe_size - reloc_size - sbat_size - raw_data; + section = init_pe_section (image_target, section, "mods", + &vma, scn_size, image_target->section_align, + &raw_data, scn_size, +@@ -1561,6 +1578,19 @@ grub_install_generate_image (const char *dir, const char *prefix, + GRUB_PE32_SCN_MEM_READ | + GRUB_PE32_SCN_MEM_WRITE); + ++ if (sbat_path != NULL) ++ { ++ pe_sbat = pe_img + raw_data; ++ grub_util_load_image (sbat_path, pe_sbat); ++ ++ section = init_pe_section (image_target, section, ".sbat", ++ &vma, sbat_size, ++ image_target->section_align, ++ &raw_data, sbat_size, ++ GRUB_PE32_SCN_CNT_INITIALIZED_DATA | ++ GRUB_PE32_SCN_MEM_READ); ++ } ++ + scn_size = reloc_size; + PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (vma); + PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (scn_size); +diff --git a/include/grub/util/install.h b/include/grub/util/install.h +index aedcd29f905..02ae1c6425e 100644 +--- a/include/grub/util/install.h ++++ b/include/grub/util/install.h +@@ -176,7 +176,8 @@ grub_install_generate_image (const char *dir, const char *prefix, + char *config_path, + const struct grub_install_image_target_desc *image_target, + int note, +- grub_compression_t comp); ++ grub_compression_t comp, ++ const char *sbat_path); + + const struct grub_install_image_target_desc * + grub_install_get_image_target (const char *arg); +diff --git a/docs/grub.texi b/docs/grub.texi +index 446574f3ddb..24840d00cf7 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -5498,6 +5498,7 @@ environment variables and commands are listed in the same order. + @menu + * Authentication and authorisation:: Users and access control + * Using digital signatures:: Booting digitally signed code ++* Secure Boot Advanced Targeting:: Embedded information for generation number based revocation + * Lockdown:: Lockdown when booting on a secure setup + + @end menu +@@ -5660,6 +5661,26 @@ or BIOS) configuration to cause the machine to boot from a different + (attacker-controlled) device. GRUB is at best only one link in a + secure boot chain. + ++ ++@node Secure Boot Advanced Targeting ++@section Embedded information for generation number based revocation ++ ++The Secure Boot Advanced Targeting (SBAT) is a mechanism to allow the revocation ++of components in the boot path by using generation numbers embedded into the EFI ++binaries. The SBAT metadata is located in an .sbat data section that has set of ++UTF-8 strings as comma-separated values (CSV). See ++@uref{https://github.com/rhboot/shim/blob/main/SBAT.md} for more details. ++ ++To add a data section containing the SBAT information into the binary, the ++@option{--sbat} option of @command{grub-mkimage} command should be used. The content ++of a CSV file, encoded with UTF-8, is copied as is to the .sbat data section into ++the generated EFI binary. The CSV file can be stored anywhere on the file system. ++ ++@example ++grub-mkimage -O x86_64-efi -o grubx64.efi -p '(tftp)/grub' --sbat sbat.csv efinet tftp ++@end example ++ ++ + @node Lockdown + @section Lockdown when booting on a secure setup + diff --git a/SOURCES/0436-util-mkimage-Refactor-section-setup-to-use-a-helper.patch b/SOURCES/0436-util-mkimage-Refactor-section-setup-to-use-a-helper.patch deleted file mode 100644 index b575a25..0000000 --- a/SOURCES/0436-util-mkimage-Refactor-section-setup-to-use-a-helper.patch +++ /dev/null @@ -1,216 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 26 Feb 2021 01:30:37 +0100 -Subject: [PATCH] util/mkimage: Refactor section setup to use a helper - -Add a init_pe_section() helper function to setup PE sections. This makes -the code simpler and easier to read. - -Signed-off-by: Peter Jones -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - util/mkimage.c | 141 +++++++++++++++++++++++++++++++-------------------------- - 1 file changed, 77 insertions(+), 64 deletions(-) - -diff --git a/util/mkimage.c b/util/mkimage.c -index f23fceef8f7..938a06a2d3f 100644 ---- a/util/mkimage.c -+++ b/util/mkimage.c -@@ -978,6 +978,38 @@ grub_install_get_image_targets_string (void) - return formats; - } - -+/* -+ * The image_target parameter is used by the grub_host_to_target32() macro. -+ */ -+static struct grub_pe32_section_table * -+init_pe_section(const struct grub_install_image_target_desc *image_target, -+ struct grub_pe32_section_table *section, -+ const char * const name, -+ grub_uint32_t *vma, grub_uint32_t vsz, grub_uint32_t valign, -+ grub_uint32_t *rda, grub_uint32_t rsz, -+ grub_uint32_t characteristics) -+{ -+ size_t len = strlen (name); -+ -+ if (len > sizeof (section->name)) -+ grub_util_error (_("section name %s length is bigger than %lu"), -+ name, (unsigned long) sizeof (section->name)); -+ -+ memcpy (section->name, name, len); -+ -+ section->virtual_address = grub_host_to_target32 (*vma); -+ section->virtual_size = grub_host_to_target32 (vsz); -+ (*vma) = ALIGN_UP (*vma + vsz, valign); -+ -+ section->raw_data_offset = grub_host_to_target32 (*rda); -+ section->raw_data_size = grub_host_to_target32 (rsz); -+ (*rda) = ALIGN_UP (*rda + rsz, GRUB_PE32_FILE_ALIGNMENT); -+ -+ section->characteristics = grub_host_to_target32 (characteristics); -+ -+ return section + 1; -+} -+ - /* - * tmp_ is just here so the compiler knows we'll never derefernce a NULL. - * It should get fully optimized away. -@@ -1414,17 +1446,13 @@ grub_install_generate_image (const char *dir, const char *prefix, - break; - case IMAGE_EFI: - { -- void *pe_img; -- grub_uint8_t *header; -- void *sections; -+ char *pe_img, *header; -+ struct grub_pe32_section_table *section; - size_t scn_size; -- size_t pe_size; -+ grub_uint32_t vma, raw_data; -+ size_t pe_size, header_size; - struct grub_pe32_coff_header *c; -- struct grub_pe32_section_table *text_section, *data_section; -- struct grub_pe32_section_table *mods_section, *reloc_section; - static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; -- int header_size; -- int reloc_addr; - struct grub_pe32_optional_header *o32 = NULL; - struct grub_pe64_optional_header *o64 = NULL; - -@@ -1433,16 +1461,12 @@ grub_install_generate_image (const char *dir, const char *prefix, - else - header_size = EFI64_HEADER_SIZE; - -- reloc_addr = ALIGN_UP (header_size + core_size, -- image_target->section_align); -+ vma = raw_data = header_size; -+ pe_size = ALIGN_UP (header_size + core_size, GRUB_PE32_FILE_ALIGNMENT) + -+ ALIGN_UP (layout.reloc_size, GRUB_PE32_FILE_ALIGNMENT); -+ header = pe_img = xcalloc (1, pe_size); - -- pe_size = ALIGN_UP (reloc_addr + reloc_size, -- image_target->section_align); -- pe_img = xmalloc (reloc_addr + reloc_size); -- memset (pe_img, 0, header_size); -- memcpy ((char *) pe_img + header_size, core_img, core_size); -- memcpy ((char *) pe_img + reloc_addr, rel_section, reloc_size); -- header = pe_img; -+ memcpy (pe_img + raw_data, core_img, core_size); - - /* The magic. */ - memcpy (header, stub, GRUB_PE32_MSDOS_STUB_SIZE); -@@ -1475,18 +1499,17 @@ grub_install_generate_image (const char *dir, const char *prefix, - o32->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); - o32->data_base = grub_host_to_target32 (header_size + exec_size); - -- sections = o32 + 1; -+ section = (struct grub_pe32_section_table *)(o32 + 1); - } - else - { - c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe64_optional_header)); -- - o64 = (struct grub_pe64_optional_header *) - (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + - sizeof (struct grub_pe32_coff_header)); - o64->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); - -- sections = o64 + 1; -+ section = (struct grub_pe32_section_table *)(o64 + 1); - } - - PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size); -@@ -1507,58 +1530,48 @@ grub_install_generate_image (const char *dir, const char *prefix, - PE_OHDR (o32, o64, num_data_directories) = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); - - /* The sections. */ -- PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (header_size); -+ PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (vma); - PE_OHDR (o32, o64, code_size) = grub_host_to_target32 (exec_size); -- text_section = sections; -- strcpy (text_section->name, ".text"); -- text_section->virtual_size = grub_host_to_target32 (exec_size); -- text_section->virtual_address = grub_host_to_target32 (header_size); -- text_section->raw_data_size = grub_host_to_target32 (exec_size); -- text_section->raw_data_offset = grub_host_to_target32 (header_size); -- text_section->characteristics = grub_cpu_to_le32_compile_time ( -- GRUB_PE32_SCN_CNT_CODE -- | GRUB_PE32_SCN_MEM_EXECUTE -- | GRUB_PE32_SCN_MEM_READ); -+ -+ section = init_pe_section (image_target, section, ".text", -+ &vma, exec_size, -+ image_target->section_align, -+ &raw_data, exec_size, -+ GRUB_PE32_SCN_CNT_CODE | -+ GRUB_PE32_SCN_MEM_EXECUTE | -+ GRUB_PE32_SCN_MEM_READ); - - scn_size = ALIGN_UP (kernel_size - exec_size, GRUB_PE32_FILE_ALIGNMENT); - PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size + - ALIGN_UP (total_module_size, - - -- data_section = text_section + 1; -- strcpy (data_section->name, ".data"); -- data_section->virtual_size = grub_host_to_target32 (kernel_size - exec_size); -- data_section->virtual_address = grub_host_to_target32 (header_size + exec_size); -- data_section->raw_data_size = grub_host_to_target32 (kernel_size - exec_size); -- data_section->raw_data_offset = grub_host_to_target32 (header_size + exec_size); -- data_section->characteristics -- = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA -- | GRUB_PE32_SCN_MEM_READ -- | GRUB_PE32_SCN_MEM_WRITE); -- -- mods_section = data_section + 1; -- strcpy (mods_section->name, "mods"); -- mods_section->virtual_size = grub_host_to_target32 (reloc_addr - kernel_size - header_size); -- mods_section->virtual_address = grub_host_to_target32 (header_size + kernel_size + bss_size); -- mods_section->raw_data_size = grub_host_to_target32 (reloc_addr - kernel_size - header_size); -- mods_section->raw_data_offset = grub_host_to_target32 (header_size + kernel_size); -- mods_section->characteristics -- = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA -- | GRUB_PE32_SCN_MEM_READ -- | GRUB_PE32_SCN_MEM_WRITE); -+ section = init_pe_section (image_target, section, ".data", -+ &vma, scn_size, image_target->section_align, -+ &raw_data, scn_size, -+ GRUB_PE32_SCN_CNT_INITIALIZED_DATA | -+ GRUB_PE32_SCN_MEM_READ | -+ GRUB_PE32_SCN_MEM_WRITE); -+ -+ scn_size = pe_size - reloc_size - raw_data; -+ section = init_pe_section (image_target, section, "mods", -+ &vma, scn_size, image_target->section_align, -+ &raw_data, scn_size, -+ GRUB_PE32_SCN_CNT_INITIALIZED_DATA | -+ GRUB_PE32_SCN_MEM_READ | -+ GRUB_PE32_SCN_MEM_WRITE); -+ -+ scn_size = reloc_size; -+ PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (vma); -+ PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (scn_size); -+ memcpy (pe_img + raw_data, rel_section, scn_size); -+ init_pe_section (image_target, section, ".reloc", -+ &vma, scn_size, image_target->section_align, -+ &raw_data, scn_size, -+ GRUB_PE32_SCN_CNT_INITIALIZED_DATA | -+ GRUB_PE32_SCN_MEM_DISCARDABLE | -+ GRUB_PE32_SCN_MEM_READ); - -- PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (reloc_addr); -- PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (reloc_size); -- reloc_section = mods_section + 1; -- strcpy (reloc_section->name, ".reloc"); -- reloc_section->virtual_size = grub_host_to_target32 (reloc_size); -- reloc_section->virtual_address = grub_host_to_target32 (reloc_addr + bss_size); -- reloc_section->raw_data_size = grub_host_to_target32 (reloc_size); -- reloc_section->raw_data_offset = grub_host_to_target32 (reloc_addr); -- reloc_section->characteristics -- = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA -- | GRUB_PE32_SCN_MEM_DISCARDABLE -- | GRUB_PE32_SCN_MEM_READ); - free (core_img); - core_img = pe_img; - core_size = pe_size; diff --git a/SOURCES/0437-kern-misc-Split-parse_printf_args-into-format-parsin.patch b/SOURCES/0437-kern-misc-Split-parse_printf_args-into-format-parsin.patch new file mode 100644 index 0000000..2fc2944 --- /dev/null +++ b/SOURCES/0437-kern-misc-Split-parse_printf_args-into-format-parsin.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Thomas Frauendorfer | Miray Software +Date: Mon, 15 Feb 2021 13:40:16 +0100 +Subject: [PATCH] kern/misc: Split parse_printf_args() into format parsing and + va_list handling + +This patch is preparing for a follow up patch which will use +the format parsing part to compare the arguments in a printf() +format from an external source against a printf() format with +expected arguments. + +Signed-off-by: Thomas Frauendorfer | Miray Software +Reviewed-by: Daniel Kiper +--- + grub-core/kern/misc.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c +index bd43b0f5f61..28bbcd6d2b8 100644 +--- a/grub-core/kern/misc.c ++++ b/grub-core/kern/misc.c +@@ -823,8 +823,7 @@ grub_lltoa (char *str, int c, unsigned long long n) + } + + static void +-parse_printf_args (const char *fmt0, struct printf_args *args, +- va_list args_in) ++parse_printf_arg_fmt (const char *fmt0, struct printf_args *args) + { + const char *fmt; + char c; +@@ -976,6 +975,14 @@ parse_printf_args (const char *fmt0, struct printf_args *args, + break; + } + } ++} ++ ++static void ++parse_printf_args (const char *fmt0, struct printf_args *args, va_list args_in) ++{ ++ grub_size_t n; ++ ++ parse_printf_arg_fmt (fmt0, args); + + for (n = 0; n < args->count; n++) + switch (args->ptr[n].type) diff --git a/SOURCES/0437-util-mkimage-Add-an-option-to-import-SBAT-metadata-i.patch b/SOURCES/0437-util-mkimage-Add-an-option-to-import-SBAT-metadata-i.patch deleted file mode 100644 index b06f33b..0000000 --- a/SOURCES/0437-util-mkimage-Add-an-option-to-import-SBAT-metadata-i.patch +++ /dev/null @@ -1,252 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 26 Feb 2021 01:43:30 +0100 -Subject: [PATCH] util/mkimage: Add an option to import SBAT metadata into a - .sbat section - -Add a --sbat option to the grub-mkimage tool which allows us to import -an SBAT metadata formatted as a CSV file into a .sbat section of the -EFI binary. - -Signed-off-by: Peter Jones -Signed-off-by: Javier Martinez Canillas -Reviewed-by: Daniel Kiper ---- - util/grub-install-common.c | 2 +- - util/grub-mkimage.c | 15 ++++++++++++++- - util/mkimage.c | 44 +++++++++++++++++++++++++++++++++++++------- - include/grub/util/install.h | 3 ++- - docs/grub.texi | 21 +++++++++++++++++++++ - 5 files changed, 75 insertions(+), 10 deletions(-) - -diff --git a/util/grub-install-common.c b/util/grub-install-common.c -index d49a93d4740..b4192cf47a3 100644 ---- a/util/grub-install-common.c -+++ b/util/grub-install-common.c -@@ -498,7 +498,7 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, - grub_install_generate_image (dir, prefix, fp, outname, - modules.entries, memdisk_path, - pubkeys, npubkeys, config_path, tgt, -- note, compression); -+ note, compression, NULL); - while (dc--) - grub_install_pop_module (); - } -diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c -index 1e0bcf1bf4f..c674f76c42a 100644 ---- a/util/grub-mkimage.c -+++ b/util/grub-mkimage.c -@@ -80,6 +80,7 @@ static struct argp_option options[] = { - {"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0}, - {"format", 'O', N_("FORMAT"), 0, 0, 0}, - {"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use for core image"), 0}, -+ {"sbat", 's', N_("FILE"), 0, N_("SBAT metadata"), 0}, - {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, - { 0, 0, 0, 0, 0, 0 } - }; -@@ -121,6 +122,7 @@ struct arguments - size_t npubkeys; - char *font; - char *config; -+ char *sbat; - int note; - const struct grub_install_image_target_desc *image_target; - grub_compression_t comp; -@@ -215,6 +217,13 @@ argp_parser (int key, char *arg, struct argp_state *state) - arguments->prefix = xstrdup (arg); - break; - -+ case 's': -+ if (arguments->sbat) -+ free (arguments->sbat); -+ -+ arguments->sbat = xstrdup (arg); -+ break; -+ - case 'v': - verbosity++; - break; -@@ -299,7 +308,8 @@ main (int argc, char *argv[]) - arguments.memdisk, arguments.pubkeys, - arguments.npubkeys, arguments.config, - arguments.image_target, arguments.note, -- arguments.comp); -+ arguments.comp, -+ arguments.sbat); - - grub_util_file_sync (fp); - fclose (fp); -@@ -310,5 +320,8 @@ main (int argc, char *argv[]) - if (arguments.output) - free (arguments.output); - -+ if (arguments.sbat) -+ free (arguments.sbat); -+ - return 0; - } -diff --git a/util/mkimage.c b/util/mkimage.c -index 938a06a2d3f..44e2b8adfd8 100644 ---- a/util/mkimage.c -+++ b/util/mkimage.c -@@ -1032,12 +1032,14 @@ grub_install_generate_image (const char *dir, const char *prefix, - size_t npubkeys, char *config_path, - const struct grub_install_image_target_desc *image_target, - int note, -- grub_compression_t comp) -+ grub_compression_t comp, -+ const char *sbat_path) - { - char *kernel_img, *core_img; - size_t kernel_size, total_module_size, core_size, exec_size; - size_t memdisk_size = 0, config_size = 0, config_size_pure = 0; - size_t prefix_size = 0; -+ size_t sbat_size = 0; - char *kernel_path; - size_t offset; - struct grub_util_path_list *path_list, *p, *next; -@@ -1085,6 +1087,9 @@ grub_install_generate_image (const char *dir, const char *prefix, - total_module_size += memdisk_size + sizeof (struct grub_module_header); - } - -+ if (sbat_path != NULL && image_target->id != IMAGE_EFI) -+ grub_util_error (_(".sbat section can be embedded into EFI images only")); -+ - if (config_path) - { - config_size_pure = grub_util_get_image_size (config_path) + 1; -@@ -1446,8 +1451,9 @@ grub_install_generate_image (const char *dir, const char *prefix, - break; - case IMAGE_EFI: - { -- char *pe_img, *header; -+ char *pe_img, *pe_sbat, *header; - struct grub_pe32_section_table *section; -+ size_t n_sections = 4; - size_t scn_size; - grub_uint32_t vma, raw_data; - size_t pe_size, header_size; -@@ -1462,8 +1468,15 @@ grub_install_generate_image (const char *dir, const char *prefix, - header_size = EFI64_HEADER_SIZE; - - vma = raw_data = header_size; -+ -+ if (sbat_path != NULL) -+ { -+ sbat_size = ALIGN_ADDR (grub_util_get_image_size (sbat_path)); -+ sbat_size = ALIGN_UP (sbat_size, GRUB_PE32_FILE_ALIGNMENT); -+ } -+ - pe_size = ALIGN_UP (header_size + core_size, GRUB_PE32_FILE_ALIGNMENT) + -- ALIGN_UP (layout.reloc_size, GRUB_PE32_FILE_ALIGNMENT); -+ ALIGN_UP (reloc_size, GRUB_PE32_FILE_ALIGNMENT) + sbat_size; - header = pe_img = xcalloc (1, pe_size); - - memcpy (pe_img + raw_data, core_img, core_size); -@@ -1478,7 +1491,10 @@ grub_install_generate_image (const char *dir, const char *prefix, - + GRUB_PE32_SIGNATURE_SIZE); - c->machine = grub_host_to_target16 (image_target->pe_target); - -- c->num_sections = grub_host_to_target16 (4); -+ if (sbat_path != NULL) -+ n_sections++; -+ -+ c->num_sections = grub_host_to_target16 (n_sections); - c->time = grub_host_to_target32 (time (0)); - c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE - | GRUB_PE32_LINE_NUMS_STRIPPED -@@ -1542,9 +1558,10 @@ grub_install_generate_image (const char *dir, const char *prefix, - GRUB_PE32_SCN_MEM_READ); - - scn_size = ALIGN_UP (kernel_size - exec_size, GRUB_PE32_FILE_ALIGNMENT); -- PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size + -+ /* ALIGN_UP (sbat_size, GRUB_PE32_FILE_ALIGNMENT) is done earlier. */ -+ PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size + sbat_size + - ALIGN_UP (total_module_size, -- -+ GRUB_PE32_FILE_ALIGNMENT)); - - section = init_pe_section (image_target, section, ".data", - &vma, scn_size, image_target->section_align, -@@ -1553,7 +1570,7 @@ grub_install_generate_image (const char *dir, const char *prefix, - GRUB_PE32_SCN_MEM_READ | - GRUB_PE32_SCN_MEM_WRITE); - -- scn_size = pe_size - reloc_size - raw_data; -+ scn_size = pe_size - reloc_size - sbat_size - raw_data; - section = init_pe_section (image_target, section, "mods", - &vma, scn_size, image_target->section_align, - &raw_data, scn_size, -@@ -1561,6 +1578,19 @@ grub_install_generate_image (const char *dir, const char *prefix, - GRUB_PE32_SCN_MEM_READ | - GRUB_PE32_SCN_MEM_WRITE); - -+ if (sbat_path != NULL) -+ { -+ pe_sbat = pe_img + raw_data; -+ grub_util_load_image (sbat_path, pe_sbat); -+ -+ section = init_pe_section (image_target, section, ".sbat", -+ &vma, sbat_size, -+ image_target->section_align, -+ &raw_data, sbat_size, -+ GRUB_PE32_SCN_CNT_INITIALIZED_DATA | -+ GRUB_PE32_SCN_MEM_READ); -+ } -+ - scn_size = reloc_size; - PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (vma); - PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (scn_size); -diff --git a/include/grub/util/install.h b/include/grub/util/install.h -index aedcd29f905..02ae1c6425e 100644 ---- a/include/grub/util/install.h -+++ b/include/grub/util/install.h -@@ -176,7 +176,8 @@ grub_install_generate_image (const char *dir, const char *prefix, - char *config_path, - const struct grub_install_image_target_desc *image_target, - int note, -- grub_compression_t comp); -+ grub_compression_t comp, -+ const char *sbat_path); - - const struct grub_install_image_target_desc * - grub_install_get_image_target (const char *arg); -diff --git a/docs/grub.texi b/docs/grub.texi -index 446574f3ddb..24840d00cf7 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -5498,6 +5498,7 @@ environment variables and commands are listed in the same order. - @menu - * Authentication and authorisation:: Users and access control - * Using digital signatures:: Booting digitally signed code -+* Secure Boot Advanced Targeting:: Embedded information for generation number based revocation - * Lockdown:: Lockdown when booting on a secure setup - - @end menu -@@ -5660,6 +5661,26 @@ or BIOS) configuration to cause the machine to boot from a different - (attacker-controlled) device. GRUB is at best only one link in a - secure boot chain. - -+ -+@node Secure Boot Advanced Targeting -+@section Embedded information for generation number based revocation -+ -+The Secure Boot Advanced Targeting (SBAT) is a mechanism to allow the revocation -+of components in the boot path by using generation numbers embedded into the EFI -+binaries. The SBAT metadata is located in an .sbat data section that has set of -+UTF-8 strings as comma-separated values (CSV). See -+@uref{https://github.com/rhboot/shim/blob/main/SBAT.md} for more details. -+ -+To add a data section containing the SBAT information into the binary, the -+@option{--sbat} option of @command{grub-mkimage} command should be used. The content -+of a CSV file, encoded with UTF-8, is copied as is to the .sbat data section into -+the generated EFI binary. The CSV file can be stored anywhere on the file system. -+ -+@example -+grub-mkimage -O x86_64-efi -o grubx64.efi -p '(tftp)/grub' --sbat sbat.csv efinet tftp -+@end example -+ -+ - @node Lockdown - @section Lockdown when booting on a secure setup - diff --git a/SOURCES/0438-kern-misc-Add-STRING-type-for-internal-printf-format.patch b/SOURCES/0438-kern-misc-Add-STRING-type-for-internal-printf-format.patch new file mode 100644 index 0000000..259edbe --- /dev/null +++ b/SOURCES/0438-kern-misc-Add-STRING-type-for-internal-printf-format.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Thomas Frauendorfer | Miray Software +Date: Mon, 15 Feb 2021 14:04:26 +0100 +Subject: [PATCH] kern/misc: Add STRING type for internal printf() format + handling + +Set printf() argument type for "%s" to new type STRING. This is in +preparation for a follow up patch to compare a printf() format string +against an expected printf() format string. + +For "%s" the corresponding printf() argument is dereferenced as pointer +while all other argument types are defined as integer value. However, +when validating a printf() format it is necessary to differentiate "%s" +from "%p" and other integers. So, let's do that. + +Signed-off-by: Thomas Frauendorfer | Miray Software +Reviewed-by: Daniel Kiper +--- + grub-core/kern/misc.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c +index 28bbcd6d2b8..eddde0c65d3 100644 +--- a/grub-core/kern/misc.c ++++ b/grub-core/kern/misc.c +@@ -33,7 +33,8 @@ union printf_arg + enum + { + INT, LONG, LONGLONG, +- UNSIGNED_INT = 3, UNSIGNED_LONG, UNSIGNED_LONGLONG ++ UNSIGNED_INT = 3, UNSIGNED_LONG, UNSIGNED_LONGLONG, ++ STRING + } type; + long long ll; + }; +@@ -963,12 +964,14 @@ parse_printf_arg_fmt (const char *fmt0, struct printf_args *args) + args->ptr[curn].type = INT + longfmt; + break; + case 'p': +- case 's': + if (sizeof (void *) == sizeof (long long)) + args->ptr[curn].type = UNSIGNED_LONGLONG; + else + args->ptr[curn].type = UNSIGNED_INT; + break; ++ case 's': ++ args->ptr[curn].type = STRING; ++ break; + case 'C': + case 'c': + args->ptr[curn].type = INT; +@@ -1003,6 +1006,12 @@ parse_printf_args (const char *fmt0, struct printf_args *args, va_list args_in) + case UNSIGNED_LONGLONG: + args->ptr[n].ll = va_arg (args_in, long long); + break; ++ case STRING: ++ if (sizeof (void *) == sizeof (long long)) ++ args->ptr[n].ll = va_arg (args_in, long long); ++ else ++ args->ptr[n].ll = va_arg (args_in, unsigned int); ++ break; + } + } + diff --git a/SOURCES/0438-kern-misc-Split-parse_printf_args-into-format-parsin.patch b/SOURCES/0438-kern-misc-Split-parse_printf_args-into-format-parsin.patch deleted file mode 100644 index 2fc2944..0000000 --- a/SOURCES/0438-kern-misc-Split-parse_printf_args-into-format-parsin.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Thomas Frauendorfer | Miray Software -Date: Mon, 15 Feb 2021 13:40:16 +0100 -Subject: [PATCH] kern/misc: Split parse_printf_args() into format parsing and - va_list handling - -This patch is preparing for a follow up patch which will use -the format parsing part to compare the arguments in a printf() -format from an external source against a printf() format with -expected arguments. - -Signed-off-by: Thomas Frauendorfer | Miray Software -Reviewed-by: Daniel Kiper ---- - grub-core/kern/misc.c | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index bd43b0f5f61..28bbcd6d2b8 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -823,8 +823,7 @@ grub_lltoa (char *str, int c, unsigned long long n) - } - - static void --parse_printf_args (const char *fmt0, struct printf_args *args, -- va_list args_in) -+parse_printf_arg_fmt (const char *fmt0, struct printf_args *args) - { - const char *fmt; - char c; -@@ -976,6 +975,14 @@ parse_printf_args (const char *fmt0, struct printf_args *args, - break; - } - } -+} -+ -+static void -+parse_printf_args (const char *fmt0, struct printf_args *args, va_list args_in) -+{ -+ grub_size_t n; -+ -+ parse_printf_arg_fmt (fmt0, args); - - for (n = 0; n < args->count; n++) - switch (args->ptr[n].type) diff --git a/SOURCES/0439-kern-misc-Add-STRING-type-for-internal-printf-format.patch b/SOURCES/0439-kern-misc-Add-STRING-type-for-internal-printf-format.patch deleted file mode 100644 index 259edbe..0000000 --- a/SOURCES/0439-kern-misc-Add-STRING-type-for-internal-printf-format.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Thomas Frauendorfer | Miray Software -Date: Mon, 15 Feb 2021 14:04:26 +0100 -Subject: [PATCH] kern/misc: Add STRING type for internal printf() format - handling - -Set printf() argument type for "%s" to new type STRING. This is in -preparation for a follow up patch to compare a printf() format string -against an expected printf() format string. - -For "%s" the corresponding printf() argument is dereferenced as pointer -while all other argument types are defined as integer value. However, -when validating a printf() format it is necessary to differentiate "%s" -from "%p" and other integers. So, let's do that. - -Signed-off-by: Thomas Frauendorfer | Miray Software -Reviewed-by: Daniel Kiper ---- - grub-core/kern/misc.c | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index 28bbcd6d2b8..eddde0c65d3 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -33,7 +33,8 @@ union printf_arg - enum - { - INT, LONG, LONGLONG, -- UNSIGNED_INT = 3, UNSIGNED_LONG, UNSIGNED_LONGLONG -+ UNSIGNED_INT = 3, UNSIGNED_LONG, UNSIGNED_LONGLONG, -+ STRING - } type; - long long ll; - }; -@@ -963,12 +964,14 @@ parse_printf_arg_fmt (const char *fmt0, struct printf_args *args) - args->ptr[curn].type = INT + longfmt; - break; - case 'p': -- case 's': - if (sizeof (void *) == sizeof (long long)) - args->ptr[curn].type = UNSIGNED_LONGLONG; - else - args->ptr[curn].type = UNSIGNED_INT; - break; -+ case 's': -+ args->ptr[curn].type = STRING; -+ break; - case 'C': - case 'c': - args->ptr[curn].type = INT; -@@ -1003,6 +1006,12 @@ parse_printf_args (const char *fmt0, struct printf_args *args, va_list args_in) - case UNSIGNED_LONGLONG: - args->ptr[n].ll = va_arg (args_in, long long); - break; -+ case STRING: -+ if (sizeof (void *) == sizeof (long long)) -+ args->ptr[n].ll = va_arg (args_in, long long); -+ else -+ args->ptr[n].ll = va_arg (args_in, unsigned int); -+ break; - } - } - diff --git a/SOURCES/0439-kern-misc-Add-function-to-check-printf-format-agains.patch b/SOURCES/0439-kern-misc-Add-function-to-check-printf-format-agains.patch new file mode 100644 index 0000000..902b8e2 --- /dev/null +++ b/SOURCES/0439-kern-misc-Add-function-to-check-printf-format-agains.patch @@ -0,0 +1,214 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Thomas Frauendorfer | Miray Software +Date: Thu, 4 Feb 2021 19:02:33 +0100 +Subject: [PATCH] kern/misc: Add function to check printf() format against + expected format + +The grub_printf_fmt_check() function parses the arguments of an untrusted +printf() format and an expected printf() format and then compares the +arguments counts and arguments types. The arguments count in the untrusted +format string must be less or equal to the arguments count in the expected +format string and both arguments types must match. + +To do this the parse_printf_arg_fmt() helper function is extended in the +following way: + + 1. Add a return value to report errors to the grub_printf_fmt_check(). + + 2. Add the fmt_check argument to enable stricter format verification: + - the function expects that arguments definitions are always + terminated by a supported conversion specifier. + - positional parameters, "$", are not allowed, as they cannot be + validated correctly with the current implementation. For example + "%s%1$d" would assign the first args entry twice while leaving the + second one unchanged. + - Return an error if preallocated space in args is too small and + allocation fails for the needed size. The grub_printf_fmt_check() + should verify all arguments. So, if validation is not possible for + any reason it should return an error. + This also adds a case entry to handle "%%", which is the escape + sequence to print "%" character. + + 3. Add the max_args argument to check for the maximum allowed arguments + count in a printf() string. This should be set to the arguments count + of the expected format. Then the parse_printf_arg_fmt() function will + return an error if the arguments count is exceeded. + +The two additional arguments allow us to use parse_printf_arg_fmt() in +printf() and grub_printf_fmt_check() calls. + +When parse_printf_arg_fmt() is used by grub_printf_fmt_check() the +function parse user provided untrusted format string too. So, in +that case it is better to be too strict than too lenient. + +Signed-off-by: Thomas Frauendorfer | Miray Software +Reviewed-by: Daniel Kiper +--- + grub-core/kern/misc.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++--- + include/grub/misc.h | 15 ++++++++++ + 2 files changed, 93 insertions(+), 4 deletions(-) + +diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c +index eddde0c65d3..0dc9f8b9465 100644 +--- a/grub-core/kern/misc.c ++++ b/grub-core/kern/misc.c +@@ -823,8 +823,26 @@ grub_lltoa (char *str, int c, unsigned long long n) + return p; + } + +-static void +-parse_printf_arg_fmt (const char *fmt0, struct printf_args *args) ++/* ++ * Parse printf() fmt0 string into args arguments. ++ * ++ * The parsed arguments are either used by a printf() function to format the fmt0 ++ * string or they are used to compare a format string from an untrusted source ++ * against a format string with expected arguments. ++ * ++ * When the fmt_check is set to !0, e.g. 1, then this function is executed in ++ * printf() format check mode. This enforces stricter rules for parsing the ++ * fmt0 to limit exposure to possible errors in printf() handling. It also ++ * disables positional parameters, "$", because some formats, e.g "%s%1$d", ++ * cannot be validated with the current implementation. ++ * ++ * The max_args allows to set a maximum number of accepted arguments. If the fmt0 ++ * string defines more arguments than the max_args then the parse_printf_arg_fmt() ++ * function returns an error. This is currently used for format check only. ++ */ ++static grub_err_t ++parse_printf_arg_fmt (const char *fmt0, struct printf_args *args, ++ int fmt_check, grub_size_t max_args) + { + const char *fmt; + char c; +@@ -851,7 +869,12 @@ parse_printf_arg_fmt (const char *fmt0, struct printf_args *args) + fmt++; + + if (*fmt == '$') +- fmt++; ++ { ++ if (fmt_check) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ "positional arguments are not supported"); ++ fmt++; ++ } + + if (*fmt =='-') + fmt++; +@@ -883,9 +906,19 @@ parse_printf_arg_fmt (const char *fmt0, struct printf_args *args) + case 's': + args->count++; + break; ++ case '%': ++ /* "%%" is the escape sequence to output "%". */ ++ break; ++ default: ++ if (fmt_check) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "unexpected format"); ++ break; + } + } + ++ if (fmt_check && args->count > max_args) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many arguments"); ++ + if (args->count <= ARRAY_SIZE (args->prealloc)) + args->ptr = args->prealloc; + else +@@ -893,6 +926,9 @@ parse_printf_arg_fmt (const char *fmt0, struct printf_args *args) + args->ptr = grub_calloc (args->count, sizeof (args->ptr[0])); + if (!args->ptr) + { ++ if (fmt_check) ++ return grub_errno; ++ + grub_errno = GRUB_ERR_NONE; + args->ptr = args->prealloc; + args->count = ARRAY_SIZE (args->prealloc); +@@ -978,6 +1014,8 @@ parse_printf_arg_fmt (const char *fmt0, struct printf_args *args) + break; + } + } ++ ++ return GRUB_ERR_NONE; + } + + static void +@@ -985,7 +1023,7 @@ parse_printf_args (const char *fmt0, struct printf_args *args, va_list args_in) + { + grub_size_t n; + +- parse_printf_arg_fmt (fmt0, args); ++ parse_printf_arg_fmt (fmt0, args, 0, 0); + + for (n = 0; n < args->count; n++) + switch (args->ptr[n].type) +@@ -1292,6 +1330,42 @@ grub_xasprintf (const char *fmt, ...) + return ret; + } + ++grub_err_t ++grub_printf_fmt_check (const char *fmt, const char *fmt_expected) ++{ ++ struct printf_args args_expected, args_fmt; ++ grub_err_t ret; ++ grub_size_t n; ++ ++ if (fmt == NULL || fmt_expected == NULL) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid format"); ++ ++ ret = parse_printf_arg_fmt (fmt_expected, &args_expected, 1, GRUB_SIZE_MAX); ++ if (ret != GRUB_ERR_NONE) ++ return ret; ++ ++ /* Limit parsing to the number of expected arguments. */ ++ ret = parse_printf_arg_fmt (fmt, &args_fmt, 1, args_expected.count); ++ if (ret != GRUB_ERR_NONE) ++ { ++ free_printf_args (&args_expected); ++ return ret; ++ } ++ ++ for (n = 0; n < args_fmt.count; n++) ++ if (args_fmt.ptr[n].type != args_expected.ptr[n].type) ++ { ++ ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments types do not match"); ++ break; ++ } ++ ++ free_printf_args (&args_expected); ++ free_printf_args (&args_fmt); ++ ++ return ret; ++} ++ ++ + /* Abort GRUB. This function does not return. */ + static void __attribute__ ((noreturn)) + grub_abort (void) +diff --git a/include/grub/misc.h b/include/grub/misc.h +index c6851fb9dcf..69da7f41efa 100644 +--- a/include/grub/misc.h ++++ b/include/grub/misc.h +@@ -535,6 +535,21 @@ EXPORT_FUNC (__umoddi3) (grub_uint64_t a, grub_uint64_t b); + + #endif /* GRUB_UTIL */ + ++/* ++ * grub_printf_fmt_checks() a fmt string for printf() against an expected ++ * format. It is intended for cases where the fmt string could come from ++ * an outside source and cannot be trusted. ++ * ++ * While expected fmt accepts a printf() format string it should be kept ++ * as simple as possible. The printf() format strings with positional ++ * parameters are NOT accepted, neither for fmt nor for fmt_expected. ++ * ++ * The fmt is accepted if it has equal or less arguments than fmt_expected ++ * and if the type of all arguments match. ++ * ++ * Returns GRUB_ERR_NONE if fmt is acceptable. ++ */ ++grub_err_t EXPORT_FUNC (grub_printf_fmt_check) (const char *fmt, const char *fmt_expected); + + #if BOOT_TIME_STATS + struct grub_boot_time diff --git a/SOURCES/0440-gfxmenu-gui-Check-printf-format-in-the-gui_progress_.patch b/SOURCES/0440-gfxmenu-gui-Check-printf-format-in-the-gui_progress_.patch new file mode 100644 index 0000000..5eecce9 --- /dev/null +++ b/SOURCES/0440-gfxmenu-gui-Check-printf-format-in-the-gui_progress_.patch @@ -0,0 +1,58 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Thomas Frauendorfer | Miray Software +Date: Tue, 4 Aug 2020 13:49:51 +0200 +Subject: [PATCH] gfxmenu/gui: Check printf() format in the gui_progress_bar + and gui_label + +The gui_progress_bar and gui_label components can display the timeout +value. The format string can be set through a theme file. This patch +adds a validation step to the format string. + +If a user loads a theme file into the GRUB without this patch then +a GUI label with the following settings + + + label { + ... + id = "__timeout__" + text = "%s" + } + +will interpret the current timeout value as string pointer and print the +memory at that position on the screen. It is not desired behavior. + +Signed-off-by: Thomas Frauendorfer | Miray Software +Reviewed-by: Daniel Kiper +--- + grub-core/gfxmenu/gui_label.c | 4 ++++ + grub-core/gfxmenu/gui_progress_bar.c | 3 +++ + 2 files changed, 7 insertions(+) + +diff --git a/grub-core/gfxmenu/gui_label.c b/grub-core/gfxmenu/gui_label.c +index a4c817891ee..1c190542a2b 100644 +--- a/grub-core/gfxmenu/gui_label.c ++++ b/grub-core/gfxmenu/gui_label.c +@@ -193,6 +193,10 @@ label_set_property (void *vself, const char *name, const char *value) + else if (grub_strcmp (value, "@KEYMAP_SHORT@") == 0) + value = _("enter: boot, `e': options, `c': cmd-line"); + /* FIXME: Add more templates here if needed. */ ++ ++ if (grub_printf_fmt_check(value, "%d") != GRUB_ERR_NONE) ++ value = ""; /* Unsupported format. */ ++ + self->template = grub_strdup (value); + self->text = grub_xasprintf (value, self->value); + } +diff --git a/grub-core/gfxmenu/gui_progress_bar.c b/grub-core/gfxmenu/gui_progress_bar.c +index 3501b01724f..048275e036e 100644 +--- a/grub-core/gfxmenu/gui_progress_bar.c ++++ b/grub-core/gfxmenu/gui_progress_bar.c +@@ -342,6 +342,9 @@ progress_bar_set_property (void *vself, const char *name, const char *value) + Please use the shortest form available in you language. */ + value = _("%ds"); + ++ if (grub_printf_fmt_check(value, "%d") != GRUB_ERR_NONE) ++ value = ""; /* Unsupported format. */ ++ + self->template = grub_strdup (value); + } + else if (grub_strcmp (name, "font") == 0) diff --git a/SOURCES/0440-kern-misc-Add-function-to-check-printf-format-agains.patch b/SOURCES/0440-kern-misc-Add-function-to-check-printf-format-agains.patch deleted file mode 100644 index 902b8e2..0000000 --- a/SOURCES/0440-kern-misc-Add-function-to-check-printf-format-agains.patch +++ /dev/null @@ -1,214 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Thomas Frauendorfer | Miray Software -Date: Thu, 4 Feb 2021 19:02:33 +0100 -Subject: [PATCH] kern/misc: Add function to check printf() format against - expected format - -The grub_printf_fmt_check() function parses the arguments of an untrusted -printf() format and an expected printf() format and then compares the -arguments counts and arguments types. The arguments count in the untrusted -format string must be less or equal to the arguments count in the expected -format string and both arguments types must match. - -To do this the parse_printf_arg_fmt() helper function is extended in the -following way: - - 1. Add a return value to report errors to the grub_printf_fmt_check(). - - 2. Add the fmt_check argument to enable stricter format verification: - - the function expects that arguments definitions are always - terminated by a supported conversion specifier. - - positional parameters, "$", are not allowed, as they cannot be - validated correctly with the current implementation. For example - "%s%1$d" would assign the first args entry twice while leaving the - second one unchanged. - - Return an error if preallocated space in args is too small and - allocation fails for the needed size. The grub_printf_fmt_check() - should verify all arguments. So, if validation is not possible for - any reason it should return an error. - This also adds a case entry to handle "%%", which is the escape - sequence to print "%" character. - - 3. Add the max_args argument to check for the maximum allowed arguments - count in a printf() string. This should be set to the arguments count - of the expected format. Then the parse_printf_arg_fmt() function will - return an error if the arguments count is exceeded. - -The two additional arguments allow us to use parse_printf_arg_fmt() in -printf() and grub_printf_fmt_check() calls. - -When parse_printf_arg_fmt() is used by grub_printf_fmt_check() the -function parse user provided untrusted format string too. So, in -that case it is better to be too strict than too lenient. - -Signed-off-by: Thomas Frauendorfer | Miray Software -Reviewed-by: Daniel Kiper ---- - grub-core/kern/misc.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++--- - include/grub/misc.h | 15 ++++++++++ - 2 files changed, 93 insertions(+), 4 deletions(-) - -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index eddde0c65d3..0dc9f8b9465 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -823,8 +823,26 @@ grub_lltoa (char *str, int c, unsigned long long n) - return p; - } - --static void --parse_printf_arg_fmt (const char *fmt0, struct printf_args *args) -+/* -+ * Parse printf() fmt0 string into args arguments. -+ * -+ * The parsed arguments are either used by a printf() function to format the fmt0 -+ * string or they are used to compare a format string from an untrusted source -+ * against a format string with expected arguments. -+ * -+ * When the fmt_check is set to !0, e.g. 1, then this function is executed in -+ * printf() format check mode. This enforces stricter rules for parsing the -+ * fmt0 to limit exposure to possible errors in printf() handling. It also -+ * disables positional parameters, "$", because some formats, e.g "%s%1$d", -+ * cannot be validated with the current implementation. -+ * -+ * The max_args allows to set a maximum number of accepted arguments. If the fmt0 -+ * string defines more arguments than the max_args then the parse_printf_arg_fmt() -+ * function returns an error. This is currently used for format check only. -+ */ -+static grub_err_t -+parse_printf_arg_fmt (const char *fmt0, struct printf_args *args, -+ int fmt_check, grub_size_t max_args) - { - const char *fmt; - char c; -@@ -851,7 +869,12 @@ parse_printf_arg_fmt (const char *fmt0, struct printf_args *args) - fmt++; - - if (*fmt == '$') -- fmt++; -+ { -+ if (fmt_check) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ "positional arguments are not supported"); -+ fmt++; -+ } - - if (*fmt =='-') - fmt++; -@@ -883,9 +906,19 @@ parse_printf_arg_fmt (const char *fmt0, struct printf_args *args) - case 's': - args->count++; - break; -+ case '%': -+ /* "%%" is the escape sequence to output "%". */ -+ break; -+ default: -+ if (fmt_check) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "unexpected format"); -+ break; - } - } - -+ if (fmt_check && args->count > max_args) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many arguments"); -+ - if (args->count <= ARRAY_SIZE (args->prealloc)) - args->ptr = args->prealloc; - else -@@ -893,6 +926,9 @@ parse_printf_arg_fmt (const char *fmt0, struct printf_args *args) - args->ptr = grub_calloc (args->count, sizeof (args->ptr[0])); - if (!args->ptr) - { -+ if (fmt_check) -+ return grub_errno; -+ - grub_errno = GRUB_ERR_NONE; - args->ptr = args->prealloc; - args->count = ARRAY_SIZE (args->prealloc); -@@ -978,6 +1014,8 @@ parse_printf_arg_fmt (const char *fmt0, struct printf_args *args) - break; - } - } -+ -+ return GRUB_ERR_NONE; - } - - static void -@@ -985,7 +1023,7 @@ parse_printf_args (const char *fmt0, struct printf_args *args, va_list args_in) - { - grub_size_t n; - -- parse_printf_arg_fmt (fmt0, args); -+ parse_printf_arg_fmt (fmt0, args, 0, 0); - - for (n = 0; n < args->count; n++) - switch (args->ptr[n].type) -@@ -1292,6 +1330,42 @@ grub_xasprintf (const char *fmt, ...) - return ret; - } - -+grub_err_t -+grub_printf_fmt_check (const char *fmt, const char *fmt_expected) -+{ -+ struct printf_args args_expected, args_fmt; -+ grub_err_t ret; -+ grub_size_t n; -+ -+ if (fmt == NULL || fmt_expected == NULL) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid format"); -+ -+ ret = parse_printf_arg_fmt (fmt_expected, &args_expected, 1, GRUB_SIZE_MAX); -+ if (ret != GRUB_ERR_NONE) -+ return ret; -+ -+ /* Limit parsing to the number of expected arguments. */ -+ ret = parse_printf_arg_fmt (fmt, &args_fmt, 1, args_expected.count); -+ if (ret != GRUB_ERR_NONE) -+ { -+ free_printf_args (&args_expected); -+ return ret; -+ } -+ -+ for (n = 0; n < args_fmt.count; n++) -+ if (args_fmt.ptr[n].type != args_expected.ptr[n].type) -+ { -+ ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments types do not match"); -+ break; -+ } -+ -+ free_printf_args (&args_expected); -+ free_printf_args (&args_fmt); -+ -+ return ret; -+} -+ -+ - /* Abort GRUB. This function does not return. */ - static void __attribute__ ((noreturn)) - grub_abort (void) -diff --git a/include/grub/misc.h b/include/grub/misc.h -index c6851fb9dcf..69da7f41efa 100644 ---- a/include/grub/misc.h -+++ b/include/grub/misc.h -@@ -535,6 +535,21 @@ EXPORT_FUNC (__umoddi3) (grub_uint64_t a, grub_uint64_t b); - - #endif /* GRUB_UTIL */ - -+/* -+ * grub_printf_fmt_checks() a fmt string for printf() against an expected -+ * format. It is intended for cases where the fmt string could come from -+ * an outside source and cannot be trusted. -+ * -+ * While expected fmt accepts a printf() format string it should be kept -+ * as simple as possible. The printf() format strings with positional -+ * parameters are NOT accepted, neither for fmt nor for fmt_expected. -+ * -+ * The fmt is accepted if it has equal or less arguments than fmt_expected -+ * and if the type of all arguments match. -+ * -+ * Returns GRUB_ERR_NONE if fmt is acceptable. -+ */ -+grub_err_t EXPORT_FUNC (grub_printf_fmt_check) (const char *fmt, const char *fmt_expected); - - #if BOOT_TIME_STATS - struct grub_boot_time diff --git a/SOURCES/0441-gfxmenu-gui-Check-printf-format-in-the-gui_progress_.patch b/SOURCES/0441-gfxmenu-gui-Check-printf-format-in-the-gui_progress_.patch deleted file mode 100644 index 5eecce9..0000000 --- a/SOURCES/0441-gfxmenu-gui-Check-printf-format-in-the-gui_progress_.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Thomas Frauendorfer | Miray Software -Date: Tue, 4 Aug 2020 13:49:51 +0200 -Subject: [PATCH] gfxmenu/gui: Check printf() format in the gui_progress_bar - and gui_label - -The gui_progress_bar and gui_label components can display the timeout -value. The format string can be set through a theme file. This patch -adds a validation step to the format string. - -If a user loads a theme file into the GRUB without this patch then -a GUI label with the following settings - - + label { - ... - id = "__timeout__" - text = "%s" - } - -will interpret the current timeout value as string pointer and print the -memory at that position on the screen. It is not desired behavior. - -Signed-off-by: Thomas Frauendorfer | Miray Software -Reviewed-by: Daniel Kiper ---- - grub-core/gfxmenu/gui_label.c | 4 ++++ - grub-core/gfxmenu/gui_progress_bar.c | 3 +++ - 2 files changed, 7 insertions(+) - -diff --git a/grub-core/gfxmenu/gui_label.c b/grub-core/gfxmenu/gui_label.c -index a4c817891ee..1c190542a2b 100644 ---- a/grub-core/gfxmenu/gui_label.c -+++ b/grub-core/gfxmenu/gui_label.c -@@ -193,6 +193,10 @@ label_set_property (void *vself, const char *name, const char *value) - else if (grub_strcmp (value, "@KEYMAP_SHORT@") == 0) - value = _("enter: boot, `e': options, `c': cmd-line"); - /* FIXME: Add more templates here if needed. */ -+ -+ if (grub_printf_fmt_check(value, "%d") != GRUB_ERR_NONE) -+ value = ""; /* Unsupported format. */ -+ - self->template = grub_strdup (value); - self->text = grub_xasprintf (value, self->value); - } -diff --git a/grub-core/gfxmenu/gui_progress_bar.c b/grub-core/gfxmenu/gui_progress_bar.c -index 3501b01724f..048275e036e 100644 ---- a/grub-core/gfxmenu/gui_progress_bar.c -+++ b/grub-core/gfxmenu/gui_progress_bar.c -@@ -342,6 +342,9 @@ progress_bar_set_property (void *vself, const char *name, const char *value) - Please use the shortest form available in you language. */ - value = _("%ds"); - -+ if (grub_printf_fmt_check(value, "%d") != GRUB_ERR_NONE) -+ value = ""; /* Unsupported format. */ -+ - self->template = grub_strdup (value); - } - else if (grub_strcmp (name, "font") == 0) diff --git a/SOURCES/0441-kern-mm-Fix-grub_debug_calloc-compilation-error.patch b/SOURCES/0441-kern-mm-Fix-grub_debug_calloc-compilation-error.patch new file mode 100644 index 0000000..00c71c9 --- /dev/null +++ b/SOURCES/0441-kern-mm-Fix-grub_debug_calloc-compilation-error.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Marco A Benatto +Date: Tue, 9 Feb 2021 12:33:06 -0300 +Subject: [PATCH] kern/mm: Fix grub_debug_calloc() compilation error + +Fix compilation error due to missing parameter to +grub_printf() when MM_DEBUG is defined. + +Fixes: 64e26162e (calloc: Make sure we always have an overflow-checking calloc() available) + +Signed-off-by: Marco A Benatto +Reviewed-by: Daniel Kiper +--- + grub-core/kern/mm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c +index a424b7d0943..952f3d53e6d 100644 +--- a/grub-core/kern/mm.c ++++ b/grub-core/kern/mm.c +@@ -585,7 +585,7 @@ grub_debug_calloc (const char *file, int line, grub_size_t nmemb, grub_size_t si + + if (grub_mm_debug) + grub_printf ("%s:%d: calloc (0x%" PRIxGRUB_SIZE ", 0x%" PRIxGRUB_SIZE ") = ", +- file, line, size); ++ file, line, nmemb, size); + ptr = grub_calloc (nmemb, size); + if (grub_mm_debug) + grub_printf ("%p\n", ptr); diff --git a/SOURCES/0442-efi-net-Fix-malformed-device-path-arithmetic-errors-.patch b/SOURCES/0442-efi-net-Fix-malformed-device-path-arithmetic-errors-.patch new file mode 100644 index 0000000..270baeb --- /dev/null +++ b/SOURCES/0442-efi-net-Fix-malformed-device-path-arithmetic-errors-.patch @@ -0,0 +1,74 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Thomas Frauendorfer | Miray Software +Date: Tue, 4 Aug 2020 17:13:05 +0200 +Subject: [PATCH] efi/net: Fix malformed device path arithmetic errors in efi + net methods + +--- + grub-core/net/efi/net.c | 26 ++++++++++++++++++++------ + 1 file changed, 20 insertions(+), 6 deletions(-) + +diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c +index 86bcae281a7..4a37523dd1f 100644 +--- a/grub-core/net/efi/net.c ++++ b/grub-core/net/efi/net.c +@@ -1318,11 +1318,18 @@ grub_efi_net_boot_from_https (void) + + dp = grub_efi_get_device_path (image->device_handle); + +- while (1) ++ while (dp) + { ++ grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp); ++ if (len < 4) ++ { ++ grub_error(GRUB_ERR_OUT_OF_RANGE, ++ "malformed EFI Device Path node has length=%d", len); ++ break; ++ } ++ + grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); + grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); +- grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp); + + if ((type == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE) + && (subtype == GRUB_EFI_URI_DEVICE_PATH_SUBTYPE)) +@@ -1335,7 +1342,7 @@ grub_efi_net_boot_from_https (void) + + if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) + break; +- dp = (grub_efi_device_path_t *) ((char *) dp + len); ++ dp = GRUB_EFI_NEXT_DEVICE_PATH(dp); + } + + return 0; +@@ -1353,11 +1360,18 @@ grub_efi_net_boot_from_opa (void) + + dp = grub_efi_get_device_path (image->device_handle); + +- while (1) ++ while (dp) + { ++ grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp); ++ if (len < 4) ++ { ++ grub_error(GRUB_ERR_OUT_OF_RANGE, ++ "malformed EFI Device Path node has length=%d", len); ++ break; ++ } ++ + grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); + grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); +- grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp); + + if ((type == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE) + && (subtype == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE)) +@@ -1368,7 +1382,7 @@ grub_efi_net_boot_from_opa (void) + + if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) + break; +- dp = (grub_efi_device_path_t *) ((char *) dp + len); ++ dp = GRUB_EFI_NEXT_DEVICE_PATH(dp); + } + + return 0; diff --git a/SOURCES/0442-kern-mm-Fix-grub_debug_calloc-compilation-error.patch b/SOURCES/0442-kern-mm-Fix-grub_debug_calloc-compilation-error.patch deleted file mode 100644 index 00c71c9..0000000 --- a/SOURCES/0442-kern-mm-Fix-grub_debug_calloc-compilation-error.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Marco A Benatto -Date: Tue, 9 Feb 2021 12:33:06 -0300 -Subject: [PATCH] kern/mm: Fix grub_debug_calloc() compilation error - -Fix compilation error due to missing parameter to -grub_printf() when MM_DEBUG is defined. - -Fixes: 64e26162e (calloc: Make sure we always have an overflow-checking calloc() available) - -Signed-off-by: Marco A Benatto -Reviewed-by: Daniel Kiper ---- - grub-core/kern/mm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c -index a424b7d0943..952f3d53e6d 100644 ---- a/grub-core/kern/mm.c -+++ b/grub-core/kern/mm.c -@@ -585,7 +585,7 @@ grub_debug_calloc (const char *file, int line, grub_size_t nmemb, grub_size_t si - - if (grub_mm_debug) - grub_printf ("%s:%d: calloc (0x%" PRIxGRUB_SIZE ", 0x%" PRIxGRUB_SIZE ") = ", -- file, line, size); -+ file, line, nmemb, size); - ptr = grub_calloc (nmemb, size); - if (grub_mm_debug) - grub_printf ("%p\n", ptr); diff --git a/SOURCES/0443-efi-net-Fix-malformed-device-path-arithmetic-errors-.patch b/SOURCES/0443-efi-net-Fix-malformed-device-path-arithmetic-errors-.patch deleted file mode 100644 index 270baeb..0000000 --- a/SOURCES/0443-efi-net-Fix-malformed-device-path-arithmetic-errors-.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Thomas Frauendorfer | Miray Software -Date: Tue, 4 Aug 2020 17:13:05 +0200 -Subject: [PATCH] efi/net: Fix malformed device path arithmetic errors in efi - net methods - ---- - grub-core/net/efi/net.c | 26 ++++++++++++++++++++------ - 1 file changed, 20 insertions(+), 6 deletions(-) - -diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c -index 86bcae281a7..4a37523dd1f 100644 ---- a/grub-core/net/efi/net.c -+++ b/grub-core/net/efi/net.c -@@ -1318,11 +1318,18 @@ grub_efi_net_boot_from_https (void) - - dp = grub_efi_get_device_path (image->device_handle); - -- while (1) -+ while (dp) - { -+ grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp); -+ if (len < 4) -+ { -+ grub_error(GRUB_ERR_OUT_OF_RANGE, -+ "malformed EFI Device Path node has length=%d", len); -+ break; -+ } -+ - grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); - grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); -- grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp); - - if ((type == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE) - && (subtype == GRUB_EFI_URI_DEVICE_PATH_SUBTYPE)) -@@ -1335,7 +1342,7 @@ grub_efi_net_boot_from_https (void) - - if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) - break; -- dp = (grub_efi_device_path_t *) ((char *) dp + len); -+ dp = GRUB_EFI_NEXT_DEVICE_PATH(dp); - } - - return 0; -@@ -1353,11 +1360,18 @@ grub_efi_net_boot_from_opa (void) - - dp = grub_efi_get_device_path (image->device_handle); - -- while (1) -+ while (dp) - { -+ grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp); -+ if (len < 4) -+ { -+ grub_error(GRUB_ERR_OUT_OF_RANGE, -+ "malformed EFI Device Path node has length=%d", len); -+ break; -+ } -+ - grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); - grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); -- grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp); - - if ((type == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE) - && (subtype == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE)) -@@ -1368,7 +1382,7 @@ grub_efi_net_boot_from_opa (void) - - if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) - break; -- dp = (grub_efi_device_path_t *) ((char *) dp + len); -+ dp = GRUB_EFI_NEXT_DEVICE_PATH(dp); - } - - return 0; diff --git a/SOURCES/0443-grub-core-term-at_keyboard.c-Retry-probing-keyboard-.patch b/SOURCES/0443-grub-core-term-at_keyboard.c-Retry-probing-keyboard-.patch new file mode 100644 index 0000000..67f6310 --- /dev/null +++ b/SOURCES/0443-grub-core-term-at_keyboard.c-Retry-probing-keyboard-.patch @@ -0,0 +1,84 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Vladimir Serbinenko +Date: Wed, 13 Aug 2014 23:04:01 +0200 +Subject: [PATCH] * grub-core/term/at_keyboard.c: Retry probing keyboard + if scancode setup failed. + +--- + grub-core/term/at_keyboard.c | 11 +++++------ + ChangeLog | 5 +++++ + 2 files changed, 10 insertions(+), 6 deletions(-) + +diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c +index b4257e84a04..c234e92f246 100644 +--- a/grub-core/term/at_keyboard.c ++++ b/grub-core/term/at_keyboard.c +@@ -226,7 +226,7 @@ static const struct + {0x7d, GRUB_KEYBOARD_KEY_PPAGE}, + }; + +-static int alive = 0, ping_sent; ++static int ping_sent; + + static void + keyboard_controller_wait_until_ready (void) +@@ -373,7 +373,7 @@ set_scancodes (void) + grub_dprintf ("atkeyb", "returned set %d\n", current_set); + if (current_set == 1) + return; +- grub_printf ("No supported scancode set found\n"); ++ grub_dprintf ("atkeyb", "no supported scancode set found\n"); + #endif + } + +@@ -543,7 +543,7 @@ grub_keyboard_getkey (void) + int + grub_at_keyboard_is_alive (void) + { +- if (alive) ++ if (current_set != 0) + return 1; + if (ping_sent + && KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS)) +@@ -611,7 +611,6 @@ static void + grub_keyboard_controller_init (void) + { + at_keyboard_status = 0; +- alive = 1; + /* Drain input buffer. */ + while (1) + { +@@ -639,7 +638,7 @@ grub_keyboard_controller_init (void) + static grub_err_t + grub_keyboard_controller_fini (struct grub_term_input *term __attribute__ ((unused))) + { +- if (!alive) ++ if (current_set == 0) + return GRUB_ERR_NONE; + if (grub_keyboard_orig_set) + write_mode (grub_keyboard_orig_set); +@@ -656,7 +655,7 @@ grub_at_fini_hw (int noreturn __attribute__ ((unused))) + static grub_err_t + grub_at_restore_hw (void) + { +- if (!alive) ++ if (current_set == 0) + return GRUB_ERR_NONE; + + /* Drain input buffer. */ +diff --git a/ChangeLog b/ChangeLog +index d3f26cf2f0d..f3afd5cad8d 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -2,6 +2,11 @@ + * grub-core/kern/emu/hostfs.c: use _DEFAULT_SOURCE in addition to + _BSD_SOURCE to avoid warnings under glibc 2.20+. + ++2014-08-13 Vladimir Serbinenko ++ ++ * grub-core/term/at_keyboard.c: Retry probing keyboard if ++ scancode setup failed. ++ + 2014-06-21 Роман Пехов + + * grub-core/commands/loadenv.c (check_blocklists): Fix overlap check. diff --git a/SOURCES/0444-at_keyboard-use-set-1-when-keyboard-is-in-Translate-.patch b/SOURCES/0444-at_keyboard-use-set-1-when-keyboard-is-in-Translate-.patch new file mode 100644 index 0000000..9cb3a2e --- /dev/null +++ b/SOURCES/0444-at_keyboard-use-set-1-when-keyboard-is-in-Translate-.patch @@ -0,0 +1,122 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Renaud=20M=C3=A9trich?= +Date: Thu, 3 Dec 2020 09:13:24 +0100 +Subject: [PATCH] at_keyboard: use set 1 when keyboard is in Translate mode +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When keyboard controller acts in Translate mode (0x40 mask), then use +set 1 since translation is done. +Otherwise use the mode queried from the controller (usually set 2). + +Added "atkeyb" debugging messages in at_keyboard module as well. + +Resolves: rhbz#1897587 + +Tested on: +- Asus N53SN (set 1 used) +- Dell Precision (set 1 used) +- HP Elitebook (set 2 used) +- HP G5430 (set 1 used, keyboard in XT mode!) +- Lenovo P71 & Lenovo T460s (set 2 used) +- QEMU/KVM (set 1 used) + +Signed-off-by: Renaud Métrich +--- + grub-core/term/at_keyboard.c | 29 ++++++++++++++++++++++++----- + include/grub/at_keyboard.h | 4 ++++ + 2 files changed, 28 insertions(+), 5 deletions(-) + +diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c +index c234e92f246..bbeea257745 100644 +--- a/grub-core/term/at_keyboard.c ++++ b/grub-core/term/at_keyboard.c +@@ -323,8 +323,10 @@ query_mode (void) + int e; + + e = write_mode (0); +- if (!e) ++ if (!e) { ++ grub_dprintf("atkeyb", "query_mode: write_mode(0) failed\n"); + return 0; ++ } + + keyboard_controller_wait_until_ready (); + +@@ -333,12 +335,18 @@ query_mode (void) + while (ret == GRUB_AT_ACK); + + /* QEMU translates the set even in no-translate mode. */ +- if (ret == 0x43 || ret == 1) ++ if (ret == 0x43 || ret == 1) { ++ grub_dprintf("atkeyb", "query_mode: returning 1 (ret=0x%x)\n", ret); + return 1; +- if (ret == 0x41 || ret == 2) ++ } ++ if (ret == 0x41 || ret == 2) { ++ grub_dprintf("atkeyb", "query_mode: returning 2 (ret=0x%x)\n", ret); + return 2; +- if (ret == 0x3f || ret == 3) ++ } ++ if (ret == 0x3f || ret == 3) { ++ grub_dprintf("atkeyb", "query_mode: returning 3 (ret=0x%x)\n", ret); + return 3; ++ } + return 0; + } + +@@ -355,7 +363,13 @@ set_scancodes (void) + } + + #if !USE_SCANCODE_SET +- current_set = 1; ++ if ((grub_keyboard_controller_orig & KEYBOARD_AT_TRANSLATE) == KEYBOARD_AT_TRANSLATE) { ++ grub_dprintf ("atkeyb", "queried set is %d but keyboard in Translate mode, so actually in set 1\n", grub_keyboard_orig_set); ++ current_set = 1; ++ } else { ++ grub_dprintf ("atkeyb", "using queried set %d\n", grub_keyboard_orig_set); ++ current_set = grub_keyboard_orig_set; ++ } + return; + #else + +@@ -629,6 +643,7 @@ grub_keyboard_controller_init (void) + grub_keyboard_orig_set = 2; + #else + grub_keyboard_controller_orig = grub_keyboard_controller_read (); ++ grub_dprintf ("atkeyb", "grub_keyboard_controller_orig = 0x%x\n", grub_keyboard_controller_orig); + grub_keyboard_orig_set = query_mode (); + #endif + set_scancodes (); +@@ -638,11 +653,15 @@ grub_keyboard_controller_init (void) + static grub_err_t + grub_keyboard_controller_fini (struct grub_term_input *term __attribute__ ((unused))) + { ++/* In !USE_SCANCODE_SET mode, we didn't change anything, so nothing to restore */ ++#if USE_SCANCODE_SET + if (current_set == 0) + return GRUB_ERR_NONE; ++ grub_dprintf ("atkeyb", "restoring set %d, controller 0x%x\n", grub_keyboard_orig_set, grub_keyboard_controller_orig); + if (grub_keyboard_orig_set) + write_mode (grub_keyboard_orig_set); + grub_keyboard_controller_write (grub_keyboard_controller_orig); ++#endif + return GRUB_ERR_NONE; + } + +diff --git a/include/grub/at_keyboard.h b/include/grub/at_keyboard.h +index b4f8ff0a061..97e827e9eb9 100644 +--- a/include/grub/at_keyboard.h ++++ b/include/grub/at_keyboard.h +@@ -19,6 +19,10 @@ + #ifndef GRUB_AT_KEYBOARD_HEADER + #define GRUB_AT_KEYBOARD_HEADER 1 + ++/* ++ * Refer to https://wiki.osdev.org/%228042%22_PS/2_Controller for details. ++ */ ++ + /* Used for sending commands to the controller. */ + #define KEYBOARD_COMMAND_ISREADY(x) !((x) & 0x02) + #define KEYBOARD_COMMAND_READ 0x20 diff --git a/SOURCES/0445-Add-at_keyboard_fallback_set-var-to-force-the-set-ma.patch b/SOURCES/0445-Add-at_keyboard_fallback_set-var-to-force-the-set-ma.patch new file mode 100644 index 0000000..73fff3e --- /dev/null +++ b/SOURCES/0445-Add-at_keyboard_fallback_set-var-to-force-the-set-ma.patch @@ -0,0 +1,245 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Renaud=20M=C3=A9trich?= +Date: Fri, 18 Dec 2020 15:39:26 +0100 +Subject: [PATCH] Add 'at_keyboard_fallback_set' var to force the set manually + +This seems required with HP DL380p Gen 8 systems. +Indeed, with this system, we can see the following sequence: + +1. controller is queried to get current configuration (returns 0x30 which is quite standard) +2. controller is queried to get the current keyboard set in used, using code 0xf0 (first part) +3. controller answers with 0xfa which means "ACK" (== ok) +4. then we send "0" to tell "we want to know which set your are supporting" +5. controller answers with 0xfa ("ACK") +6. controller should then give us 1, 2, 3 or 0x43, 0x41, 0x3f, but here it gives us 0xfe which means "NACK" + +Since there seems no way to determine the current set, and in fact the +controller expects set2 to be used, we need to rely on an environment +variable. +Everything has been tested on this system: using 0xFE (resend command), +making sure we wait for ACK in the 2 steps "write_mode", etc. + +Below is litterature I used to come up with "there is no other +solution": +- https://wiki.osdev.org/%228042%22_PS/2_Controller +- http://www-ug.eecg.toronto.edu/msl/nios_devices/datasheets/PS2%20Keyboard%20Protocol.htm +- http://www.s100computers.com/My%20System%20Pages/MSDOS%20Board/PC%20Keyboard.pdf +--- + grub-core/term/at_keyboard.c | 126 +++++++++++++++++++++++++++++++++---------- + 1 file changed, 99 insertions(+), 27 deletions(-) + +diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c +index bbeea257745..89dc3e20c30 100644 +--- a/grub-core/term/at_keyboard.c ++++ b/grub-core/term/at_keyboard.c +@@ -40,7 +40,11 @@ static grub_uint8_t led_status; + + static grub_uint8_t grub_keyboard_controller_orig; + static grub_uint8_t grub_keyboard_orig_set; ++ + static grub_uint8_t current_set; ++static int fallback_set; ++ ++static int ping_sent; + + static void + grub_keyboard_controller_init (void); +@@ -264,6 +268,8 @@ at_command (grub_uint8_t data) + break; + return 0; + } ++ if (i == GRUB_AT_TRIES) ++ grub_dprintf ("atkeyb", "at_command() timed out! (stopped after %d tries)\n", i); + return (i != GRUB_AT_TRIES); + } + +@@ -293,6 +299,21 @@ grub_keyboard_controller_read (void) + + #endif + ++static int ++resend_last_result (void) ++{ ++ grub_uint8_t ret; ++ keyboard_controller_wait_until_ready (); ++ grub_dprintf ("atkeyb", "resend_last_result: sending 0xfe\n"); ++ grub_outb (0xfe, KEYBOARD_REG_DATA); ++ ret = wait_ack (); ++ grub_dprintf ("atkeyb", "resend_last_result: wait_ack() returned 0x%x\n", ret); ++ keyboard_controller_wait_until_ready (); ++ ret = grub_inb (KEYBOARD_REG_DATA); ++ grub_dprintf ("atkeyb", "resend_last_result: read 0x%x from controller\n", ret); ++ return ret; ++} ++ + static int + write_mode (int mode) + { +@@ -301,11 +322,14 @@ write_mode (int mode) + { + grub_uint8_t ack; + keyboard_controller_wait_until_ready (); ++ grub_dprintf ("atkeyb", "write_mode: sending 0xf0\n"); + grub_outb (0xf0, KEYBOARD_REG_DATA); + keyboard_controller_wait_until_ready (); ++ grub_dprintf ("atkeyb", "write_mode: sending mode %d\n", mode); + grub_outb (mode, KEYBOARD_REG_DATA); + keyboard_controller_wait_until_ready (); + ack = wait_ack (); ++ grub_dprintf ("atkeyb", "write_mode: wait_ack() returned 0x%x\n", ack); + if (ack == GRUB_AT_NACK) + continue; + if (ack == GRUB_AT_ACK) +@@ -313,6 +337,9 @@ write_mode (int mode) + return 0; + } + ++ if (i == GRUB_AT_TRIES) ++ grub_dprintf ("atkeyb", "write_mode() timed out! (stopped after %d tries)\n", i); ++ + return (i != GRUB_AT_TRIES); + } + +@@ -320,33 +347,66 @@ static int + query_mode (void) + { + grub_uint8_t ret; ++ grub_uint64_t endtime; ++ unsigned i; + int e; ++ char *envvar; + +- e = write_mode (0); +- if (!e) { +- grub_dprintf("atkeyb", "query_mode: write_mode(0) failed\n"); +- return 0; +- } +- +- keyboard_controller_wait_until_ready (); +- +- do +- ret = grub_inb (KEYBOARD_REG_DATA); +- while (ret == GRUB_AT_ACK); ++ for (i = 0; i < GRUB_AT_TRIES; i++) { ++ grub_dprintf ("atkeyb", "query_mode: sending command to controller\n"); ++ e = write_mode (0); ++ if (!e) { ++ grub_dprintf ("atkeyb", "query_mode: write_mode(0) failed\n"); ++ return 0; ++ } + +- /* QEMU translates the set even in no-translate mode. */ +- if (ret == 0x43 || ret == 1) { +- grub_dprintf("atkeyb", "query_mode: returning 1 (ret=0x%x)\n", ret); +- return 1; ++ endtime = grub_get_time_ms () + 20; ++ do { ++ keyboard_controller_wait_until_ready (); ++ ret = grub_inb (KEYBOARD_REG_DATA); ++ grub_dprintf ("atkeyb", "query_mode/loop: read 0x%x from controller\n", ret); ++ } while ((ret == GRUB_AT_ACK || ret == GRUB_AT_NACK) && grub_get_time_ms () < endtime); ++ if (ret == 0xfe) { ++ grub_dprintf ("atkeyb", "query_mode: asking controller to resend last result\n"); ++ ret = resend_last_result(); ++ grub_dprintf ("atkeyb", "query_mode: read 0x%x from controller\n", ret); ++ } ++ /* QEMU translates the set even in no-translate mode. */ ++ if (ret == 0x43 || ret == 1) { ++ grub_dprintf ("atkeyb", "query_mode: controller returned 0x%x, returning 1\n", ret); ++ return 1; ++ } ++ if (ret == 0x41 || ret == 2) { ++ grub_dprintf ("atkeyb", "query_mode: controller returned 0x%x, returning 2\n", ret); ++ return 2; ++ } ++ if (ret == 0x3f || ret == 3) { ++ grub_dprintf ("atkeyb", "query_mode: controller returned 0x%x, returning 3\n", ret); ++ return 3; ++ } ++ grub_dprintf ("atkeyb", "query_mode: controller returned unexpected value 0x%x, retrying\n", ret); + } +- if (ret == 0x41 || ret == 2) { +- grub_dprintf("atkeyb", "query_mode: returning 2 (ret=0x%x)\n", ret); +- return 2; +- } +- if (ret == 0x3f || ret == 3) { +- grub_dprintf("atkeyb", "query_mode: returning 3 (ret=0x%x)\n", ret); +- return 3; ++ ++ /* ++ * Falling here means we tried querying and the controller returned something ++ * we don't understand, try to use 'at_keyboard_fallback_set' if it exists, ++ * otherwise return 0. ++ */ ++ envvar = grub_env_get ("at_keyboard_fallback_set"); ++ if (envvar) { ++ fallback_set = grub_strtoul (envvar, 0, 10); ++ if ((grub_errno) || (fallback_set < 1) || (fallback_set > 3)) { ++ grub_dprintf ("atkeyb", "WARNING: ignoring unexpected value '%s' for '%s' variable\n", ++ envvar, "at_keyboard_fallback_set"); ++ fallback_set = 0; ++ } else { ++ grub_dprintf ("atkeyb", "query_mode: '%s' specified in environment, returning %d\n", ++ "at_keyboard_fallback_set", fallback_set); ++ } ++ return fallback_set; + } ++ grub_dprintf ("atkeyb", "WARNING: no '%s' specified in environment, returning 0\n", ++ "at_keyboard_fallback_set"); + return 0; + } + +@@ -355,14 +415,25 @@ set_scancodes (void) + { + /* You must have visited computer museum. Keyboard without scancode set + knowledge. Assume XT. */ +- if (!grub_keyboard_orig_set) +- { +- grub_dprintf ("atkeyb", "No sets support assumed\n"); +- current_set = 1; ++ if (!grub_keyboard_orig_set) { ++ if (fallback_set) { ++ grub_dprintf ("atkeyb", "No sets support assumed but set forced to %d\n", fallback_set); ++ current_set = fallback_set; + return; + } ++ grub_dprintf ("atkeyb", "No sets support assumed, forcing to set 1\n"); ++ current_set = 1; ++ return; ++ } + + #if !USE_SCANCODE_SET ++ if (fallback_set) { ++ grub_dprintf ("atkeyb", "queried set is %d but set forced to %d\n", ++ grub_keyboard_orig_set, fallback_set); ++ current_set = fallback_set; ++ return; ++ } ++ + if ((grub_keyboard_controller_orig & KEYBOARD_AT_TRANSLATE) == KEYBOARD_AT_TRANSLATE) { + grub_dprintf ("atkeyb", "queried set is %d but keyboard in Translate mode, so actually in set 1\n", grub_keyboard_orig_set); + current_set = 1; +@@ -624,6 +695,7 @@ grub_at_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused))) + static void + grub_keyboard_controller_init (void) + { ++ grub_dprintf ("atkeyb", "initializing the controller\n"); + at_keyboard_status = 0; + /* Drain input buffer. */ + while (1) +@@ -645,6 +717,7 @@ grub_keyboard_controller_init (void) + grub_keyboard_controller_orig = grub_keyboard_controller_read (); + grub_dprintf ("atkeyb", "grub_keyboard_controller_orig = 0x%x\n", grub_keyboard_controller_orig); + grub_keyboard_orig_set = query_mode (); ++ grub_dprintf ("atkeyb", "grub_keyboard_orig_set = %d\n", grub_keyboard_orig_set); + #endif + set_scancodes (); + keyboard_controller_led (led_status); +@@ -692,7 +765,6 @@ grub_at_restore_hw (void) + return GRUB_ERR_NONE; + } + +- + static struct grub_term_input grub_at_keyboard_term = + { + .name = "at_keyboard", diff --git a/SOURCES/0446-ieee1275-powerpc-implements-fibre-channel-discovery-.patch b/SOURCES/0446-ieee1275-powerpc-implements-fibre-channel-discovery-.patch new file mode 100644 index 0000000..6cdad57 --- /dev/null +++ b/SOURCES/0446-ieee1275-powerpc-implements-fibre-channel-discovery-.patch @@ -0,0 +1,105 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Diego Domingos +Date: Wed, 24 Jun 2020 08:17:18 -0400 +Subject: [PATCH] ieee1275/powerpc: implements fibre channel discovery for + ofpathname + +grub-ofpathname doesn't work with fibre channel because there is no +function currently implemented for it. +This patch enables it by prividing a function that looks for the port +name, building the entire path for OF devices. +--- + grub-core/osdep/linux/ofpath.c | 52 +++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 51 insertions(+), 1 deletion(-) + +diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c +index 8f24bc9e897..4334b19cace 100644 +--- a/grub-core/osdep/linux/ofpath.c ++++ b/grub-core/osdep/linux/ofpath.c +@@ -300,6 +300,38 @@ of_path_of_ide(const char *sys_devname __attribute__((unused)), const char *devi + return ret; + } + ++ ++static void ++of_fc_port_name(const char *path, const char *subpath, char *port_name) ++{ ++ char *bname, *basepath, *p; ++ int fd; ++ ++ bname = xmalloc(sizeof(char)*150); ++ basepath = xmalloc(strlen(path)); ++ ++ /* Generate the path to get port name information from the drive */ ++ strncpy(basepath,path,subpath-path); ++ basepath[subpath-path-1] = '\0'; ++ p = get_basename(basepath); ++ snprintf(bname,sizeof(char)*150,"%s/fc_transport/%s/port_name",basepath,p); ++ ++ /* Read the information from the port name */ ++ fd = open (bname, O_RDONLY); ++ if (fd < 0) ++ grub_util_error (_("cannot open `%s': %s"), bname, strerror (errno)); ++ ++ if (read(fd,port_name,sizeof(char)*19) < 0) ++ grub_util_error (_("cannot read `%s': %s"), bname, strerror (errno)); ++ ++ sscanf(port_name,"0x%s",port_name); ++ ++ close(fd); ++ ++ free(bname); ++ free(basepath); ++} ++ + static int + vendor_is_ATA(const char *path) + { +@@ -404,7 +436,7 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev + } + + of_path = find_obppath(sysfs_path); +- free (sysfs_path); ++ + if (!of_path) + return NULL; + +@@ -419,6 +451,16 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev + digit_string = trailing_digits (device); + if (strncmp (of_path, "/vdevice/", sizeof ("/vdevice/") - 1) == 0) + { ++ if(strstr(of_path,"vfc-client")) ++ { ++ char * port_name = xmalloc(sizeof(char)*17); ++ of_fc_port_name(sysfs_path, p, port_name); ++ ++ snprintf(disk,sizeof(disk),"/%s@%s", disk_name, port_name); ++ free(port_name); ++ } ++ else ++ { + unsigned long id = 0x8000 | (tgt << 8) | (bus << 5) | lun; + if (*digit_string == '\0') + { +@@ -432,6 +474,13 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev + snprintf(disk, sizeof (disk), + "/%s@%04lx000000000000:%c", disk_name, id, 'a' + (part - 1)); + } ++ } ++ } else if (strstr(of_path,"fibre-channel")||(strstr(of_path,"vfc-client"))){ ++ char * port_name = xmalloc(sizeof(char)*17); ++ of_fc_port_name(sysfs_path, p, port_name); ++ ++ snprintf(disk,sizeof(disk),"/%s@%s", disk_name, port_name); ++ free(port_name); + } + else + { +@@ -482,6 +531,7 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev + } + } + } ++ free (sysfs_path); + strcat(of_path, disk); + return of_path; + } diff --git a/SOURCES/0447-ieee1275-powerpc-enables-device-mapper-discovery.patch b/SOURCES/0447-ieee1275-powerpc-enables-device-mapper-discovery.patch new file mode 100644 index 0000000..d918832 --- /dev/null +++ b/SOURCES/0447-ieee1275-powerpc-enables-device-mapper-discovery.patch @@ -0,0 +1,104 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Diego Domingos +Date: Wed, 24 Jun 2020 08:22:50 -0400 +Subject: [PATCH] ieee1275/powerpc: enables device mapper discovery + +this patch enables the device mapper discovery on ofpath.c. Currently, +when we are dealing with a device like /dev/dm-* the ofpath returns null +since there is no function implemented to handle this case. + +This patch implements a function that will look into /sys/block/dm-* +devices and search recursively inside slaves directory to find the root +disk. +--- + grub-core/osdep/linux/ofpath.c | 64 +++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 63 insertions(+), 1 deletion(-) + +diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c +index 4334b19cace..9cf87b1aa9e 100644 +--- a/grub-core/osdep/linux/ofpath.c ++++ b/grub-core/osdep/linux/ofpath.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + + #ifdef OFPATH_STANDALONE + #define xmalloc malloc +@@ -553,13 +554,74 @@ strip_trailing_digits (const char *p) + return new; + } + ++static char * ++get_slave_from_dm(const char * device){ ++ char *curr_device, *tmp; ++ char *directory; ++ char *ret = NULL; ++ ++ directory = grub_strdup (device); ++ tmp = get_basename(directory); ++ curr_device = grub_strdup (tmp); ++ *tmp = '\0'; ++ ++ /* Recursively check for slaves devices so we can find the root device */ ++ while ((curr_device[0] == 'd') && (curr_device[1] == 'm') && (curr_device[2] == '-')){ ++ DIR *dp; ++ struct dirent *ep; ++ char* device_path; ++ ++ device_path = grub_xasprintf ("/sys/block/%s/slaves", curr_device); ++ dp = opendir(device_path); ++ free(device_path); ++ ++ if (dp != NULL) ++ { ++ ep = readdir (dp); ++ while (ep != NULL){ ++ ++ /* avoid some system directories */ ++ if (!strcmp(ep->d_name,".")) ++ goto next_dir; ++ if (!strcmp(ep->d_name,"..")) ++ goto next_dir; ++ ++ free (curr_device); ++ free (ret); ++ curr_device = grub_strdup (ep->d_name); ++ ret = grub_xasprintf ("%s%s", directory, curr_device); ++ break; ++ ++ next_dir: ++ ep = readdir (dp); ++ continue; ++ } ++ closedir (dp); ++ } ++ else ++ grub_util_warn (_("cannot open directory `%s'"), device_path); ++ } ++ ++ free (directory); ++ free (curr_device); ++ ++ return ret; ++} ++ + char * + grub_util_devname_to_ofpath (const char *sys_devname) + { +- char *name_buf, *device, *devnode, *devicenode, *ofpath; ++ char *name_buf, *device, *devnode, *devicenode, *ofpath, *realname; + + name_buf = xrealpath (sys_devname); + ++ realname = get_slave_from_dm (name_buf); ++ if (realname) ++ { ++ free (name_buf); ++ name_buf = realname; ++ } ++ + device = get_basename (name_buf); + devnode = strip_trailing_digits (name_buf); + devicenode = strip_trailing_digits (device); diff --git a/SOURCES/0448-ieee1275-Avoiding-many-unecessary-open-close.patch b/SOURCES/0448-ieee1275-Avoiding-many-unecessary-open-close.patch new file mode 100644 index 0000000..9c0679e --- /dev/null +++ b/SOURCES/0448-ieee1275-Avoiding-many-unecessary-open-close.patch @@ -0,0 +1,130 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: root +Date: Mon, 1 Mar 2021 13:35:34 -0500 +Subject: [PATCH] ieee1275: Avoiding many unecessary open/close + +This patch aims to change the grub_ofdisk_open and grub_ofdisk_close behaviors. Since some devices (Fibre Channel and NVMe) can have a long time for shutdown notification, we should avoid open and close the disks as much as we can. + +So, we are changing how those functions works. The grub_ofdisk_close will take care of just changing the disk element status, by doing a soft close, i.e, the firmware will not be called. On the other hand, the grub_ofdisk_open will take care of closing the current disk opened only if the disk requested in the current call is different from the current one. This close will be responsible to request the firmware to actually close the disk. + +Yet, this patch modifies the grub_ofdisk_get_block_size function, avoiding open and close calls inside of it. +--- + grub-core/disk/ieee1275/ofdisk.c | 76 +++++++++++++++++++++++----------------- + 1 file changed, 44 insertions(+), 32 deletions(-) + +diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c +index 6870b39587d..5fabe365eca 100644 +--- a/grub-core/disk/ieee1275/ofdisk.c ++++ b/grub-core/disk/ieee1275/ofdisk.c +@@ -385,6 +385,36 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) + + grub_dprintf ("disk", "Opening `%s'.\n", devpath); + ++ struct ofdisk_hash_ent *op; ++ op = ofdisk_hash_find (devpath); ++ if (!op) ++ op = ofdisk_hash_add (devpath, NULL); ++ else ++ grub_free (devpath); ++ if (!op) ++ return grub_errno; ++ ++ /* Check if the call to open is the same to the last disk already opened */ ++ if (last_devpath && !grub_strcmp(op->open_path,last_devpath)) ++ { ++ goto finish; ++ } ++ ++ /* If not, we need to close the previous disk and open the new one */ ++ else { ++ if (last_ihandle){ ++ grub_ieee1275_close (last_ihandle); ++ } ++ last_ihandle = 0; ++ last_devpath = NULL; ++ ++ grub_ieee1275_open (op->open_path, &last_ihandle); ++ if (! last_ihandle) ++ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); ++ last_devpath = op->open_path; ++ } ++ ++ + if (grub_ieee1275_finddevice (devpath, &dev)) + { + grub_free (devpath); +@@ -405,30 +435,28 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a block device"); + } + +- grub_uint32_t block_size = 0; +- if (grub_ofdisk_get_block_size (devpath, &block_size) == 0) +- { +- for (disk->log_sector_size = 0; +- (1U << disk->log_sector_size) < block_size; +- disk->log_sector_size++); +- } +- ++ finish: + /* XXX: There is no property to read the number of blocks. There + should be a property `#blocks', but it is not there. Perhaps it + is possible to use seek for this. */ + disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN; + + { +- struct ofdisk_hash_ent *op; +- op = ofdisk_hash_find (devpath); +- if (!op) +- op = ofdisk_hash_add (devpath, NULL); +- else +- grub_free (devpath); +- if (!op) +- return grub_errno; + disk->id = (unsigned long) op; + disk->data = op->open_path; ++ ++ grub_uint32_t block_size = 0; ++ if (grub_ofdisk_get_block_size (devpath, &block_size) == 0) ++ { ++ for (disk->log_sector_size = 0; ++ (1U << disk->log_sector_size) < block_size; ++ disk->log_sector_size++); ++ } ++ else ++ { ++ grub_free (devpath); ++ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "error getting block size"); ++ } + } + + return 0; +@@ -437,13 +465,6 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) + static void + grub_ofdisk_close (grub_disk_t disk) + { +- if (disk->data == last_devpath) +- { +- if (last_ihandle) +- grub_ieee1275_close (last_ihandle); +- last_ihandle = 0; +- last_devpath = NULL; +- } + disk->data = 0; + } + +@@ -602,15 +623,6 @@ grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size) + grub_ieee1275_cell_t size2; + } args_ieee1275; + +- if (last_ihandle) +- grub_ieee1275_close (last_ihandle); +- +- last_ihandle = 0; +- last_devpath = NULL; +- +- grub_ieee1275_open (device, &last_ihandle); +- if (! last_ihandle) +- return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); + + INIT_IEEE1275_COMMON (&args_ieee1275.common, "call-method", 2, 2); + args_ieee1275.method = (grub_ieee1275_cell_t) "block-size"; diff --git a/SOURCES/centos-ca-secureboot.der b/SOURCES/centos-ca-secureboot.der deleted file mode 100644 index 44a2563..0000000 Binary files a/SOURCES/centos-ca-secureboot.der and /dev/null differ diff --git a/SOURCES/centossecureboot001.crt b/SOURCES/centossecureboot001.crt deleted file mode 100644 index 294b05f..0000000 --- a/SOURCES/centossecureboot001.crt +++ /dev/null @@ -1,425 +0,0 @@ - - - - - - Tree - rpms/kernel - CentOS Git server - - - - - - - - - - - - - - - - -
- - -
-
-
-
-
-
-

-

-
-
-

-rpms / kernel -

-
-
-
-
-
-
- - - Clone - - - -
-
-
-
- - -
-
- -
-
- -
- -
-
- -
- -
-
-
- - -
- - Blob - - Blame - - Raw -
- -
Certificate:
-    Data:
-        Version: 3 (0x2)
-        Serial Number:
-            b6:16:15:71:72:fb:31:7e
-        Signature Algorithm: sha256WithRSAEncryption
-        Issuer: CN=CentOS Secure Boot (CA key 1)/emailAddress=security@centos.org
-        Validity
-            Not Before: Aug  1 11:47:30 2018 GMT
-            Not After : Dec 31 11:47:30 2037 GMT
-        Subject: CN=CentOS Secure Boot (key 1)/emailAddress=security@centos.org
-        Subject Public Key Info:
-            Public Key Algorithm: rsaEncryption
-            RSA Public Key: (2048 bit)
-                Modulus (2048 bit):
-                    00:c1:a3:6a:f4:2d:71:83:6c:21:ca:0c:b7:ac:fa:
-                    76:80:43:03:40:87:5d:de:e9:1e:df:ad:e7:2b:51:
-                    cb:f8:31:0f:9a:db:ab:23:25:04:11:05:57:7d:f2:
-                    4b:8d:1e:b3:75:78:1d:b9:57:8b:18:0b:bb:7e:e3:
-                    24:0f:6a:40:5f:2b:4f:03:a5:85:94:d2:f9:08:a0:
-                    bc:db:a5:ea:4f:7f:e8:7c:d1:a9:f8:f0:9c:25:18:
-                    00:14:c4:c4:35:7d:1d:4c:8a:8d:95:f8:ed:65:97:
-                    a5:a4:da:7d:cb:f0:33:3b:b7:03:94:68:47:05:57:
-                    6c:96:91:ac:14:f2:e3:f6:6d:4a:18:cf:68:8a:35:
-                    6f:8e:26:99:7f:db:c9:83:54:c2:c3:bf:ad:45:a0:
-                    aa:a0:86:5f:20:b1:86:1b:ae:b7:28:15:11:f9:65:
-                    53:5d:70:33:9b:a3:c7:b5:c8:11:ff:55:3b:e7:46:
-                    f1:6c:6b:8c:bb:f2:9f:36:23:b1:2d:23:2f:8f:4f:
-                    6c:a8:cc:ae:f5:56:9e:22:6c:0e:9a:4a:b1:bd:b2:
-                    76:15:5c:05:85:b8:5e:dc:8c:a5:c3:e0:75:51:a4:
-                    94:9b:03:2e:7b:f8:d3:b9:dd:7f:88:ce:2e:2f:28:
-                    4c:b4:92:2f:e6:e0:67:0a:d0:ff:c5:d2:79:a6:ef:
-                    94:0f
-                Exponent: 65537 (0x10001)
-        X509v3 extensions:
-            X509v3 Basic Constraints: critical
-                CA:FALSE
-            X509v3 Key Usage: 
-                Digital Signature
-            X509v3 Subject Key Identifier: 
-                F0:37:C6:EA:EC:36:D4:05:7A:52:6C:0E:C6:D5:A9:5B:32:4E:E1:29
-            X509v3 Authority Key Identifier: 
-                keyid:54:EC:81:85:89:3E:E9:1A:DB:08:F7:44:88:54:7E:8E:3F:74:3A:F3
-
-    Signature Algorithm: sha256WithRSAEncryption
-        97:97:ba:a6:0b:5b:bb:84:39:2e:ef:8b:51:9a:89:bb:65:3c:
-        dc:15:d0:5a:88:c5:af:ce:93:f5:c1:74:98:15:59:a9:38:da:
-        11:fd:46:d5:4f:23:7c:03:1f:ae:0c:70:93:94:a7:61:2f:4b:
-        2f:5f:bb:cc:8a:d7:4a:24:66:73:85:b4:19:13:fc:6a:61:4a:
-        28:1f:a2:38:f4:72:90:03:c4:3e:64:63:8b:fb:15:22:22:4e:
-        b9:43:d9:b4:3d:3a:60:c1:4d:3a:09:85:68:7a:bc:3b:f9:ef:
-        f3:f5:e9:c9:4f:80:8c:c6:e9:cb:ef:28:44:b0:5d:d4:9e:4f:
-        0f:02:9a:65:aa:98:35:b4:6f:d2:80:e3:08:ef:12:d0:17:56:
-        a6:a1:42:1e:1d:ab:e5:33:c0:fd:88:0d:40:42:81:c8:27:30:
-        17:07:57:3e:05:9d:aa:05:0e:5b:3a:79:b4:29:aa:7c:42:5a:
-        ad:43:59:fb:34:4d:dc:62:58:63:e4:fb:de:bb:fd:6c:4e:97:
-        58:f4:b9:99:4a:71:fe:7f:16:50:55:25:46:39:96:9b:88:6c:
-        75:19:33:9e:70:b3:04:82:fe:16:a8:8e:22:47:83:6d:16:77:
-        da:26:ad:31:d8:06:6d:c5:7e:46:4b:21:ab:ae:ec:2a:93:71:
-        da:7f:89:1d
------BEGIN CERTIFICATE-----
-MIIDdTCCAl2gAwIBAgIJALYWFXFy+zF+MA0GCSqGSIb3DQEBCwUAMEwxJjAkBgNV
-BAMMHUNlbnRPUyBTZWN1cmUgQm9vdCAoQ0Ega2V5IDEpMSIwIAYJKoZIhvcNAQkB
-FhNzZWN1cml0eUBjZW50b3Mub3JnMB4XDTE4MDgwMTExNDczMFoXDTM3MTIzMTEx
-NDczMFowSTEjMCEGA1UEAxMaQ2VudE9TIFNlY3VyZSBCb290IChrZXkgMSkxIjAg
-BgkqhkiG9w0BCQEWE3NlY3VyaXR5QGNlbnRvcy5vcmcwggEiMA0GCSqGSIb3DQEB
-AQUAA4IBDwAwggEKAoIBAQDBo2r0LXGDbCHKDLes+naAQwNAh13e6R7frecrUcv4
-MQ+a26sjJQQRBVd98kuNHrN1eB25V4sYC7t+4yQPakBfK08DpYWU0vkIoLzbpepP
-f+h80an48JwlGAAUxMQ1fR1Mio2V+O1ll6Wk2n3L8DM7twOUaEcFV2yWkawU8uP2
-bUoYz2iKNW+OJpl/28mDVMLDv61FoKqghl8gsYYbrrcoFRH5ZVNdcDObo8e1yBH/
-VTvnRvFsa4y78p82I7EtIy+PT2yozK71Vp4ibA6aSrG9snYVXAWFuF7cjKXD4HVR
-pJSbAy57+NO53X+Izi4vKEy0ki/m4GcK0P/F0nmm75QPAgMBAAGjXTBbMAwGA1Ud
-EwEB/wQCMAAwCwYDVR0PBAQDAgeAMB0GA1UdDgQWBBTwN8bq7DbUBXpSbA7G1alb
-Mk7hKTAfBgNVHSMEGDAWgBRU7IGFiT7pGtsI90SIVH6OP3Q68zANBgkqhkiG9w0B
-AQsFAAOCAQEAl5e6pgtbu4Q5Lu+LUZqJu2U83BXQWojFr86T9cF0mBVZqTjaEf1G
-1U8jfAMfrgxwk5SnYS9LL1+7zIrXSiRmc4W0GRP8amFKKB+iOPRykAPEPmRji/sV
-IiJOuUPZtD06YMFNOgmFaHq8O/nv8/XpyU+AjMbpy+8oRLBd1J5PDwKaZaqYNbRv
-0oDjCO8S0BdWpqFCHh2r5TPA/YgNQEKByCcwFwdXPgWdqgUOWzp5tCmqfEJarUNZ
-+zRN3GJYY+T73rv9bE6XWPS5mUpx/n8WUFUlRjmWm4hsdRkznnCzBIL+FqiOIkeD
-bRZ32iatMdgGbcV+Rkshq67sKpNx2n+JHQ==
------END CERTIFICATE-----
-
-
-
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/SOURCES/centossecureboot202.crt b/SOURCES/centossecureboot202.crt deleted file mode 100644 index fba3730..0000000 --- a/SOURCES/centossecureboot202.crt +++ /dev/null @@ -1,84 +0,0 @@ -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 93:c2:04:d8:bd:77:6b:12 - Signature Algorithm: sha256WithRSAEncryption - Issuer: CN=CentOS Secure Boot CA 2/emailAddress=security@centos.org - Validity - Not Before: Jun 9 10:37:54 2020 GMT - Not After : Jan 18 10:37:54 2038 GMT - Subject: CN=CentOS Secure Boot Signing 202/emailAddress=security@centos.org - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:d4:f0:32:4d:50:7a:c0:41:d6:61:68:59:5e:5b: - ce:65:e3:e9:7b:01:e4:53:94:c9:b7:c1:6b:b7:12: - 0b:bc:8f:d7:17:1b:c1:77:3a:08:17:ba:23:f1:bd: - 98:f0:7c:cb:96:70:2e:0e:2e:96:66:b7:9f:29:12: - 6f:ee:30:33:a1:a5:ee:f9:4b:a3:fb:52:45:d8:7e: - c2:e8:a9:20:a9:f2:2e:f4:44:b7:85:3f:34:7c:c0: - 73:1d:73:63:2f:11:a0:7d:df:e7:5a:20:b9:b9:ff: - 5d:0e:6d:90:86:1f:2e:fa:c7:b5:94:37:80:46:0d: - fb:5f:f8:26:f4:ce:2f:0d:5b:bf:e5:8d:a5:12:d7: - ba:cf:16:f2:5c:10:ae:a0:80:a8:dc:c4:6b:00:24: - f4:4b:f0:01:82:7e:4b:1c:b6:d6:ac:e1:72:32:07: - 5d:48:4a:cd:ba:5c:9c:09:72:89:b2:2e:60:f7:b7: - ed:ea:b6:0d:ae:63:f8:09:a1:8f:62:ee:09:d2:cb: - 0a:81:df:7c:72:4b:bf:bd:fb:59:24:84:1f:1d:ce: - 36:bc:4c:13:84:ca:c5:e0:81:bb:ec:61:8f:9f:78: - 88:43:8d:e0:16:b2:ab:90:14:23:29:ce:1d:e7:a1: - bb:4a:93:f9:f8:8d:b8:ff:2f:30:74:66:b2:31:89: - b1:7d - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:FALSE - X509v3 Key Usage: critical - Digital Signature - X509v3 Extended Key Usage: critical - Code Signing - X509v3 Subject Key Identifier: - 1E:55:FF:FF:01:71:5F:F1:28:7F:C8:A9:7C:AF:83:9F:ED:7A:33:0B - X509v3 Authority Key Identifier: - keyid:70:00:7F:99:20:9C:12:6B:E1:47:74:EA:EC:7B:6D:96:31:F3:4D:CA - - Signature Algorithm: sha256WithRSAEncryption - 6b:1b:fa:f3:a8:c0:1e:e7:55:49:f2:4e:16:1f:9a:1b:22:9c: - ff:c9:81:d0:5b:d6:28:3c:38:91:65:b5:ca:63:e6:9d:13:2d: - 5f:f5:cc:67:c2:82:55:73:8f:8b:0c:0c:a9:60:2a:a8:b2:19: - c1:a7:87:94:d8:69:5e:3c:88:e5:32:8a:4c:a6:6f:69:8b:c5: - f2:7e:8e:d2:af:37:2d:27:73:c7:ad:9d:bc:14:08:a8:aa:57: - 22:37:be:c6:d2:2d:a3:70:81:4a:88:8c:a3:44:89:6c:7d:9d: - 9f:db:ff:5c:c6:ec:6d:97:b0:08:8d:76:c6:14:d0:25:81:a3: - 09:b6:f2:89:32:12:b2:f2:71:71:b6:ac:c1:65:d1:9c:6b:e1: - a4:4e:74:d0:01:17:ad:38:0f:17:86:07:56:b3:a1:86:5d:99: - ef:d6:55:98:b9:ce:63:46:8b:37:c4:53:55:8b:7a:10:75:90: - fd:e6:62:f0:6c:af:89:91:17:34:f7:99:77:6d:29:fa:92:bb: - c3:45:77:fe:a3:15:da:54:7d:47:16:b6:6f:94:09:b8:5f:ca: - e9:34:a2:bf:18:cd:d3:f4:17:2c:98:e4:e4:ca:46:ad:4b:a4: - 34:77:47:ec:5d:21:a6:cf:5c:b9:5a:47:ca:04:a1:93:56:13: - 0a:cc:47:91 ------BEGIN CERTIFICATE----- -MIIDjjCCAnagAwIBAgIJAJPCBNi9d2sSMA0GCSqGSIb3DQEBCwUAMEYxIDAeBgNV -BAMMF0NlbnRPUyBTZWN1cmUgQm9vdCBDQSAyMSIwIAYJKoZIhvcNAQkBFhNzZWN1 -cml0eUBjZW50b3Mub3JnMB4XDTIwMDYwOTEwMzc1NFoXDTM4MDExODEwMzc1NFow -TTEnMCUGA1UEAwweQ2VudE9TIFNlY3VyZSBCb290IFNpZ25pbmcgMjAyMSIwIAYJ -KoZIhvcNAQkBFhNzZWN1cml0eUBjZW50b3Mub3JnMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEA1PAyTVB6wEHWYWhZXlvOZePpewHkU5TJt8FrtxILvI/X -FxvBdzoIF7oj8b2Y8HzLlnAuDi6WZrefKRJv7jAzoaXu+Uuj+1JF2H7C6KkgqfIu -9ES3hT80fMBzHXNjLxGgfd/nWiC5uf9dDm2Qhh8u+se1lDeARg37X/gm9M4vDVu/ -5Y2lEte6zxbyXBCuoICo3MRrACT0S/ABgn5LHLbWrOFyMgddSErNulycCXKJsi5g -97ft6rYNrmP4CaGPYu4J0ssKgd98cku/vftZJIQfHc42vEwThMrF4IG77GGPn3iI -Q43gFrKrkBQjKc4d56G7SpP5+I24/y8wdGayMYmxfQIDAQABo3gwdjAMBgNVHRMB -Af8EAjAAMA4GA1UdDwEB/wQEAwIHgDAWBgNVHSUBAf8EDDAKBggrBgEFBQcDAzAd -BgNVHQ4EFgQUHlX//wFxX/Eof8ipfK+Dn+16MwswHwYDVR0jBBgwFoAUcAB/mSCc -EmvhR3Tq7HttljHzTcowDQYJKoZIhvcNAQELBQADggEBAGsb+vOowB7nVUnyThYf -mhsinP/JgdBb1ig8OJFltcpj5p0TLV/1zGfCglVzj4sMDKlgKqiyGcGnh5TYaV48 -iOUyikymb2mLxfJ+jtKvNy0nc8etnbwUCKiqVyI3vsbSLaNwgUqIjKNEiWx9nZ/b -/1zG7G2XsAiNdsYU0CWBowm28okyErLycXG2rMFl0Zxr4aROdNABF604DxeGB1az -oYZdme/WVZi5zmNGizfEU1WLehB1kP3mYvBsr4mRFzT3mXdtKfqSu8NFd/6jFdpU -fUcWtm+UCbhfyuk0or8YzdP0FyyY5OTKRq1LpDR3R+xdIabPXLlaR8oEoZNWEwrM -R5E= ------END CERTIFICATE----- diff --git a/SOURCES/centossecurebootca2.crt b/SOURCES/centossecurebootca2.crt deleted file mode 100644 index ff4e981..0000000 --- a/SOURCES/centossecurebootca2.crt +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDYjCCAkqgAwIBAgIJAIlReu6IOzL7MA0GCSqGSIb3DQEBCwUAMEYxIDAeBgNV -BAMMF0NlbnRPUyBTZWN1cmUgQm9vdCBDQSAyMSIwIAYJKoZIhvcNAQkBFhNzZWN1 -cml0eUBjZW50b3Mub3JnMB4XDTIwMDYwOTA4MTkzMloXDTM4MDExODA4MTkzMlow -RjEgMB4GA1UEAwwXQ2VudE9TIFNlY3VyZSBCb290IENBIDIxIjAgBgkqhkiG9w0B -CQEWE3NlY3VyaXR5QGNlbnRvcy5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQChatbNaQDV0RTCqff1tl92xI6gu1k8jYufW8FyzZ6uDnxoGpBT0LiU -WKuGjMQ89JgiApFzDYSLWrZg8NbTnVdz0hny4SMyspe5weUk6IToKXvEejZNFn6i -vae2vfT0/ASKsgIvUcz4sWHMK43vbfv/pVpYGLgoG5aNUkt7VhkeURwJzR3ODgDp -aL4bQ/7qEo8ASHCEvQx6klG330Z06O0kjS6GK12cPC1t5ZlimVXCNWP1jf0pMWmh -aBrZjbyY0j8R7Yns3cEovAM230chsVdyFxSYpqCLzMlmWNxiIlvcAoDIRMWEa7Da -SSAfJWH+ygAzad1PHlnCB0zAFbLAMJH1AgMBAAGjUzBRMB0GA1UdDgQWBBRwAH+Z -IJwSa+FHdOrse22WMfNNyjAfBgNVHSMEGDAWgBRwAH+ZIJwSa+FHdOrse22WMfNN -yjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAe5NcVSUd/POZs -Jkiep8ATNwXglLAeYxB55F42sXx5OOdKMBmhqWQIVJvaih/wsfKIBfdUGv2L9dH8 -IQgiU1PRYx0baSVJno3HcQTbCqLvnvckusR7IUTDAFj774MvXwS6yV6pXzxDmuh2 -t8hRktOKFeUtdlDYqg9X3Ia3GkoB5huyEbuaZTNcV4TAfU/yAERNIAgRs+fLQU70 -OgGlWsp35J8qPkZKabGf0surDa2xa6iAoFyknxruoKQ8uNSB9KB7/0JvVouNx90+ -ncykWW96GVKs8+H5WGza10FqrchtThSNCSXTtLbTXoK0Atdvu0o04XUbsCGMnlcG -zAVb3/m0 ------END CERTIFICATE----- diff --git a/SOURCES/grub.macros b/SOURCES/grub.macros index 22b26cc..0dade27 100644 --- a/SOURCES/grub.macros +++ b/SOURCES/grub.macros @@ -78,7 +78,7 @@ %ifarch aarch64 %{arm} %global efi_modules " http linux " %else -%global efi_modules " backtrace http linuxefi usb usbserial_common usbserial_pl2303 usbserial_ftdi usbserial_usbdebug " +%global efi_modules " backtrace http linuxefi usb usbserial_common usbserial_pl2303 usbserial_ftdi usbserial_usbdebug keylayouts at_keyboard " %endif %ifarch x86_64 @@ -101,6 +101,16 @@ -e 's/-m64//g' \\\ ) %{nil} %endif +%ifarch %{ix86} +%global target_cpu_name %{_arch} +%global grub_target_name %{_arch}-pc + +%global legacy_target_cpu_name i386 +%global legacy_package_arch pc +%global platform pc + +%global with_legacy_arch 0 +%endif %ifarch aarch64 %global efiarch aa64 @@ -152,6 +162,14 @@ %global with_efi_common 1 %global with_legacy_common 0 %endif +%ifarch %{ix86} +%global with_efi_arch 0 +%global with_alt_efi_arch 0 +%global with_efi_common 0 +%global with_legacy_common 1 +%global with_legacy_utils 1 +%global with_legacy_arch 0 +%endif %if 0%{with_efi_common} %global common_srcdir grub-%{grubefiarch}-%{tarversion} @@ -331,7 +349,7 @@ GRUB_MODULES=" all_video boot btrfs cat chain configfile echo \\\ gzio halt hfsplus iso9660 jpeg loadenv loopback \\\ lvm mdraid09 mdraid1x minicmd normal part_apple \\\ part_msdos part_gpt password_pbkdf2 png reboot \\\ - search search_fs_uuid search_fs_file \\\ + regexp search search_fs_uuid search_fs_file \\\ search_label serial sleep syslinuxcfg test tftp \\\ video xfs" \ GRUB_MODULES+=%{efi_modules} \ diff --git a/SOURCES/grub.patches b/SOURCES/grub.patches index 4630461..e039536 100644 --- a/SOURCES/grub.patches +++ b/SOURCES/grub.patches @@ -332,112 +332,117 @@ Patch0331: 0331-efilinux-Fix-integer-overflows-in-grub_cmd_initrd.patch Patch0332: 0332-linux-loader-avoid-overflow-on-initrd-size-calculati.patch Patch0333: 0333-linuxefi-fail-kernel-validation-without-shim-protoco.patch Patch0334: 0334-linux-Fix-integer-overflows-in-initrd-size-handling.patch -Patch0335: 0335-tftp-roll-over-block-counter-to-prevent-timeouts-with.patch -Patch0336: 0336-at_keyboard-Fix-keyboards-that-report-IBM-PC-AT-scan.patch -Patch0337: 0337-kern-Add-lockdown-support.patch -Patch0338: 0338-kern-lockdown-Set-a-variable-if-the-GRUB-is-locked-d.patch -Patch0339: 0339-efi-Lockdown-the-GRUB-when-the-UEFI-Secure-Boot-is-e.patch -Patch0340: 0340-efi-Use-grub_is_lockdown-instead-of-hardcoding-a-dis.patch -Patch0341: 0341-acpi-Don-t-register-the-acpi-command-when-locked-dow.patch -Patch0342: 0342-mmap-Don-t-register-cutmem-and-badram-commands-when-.patch -Patch0343: 0343-commands-Restrict-commands-that-can-load-BIOS-or-DT-.patch -Patch0344: 0344-commands-setpci-Restrict-setpci-command-when-locked-.patch -Patch0345: 0345-commands-hdparm-Restrict-hdparm-command-when-locked-.patch -Patch0346: 0346-gdb-Restrict-GDB-access-when-locked-down.patch -Patch0347: 0347-loader-xnu-Don-t-allow-loading-extension-and-package.patch -Patch0348: 0348-docs-Document-the-cutmem-command.patch -Patch0349: 0349-dl-Only-allow-unloading-modules-that-are-not-depende.patch -Patch0350: 0350-usb-Avoid-possible-out-of-bound-accesses-caused-by-m.patch -Patch0351: 0351-mmap-Fix-memory-leak-when-iterating-over-mapped-memo.patch -Patch0352: 0352-net-net-Fix-possible-dereference-to-of-a-NULL-pointe.patch -Patch0353: 0353-net-tftp-Fix-dangling-memory-pointer.patch -Patch0354: 0354-kern-parser-Fix-resource-leak-if-argc-0.patch -Patch0355: 0355-kern-efi-Fix-memory-leak-on-failure.patch -Patch0356: 0356-kern-efi-mm-Fix-possible-NULL-pointer-dereference.patch -Patch0357: 0357-gnulib-regexec-Resolve-unused-variable.patch -Patch0358: 0358-gnulib-regcomp-Fix-uninitialized-token-structure.patch -Patch0359: 0359-gnulib-argp-help-Fix-dereference-of-a-possibly-NULL-.patch -Patch0360: 0360-gnulib-regexec-Fix-possible-null-dereference.patch -Patch0361: 0361-gnulib-regcomp-Fix-uninitialized-re_token.patch -Patch0362: 0362-io-lzopio-Resolve-unnecessary-self-assignment-errors.patch -Patch0363: 0363-kern-partition-Check-for-NULL-before-dereferencing-i.patch -Patch0364: 0364-disk-ldm-Make-sure-comp-data-is-freed-before-exiting.patch -Patch0365: 0365-disk-ldm-If-failed-then-free-vg-variable-too.patch -Patch0366: 0366-disk-ldm-Fix-memory-leak-on-uninserted-lv-references.patch -Patch0367: 0367-disk-cryptodisk-Fix-potential-integer-overflow.patch -Patch0368: 0368-hfsplus-Check-that-the-volume-name-length-is-valid.patch -Patch0369: 0369-zfs-Fix-possible-negative-shift-operation.patch -Patch0370: 0370-zfs-Fix-resource-leaks-while-constructing-path.patch -Patch0371: 0371-zfs-Fix-possible-integer-overflows.patch -Patch0372: 0372-zfsinfo-Correct-a-check-for-error-allocating-memory.patch -Patch0373: 0373-affs-Fix-memory-leaks.patch -Patch0374: 0374-libgcrypt-mpi-Fix-possible-unintended-sign-extension.patch -Patch0375: 0375-libgcrypt-mpi-Fix-possible-NULL-dereference.patch -Patch0376: 0376-syslinux-Fix-memory-leak-while-parsing.patch -Patch0377: 0377-normal-completion-Fix-leaking-of-memory-when-process.patch -Patch0378: 0378-commands-hashsum-Fix-a-memory-leak.patch -Patch0379: 0379-video-efi_gop-Remove-unnecessary-return-value-of-gru.patch -Patch0380: 0380-video-fb-fbfill-Fix-potential-integer-overflow.patch -Patch0381: 0381-video-fb-video_fb-Fix-multiple-integer-overflows.patch -Patch0382: 0382-video-fb-video_fb-Fix-possible-integer-overflow.patch -Patch0383: 0383-video-readers-jpeg-Test-for-an-invalid-next-marker-r.patch -Patch0384: 0384-gfxmenu-gui_list-Remove-code-that-coverity-is-flaggi.patch -Patch0385: 0385-loader-bsd-Check-for-NULL-arg-up-front.patch -Patch0386: 0386-loader-xnu-Free-driverkey-data-when-an-error-is-dete.patch -Patch0387: 0387-loader-xnu-Check-if-pointer-is-NULL-before-using-it.patch -Patch0388: 0388-util-grub-editenv-Fix-incorrect-casting-of-a-signed-.patch -Patch0389: 0389-util-glue-efi-Fix-incorrect-use-of-a-possibly-negati.patch -Patch0390: 0390-script-execute-Fix-NULL-dereference-in-grub_script_e.patch -Patch0391: 0391-commands-ls-Require-device_name-is-not-NULL-before-p.patch -Patch0392: 0392-script-execute-Avoid-crash-when-using-outside-a-func.patch -Patch0393: 0393-lib-arg-Block-repeated-short-options-that-require-an.patch -Patch0394: 0394-script-execute-Don-t-crash-on-a-for-loop-with-no-ite.patch -Patch0395: 0395-commands-menuentry-Fix-quoting-in-setparams_prefix.patch -Patch0396: 0396-kern-misc-Always-set-end-in-grub_strtoull.patch -Patch0397: 0397-video-readers-jpeg-Catch-files-with-unsupported-quan.patch -Patch0398: 0398-video-readers-jpeg-Catch-OOB-reads-writes-in-grub_jp.patch -Patch0399: 0399-video-readers-jpeg-Don-t-decode-data-before-start-of.patch -Patch0400: 0400-term-gfxterm-Don-t-set-up-a-font-with-glyphs-that-ar.patch -Patch0401: 0401-fs-fshelp-Catch-impermissibly-large-block-sizes-in-r.patch -Patch0402: 0402-fs-hfsplus-Don-t-fetch-a-key-beyond-the-end-of-the-n.patch -Patch0403: 0403-fs-hfsplus-Don-t-use-uninitialized-data-on-corrupt-f.patch -Patch0404: 0404-fs-hfs-Disable-under-lockdown.patch -Patch0405: 0405-fs-sfs-Fix-over-read-of-root-object-name.patch -Patch0406: 0406-fs-jfs-Do-not-move-to-leaf-level-if-name-length-is-n.patch -Patch0407: 0407-fs-jfs-Limit-the-extents-that-getblk-can-consider.patch -Patch0408: 0408-fs-jfs-Catch-infinite-recursion.patch -Patch0409: 0409-fs-nilfs2-Reject-too-large-keys.patch -Patch0410: 0410-fs-nilfs2-Don-t-search-children-if-provided-number-i.patch -Patch0411: 0411-fs-nilfs2-Properly-bail-on-errors-in-grub_nilfs2_btr.patch -Patch0412: 0412-io-gzio-Bail-if-gzio-tl-td-is-NULL.patch -Patch0413: 0413-io-gzio-Add-init_dynamic_block-clean-up-if-unpacking.patch -Patch0414: 0414-io-gzio-Catch-missing-values-in-huft_build-and-bail.patch -Patch0415: 0415-io-gzio-Zero-gzio-tl-td-in-init_dynamic_block-if-huf.patch -Patch0416: 0416-disk-lvm-Don-t-go-beyond-the-end-of-the-data-we-read.patch -Patch0417: 0417-disk-lvm-Don-t-blast-past-the-end-of-the-circular-me.patch -Patch0418: 0418-disk-lvm-Bail-on-missing-PV-list.patch -Patch0419: 0419-disk-lvm-Do-not-crash-if-an-expected-string-is-not-f.patch -Patch0420: 0420-disk-lvm-Do-not-overread-metadata.patch -Patch0421: 0421-disk-lvm-Sanitize-rlocn-offset-to-prevent-wild-read.patch -Patch0422: 0422-disk-lvm-Do-not-allow-a-LV-to-be-it-s-own-segment-s-.patch -Patch0423: 0423-kern-parser-Fix-a-memory-leak.patch -Patch0424: 0424-kern-parser-Introduce-process_char-helper.patch -Patch0425: 0425-kern-parser-Introduce-terminate_arg-helper.patch -Patch0426: 0426-kern-parser-Refactor-grub_parser_split_cmdline-clean.patch -Patch0427: 0427-kern-buffer-Add-variable-sized-heap-buffer.patch -Patch0428: 0428-kern-parser-Fix-a-stack-buffer-overflow.patch -Patch0429: 0429-kern-efi-Add-initial-stack-protector-implementation.patch -Patch0430: 0430-util-mkimage-Remove-unused-code-to-add-BSS-section.patch -Patch0431: 0431-util-mkimage-Use-grub_host_to_target32-instead-of-gr.patch -Patch0432: 0432-util-mkimage-Always-use-grub_host_to_target32-to-ini.patch -Patch0433: 0433-util-mkimage-Unify-more-of-the-PE32-and-PE32-header-.patch -Patch0434: 0434-util-mkimage-Reorder-PE-optional-header-fields-set-u.patch -Patch0435: 0435-util-mkimage-Improve-data_size-value-calculation.patch -Patch0436: 0436-util-mkimage-Refactor-section-setup-to-use-a-helper.patch -Patch0437: 0437-util-mkimage-Add-an-option-to-import-SBAT-metadata-i.patch -Patch0438: 0438-kern-misc-Split-parse_printf_args-into-format-parsin.patch -Patch0439: 0439-kern-misc-Add-STRING-type-for-internal-printf-format.patch -Patch0440: 0440-kern-misc-Add-function-to-check-printf-format-agains.patch -Patch0441: 0441-gfxmenu-gui-Check-printf-format-in-the-gui_progress_.patch -Patch0442: 0442-kern-mm-Fix-grub_debug_calloc-compilation-error.patch -Patch0443: 0443-efi-net-Fix-malformed-device-path-arithmetic-errors-.patch +Patch0335: 0335-tftp-roll-over-block-counter-to-prevent-timeouts-wit.patch +Patch0336: 0336-kern-Add-lockdown-support.patch +Patch0337: 0337-kern-lockdown-Set-a-variable-if-the-GRUB-is-locked-d.patch +Patch0338: 0338-efi-Lockdown-the-GRUB-when-the-UEFI-Secure-Boot-is-e.patch +Patch0339: 0339-efi-Use-grub_is_lockdown-instead-of-hardcoding-a-dis.patch +Patch0340: 0340-acpi-Don-t-register-the-acpi-command-when-locked-dow.patch +Patch0341: 0341-mmap-Don-t-register-cutmem-and-badram-commands-when-.patch +Patch0342: 0342-commands-Restrict-commands-that-can-load-BIOS-or-DT-.patch +Patch0343: 0343-commands-setpci-Restrict-setpci-command-when-locked-.patch +Patch0344: 0344-commands-hdparm-Restrict-hdparm-command-when-locked-.patch +Patch0345: 0345-gdb-Restrict-GDB-access-when-locked-down.patch +Patch0346: 0346-loader-xnu-Don-t-allow-loading-extension-and-package.patch +Patch0347: 0347-docs-Document-the-cutmem-command.patch +Patch0348: 0348-dl-Only-allow-unloading-modules-that-are-not-depende.patch +Patch0349: 0349-usb-Avoid-possible-out-of-bound-accesses-caused-by-m.patch +Patch0350: 0350-mmap-Fix-memory-leak-when-iterating-over-mapped-memo.patch +Patch0351: 0351-net-net-Fix-possible-dereference-to-of-a-NULL-pointe.patch +Patch0352: 0352-net-tftp-Fix-dangling-memory-pointer.patch +Patch0353: 0353-kern-parser-Fix-resource-leak-if-argc-0.patch +Patch0354: 0354-kern-efi-Fix-memory-leak-on-failure.patch +Patch0355: 0355-kern-efi-mm-Fix-possible-NULL-pointer-dereference.patch +Patch0356: 0356-gnulib-regexec-Resolve-unused-variable.patch +Patch0357: 0357-gnulib-regcomp-Fix-uninitialized-token-structure.patch +Patch0358: 0358-gnulib-argp-help-Fix-dereference-of-a-possibly-NULL-.patch +Patch0359: 0359-gnulib-regexec-Fix-possible-null-dereference.patch +Patch0360: 0360-gnulib-regcomp-Fix-uninitialized-re_token.patch +Patch0361: 0361-io-lzopio-Resolve-unnecessary-self-assignment-errors.patch +Patch0362: 0362-kern-partition-Check-for-NULL-before-dereferencing-i.patch +Patch0363: 0363-disk-ldm-Make-sure-comp-data-is-freed-before-exiting.patch +Patch0364: 0364-disk-ldm-If-failed-then-free-vg-variable-too.patch +Patch0365: 0365-disk-ldm-Fix-memory-leak-on-uninserted-lv-references.patch +Patch0366: 0366-disk-cryptodisk-Fix-potential-integer-overflow.patch +Patch0367: 0367-hfsplus-Check-that-the-volume-name-length-is-valid.patch +Patch0368: 0368-zfs-Fix-possible-negative-shift-operation.patch +Patch0369: 0369-zfs-Fix-resource-leaks-while-constructing-path.patch +Patch0370: 0370-zfs-Fix-possible-integer-overflows.patch +Patch0371: 0371-zfsinfo-Correct-a-check-for-error-allocating-memory.patch +Patch0372: 0372-affs-Fix-memory-leaks.patch +Patch0373: 0373-libgcrypt-mpi-Fix-possible-unintended-sign-extension.patch +Patch0374: 0374-libgcrypt-mpi-Fix-possible-NULL-dereference.patch +Patch0375: 0375-syslinux-Fix-memory-leak-while-parsing.patch +Patch0376: 0376-normal-completion-Fix-leaking-of-memory-when-process.patch +Patch0377: 0377-commands-hashsum-Fix-a-memory-leak.patch +Patch0378: 0378-video-efi_gop-Remove-unnecessary-return-value-of-gru.patch +Patch0379: 0379-video-fb-fbfill-Fix-potential-integer-overflow.patch +Patch0380: 0380-video-fb-video_fb-Fix-multiple-integer-overflows.patch +Patch0381: 0381-video-fb-video_fb-Fix-possible-integer-overflow.patch +Patch0382: 0382-video-readers-jpeg-Test-for-an-invalid-next-marker-r.patch +Patch0383: 0383-gfxmenu-gui_list-Remove-code-that-coverity-is-flaggi.patch +Patch0384: 0384-loader-bsd-Check-for-NULL-arg-up-front.patch +Patch0385: 0385-loader-xnu-Free-driverkey-data-when-an-error-is-dete.patch +Patch0386: 0386-loader-xnu-Check-if-pointer-is-NULL-before-using-it.patch +Patch0387: 0387-util-grub-editenv-Fix-incorrect-casting-of-a-signed-.patch +Patch0388: 0388-util-glue-efi-Fix-incorrect-use-of-a-possibly-negati.patch +Patch0389: 0389-script-execute-Fix-NULL-dereference-in-grub_script_e.patch +Patch0390: 0390-commands-ls-Require-device_name-is-not-NULL-before-p.patch +Patch0391: 0391-script-execute-Avoid-crash-when-using-outside-a-func.patch +Patch0392: 0392-lib-arg-Block-repeated-short-options-that-require-an.patch +Patch0393: 0393-script-execute-Don-t-crash-on-a-for-loop-with-no-ite.patch +Patch0394: 0394-commands-menuentry-Fix-quoting-in-setparams_prefix.patch +Patch0395: 0395-kern-misc-Always-set-end-in-grub_strtoull.patch +Patch0396: 0396-video-readers-jpeg-Catch-files-with-unsupported-quan.patch +Patch0397: 0397-video-readers-jpeg-Catch-OOB-reads-writes-in-grub_jp.patch +Patch0398: 0398-video-readers-jpeg-Don-t-decode-data-before-start-of.patch +Patch0399: 0399-term-gfxterm-Don-t-set-up-a-font-with-glyphs-that-ar.patch +Patch0400: 0400-fs-fshelp-Catch-impermissibly-large-block-sizes-in-r.patch +Patch0401: 0401-fs-hfsplus-Don-t-fetch-a-key-beyond-the-end-of-the-n.patch +Patch0402: 0402-fs-hfsplus-Don-t-use-uninitialized-data-on-corrupt-f.patch +Patch0403: 0403-fs-hfs-Disable-under-lockdown.patch +Patch0404: 0404-fs-sfs-Fix-over-read-of-root-object-name.patch +Patch0405: 0405-fs-jfs-Do-not-move-to-leaf-level-if-name-length-is-n.patch +Patch0406: 0406-fs-jfs-Limit-the-extents-that-getblk-can-consider.patch +Patch0407: 0407-fs-jfs-Catch-infinite-recursion.patch +Patch0408: 0408-fs-nilfs2-Reject-too-large-keys.patch +Patch0409: 0409-fs-nilfs2-Don-t-search-children-if-provided-number-i.patch +Patch0410: 0410-fs-nilfs2-Properly-bail-on-errors-in-grub_nilfs2_btr.patch +Patch0411: 0411-io-gzio-Bail-if-gzio-tl-td-is-NULL.patch +Patch0412: 0412-io-gzio-Add-init_dynamic_block-clean-up-if-unpacking.patch +Patch0413: 0413-io-gzio-Catch-missing-values-in-huft_build-and-bail.patch +Patch0414: 0414-io-gzio-Zero-gzio-tl-td-in-init_dynamic_block-if-huf.patch +Patch0415: 0415-disk-lvm-Don-t-go-beyond-the-end-of-the-data-we-read.patch +Patch0416: 0416-disk-lvm-Don-t-blast-past-the-end-of-the-circular-me.patch +Patch0417: 0417-disk-lvm-Bail-on-missing-PV-list.patch +Patch0418: 0418-disk-lvm-Do-not-crash-if-an-expected-string-is-not-f.patch +Patch0419: 0419-disk-lvm-Do-not-overread-metadata.patch +Patch0420: 0420-disk-lvm-Sanitize-rlocn-offset-to-prevent-wild-read.patch +Patch0421: 0421-disk-lvm-Do-not-allow-a-LV-to-be-it-s-own-segment-s-.patch +Patch0422: 0422-kern-parser-Fix-a-memory-leak.patch +Patch0423: 0423-kern-parser-Introduce-process_char-helper.patch +Patch0424: 0424-kern-parser-Introduce-terminate_arg-helper.patch +Patch0425: 0425-kern-parser-Refactor-grub_parser_split_cmdline-clean.patch +Patch0426: 0426-kern-buffer-Add-variable-sized-heap-buffer.patch +Patch0427: 0427-kern-parser-Fix-a-stack-buffer-overflow.patch +Patch0428: 0428-kern-efi-Add-initial-stack-protector-implementation.patch +Patch0429: 0429-util-mkimage-Remove-unused-code-to-add-BSS-section.patch +Patch0430: 0430-util-mkimage-Use-grub_host_to_target32-instead-of-gr.patch +Patch0431: 0431-util-mkimage-Always-use-grub_host_to_target32-to-ini.patch +Patch0432: 0432-util-mkimage-Unify-more-of-the-PE32-and-PE32-header-.patch +Patch0433: 0433-util-mkimage-Reorder-PE-optional-header-fields-set-u.patch +Patch0434: 0434-util-mkimage-Improve-data_size-value-calculation.patch +Patch0435: 0435-util-mkimage-Refactor-section-setup-to-use-a-helper.patch +Patch0436: 0436-util-mkimage-Add-an-option-to-import-SBAT-metadata-i.patch +Patch0437: 0437-kern-misc-Split-parse_printf_args-into-format-parsin.patch +Patch0438: 0438-kern-misc-Add-STRING-type-for-internal-printf-format.patch +Patch0439: 0439-kern-misc-Add-function-to-check-printf-format-agains.patch +Patch0440: 0440-gfxmenu-gui-Check-printf-format-in-the-gui_progress_.patch +Patch0441: 0441-kern-mm-Fix-grub_debug_calloc-compilation-error.patch +Patch0442: 0442-efi-net-Fix-malformed-device-path-arithmetic-errors-.patch +Patch0443: 0443-grub-core-term-at_keyboard.c-Retry-probing-keyboard-.patch +Patch0444: 0444-at_keyboard-use-set-1-when-keyboard-is-in-Translate-.patch +Patch0445: 0445-Add-at_keyboard_fallback_set-var-to-force-the-set-ma.patch +Patch0446: 0446-ieee1275-powerpc-implements-fibre-channel-discovery-.patch +Patch0447: 0447-ieee1275-powerpc-enables-device-mapper-discovery.patch +Patch0448: 0448-ieee1275-Avoiding-many-unecessary-open-close.patch diff --git a/SPECS/grub2.spec b/SPECS/grub2.spec index 3c1e490..bd61888 100644 --- a/SPECS/grub2.spec +++ b/SPECS/grub2.spec @@ -1,22 +1,12 @@ %undefine _hardened_build -%global flagday 1:2.02-0.86.el7.centos + %global tarversion 2.02~beta2 %undefine _missing_build_ids_terminate_build -%ifarch i686 -%define platform pc -%define legacy_package_arch i386 -%define legacy_target_cpu_name i386 -%define target_cpu_name i386 -%endif -%ifarch x86_64 -%define mock 1 -%endif - Name: grub2 Epoch: 1 Version: 2.02 -Release: 0.87%{?dist}%{?buildid}.2 +Release: 0.87%{?dist}%{?buildid}.6 Summary: Bootloader with support for Linux, Multiboot and more Group: System Environment/Base License: GPLv3+ @@ -27,10 +17,10 @@ Source1: grub.macros Source2: grub.patches Source3: http://unifoundry.com/unifont-5.1.20080820.pcf.gz Source4: gitignore -Source5: centos-ca-secureboot.der -Source6: centossecureboot001.crt -Source7: centossecurebootca2.crt -Source8: centossecureboot202.crt +Source5: redhatsecurebootca3.cer +Source6: redhatsecureboot301.cer +Source7: redhatsecurebootca5.cer +Source8: redhatsecureboot502.cer Source9: sbat.csv.in %include %{SOURCE1} @@ -64,11 +54,8 @@ BuildRequires: pesign >= 0.99-8 %if %{?_with_ccache: 1}%{?!_with_ccache: 0} BuildRequires: ccache %endif -%if 0%{?centos} -%global efidir centos -%endif -ExcludeArch: s390 s390x %{arm} +ExcludeArch: s390 s390x %{arm} %{?ix86} Obsoletes: %{name} <= %{flagday} %if 0%{with_legacy_arch} @@ -153,10 +140,6 @@ This subpackage provides tools for support of all platforms. %prep %setup -T -c -n grub-%{tarversion} %do_common_setup -sed -i.orig -e 's@/efi/EFI/redhat/@/efi/EFI/%{efidir}/@' \ - grub-%{tarversion}/util/grub-setpassword.in -touch --reference=grub-%{tarversion}/util/grub-setpassword.in.orig \ - grub-%{tarversion}/util/grub-setpassword.in %if 0%{with_efi_arch} %do_setup %{grubefiarch} sed -e "s,@@VERSION@@,%{evr},g" %{SOURCE9} \ @@ -171,10 +154,10 @@ sed -e "s,@@VERSION@@,%{evr},g" %{SOURCE9} \ %build %if 0%{with_efi_arch} -%do_primary_efi_build %{grubefiarch} %{grubefiname} %{grubeficdname} %{_target_platform} "'%{efi_cflags}'" %{SOURCE5} %{SOURCE6} centossecureboot001 %{SOURCE7} %{SOURCE8} centossecureboot202 +%do_primary_efi_build %{grubefiarch} %{grubefiname} %{grubeficdname} %{_target_platform} "'%{efi_cflags}'" %{SOURCE5} %{SOURCE6} redhatsecureboot301 %{SOURCE7} %{SOURCE8} redhatsecureboot502 %endif %if 0%{with_alt_efi_arch} -%do_alt_efi_build %{grubaltefiarch} %{grubaltefiname} %{grubalteficdname} %{_alt_target_platform} "'%{alt_efi_cflags}'" %{SOURCE5} %{SOURCE6} centossecureboot001 %{SOURCE7} %{SOURCE8} centossecureboot202 +%do_alt_efi_build %{grubaltefiarch} %{grubaltefiname} %{grubalteficdname} %{_alt_target_platform} "'%{alt_efi_cflags}'" %{SOURCE5} %{SOURCE6} redhatsecureboot301 %{SOURCE7} %{SOURCE8} redhatsecureboot502 %endif %if 0%{with_legacy_arch}%{with_legacy_utils} %do_legacy_build %{grublegacyarch} @@ -486,6 +469,22 @@ fi %endif %changelog +* Fri Mar 05 2021 Javier Martinez Canillas - 2.02-0.87.e7.6 +- Fix ppc64le performance issues (diegodo) + Resolves: rhbz#1759298 + +* Thu Mar 04 2021 Javier Martinez Canillas - 2.02-0.87.e7.5 +- Add the at keyboard patches that weren't included + Resolves: rhbz#1892240 + +* Thu Mar 04 2021 Javier Martinez Canillas - 2.02-0.87.e7.4 +- add keylayouts and at_keyboard modules to EFI binary + Resolves: rhbz#1892240 + +* Wed Mar 03 2021 Javier Martinez Canillas - 2.02-0.87.e7.3 +- at_keyboard: use set 1 when keyboard is in Translate mode (rmetrich) + Resolves: rhbz#1892240 + * Fri Feb 26 2021 Javier Martinez Canillas - 2.02-0.87.e7.2 - Fix another batch of CVEs Resolves: CVE-2020-14372