* [dunfell][PATCH 1/2] gdk-pixbuf: fix CVE-2021-20240 @ 2021-09-05 22:58 Armin Kuster 2021-09-05 22:58 ` [dunfell][PATCH 2/2] grub2: Several cve fixes Armin Kuster 0 siblings, 1 reply; 4+ messages in thread From: Armin Kuster @ 2021-09-05 22:58 UTC (permalink / raw) To: openembedded-core; +Cc: Changqing Li, Anuj Mittal, Richard Purdie, Armin Kuster From: Changqing Li <changqing.li@windriver.com> Source: https://git.openembedded.org/openembedded-core MR: 111543 Type: Security Fix Disposition: Backport from https://git.openembedded.org/openembedded-core/commit/meta/recipes-gnome/gdk-pixbuf?h=hardknott&id=bd08e4d179979937604c196b4047f59c5499a960 ChangeID: bd08e4d179979937604c196b4047f59c5499a960 Description: (From OE-Core rev: bd08e4d179979937604c196b4047f59c5499a960) Signed-off-by: Changqing Li <changqing.li@windriver.com> Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> (cherry picked from commit de631334ccd2d6af74ed795228394ee2b7218403) Signed-off-by: Armin Kuster <akuster@mvista.com> --- .../gdk-pixbuf/CVE-2021-20240.patch | 40 +++++++++++++++++++ .../gdk-pixbuf/gdk-pixbuf_2.40.0.bb | 1 + 2 files changed, 41 insertions(+) create mode 100644 meta/recipes-gnome/gdk-pixbuf/gdk-pixbuf/CVE-2021-20240.patch diff --git a/meta/recipes-gnome/gdk-pixbuf/gdk-pixbuf/CVE-2021-20240.patch b/meta/recipes-gnome/gdk-pixbuf/gdk-pixbuf/CVE-2021-20240.patch new file mode 100644 index 0000000000..fe594b24bb --- /dev/null +++ b/meta/recipes-gnome/gdk-pixbuf/gdk-pixbuf/CVE-2021-20240.patch @@ -0,0 +1,40 @@ +From 086e8adf4cc352cd11572f96066b001b545f354e Mon Sep 17 00:00:00 2001 +From: Emmanuele Bassi <ebassi@gnome.org> +Date: Wed, 1 Apr 2020 18:11:55 +0100 +Subject: [PATCH] Check the memset length argument + +Avoid overflows by using the checked multiplication macro for gsize. + +Fixes: #132 + +Upstream-Status: Backported [https://gitlab.gnome.org/GNOME/gdk-pixbuf/-/commit/086e8adf4cc352cd11572f96066b001b545f354e] +CVE: CVE-2021-20240 + +Signed-off-by: Changqing Li <changqing.li@windriver.com> +--- + gdk-pixbuf/io-gif-animation.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/gdk-pixbuf/io-gif-animation.c b/gdk-pixbuf/io-gif-animation.c +index c9db3c66e..49674fd2e 100644 +--- a/gdk-pixbuf/io-gif-animation.c ++++ b/gdk-pixbuf/io-gif-animation.c +@@ -412,11 +412,15 @@ gdk_pixbuf_gif_anim_iter_get_pixbuf (GdkPixbufAnimationIter *anim_iter) + + /* If no rendered frame, render the first frame */ + if (anim->last_frame == NULL) { ++ gsize len = 0; + if (anim->last_frame_data == NULL) + anim->last_frame_data = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, anim->width, anim->height); + if (anim->last_frame_data == NULL) + return NULL; +- memset (gdk_pixbuf_get_pixels (anim->last_frame_data), 0, gdk_pixbuf_get_rowstride (anim->last_frame_data) * anim->height); ++ if (g_size_checked_mul (&len, gdk_pixbuf_get_rowstride (anim->last_frame_data), anim->height)) ++ memset (gdk_pixbuf_get_pixels (anim->last_frame_data), 0, len); ++ else ++ return NULL; + composite_frame (anim, g_list_nth_data (anim->frames, 0)); + } + +-- +GitLab diff --git a/meta/recipes-gnome/gdk-pixbuf/gdk-pixbuf_2.40.0.bb b/meta/recipes-gnome/gdk-pixbuf/gdk-pixbuf_2.40.0.bb index 54861e83c6..60a04c3581 100644 --- a/meta/recipes-gnome/gdk-pixbuf/gdk-pixbuf_2.40.0.bb +++ b/meta/recipes-gnome/gdk-pixbuf/gdk-pixbuf_2.40.0.bb @@ -25,6 +25,7 @@ SRC_URI = "${GNOME_MIRROR}/${BPN}/${MAJ_VER}/${BPN}-${PV}.tar.xz \ file://0006-Build-thumbnailer-and-tests-also-in-cross-builds.patch \ file://missing-test-data.patch \ file://CVE-2020-29385.patch \ + file://CVE-2021-20240.patch \ " SRC_URI_append_class-target = " \ -- 2.25.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [dunfell][PATCH 2/2] grub2: Several cve fixes 2021-09-05 22:58 [dunfell][PATCH 1/2] gdk-pixbuf: fix CVE-2021-20240 Armin Kuster @ 2021-09-05 22:58 ` Armin Kuster 2021-09-06 17:28 ` [OE-core] " Steve Sakoman 0 siblings, 1 reply; 4+ messages in thread From: Armin Kuster @ 2021-09-05 22:58 UTC (permalink / raw) To: openembedded-core; +Cc: Armin Kuster From: Armin Kuster <akuster@mvista.com> Source: Debian.org MR: 109156, 109169, 109336, 109349, 109362, 109375, 109388 Type: Security Fix https://sources.debian.org/patches/grub2/2.04-20/ Disposition: Backport from ChangeID: f87f309a172004f21ac28870b85477cb90438d50 Description: Affects < 2.06 Fixes these CVE's: CVE-2020-14372 CVE-2020-25632 CVE-2020-25647 CVE-2020-27749 CVE-2020-27779 CVE-2021-20225 CVE-2021-20233 Signed-off-by: Armin Kuster <akuster@mvista.com> --- .../grub/files/CVE-2020-14372.patch | 79 ++++ .../grub/files/CVE-2020-14372_p1.patch | 432 ++++++++++++++++++ .../grub/files/CVE-2020-14372_p2.patch | 60 +++ .../grub/files/CVE-2020-14372_p3.patch | 57 +++ .../grub/files/CVE-2020-14372_p4.patch | 168 +++++++ .../grub/files/CVE-2020-25632.patch | 90 ++++ .../grub/files/CVE-2020-25647.patch | 117 +++++ .../grub/files/CVE-2020-27749_1.patch | 80 ++++ .../grub/files/CVE-2020-27749_2.patch | 123 +++++ .../grub/files/CVE-2020-27749_3.patch | 69 +++ .../grub/files/CVE-2020-27749_4.patch | 97 ++++ .../grub/files/CVE-2020-27749_5.patch | 311 +++++++++++++ .../grub/files/CVE-2020-27749_6.patch | 254 ++++++++++ .../grub/files/CVE-2020-27779.patch | 72 +++ .../grub/files/CVE-2021-20225.patch | 57 +++ .../grub/files/CVE-2021-20233.patch | 50 ++ meta/recipes-bsp/grub/grub2.inc | 16 + 17 files changed, 2132 insertions(+) create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-14372.patch create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-14372_p1.patch create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-14372_p2.patch create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-14372_p3.patch create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-14372_p4.patch create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-25632.patch create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-25647.patch create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27749_1.patch create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27749_2.patch create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27749_3.patch create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27749_4.patch create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27749_5.patch create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27749_6.patch create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27779.patch create mode 100644 meta/recipes-bsp/grub/files/CVE-2021-20225.patch create mode 100644 meta/recipes-bsp/grub/files/CVE-2021-20233.patch diff --git a/meta/recipes-bsp/grub/files/CVE-2020-14372.patch b/meta/recipes-bsp/grub/files/CVE-2020-14372.patch new file mode 100644 index 0000000000..cb51686ca5 --- /dev/null +++ b/meta/recipes-bsp/grub/files/CVE-2020-14372.patch @@ -0,0 +1,79 @@ +From b62501e6d869aa0968a17c8cb2379bde475dab20 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas <javierm@redhat.com> +Date: Mon, 28 Sep 2020 20:08:41 +0200 +Subject: 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 <km@mkukri.xyz> +Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> + +Patch-Name: 2021-02-security/006-acpi-Don-t-register-the-acpi-command-when-locked-down.patch + +Upstream-Status: Backport +CVE: CVE-2020-14372 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + docs/grub.texi | 5 +++++ + grub-core/commands/acpi.c | 15 ++++++++------- + 2 files changed, 13 insertions(+), 7 deletions(-) + +Index: grub-2.04/docs/grub.texi +=================================================================== +--- grub-2.04.orig/docs/grub.texi ++++ grub-2.04/docs/grub.texi +@@ -3986,6 +3986,11 @@ Normally, this command will replace the + (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 + + +Index: grub-2.04/grub-core/commands/acpi.c +=================================================================== +--- grub-2.04.orig/grub-core/commands/acpi.c ++++ grub-2.04/grub-core/commands/acpi.c +@@ -27,6 +27,7 @@ + #include <grub/mm.h> + #include <grub/memory.h> + #include <grub/i18n.h> ++#include <grub/lockdown.h> + + #ifdef GRUB_MACHINE_EFI + #include <grub/efi/efi.h> +@@ -775,13 +776,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/meta/recipes-bsp/grub/files/CVE-2020-14372_p1.patch b/meta/recipes-bsp/grub/files/CVE-2020-14372_p1.patch new file mode 100644 index 0000000000..47bbc594dc --- /dev/null +++ b/meta/recipes-bsp/grub/files/CVE-2020-14372_p1.patch @@ -0,0 +1,432 @@ +From 4484c5c41f65b0975c0b300015764c0980765f0b Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas <javierm@redhat.com> +Date: Mon, 28 Sep 2020 20:08:02 +0200 +Subject: 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 <javierm@redhat.com> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> + +Patch-Name: 2021-02-security/002-kern-Add-lockdown-support.patch + +Upstream-Status: Backport +CVE: CVE-2020-14372 Patch #1 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + conf/Makefile.common | 2 + + docs/grub-dev.texi | 27 +++++++++++++ + docs/grub.texi | 8 ++++ + grub-core/Makefile.am | 5 ++- + grub-core/Makefile.core.def | 1 + + grub-core/commands/extcmd.c | 23 +++++++++++ + grub-core/kern/command.c | 24 +++++++++++ + grub-core/kern/lockdown.c | 80 +++++++++++++++++++++++++++++++++++++ + include/grub/command.h | 5 +++ + include/grub/extcmd.h | 7 ++++ + include/grub/lockdown.h | 44 ++++++++++++++++++++ + 11 files changed, 225 insertions(+), 1 deletion(-) + create mode 100644 grub-core/kern/lockdown.c + create mode 100644 include/grub/lockdown.h + +Index: grub-2.04/conf/Makefile.common +=================================================================== +--- grub-2.04.orig/conf/Makefile.common ++++ grub-2.04/conf/Makefile.common +@@ -84,7 +84,9 @@ CPPFLAGS_PARTTOOL_LIST = -Dgrub_parttool + 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_FDT_LIST := '-Dgrub_fdtbus_register(...)=FDT_DRIVER_LIST_MARKER(__VA_ARGS__)' + CPPFLAGS_MARKER = $(CPPFLAGS_FS_LIST) $(CPPFLAGS_VIDEO_LIST) \ +Index: grub-2.04/docs/grub-dev.texi +=================================================================== +--- grub-2.04.orig/docs/grub-dev.texi ++++ grub-2.04/docs/grub-dev.texi +@@ -86,6 +86,7 @@ This edition documents version @value{VE + * PFF2 Font File Format:: + * Graphical Menu Software Design:: + * Verifiers framework:: ++* Lockdown framework:: + * Copying This Manual:: Copying This Manual + * Index:: + @end menu +@@ -2086,6 +2087,32 @@ Optionally at the end of the file @samp{ + the context. If you return no error during any of @samp{init}, @samp{write} and + @samp{fini} then the file is considered as having succeded verification. + ++@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 + +Index: grub-2.04/docs/grub.texi +=================================================================== +--- grub-2.04.orig/docs/grub.texi ++++ grub-2.04/docs/grub.texi +@@ -5581,6 +5581,7 @@ environment variables and commands are l + * Using digital signatures:: Booting digitally signed code + * UEFI secure boot and shim:: Booting digitally signed PE files + * Measured Boot:: Measuring boot components ++* Lockdown:: Lockdown when booting on a secure setup + @end menu + + @node Authentication and authorisation +@@ -5794,6 +5795,13 @@ into @file{core.img} in order to avoid a + + Measured boot is currently only supported on EFI platforms. + ++@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 + +Index: grub-2.04/grub-core/Makefile.am +=================================================================== +--- grub-2.04.orig/grub-core/Makefile.am ++++ grub-2.04/grub-core/Makefile.am +@@ -79,6 +79,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/inc + 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 + if COND_emu + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/compiler-rt-emu.h +@@ -375,8 +376,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 +Index: grub-2.04/grub-core/Makefile.core.def +=================================================================== +--- grub-2.04.orig/grub-core/Makefile.core.def ++++ grub-2.04/grub-core/Makefile.core.def +@@ -203,6 +203,7 @@ kernel = { + efi = term/efi/console.c; + efi = kern/acpi.c; + efi = kern/efi/acpi.c; ++ efi = kern/lockdown.c; + i386_coreboot = kern/i386/pc/acpi.c; + i386_multiboot = kern/i386/pc/acpi.c; + i386_coreboot = kern/acpi.c; +Index: grub-2.04/grub-core/commands/extcmd.c +=================================================================== +--- grub-2.04.orig/grub-core/commands/extcmd.c ++++ grub-2.04/grub-core/commands/extcmd.c +@@ -19,6 +19,7 @@ + + #include <grub/mm.h> + #include <grub/list.h> ++#include <grub/lockdown.h> + #include <grub/misc.h> + #include <grub/extcmd.h> + #include <grub/script_sh.h> +@@ -110,6 +111,28 @@ grub_register_extcmd (const char *name, + 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) + { +Index: grub-2.04/grub-core/kern/command.c +=================================================================== +--- grub-2.04.orig/grub-core/kern/command.c ++++ grub-2.04/grub-core/kern/command.c +@@ -17,6 +17,7 @@ + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. + */ + ++#include <grub/lockdown.h> + #include <grub/mm.h> + #include <grub/command.h> + +@@ -77,6 +78,29 @@ grub_register_command_prio (const char * + 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) + { +Index: grub-2.04/grub-core/kern/lockdown.c +=================================================================== +--- /dev/null ++++ grub-2.04/grub-core/kern/lockdown.c +@@ -0,0 +1,80 @@ ++/* ++ * 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 <http://www.gnu.org/licenses/>. ++ * ++ */ ++ ++#include <grub/dl.h> ++#include <grub/file.h> ++#include <grub/lockdown.h> ++#include <grub/verify.h> ++ ++static int lockdown = GRUB_LOCKDOWN_DISABLED; ++ ++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, ++ }; ++ ++void ++grub_lockdown (void) ++{ ++ lockdown = GRUB_LOCKDOWN_ENABLED; ++ ++ grub_verifier_register (&lockdown_verifier); ++} ++ ++int ++grub_is_lockdown (void) ++{ ++ return lockdown; ++} +Index: grub-2.04/include/grub/command.h +=================================================================== +--- grub-2.04.orig/include/grub/command.h ++++ grub-2.04/include/grub/command.h +@@ -86,6 +86,11 @@ EXPORT_FUNC(grub_register_command_prio) + 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 +Index: grub-2.04/include/grub/extcmd.h +=================================================================== +--- grub-2.04.orig/include/grub/extcmd.h ++++ grub-2.04/include/grub/extcmd.h +@@ -62,6 +62,13 @@ grub_extcmd_t EXPORT_FUNC(grub_register_ + 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, +Index: grub-2.04/include/grub/lockdown.h +=================================================================== +--- /dev/null ++++ grub-2.04/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 <http://www.gnu.org/licenses/>. ++ */ ++ ++#ifndef GRUB_LOCKDOWN_H ++#define GRUB_LOCKDOWN_H 1 ++ ++#include <grub/symbol.h> ++ ++#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/meta/recipes-bsp/grub/files/CVE-2020-14372_p2.patch b/meta/recipes-bsp/grub/files/CVE-2020-14372_p2.patch new file mode 100644 index 0000000000..5dffbb1506 --- /dev/null +++ b/meta/recipes-bsp/grub/files/CVE-2020-14372_p2.patch @@ -0,0 +1,60 @@ +From fbcb8c44aa9136f9421f60d4d0bb9d055dc8c2eb Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas <javierm@redhat.com> +Date: Tue, 2 Feb 2021 19:59:48 +0100 +Subject: 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 <xnox@ubuntu.com> +Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> + +Patch-Name: 2021-02-security/003-kern-lockdown-Set-a-variable-if-the-GRUB-is-locked-down.patch + +Upstream-Status: Backport +CVE: CVE-2020-14372 Patch #2 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + docs/grub.texi | 3 +++ + grub-core/kern/lockdown.c | 4 ++++ + 2 files changed, 7 insertions(+) + +Index: grub-2.04/docs/grub.texi +=================================================================== +--- grub-2.04.orig/docs/grub.texi ++++ grub-2.04/docs/grub.texi +@@ -5802,6 +5802,9 @@ The GRUB can be locked down when booted + 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 + +Index: grub-2.04/grub-core/kern/lockdown.c +=================================================================== +--- grub-2.04.orig/grub-core/kern/lockdown.c ++++ grub-2.04/grub-core/kern/lockdown.c +@@ -18,6 +18,7 @@ + */ + + #include <grub/dl.h> ++#include <grub/env.h> + #include <grub/file.h> + #include <grub/lockdown.h> + #include <grub/verify.h> +@@ -71,6 +72,9 @@ grub_lockdown (void) + lockdown = GRUB_LOCKDOWN_ENABLED; + + grub_verifier_register (&lockdown_verifier); ++ ++ grub_env_set ("lockdown", "y"); ++ grub_env_export ("lockdown"); + } + + int diff --git a/meta/recipes-bsp/grub/files/CVE-2020-14372_p3.patch b/meta/recipes-bsp/grub/files/CVE-2020-14372_p3.patch new file mode 100644 index 0000000000..2a8f1ed6d6 --- /dev/null +++ b/meta/recipes-bsp/grub/files/CVE-2020-14372_p3.patch @@ -0,0 +1,57 @@ +From 0260afe3d0b3fe07a2c55eaf3582a21a35bfd4f5 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas <javierm@redhat.com> +Date: Mon, 28 Sep 2020 20:08:29 +0200 +Subject: 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 <javierm@redhat.com> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> + +Patch-Name: 2021-02-security/004-efi-Lockdown-the-GRUB-when-the-UEFI-Secure-Boot-is-enabled.patch +Upstream-Status: Backport +CVE: CVE-2020-14372 Patch #3 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + grub-core/kern/efi/init.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c +index 2c31847bf..811692054 100644 +--- a/grub-core/kern/efi/init.c ++++ b/grub-core/kern/efi/init.c +@@ -20,6 +20,7 @@ + #include <grub/efi/efi.h> + #include <grub/efi/console.h> + #include <grub/efi/disk.h> ++#include <grub/lockdown.h> + #include <grub/term.h> + #include <grub/misc.h> + #include <grub/env.h> +@@ -39,6 +40,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 Debian 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/meta/recipes-bsp/grub/files/CVE-2020-14372_p4.patch b/meta/recipes-bsp/grub/files/CVE-2020-14372_p4.patch new file mode 100644 index 0000000000..486c9f76aa --- /dev/null +++ b/meta/recipes-bsp/grub/files/CVE-2020-14372_p4.patch @@ -0,0 +1,168 @@ +From bcffa66a873f72f337eb79d4ce673b2db8b3e7b0 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas <javierm@redhat.com> +Date: Mon, 28 Sep 2020 20:08:33 +0200 +Subject: 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 <javierm@redhat.com> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> + +Patch-Name: 2021-02-security/005-efi-Use-grub_is_lockdown-instead-of-hardcoding-a-disabled-modules-list.patch + +Upstream-Status: Backport +CVE: CVE-2020-14372 Patch #4 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + docs/grub.texi | 17 ++++++++++------- + grub-core/commands/i386/wrmsr.c | 5 +++-- + grub-core/commands/iorw.c | 19 ++++++++++--------- + grub-core/commands/memrw.c | 19 ++++++++++--------- + 4 files changed, 33 insertions(+), 27 deletions(-) + +Index: grub-2.04/docs/grub.texi +=================================================================== +--- grub-2.04.orig/docs/grub.texi ++++ grub-2.04/docs/grub.texi +@@ -5256,6 +5256,9 @@ only applies to the particular cpu/core/ + Also, if you specify a reserved or unimplemented MSR address, it will + cause a general protection exception (which is not currently being handled) + and the system will reboot. ++ ++Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}). ++ This is done to prevent subverting various security mechanisms. + @end deffn + + @node xen_hypervisor +@@ -5750,13 +5753,13 @@ secure boot chain. + The GRUB, except the @command{chainloader} command, works with the UEFI secure + boot and the shim. This functionality is provided by the shim_lock module. It + is recommend to build in this and other required modules into the @file{core.img}. +-All modules not stored in the @file{core.img} and the ACPI tables for the +-@command{acpi} command have to be signed, e.g. using PGP. Additionally, the +-@command{iorw}, the @command{memrw} and the @command{wrmsr} commands are +-prohibited if the UEFI secure boot is enabled. This is done due to +-security reasons. All above mentioned requirements are enforced by the +-shim_lock module. And itself it is a persistent module which means that +-it cannot be unloaded if it was loaded into the memory. ++ ++All GRUB modules not stored in the @file{core.img}, OS kernels, ACPI tables, ++Device Trees, etc. have to be signed, e.g, using PGP. Additionally, the commands ++that can be used to subvert the UEFI secure boot mechanism, such as @command{iorw} ++and @command{memrw} will not be available when the UEFI secure boot is enabled. ++This is done for security reasons and are enforced by the GRUB Lockdown mechanism ++(@pxref{Lockdown}). + + @node Measured Boot + @section Measuring boot components +Index: grub-2.04/grub-core/commands/i386/wrmsr.c +=================================================================== +--- grub-2.04.orig/grub-core/commands/i386/wrmsr.c ++++ grub-2.04/grub-core/commands/i386/wrmsr.c +@@ -24,6 +24,7 @@ + #include <grub/env.h> + #include <grub/command.h> + #include <grub/extcmd.h> ++#include <grub/lockdown.h> + #include <grub/i18n.h> + #include <grub/i386/cpuid.h> + #include <grub/i386/wrmsr.h> +@@ -83,8 +84,8 @@ grub_cmd_msr_write (grub_command_t cmd _ + + GRUB_MOD_INIT(wrmsr) + { +- cmd_write = grub_register_command ("wrmsr", grub_cmd_msr_write, N_("ADDR VALUE"), +- N_("Write a value to a CPU model specific register.")); ++ cmd_write = grub_register_command_lockdown ("wrmsr", grub_cmd_msr_write, N_("ADDR VALUE"), ++ N_("Write a value to a CPU model specific register.")); + } + + GRUB_MOD_FINI(wrmsr) +Index: grub-2.04/grub-core/commands/iorw.c +=================================================================== +--- grub-2.04.orig/grub-core/commands/iorw.c ++++ grub-2.04/grub-core/commands/iorw.c +@@ -23,6 +23,7 @@ + #include <grub/env.h> + #include <grub/cpu/io.h> + #include <grub/i18n.h> ++#include <grub/lockdown.h> + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -131,17 +132,17 @@ 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) +Index: grub-2.04/grub-core/commands/memrw.c +=================================================================== +--- grub-2.04.orig/grub-core/commands/memrw.c ++++ grub-2.04/grub-core/commands/memrw.c +@@ -22,6 +22,7 @@ + #include <grub/extcmd.h> + #include <grub/env.h> + #include <grub/i18n.h> ++#include <grub/lockdown.h> + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -133,17 +134,17 @@ 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) diff --git a/meta/recipes-bsp/grub/files/CVE-2020-25632.patch b/meta/recipes-bsp/grub/files/CVE-2020-25632.patch new file mode 100644 index 0000000000..30a6997185 --- /dev/null +++ b/meta/recipes-bsp/grub/files/CVE-2020-25632.patch @@ -0,0 +1,90 @@ +From 1e3203e7ec93ba725eb27bd28210a42430bf6539 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas <javierm@redhat.com> +Date: Tue, 29 Sep 2020 14:08:55 +0200 +Subject: 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 <chris.coulson@canonical.com> +Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> + +Patch-Name: 2021-02-security/014-dl-Only-allow-unloading-modules-that-are-not-dependencies.patch + +Upstream-Status: Backport +CVE: CVE-2020-25632 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + grub-core/commands/minicmd.c | 7 +++++-- + grub-core/kern/dl.c | 9 +++++++++ + include/grub/dl.h | 8 +++++--- + 3 files changed, 19 insertions(+), 5 deletions(-) + +Index: grub-2.04/grub-core/commands/minicmd.c +=================================================================== +--- grub-2.04.orig/grub-core/commands/minicmd.c ++++ grub-2.04/grub-core/commands/minicmd.c +@@ -140,8 +140,11 @@ grub_mini_cmd_rmmod (struct grub_command + if (grub_dl_is_persistent (mod)) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "cannot unload persistent 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; + } +Index: grub-2.04/grub-core/kern/dl.c +=================================================================== +--- grub-2.04.orig/grub-core/kern/dl.c ++++ grub-2.04/grub-core/kern/dl.c +@@ -549,6 +549,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) + { +Index: grub-2.04/include/grub/dl.h +=================================================================== +--- grub-2.04.orig/include/grub/dl.h ++++ grub-2.04/include/grub/dl.h +@@ -203,9 +203,11 @@ grub_dl_t EXPORT_FUNC(grub_dl_load) (con + 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/meta/recipes-bsp/grub/files/CVE-2020-25647.patch b/meta/recipes-bsp/grub/files/CVE-2020-25647.patch new file mode 100644 index 0000000000..73b2abadf3 --- /dev/null +++ b/meta/recipes-bsp/grub/files/CVE-2020-25647.patch @@ -0,0 +1,117 @@ +From 98a777237f96dcf82a01d42c887015f6bc45174f Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas <javierm@redhat.com> +Date: Fri, 11 Dec 2020 19:19:21 +0100 +Subject: 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 <ivansprundel@ioactive.com> +Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> + +Patch-Name: 2021-02-security/015-usb-Avoid-possible-out-of-bound-accesses-caused-by-malicious-devices.patch + +Upstream-Status: Backport +CVE: CVE-2020-25647 +Signed-off-by: Armin Kuster <akuster@mvista.com> +--- + 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 8da5e4c74..7cb3cc230 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 512ae1dd0..6475c552f 100644 +--- a/include/grub/usb.h ++++ b/include/grub/usb.h +@@ -23,6 +23,10 @@ + #include <grub/usbdesc.h> + #include <grub/usbtrans.h> + ++#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/meta/recipes-bsp/grub/files/CVE-2020-27749_1.patch b/meta/recipes-bsp/grub/files/CVE-2020-27749_1.patch new file mode 100644 index 0000000000..2cc07186f7 --- /dev/null +++ b/meta/recipes-bsp/grub/files/CVE-2020-27749_1.patch @@ -0,0 +1,80 @@ +From 8d06222bb8fb5d610dcdadb221d1846e7de88980 Mon Sep 17 00:00:00 2001 +From: Chris Coulson <chris.coulson@canonical.com> +Date: Wed, 18 Nov 2020 00:59:24 +0000 +Subject: 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 <chris.coulson@canonical.com> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> + +Patch-Name: 2021-02-security/093-kern-parser-Fix-a-memory-leak.patch + +Upstream-Status: Backport +CVE: CVE-2020-27749 patch#1 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + grub-core/kern/parser.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +Index: grub-2.04/grub-core/kern/parser.c +=================================================================== +--- grub-2.04.orig/grub-core/kern/parser.c ++++ grub-2.04/grub-core/kern/parser.c +@@ -140,6 +140,7 @@ grub_parser_split_cmdline (const char *c + char buffer[1024]; + char *bp = buffer; + char *rd = (char *) cmdline; ++ char *rp = rd; + char varname[200]; + char *vp = varname; + char *args; +@@ -148,10 +149,18 @@ grub_parser_split_cmdline (const char *c + *argc = 0; + 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; + } +@@ -159,12 +168,12 @@ grub_parser_split_cmdline (const char *c + 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 +@@ -197,6 +206,9 @@ grub_parser_split_cmdline (const char *c + } + 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/meta/recipes-bsp/grub/files/CVE-2020-27749_2.patch b/meta/recipes-bsp/grub/files/CVE-2020-27749_2.patch new file mode 100644 index 0000000000..88a780bcec --- /dev/null +++ b/meta/recipes-bsp/grub/files/CVE-2020-27749_2.patch @@ -0,0 +1,123 @@ +From 45812770ce81194ede99bba4c868b3a244fc37ee Mon Sep 17 00:00:00 2001 +From: Chris Coulson <chris.coulson@canonical.com> +Date: Tue, 5 Jan 2021 22:17:28 +0000 +Subject: 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 <chris.coulson@canonical.com> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> + +Patch-Name: 2021-02-security/094-kern-parser-Introduce-process_char-helper.patch + +Upstream-Status: Backport +CVE: CVE-2020-27749 patch#2 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + grub-core/kern/parser.c | 74 +++++++++++++++++++++++++---------------- + 1 file changed, 46 insertions(+), 28 deletions(-) + +Index: grub-2.04/grub-core/kern/parser.c +=================================================================== +--- grub-2.04.orig/grub-core/kern/parser.c ++++ grub-2.04/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 + *((*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, +@@ -171,35 +211,13 @@ grub_parser_split_cmdline (const char *c + 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/meta/recipes-bsp/grub/files/CVE-2020-27749_3.patch b/meta/recipes-bsp/grub/files/CVE-2020-27749_3.patch new file mode 100644 index 0000000000..ff211a9bd4 --- /dev/null +++ b/meta/recipes-bsp/grub/files/CVE-2020-27749_3.patch @@ -0,0 +1,69 @@ +From a93ec88ea67b578c495113663a7312777de22df3 Mon Sep 17 00:00:00 2001 +From: Chris Coulson <chris.coulson@canonical.com> +Date: Thu, 7 Jan 2021 19:53:55 +0000 +Subject: 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 <chris.coulson@canonical.com> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> + +Patch-Name: 2021-02-security/095-kern-parser-Introduce-terminate_arg-helper.patch + +Upstream-Status: Backport +CVE: CVE-2020-27749 patch#3 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + grub-core/kern/parser.c | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +Index: grub-2.04/grub-core/kern/parser.c +=================================================================== +--- grub-2.04.orig/grub-core/kern/parser.c ++++ grub-2.04/grub-core/kern/parser.c +@@ -129,6 +129,16 @@ add_var (char *varname, char **bp, char + *((*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 + * 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; +@@ -231,11 +237,8 @@ grub_parser_split_cmdline (const char *c + 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); + + /* Reserve memory for the return values. */ + args = grub_malloc (bp - buffer); diff --git a/meta/recipes-bsp/grub/files/CVE-2020-27749_4.patch b/meta/recipes-bsp/grub/files/CVE-2020-27749_4.patch new file mode 100644 index 0000000000..ac18909ce9 --- /dev/null +++ b/meta/recipes-bsp/grub/files/CVE-2020-27749_4.patch @@ -0,0 +1,97 @@ +From d5d6b0d72ef3ae571720c443210b4222122cf9eb Mon Sep 17 00:00:00 2001 +From: Chris Coulson <chris.coulson@canonical.com> +Date: Wed, 6 Jan 2021 13:54:26 +0000 +Subject: 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 <chris.coulson@canonical.com> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> + +Patch-Name: 2021-02-security/096-kern-parser-Refactor-grub_parser_split_cmdline-cleanup.patch + +Upstream-Status: Backport +CVE: CVE-2020-27749 patch#4 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + grub-core/kern/parser.c | 35 ++++++++++++++++++++--------------- + 1 file changed, 20 insertions(+), 15 deletions(-) + +Index: grub-2.04/grub-core/kern/parser.c +=================================================================== +--- grub-2.04.orig/grub-core/kern/parser.c ++++ grub-2.04/grub-core/kern/parser.c +@@ -220,38 +220,37 @@ grub_parser_split_cmdline (const char *c + + 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); + ++ /* If there are no args, then we're done. */ ++ if (!*argc) ++ { ++ grub_errno = GRUB_ERR_NONE; ++ goto out; ++ } ++ + /* Ensure that the last argument is terminated. */ ++ + terminate_arg (buffer, &bp, argc); + + /* 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. */ +@@ -264,7 +263,18 @@ grub_parser_split_cmdline (const char *c + 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/meta/recipes-bsp/grub/files/CVE-2020-27749_5.patch b/meta/recipes-bsp/grub/files/CVE-2020-27749_5.patch new file mode 100644 index 0000000000..e6917c606b --- /dev/null +++ b/meta/recipes-bsp/grub/files/CVE-2020-27749_5.patch @@ -0,0 +1,311 @@ +From 4f38583d8066b81dcc04eadd2d29700f58991547 Mon Sep 17 00:00:00 2001 +From: Chris Coulson <chris.coulson@canonical.com> +Date: Thu, 7 Jan 2021 15:15:43 +0000 +Subject: 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 <chris.coulson@canonical.com> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> + +Patch-Name: 2021-02-security/097-kern-buffer-Add-variable-sized-heap-buffer.patch + +Upstream-Status: Backport +CVE: CVE-2020-27749 patch#5 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + 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 e7e4d3cf5..248835aca 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -123,6 +123,7 @@ kernel = { + riscv32_efi_startup = kern/riscv/efi/startup.S; + riscv64_efi_startup = kern/riscv/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 000000000..9f5f8b867 +--- /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 <http://www.gnu.org/licenses/>. ++ */ ++ ++#include <grub/buffer.h> ++#include <grub/err.h> ++#include <grub/misc.h> ++#include <grub/mm.h> ++#include <grub/safemath.h> ++#include <grub/types.h> ++ ++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 000000000..f4b10cf28 +--- /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 <http://www.gnu.org/licenses/>. ++ */ ++ ++#ifndef GRUB_BUFFER_H ++#define GRUB_BUFFER_H 1 ++ ++#include <grub/err.h> ++#include <grub/misc.h> ++#include <grub/mm.h> ++#include <grub/safemath.h> ++#include <grub/types.h> ++ ++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/meta/recipes-bsp/grub/files/CVE-2020-27749_6.patch b/meta/recipes-bsp/grub/files/CVE-2020-27749_6.patch new file mode 100644 index 0000000000..8e21c948ce --- /dev/null +++ b/meta/recipes-bsp/grub/files/CVE-2020-27749_6.patch @@ -0,0 +1,254 @@ +From e44c6dbbb5c344aaca6bf20967f3b2a2f9a25eba Mon Sep 17 00:00:00 2001 +From: Chris Coulson <chris.coulson@canonical.com> +Date: Thu, 7 Jan 2021 19:21:03 +0000 +Subject: 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 <chris.coulson@canonical.com> +Signed-off-by: Chris Coulson <chris.coulson@canonical.com> +Signed-off-by: Darren Kenny <darren.kenny@oracle.com> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> + +Patch-Name: 2021-02-security/098-kern-parser-Fix-a-stack-buffer-overflow.patch + +Upstream-Status: Backport +CVE: CVE-2020-27749 patch#6 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + grub-core/kern/parser.c | 110 ++++++++++++++++++++++++---------------- + 1 file changed, 67 insertions(+), 43 deletions(-) + +Index: grub-2.04/grub-core/kern/parser.c +=================================================================== +--- grub-2.04.orig/grub-core/kern/parser.c ++++ grub-2.04/grub-core/kern/parser.c +@@ -18,6 +18,7 @@ + */ + + #include <grub/parser.h> ++#include <grub/buffer.h> + #include <grub/env.h> + #include <grub/misc.h> + #include <grub/mm.h> +@@ -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 + /* 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; ++ ++ if (grub_buffer_append_char (varname, '\0') != GRUB_ERR_NONE) ++ return grub_errno; + +- *((*vp)++) = '\0'; +- val = grub_env_get (varname); +- *vp = varname; ++ 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 + * 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 + * 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,18 +193,21 @@ grub_parser_split_cmdline (const char *c + 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; ++ ++ 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') +@@ -218,7 +233,7 @@ grub_parser_split_cmdline (const char *c + { + 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; + +@@ -229,7 +244,13 @@ grub_parser_split_cmdline (const char *c + + /* 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. */ ++ ++ if (terminate_arg (buffer, argc) != GRUB_ERR_NONE) ++ goto fail; + + /* If there are no args, then we're done. */ + if (!*argc) +@@ -238,15 +259,6 @@ grub_parser_split_cmdline (const char *c + goto out; + } + +- /* Ensure that the last argument is terminated. */ +- +- terminate_arg (buffer, &bp, argc); +- +- /* 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) +@@ -254,26 +266,39 @@ grub_parser_split_cmdline (const char *c + + /* 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/meta/recipes-bsp/grub/files/CVE-2020-27779.patch b/meta/recipes-bsp/grub/files/CVE-2020-27779.patch new file mode 100644 index 0000000000..cf489a5468 --- /dev/null +++ b/meta/recipes-bsp/grub/files/CVE-2020-27779.patch @@ -0,0 +1,72 @@ +From 4ad34d7d0aff5467cc2a2b3e0c55750856c19545 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas <javierm@redhat.com> +Date: Wed, 14 Oct 2020 16:33:42 +0200 +Subject: 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 <teddy.reed@gmail.com> +Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> + +Patch-Name: 2021-02-security/007-mmap-Don-t-register-cutmem-and-badram-commands-when-lockdown-is-enforced.patch + +Upstream-Status: Backport +CVE: CVE-2020-27779 +Signed-off-by: Armin Kuster <akuster@mvista.com> +--- + docs/grub.texi | 4 ++++ + grub-core/mmap/mmap.c | 13 +++++++------ + 2 files changed, 11 insertions(+), 6 deletions(-) + +Index: grub-2.04/docs/grub.texi +=================================================================== +--- grub-2.04.orig/docs/grub.texi ++++ grub-2.04/docs/grub.texi +@@ -4051,6 +4051,10 @@ this page is to be filtered. This synta + 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 + +Index: grub-2.04/grub-core/mmap/mmap.c +=================================================================== +--- grub-2.04.orig/grub-core/mmap/mmap.c ++++ grub-2.04/grub-core/mmap/mmap.c +@@ -20,6 +20,7 @@ + #include <grub/memory.h> + #include <grub/machine/memory.h> + #include <grub/err.h> ++#include <grub/lockdown.h> + #include <grub/misc.h> + #include <grub/mm.h> + #include <grub/command.h> +@@ -534,12 +535,12 @@ static grub_command_t cmd, cmd_cut; + \f + 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/meta/recipes-bsp/grub/files/CVE-2021-20225.patch b/meta/recipes-bsp/grub/files/CVE-2021-20225.patch new file mode 100644 index 0000000000..e7b213868e --- /dev/null +++ b/meta/recipes-bsp/grub/files/CVE-2021-20225.patch @@ -0,0 +1,57 @@ +From e46927de3e5bac21bc91986099c6b7ae014a4016 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens <dja@axtens.net> +Date: Fri, 22 Jan 2021 16:07:29 +1100 +Subject: 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 <dja@axtens.net> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> + +Patch-Name: 2021-02-security/061-lib-arg-Block-repeated-short-options-that-require-an-argument.patch + +Upstream-Status: Backport +CVE: CVE-2021-20225 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + 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 3288609a5..537c5e94b 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/meta/recipes-bsp/grub/files/CVE-2021-20233.patch b/meta/recipes-bsp/grub/files/CVE-2021-20233.patch new file mode 100644 index 0000000000..3f0abe0bde --- /dev/null +++ b/meta/recipes-bsp/grub/files/CVE-2021-20233.patch @@ -0,0 +1,50 @@ +From e8813743f74b8ac23bf40ed9ee86b759d0475666 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens <dja@axtens.net> +Date: Fri, 22 Jan 2021 17:10:48 +1100 +Subject: 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 <dja@axtens.net> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> + +Patch-Name: 2021-02-security/063-commands-menuentry-Fix-quoting-in-setparams_prefix.patch + +Upstream-Status: Backport +CVE: CVE-2021-20233 +Signed-off-by: Armin Kuster <akuster@mvista.com> + +--- + 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 9164df744..720e6d8ea 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/meta/recipes-bsp/grub/grub2.inc b/meta/recipes-bsp/grub/grub2.inc index 180e3752f8..d8c4337cf3 100644 --- a/meta/recipes-bsp/grub/grub2.inc +++ b/meta/recipes-bsp/grub/grub2.inc @@ -31,6 +31,22 @@ SRC_URI = "${GNU_MIRROR}/grub/grub-${PV}.tar.gz \ file://CVE-2020-15706-script-Avoid-a-use-after-free-when-redefining-a-func.patch \ file://CVE-2020-15707-linux-Fix-integer-overflows-in-initrd-size-handling.patch \ file://determinism.patch \ + file://CVE-2020-25632.patch \ + file://CVE-2020-25647.patch \ + file://CVE-2020-14372_p1.patch \ + file://CVE-2020-14372_p2.patch \ + file://CVE-2020-14372_p3.patch \ + file://CVE-2020-14372_p4.patch \ + file://CVE-2020-14372.patch \ + file://CVE-2020-27779.patch \ + file://CVE-2021-20225.patch \ + file://CVE-2021-20233.patch \ + file://CVE-2020-27749_1.patch \ + file://CVE-2020-27749_2.patch \ + file://CVE-2020-27749_3.patch \ + file://CVE-2020-27749_4.patch \ + file://CVE-2020-27749_5.patch \ + file://CVE-2020-27749_6.patch \ " SRC_URI[md5sum] = "5ce674ca6b2612d8939b9e6abed32934" SRC_URI[sha256sum] = "f10c85ae3e204dbaec39ae22fa3c5e99f0665417e91c2cb49b7e5031658ba6ea" -- 2.25.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [OE-core] [dunfell][PATCH 2/2] grub2: Several cve fixes 2021-09-05 22:58 ` [dunfell][PATCH 2/2] grub2: Several cve fixes Armin Kuster @ 2021-09-06 17:28 ` Steve Sakoman 2021-09-06 23:58 ` Armin Kuster 0 siblings, 1 reply; 4+ messages in thread From: Steve Sakoman @ 2021-09-06 17:28 UTC (permalink / raw) To: Armin Kuster Cc: Patches and discussions about the oe-core layer, Armin Kuster On Sun, Sep 5, 2021 at 12:58 PM Armin Kuster <akuster808@gmail.com> wrote: > > From: Armin Kuster <akuster@mvista.com> > > Source: Debian.org > MR: 109156, 109169, 109336, 109349, 109362, 109375, 109388 > Type: Security Fix https://sources.debian.org/patches/grub2/2.04-20/ > Disposition: Backport from > ChangeID: f87f309a172004f21ac28870b85477cb90438d50 > Description: > > Affects < 2.06 > > Fixes these CVE's: > CVE-2020-14372 > CVE-2020-25632 > CVE-2020-25647 > CVE-2020-27749 > CVE-2020-27779 > CVE-2021-20225 > CVE-2021-20233 This patch is causing autobuilder errors of this type: https://errors.yoctoproject.org/Errors/Details/603310/ Dunfell's grub version seems to be missing grub_efi_secure_boot() Steve > Signed-off-by: Armin Kuster <akuster@mvista.com> > --- > .../grub/files/CVE-2020-14372.patch | 79 ++++ > .../grub/files/CVE-2020-14372_p1.patch | 432 ++++++++++++++++++ > .../grub/files/CVE-2020-14372_p2.patch | 60 +++ > .../grub/files/CVE-2020-14372_p3.patch | 57 +++ > .../grub/files/CVE-2020-14372_p4.patch | 168 +++++++ > .../grub/files/CVE-2020-25632.patch | 90 ++++ > .../grub/files/CVE-2020-25647.patch | 117 +++++ > .../grub/files/CVE-2020-27749_1.patch | 80 ++++ > .../grub/files/CVE-2020-27749_2.patch | 123 +++++ > .../grub/files/CVE-2020-27749_3.patch | 69 +++ > .../grub/files/CVE-2020-27749_4.patch | 97 ++++ > .../grub/files/CVE-2020-27749_5.patch | 311 +++++++++++++ > .../grub/files/CVE-2020-27749_6.patch | 254 ++++++++++ > .../grub/files/CVE-2020-27779.patch | 72 +++ > .../grub/files/CVE-2021-20225.patch | 57 +++ > .../grub/files/CVE-2021-20233.patch | 50 ++ > meta/recipes-bsp/grub/grub2.inc | 16 + > 17 files changed, 2132 insertions(+) > create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-14372.patch > create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-14372_p1.patch > create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-14372_p2.patch > create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-14372_p3.patch > create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-14372_p4.patch > create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-25632.patch > create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-25647.patch > create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27749_1.patch > create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27749_2.patch > create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27749_3.patch > create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27749_4.patch > create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27749_5.patch > create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27749_6.patch > create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27779.patch > create mode 100644 meta/recipes-bsp/grub/files/CVE-2021-20225.patch > create mode 100644 meta/recipes-bsp/grub/files/CVE-2021-20233.patch > > diff --git a/meta/recipes-bsp/grub/files/CVE-2020-14372.patch b/meta/recipes-bsp/grub/files/CVE-2020-14372.patch > new file mode 100644 > index 0000000000..cb51686ca5 > --- /dev/null > +++ b/meta/recipes-bsp/grub/files/CVE-2020-14372.patch > @@ -0,0 +1,79 @@ > +From b62501e6d869aa0968a17c8cb2379bde475dab20 Mon Sep 17 00:00:00 2001 > +From: Javier Martinez Canillas <javierm@redhat.com> > +Date: Mon, 28 Sep 2020 20:08:41 +0200 > +Subject: 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 <km@mkukri.xyz> > +Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> > +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > + > +Patch-Name: 2021-02-security/006-acpi-Don-t-register-the-acpi-command-when-locked-down.patch > + > +Upstream-Status: Backport > +CVE: CVE-2020-14372 > +Signed-off-by: Armin Kuster <akuster@mvista.com> > + > +--- > + docs/grub.texi | 5 +++++ > + grub-core/commands/acpi.c | 15 ++++++++------- > + 2 files changed, 13 insertions(+), 7 deletions(-) > + > +Index: grub-2.04/docs/grub.texi > +=================================================================== > +--- grub-2.04.orig/docs/grub.texi > ++++ grub-2.04/docs/grub.texi > +@@ -3986,6 +3986,11 @@ Normally, this command will replace the > + (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 > + > + > +Index: grub-2.04/grub-core/commands/acpi.c > +=================================================================== > +--- grub-2.04.orig/grub-core/commands/acpi.c > ++++ grub-2.04/grub-core/commands/acpi.c > +@@ -27,6 +27,7 @@ > + #include <grub/mm.h> > + #include <grub/memory.h> > + #include <grub/i18n.h> > ++#include <grub/lockdown.h> > + > + #ifdef GRUB_MACHINE_EFI > + #include <grub/efi/efi.h> > +@@ -775,13 +776,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/meta/recipes-bsp/grub/files/CVE-2020-14372_p1.patch b/meta/recipes-bsp/grub/files/CVE-2020-14372_p1.patch > new file mode 100644 > index 0000000000..47bbc594dc > --- /dev/null > +++ b/meta/recipes-bsp/grub/files/CVE-2020-14372_p1.patch > @@ -0,0 +1,432 @@ > +From 4484c5c41f65b0975c0b300015764c0980765f0b Mon Sep 17 00:00:00 2001 > +From: Javier Martinez Canillas <javierm@redhat.com> > +Date: Mon, 28 Sep 2020 20:08:02 +0200 > +Subject: 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 <javierm@redhat.com> > +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > + > +Patch-Name: 2021-02-security/002-kern-Add-lockdown-support.patch > + > +Upstream-Status: Backport > +CVE: CVE-2020-14372 Patch #1 > +Signed-off-by: Armin Kuster <akuster@mvista.com> > + > +--- > + conf/Makefile.common | 2 + > + docs/grub-dev.texi | 27 +++++++++++++ > + docs/grub.texi | 8 ++++ > + grub-core/Makefile.am | 5 ++- > + grub-core/Makefile.core.def | 1 + > + grub-core/commands/extcmd.c | 23 +++++++++++ > + grub-core/kern/command.c | 24 +++++++++++ > + grub-core/kern/lockdown.c | 80 +++++++++++++++++++++++++++++++++++++ > + include/grub/command.h | 5 +++ > + include/grub/extcmd.h | 7 ++++ > + include/grub/lockdown.h | 44 ++++++++++++++++++++ > + 11 files changed, 225 insertions(+), 1 deletion(-) > + create mode 100644 grub-core/kern/lockdown.c > + create mode 100644 include/grub/lockdown.h > + > +Index: grub-2.04/conf/Makefile.common > +=================================================================== > +--- grub-2.04.orig/conf/Makefile.common > ++++ grub-2.04/conf/Makefile.common > +@@ -84,7 +84,9 @@ CPPFLAGS_PARTTOOL_LIST = -Dgrub_parttool > + 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_FDT_LIST := '-Dgrub_fdtbus_register(...)=FDT_DRIVER_LIST_MARKER(__VA_ARGS__)' > + CPPFLAGS_MARKER = $(CPPFLAGS_FS_LIST) $(CPPFLAGS_VIDEO_LIST) \ > +Index: grub-2.04/docs/grub-dev.texi > +=================================================================== > +--- grub-2.04.orig/docs/grub-dev.texi > ++++ grub-2.04/docs/grub-dev.texi > +@@ -86,6 +86,7 @@ This edition documents version @value{VE > + * PFF2 Font File Format:: > + * Graphical Menu Software Design:: > + * Verifiers framework:: > ++* Lockdown framework:: > + * Copying This Manual:: Copying This Manual > + * Index:: > + @end menu > +@@ -2086,6 +2087,32 @@ Optionally at the end of the file @samp{ > + the context. If you return no error during any of @samp{init}, @samp{write} and > + @samp{fini} then the file is considered as having succeded verification. > + > ++@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 > + > +Index: grub-2.04/docs/grub.texi > +=================================================================== > +--- grub-2.04.orig/docs/grub.texi > ++++ grub-2.04/docs/grub.texi > +@@ -5581,6 +5581,7 @@ environment variables and commands are l > + * Using digital signatures:: Booting digitally signed code > + * UEFI secure boot and shim:: Booting digitally signed PE files > + * Measured Boot:: Measuring boot components > ++* Lockdown:: Lockdown when booting on a secure setup > + @end menu > + > + @node Authentication and authorisation > +@@ -5794,6 +5795,13 @@ into @file{core.img} in order to avoid a > + > + Measured boot is currently only supported on EFI platforms. > + > ++@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 > + > +Index: grub-2.04/grub-core/Makefile.am > +=================================================================== > +--- grub-2.04.orig/grub-core/Makefile.am > ++++ grub-2.04/grub-core/Makefile.am > +@@ -79,6 +79,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/inc > + 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 > + if COND_emu > + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/compiler-rt-emu.h > +@@ -375,8 +376,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 > +Index: grub-2.04/grub-core/Makefile.core.def > +=================================================================== > +--- grub-2.04.orig/grub-core/Makefile.core.def > ++++ grub-2.04/grub-core/Makefile.core.def > +@@ -203,6 +203,7 @@ kernel = { > + efi = term/efi/console.c; > + efi = kern/acpi.c; > + efi = kern/efi/acpi.c; > ++ efi = kern/lockdown.c; > + i386_coreboot = kern/i386/pc/acpi.c; > + i386_multiboot = kern/i386/pc/acpi.c; > + i386_coreboot = kern/acpi.c; > +Index: grub-2.04/grub-core/commands/extcmd.c > +=================================================================== > +--- grub-2.04.orig/grub-core/commands/extcmd.c > ++++ grub-2.04/grub-core/commands/extcmd.c > +@@ -19,6 +19,7 @@ > + > + #include <grub/mm.h> > + #include <grub/list.h> > ++#include <grub/lockdown.h> > + #include <grub/misc.h> > + #include <grub/extcmd.h> > + #include <grub/script_sh.h> > +@@ -110,6 +111,28 @@ grub_register_extcmd (const char *name, > + 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) > + { > +Index: grub-2.04/grub-core/kern/command.c > +=================================================================== > +--- grub-2.04.orig/grub-core/kern/command.c > ++++ grub-2.04/grub-core/kern/command.c > +@@ -17,6 +17,7 @@ > + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. > + */ > + > ++#include <grub/lockdown.h> > + #include <grub/mm.h> > + #include <grub/command.h> > + > +@@ -77,6 +78,29 @@ grub_register_command_prio (const char * > + 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) > + { > +Index: grub-2.04/grub-core/kern/lockdown.c > +=================================================================== > +--- /dev/null > ++++ grub-2.04/grub-core/kern/lockdown.c > +@@ -0,0 +1,80 @@ > ++/* > ++ * 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 <http://www.gnu.org/licenses/>. > ++ * > ++ */ > ++ > ++#include <grub/dl.h> > ++#include <grub/file.h> > ++#include <grub/lockdown.h> > ++#include <grub/verify.h> > ++ > ++static int lockdown = GRUB_LOCKDOWN_DISABLED; > ++ > ++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, > ++ }; > ++ > ++void > ++grub_lockdown (void) > ++{ > ++ lockdown = GRUB_LOCKDOWN_ENABLED; > ++ > ++ grub_verifier_register (&lockdown_verifier); > ++} > ++ > ++int > ++grub_is_lockdown (void) > ++{ > ++ return lockdown; > ++} > +Index: grub-2.04/include/grub/command.h > +=================================================================== > +--- grub-2.04.orig/include/grub/command.h > ++++ grub-2.04/include/grub/command.h > +@@ -86,6 +86,11 @@ EXPORT_FUNC(grub_register_command_prio) > + 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 > +Index: grub-2.04/include/grub/extcmd.h > +=================================================================== > +--- grub-2.04.orig/include/grub/extcmd.h > ++++ grub-2.04/include/grub/extcmd.h > +@@ -62,6 +62,13 @@ grub_extcmd_t EXPORT_FUNC(grub_register_ > + 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, > +Index: grub-2.04/include/grub/lockdown.h > +=================================================================== > +--- /dev/null > ++++ grub-2.04/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 <http://www.gnu.org/licenses/>. > ++ */ > ++ > ++#ifndef GRUB_LOCKDOWN_H > ++#define GRUB_LOCKDOWN_H 1 > ++ > ++#include <grub/symbol.h> > ++ > ++#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/meta/recipes-bsp/grub/files/CVE-2020-14372_p2.patch b/meta/recipes-bsp/grub/files/CVE-2020-14372_p2.patch > new file mode 100644 > index 0000000000..5dffbb1506 > --- /dev/null > +++ b/meta/recipes-bsp/grub/files/CVE-2020-14372_p2.patch > @@ -0,0 +1,60 @@ > +From fbcb8c44aa9136f9421f60d4d0bb9d055dc8c2eb Mon Sep 17 00:00:00 2001 > +From: Javier Martinez Canillas <javierm@redhat.com> > +Date: Tue, 2 Feb 2021 19:59:48 +0100 > +Subject: 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 <xnox@ubuntu.com> > +Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> > +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > + > +Patch-Name: 2021-02-security/003-kern-lockdown-Set-a-variable-if-the-GRUB-is-locked-down.patch > + > +Upstream-Status: Backport > +CVE: CVE-2020-14372 Patch #2 > +Signed-off-by: Armin Kuster <akuster@mvista.com> > + > +--- > + docs/grub.texi | 3 +++ > + grub-core/kern/lockdown.c | 4 ++++ > + 2 files changed, 7 insertions(+) > + > +Index: grub-2.04/docs/grub.texi > +=================================================================== > +--- grub-2.04.orig/docs/grub.texi > ++++ grub-2.04/docs/grub.texi > +@@ -5802,6 +5802,9 @@ The GRUB can be locked down when booted > + 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 > + > +Index: grub-2.04/grub-core/kern/lockdown.c > +=================================================================== > +--- grub-2.04.orig/grub-core/kern/lockdown.c > ++++ grub-2.04/grub-core/kern/lockdown.c > +@@ -18,6 +18,7 @@ > + */ > + > + #include <grub/dl.h> > ++#include <grub/env.h> > + #include <grub/file.h> > + #include <grub/lockdown.h> > + #include <grub/verify.h> > +@@ -71,6 +72,9 @@ grub_lockdown (void) > + lockdown = GRUB_LOCKDOWN_ENABLED; > + > + grub_verifier_register (&lockdown_verifier); > ++ > ++ grub_env_set ("lockdown", "y"); > ++ grub_env_export ("lockdown"); > + } > + > + int > diff --git a/meta/recipes-bsp/grub/files/CVE-2020-14372_p3.patch b/meta/recipes-bsp/grub/files/CVE-2020-14372_p3.patch > new file mode 100644 > index 0000000000..2a8f1ed6d6 > --- /dev/null > +++ b/meta/recipes-bsp/grub/files/CVE-2020-14372_p3.patch > @@ -0,0 +1,57 @@ > +From 0260afe3d0b3fe07a2c55eaf3582a21a35bfd4f5 Mon Sep 17 00:00:00 2001 > +From: Javier Martinez Canillas <javierm@redhat.com> > +Date: Mon, 28 Sep 2020 20:08:29 +0200 > +Subject: 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 <javierm@redhat.com> > +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > + > +Patch-Name: 2021-02-security/004-efi-Lockdown-the-GRUB-when-the-UEFI-Secure-Boot-is-enabled.patch > +Upstream-Status: Backport > +CVE: CVE-2020-14372 Patch #3 > +Signed-off-by: Armin Kuster <akuster@mvista.com> > + > +--- > + grub-core/kern/efi/init.c | 18 ++++++++++++++++++ > + 1 file changed, 18 insertions(+) > + > +diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c > +index 2c31847bf..811692054 100644 > +--- a/grub-core/kern/efi/init.c > ++++ b/grub-core/kern/efi/init.c > +@@ -20,6 +20,7 @@ > + #include <grub/efi/efi.h> > + #include <grub/efi/console.h> > + #include <grub/efi/disk.h> > ++#include <grub/lockdown.h> > + #include <grub/term.h> > + #include <grub/misc.h> > + #include <grub/env.h> > +@@ -39,6 +40,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 Debian 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/meta/recipes-bsp/grub/files/CVE-2020-14372_p4.patch b/meta/recipes-bsp/grub/files/CVE-2020-14372_p4.patch > new file mode 100644 > index 0000000000..486c9f76aa > --- /dev/null > +++ b/meta/recipes-bsp/grub/files/CVE-2020-14372_p4.patch > @@ -0,0 +1,168 @@ > +From bcffa66a873f72f337eb79d4ce673b2db8b3e7b0 Mon Sep 17 00:00:00 2001 > +From: Javier Martinez Canillas <javierm@redhat.com> > +Date: Mon, 28 Sep 2020 20:08:33 +0200 > +Subject: 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 <javierm@redhat.com> > +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > + > +Patch-Name: 2021-02-security/005-efi-Use-grub_is_lockdown-instead-of-hardcoding-a-disabled-modules-list.patch > + > +Upstream-Status: Backport > +CVE: CVE-2020-14372 Patch #4 > +Signed-off-by: Armin Kuster <akuster@mvista.com> > + > +--- > + docs/grub.texi | 17 ++++++++++------- > + grub-core/commands/i386/wrmsr.c | 5 +++-- > + grub-core/commands/iorw.c | 19 ++++++++++--------- > + grub-core/commands/memrw.c | 19 ++++++++++--------- > + 4 files changed, 33 insertions(+), 27 deletions(-) > + > +Index: grub-2.04/docs/grub.texi > +=================================================================== > +--- grub-2.04.orig/docs/grub.texi > ++++ grub-2.04/docs/grub.texi > +@@ -5256,6 +5256,9 @@ only applies to the particular cpu/core/ > + Also, if you specify a reserved or unimplemented MSR address, it will > + cause a general protection exception (which is not currently being handled) > + and the system will reboot. > ++ > ++Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}). > ++ This is done to prevent subverting various security mechanisms. > + @end deffn > + > + @node xen_hypervisor > +@@ -5750,13 +5753,13 @@ secure boot chain. > + The GRUB, except the @command{chainloader} command, works with the UEFI secure > + boot and the shim. This functionality is provided by the shim_lock module. It > + is recommend to build in this and other required modules into the @file{core.img}. > +-All modules not stored in the @file{core.img} and the ACPI tables for the > +-@command{acpi} command have to be signed, e.g. using PGP. Additionally, the > +-@command{iorw}, the @command{memrw} and the @command{wrmsr} commands are > +-prohibited if the UEFI secure boot is enabled. This is done due to > +-security reasons. All above mentioned requirements are enforced by the > +-shim_lock module. And itself it is a persistent module which means that > +-it cannot be unloaded if it was loaded into the memory. > ++ > ++All GRUB modules not stored in the @file{core.img}, OS kernels, ACPI tables, > ++Device Trees, etc. have to be signed, e.g, using PGP. Additionally, the commands > ++that can be used to subvert the UEFI secure boot mechanism, such as @command{iorw} > ++and @command{memrw} will not be available when the UEFI secure boot is enabled. > ++This is done for security reasons and are enforced by the GRUB Lockdown mechanism > ++(@pxref{Lockdown}). > + > + @node Measured Boot > + @section Measuring boot components > +Index: grub-2.04/grub-core/commands/i386/wrmsr.c > +=================================================================== > +--- grub-2.04.orig/grub-core/commands/i386/wrmsr.c > ++++ grub-2.04/grub-core/commands/i386/wrmsr.c > +@@ -24,6 +24,7 @@ > + #include <grub/env.h> > + #include <grub/command.h> > + #include <grub/extcmd.h> > ++#include <grub/lockdown.h> > + #include <grub/i18n.h> > + #include <grub/i386/cpuid.h> > + #include <grub/i386/wrmsr.h> > +@@ -83,8 +84,8 @@ grub_cmd_msr_write (grub_command_t cmd _ > + > + GRUB_MOD_INIT(wrmsr) > + { > +- cmd_write = grub_register_command ("wrmsr", grub_cmd_msr_write, N_("ADDR VALUE"), > +- N_("Write a value to a CPU model specific register.")); > ++ cmd_write = grub_register_command_lockdown ("wrmsr", grub_cmd_msr_write, N_("ADDR VALUE"), > ++ N_("Write a value to a CPU model specific register.")); > + } > + > + GRUB_MOD_FINI(wrmsr) > +Index: grub-2.04/grub-core/commands/iorw.c > +=================================================================== > +--- grub-2.04.orig/grub-core/commands/iorw.c > ++++ grub-2.04/grub-core/commands/iorw.c > +@@ -23,6 +23,7 @@ > + #include <grub/env.h> > + #include <grub/cpu/io.h> > + #include <grub/i18n.h> > ++#include <grub/lockdown.h> > + > + GRUB_MOD_LICENSE ("GPLv3+"); > + > +@@ -131,17 +132,17 @@ 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) > +Index: grub-2.04/grub-core/commands/memrw.c > +=================================================================== > +--- grub-2.04.orig/grub-core/commands/memrw.c > ++++ grub-2.04/grub-core/commands/memrw.c > +@@ -22,6 +22,7 @@ > + #include <grub/extcmd.h> > + #include <grub/env.h> > + #include <grub/i18n.h> > ++#include <grub/lockdown.h> > + > + GRUB_MOD_LICENSE ("GPLv3+"); > + > +@@ -133,17 +134,17 @@ 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) > diff --git a/meta/recipes-bsp/grub/files/CVE-2020-25632.patch b/meta/recipes-bsp/grub/files/CVE-2020-25632.patch > new file mode 100644 > index 0000000000..30a6997185 > --- /dev/null > +++ b/meta/recipes-bsp/grub/files/CVE-2020-25632.patch > @@ -0,0 +1,90 @@ > +From 1e3203e7ec93ba725eb27bd28210a42430bf6539 Mon Sep 17 00:00:00 2001 > +From: Javier Martinez Canillas <javierm@redhat.com> > +Date: Tue, 29 Sep 2020 14:08:55 +0200 > +Subject: 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 <chris.coulson@canonical.com> > +Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> > +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > + > +Patch-Name: 2021-02-security/014-dl-Only-allow-unloading-modules-that-are-not-dependencies.patch > + > +Upstream-Status: Backport > +CVE: CVE-2020-25632 > +Signed-off-by: Armin Kuster <akuster@mvista.com> > + > +--- > + grub-core/commands/minicmd.c | 7 +++++-- > + grub-core/kern/dl.c | 9 +++++++++ > + include/grub/dl.h | 8 +++++--- > + 3 files changed, 19 insertions(+), 5 deletions(-) > + > +Index: grub-2.04/grub-core/commands/minicmd.c > +=================================================================== > +--- grub-2.04.orig/grub-core/commands/minicmd.c > ++++ grub-2.04/grub-core/commands/minicmd.c > +@@ -140,8 +140,11 @@ grub_mini_cmd_rmmod (struct grub_command > + if (grub_dl_is_persistent (mod)) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, "cannot unload persistent 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; > + } > +Index: grub-2.04/grub-core/kern/dl.c > +=================================================================== > +--- grub-2.04.orig/grub-core/kern/dl.c > ++++ grub-2.04/grub-core/kern/dl.c > +@@ -549,6 +549,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) > + { > +Index: grub-2.04/include/grub/dl.h > +=================================================================== > +--- grub-2.04.orig/include/grub/dl.h > ++++ grub-2.04/include/grub/dl.h > +@@ -203,9 +203,11 @@ grub_dl_t EXPORT_FUNC(grub_dl_load) (con > + 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/meta/recipes-bsp/grub/files/CVE-2020-25647.patch b/meta/recipes-bsp/grub/files/CVE-2020-25647.patch > new file mode 100644 > index 0000000000..73b2abadf3 > --- /dev/null > +++ b/meta/recipes-bsp/grub/files/CVE-2020-25647.patch > @@ -0,0 +1,117 @@ > +From 98a777237f96dcf82a01d42c887015f6bc45174f Mon Sep 17 00:00:00 2001 > +From: Javier Martinez Canillas <javierm@redhat.com> > +Date: Fri, 11 Dec 2020 19:19:21 +0100 > +Subject: 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 <ivansprundel@ioactive.com> > +Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> > +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > + > +Patch-Name: 2021-02-security/015-usb-Avoid-possible-out-of-bound-accesses-caused-by-malicious-devices.patch > + > +Upstream-Status: Backport > +CVE: CVE-2020-25647 > +Signed-off-by: Armin Kuster <akuster@mvista.com> > +--- > + 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 8da5e4c74..7cb3cc230 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 512ae1dd0..6475c552f 100644 > +--- a/include/grub/usb.h > ++++ b/include/grub/usb.h > +@@ -23,6 +23,10 @@ > + #include <grub/usbdesc.h> > + #include <grub/usbtrans.h> > + > ++#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/meta/recipes-bsp/grub/files/CVE-2020-27749_1.patch b/meta/recipes-bsp/grub/files/CVE-2020-27749_1.patch > new file mode 100644 > index 0000000000..2cc07186f7 > --- /dev/null > +++ b/meta/recipes-bsp/grub/files/CVE-2020-27749_1.patch > @@ -0,0 +1,80 @@ > +From 8d06222bb8fb5d610dcdadb221d1846e7de88980 Mon Sep 17 00:00:00 2001 > +From: Chris Coulson <chris.coulson@canonical.com> > +Date: Wed, 18 Nov 2020 00:59:24 +0000 > +Subject: 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 <chris.coulson@canonical.com> > +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > + > +Patch-Name: 2021-02-security/093-kern-parser-Fix-a-memory-leak.patch > + > +Upstream-Status: Backport > +CVE: CVE-2020-27749 patch#1 > +Signed-off-by: Armin Kuster <akuster@mvista.com> > + > +--- > + grub-core/kern/parser.c | 20 ++++++++++++++++---- > + 1 file changed, 16 insertions(+), 4 deletions(-) > + > +Index: grub-2.04/grub-core/kern/parser.c > +=================================================================== > +--- grub-2.04.orig/grub-core/kern/parser.c > ++++ grub-2.04/grub-core/kern/parser.c > +@@ -140,6 +140,7 @@ grub_parser_split_cmdline (const char *c > + char buffer[1024]; > + char *bp = buffer; > + char *rd = (char *) cmdline; > ++ char *rp = rd; > + char varname[200]; > + char *vp = varname; > + char *args; > +@@ -148,10 +149,18 @@ grub_parser_split_cmdline (const char *c > + *argc = 0; > + 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; > + } > +@@ -159,12 +168,12 @@ grub_parser_split_cmdline (const char *c > + 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 > +@@ -197,6 +206,9 @@ grub_parser_split_cmdline (const char *c > + } > + 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/meta/recipes-bsp/grub/files/CVE-2020-27749_2.patch b/meta/recipes-bsp/grub/files/CVE-2020-27749_2.patch > new file mode 100644 > index 0000000000..88a780bcec > --- /dev/null > +++ b/meta/recipes-bsp/grub/files/CVE-2020-27749_2.patch > @@ -0,0 +1,123 @@ > +From 45812770ce81194ede99bba4c868b3a244fc37ee Mon Sep 17 00:00:00 2001 > +From: Chris Coulson <chris.coulson@canonical.com> > +Date: Tue, 5 Jan 2021 22:17:28 +0000 > +Subject: 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 <chris.coulson@canonical.com> > +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > + > +Patch-Name: 2021-02-security/094-kern-parser-Introduce-process_char-helper.patch > + > +Upstream-Status: Backport > +CVE: CVE-2020-27749 patch#2 > +Signed-off-by: Armin Kuster <akuster@mvista.com> > + > +--- > + grub-core/kern/parser.c | 74 +++++++++++++++++++++++++---------------- > + 1 file changed, 46 insertions(+), 28 deletions(-) > + > +Index: grub-2.04/grub-core/kern/parser.c > +=================================================================== > +--- grub-2.04.orig/grub-core/kern/parser.c > ++++ grub-2.04/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 > + *((*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, > +@@ -171,35 +211,13 @@ grub_parser_split_cmdline (const char *c > + 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/meta/recipes-bsp/grub/files/CVE-2020-27749_3.patch b/meta/recipes-bsp/grub/files/CVE-2020-27749_3.patch > new file mode 100644 > index 0000000000..ff211a9bd4 > --- /dev/null > +++ b/meta/recipes-bsp/grub/files/CVE-2020-27749_3.patch > @@ -0,0 +1,69 @@ > +From a93ec88ea67b578c495113663a7312777de22df3 Mon Sep 17 00:00:00 2001 > +From: Chris Coulson <chris.coulson@canonical.com> > +Date: Thu, 7 Jan 2021 19:53:55 +0000 > +Subject: 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 <chris.coulson@canonical.com> > +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > + > +Patch-Name: 2021-02-security/095-kern-parser-Introduce-terminate_arg-helper.patch > + > +Upstream-Status: Backport > +CVE: CVE-2020-27749 patch#3 > +Signed-off-by: Armin Kuster <akuster@mvista.com> > + > +--- > + grub-core/kern/parser.c | 23 +++++++++++++---------- > + 1 file changed, 13 insertions(+), 10 deletions(-) > + > +Index: grub-2.04/grub-core/kern/parser.c > +=================================================================== > +--- grub-2.04.orig/grub-core/kern/parser.c > ++++ grub-2.04/grub-core/kern/parser.c > +@@ -129,6 +129,16 @@ add_var (char *varname, char **bp, char > + *((*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 > + * 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; > +@@ -231,11 +237,8 @@ grub_parser_split_cmdline (const char *c > + 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); > + > + /* Reserve memory for the return values. */ > + args = grub_malloc (bp - buffer); > diff --git a/meta/recipes-bsp/grub/files/CVE-2020-27749_4.patch b/meta/recipes-bsp/grub/files/CVE-2020-27749_4.patch > new file mode 100644 > index 0000000000..ac18909ce9 > --- /dev/null > +++ b/meta/recipes-bsp/grub/files/CVE-2020-27749_4.patch > @@ -0,0 +1,97 @@ > +From d5d6b0d72ef3ae571720c443210b4222122cf9eb Mon Sep 17 00:00:00 2001 > +From: Chris Coulson <chris.coulson@canonical.com> > +Date: Wed, 6 Jan 2021 13:54:26 +0000 > +Subject: 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 <chris.coulson@canonical.com> > +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > + > +Patch-Name: 2021-02-security/096-kern-parser-Refactor-grub_parser_split_cmdline-cleanup.patch > + > +Upstream-Status: Backport > +CVE: CVE-2020-27749 patch#4 > +Signed-off-by: Armin Kuster <akuster@mvista.com> > + > +--- > + grub-core/kern/parser.c | 35 ++++++++++++++++++++--------------- > + 1 file changed, 20 insertions(+), 15 deletions(-) > + > +Index: grub-2.04/grub-core/kern/parser.c > +=================================================================== > +--- grub-2.04.orig/grub-core/kern/parser.c > ++++ grub-2.04/grub-core/kern/parser.c > +@@ -220,38 +220,37 @@ grub_parser_split_cmdline (const char *c > + > + 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); > + > ++ /* If there are no args, then we're done. */ > ++ if (!*argc) > ++ { > ++ grub_errno = GRUB_ERR_NONE; > ++ goto out; > ++ } > ++ > + /* Ensure that the last argument is terminated. */ > ++ > + terminate_arg (buffer, &bp, argc); > + > + /* 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. */ > +@@ -264,7 +263,18 @@ grub_parser_split_cmdline (const char *c > + 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/meta/recipes-bsp/grub/files/CVE-2020-27749_5.patch b/meta/recipes-bsp/grub/files/CVE-2020-27749_5.patch > new file mode 100644 > index 0000000000..e6917c606b > --- /dev/null > +++ b/meta/recipes-bsp/grub/files/CVE-2020-27749_5.patch > @@ -0,0 +1,311 @@ > +From 4f38583d8066b81dcc04eadd2d29700f58991547 Mon Sep 17 00:00:00 2001 > +From: Chris Coulson <chris.coulson@canonical.com> > +Date: Thu, 7 Jan 2021 15:15:43 +0000 > +Subject: 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 <chris.coulson@canonical.com> > +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > + > +Patch-Name: 2021-02-security/097-kern-buffer-Add-variable-sized-heap-buffer.patch > + > +Upstream-Status: Backport > +CVE: CVE-2020-27749 patch#5 > +Signed-off-by: Armin Kuster <akuster@mvista.com> > + > +--- > + 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 e7e4d3cf5..248835aca 100644 > +--- a/grub-core/Makefile.core.def > ++++ b/grub-core/Makefile.core.def > +@@ -123,6 +123,7 @@ kernel = { > + riscv32_efi_startup = kern/riscv/efi/startup.S; > + riscv64_efi_startup = kern/riscv/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 000000000..9f5f8b867 > +--- /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 <http://www.gnu.org/licenses/>. > ++ */ > ++ > ++#include <grub/buffer.h> > ++#include <grub/err.h> > ++#include <grub/misc.h> > ++#include <grub/mm.h> > ++#include <grub/safemath.h> > ++#include <grub/types.h> > ++ > ++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 000000000..f4b10cf28 > +--- /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 <http://www.gnu.org/licenses/>. > ++ */ > ++ > ++#ifndef GRUB_BUFFER_H > ++#define GRUB_BUFFER_H 1 > ++ > ++#include <grub/err.h> > ++#include <grub/misc.h> > ++#include <grub/mm.h> > ++#include <grub/safemath.h> > ++#include <grub/types.h> > ++ > ++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/meta/recipes-bsp/grub/files/CVE-2020-27749_6.patch b/meta/recipes-bsp/grub/files/CVE-2020-27749_6.patch > new file mode 100644 > index 0000000000..8e21c948ce > --- /dev/null > +++ b/meta/recipes-bsp/grub/files/CVE-2020-27749_6.patch > @@ -0,0 +1,254 @@ > +From e44c6dbbb5c344aaca6bf20967f3b2a2f9a25eba Mon Sep 17 00:00:00 2001 > +From: Chris Coulson <chris.coulson@canonical.com> > +Date: Thu, 7 Jan 2021 19:21:03 +0000 > +Subject: 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 <chris.coulson@canonical.com> > +Signed-off-by: Chris Coulson <chris.coulson@canonical.com> > +Signed-off-by: Darren Kenny <darren.kenny@oracle.com> > +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > + > +Patch-Name: 2021-02-security/098-kern-parser-Fix-a-stack-buffer-overflow.patch > + > +Upstream-Status: Backport > +CVE: CVE-2020-27749 patch#6 > +Signed-off-by: Armin Kuster <akuster@mvista.com> > + > +--- > + grub-core/kern/parser.c | 110 ++++++++++++++++++++++++---------------- > + 1 file changed, 67 insertions(+), 43 deletions(-) > + > +Index: grub-2.04/grub-core/kern/parser.c > +=================================================================== > +--- grub-2.04.orig/grub-core/kern/parser.c > ++++ grub-2.04/grub-core/kern/parser.c > +@@ -18,6 +18,7 @@ > + */ > + > + #include <grub/parser.h> > ++#include <grub/buffer.h> > + #include <grub/env.h> > + #include <grub/misc.h> > + #include <grub/mm.h> > +@@ -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 > + /* 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; > ++ > ++ if (grub_buffer_append_char (varname, '\0') != GRUB_ERR_NONE) > ++ return grub_errno; > + > +- *((*vp)++) = '\0'; > +- val = grub_env_get (varname); > +- *vp = varname; > ++ 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 > + * 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 > + * 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,18 +193,21 @@ grub_parser_split_cmdline (const char *c > + 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; > ++ > ++ 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') > +@@ -218,7 +233,7 @@ grub_parser_split_cmdline (const char *c > + { > + 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; > + > +@@ -229,7 +244,13 @@ grub_parser_split_cmdline (const char *c > + > + /* 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. */ > ++ > ++ if (terminate_arg (buffer, argc) != GRUB_ERR_NONE) > ++ goto fail; > + > + /* If there are no args, then we're done. */ > + if (!*argc) > +@@ -238,15 +259,6 @@ grub_parser_split_cmdline (const char *c > + goto out; > + } > + > +- /* Ensure that the last argument is terminated. */ > +- > +- terminate_arg (buffer, &bp, argc); > +- > +- /* 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) > +@@ -254,26 +266,39 @@ grub_parser_split_cmdline (const char *c > + > + /* 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/meta/recipes-bsp/grub/files/CVE-2020-27779.patch b/meta/recipes-bsp/grub/files/CVE-2020-27779.patch > new file mode 100644 > index 0000000000..cf489a5468 > --- /dev/null > +++ b/meta/recipes-bsp/grub/files/CVE-2020-27779.patch > @@ -0,0 +1,72 @@ > +From 4ad34d7d0aff5467cc2a2b3e0c55750856c19545 Mon Sep 17 00:00:00 2001 > +From: Javier Martinez Canillas <javierm@redhat.com> > +Date: Wed, 14 Oct 2020 16:33:42 +0200 > +Subject: 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 <teddy.reed@gmail.com> > +Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> > +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > + > +Patch-Name: 2021-02-security/007-mmap-Don-t-register-cutmem-and-badram-commands-when-lockdown-is-enforced.patch > + > +Upstream-Status: Backport > +CVE: CVE-2020-27779 > +Signed-off-by: Armin Kuster <akuster@mvista.com> > +--- > + docs/grub.texi | 4 ++++ > + grub-core/mmap/mmap.c | 13 +++++++------ > + 2 files changed, 11 insertions(+), 6 deletions(-) > + > +Index: grub-2.04/docs/grub.texi > +=================================================================== > +--- grub-2.04.orig/docs/grub.texi > ++++ grub-2.04/docs/grub.texi > +@@ -4051,6 +4051,10 @@ this page is to be filtered. This synta > + 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 > + > +Index: grub-2.04/grub-core/mmap/mmap.c > +=================================================================== > +--- grub-2.04.orig/grub-core/mmap/mmap.c > ++++ grub-2.04/grub-core/mmap/mmap.c > +@@ -20,6 +20,7 @@ > + #include <grub/memory.h> > + #include <grub/machine/memory.h> > + #include <grub/err.h> > ++#include <grub/lockdown.h> > + #include <grub/misc.h> > + #include <grub/mm.h> > + #include <grub/command.h> > +@@ -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/meta/recipes-bsp/grub/files/CVE-2021-20225.patch b/meta/recipes-bsp/grub/files/CVE-2021-20225.patch > new file mode 100644 > index 0000000000..e7b213868e > --- /dev/null > +++ b/meta/recipes-bsp/grub/files/CVE-2021-20225.patch > @@ -0,0 +1,57 @@ > +From e46927de3e5bac21bc91986099c6b7ae014a4016 Mon Sep 17 00:00:00 2001 > +From: Daniel Axtens <dja@axtens.net> > +Date: Fri, 22 Jan 2021 16:07:29 +1100 > +Subject: 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 <dja@axtens.net> > +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > + > +Patch-Name: 2021-02-security/061-lib-arg-Block-repeated-short-options-that-require-an-argument.patch > + > +Upstream-Status: Backport > +CVE: CVE-2021-20225 > +Signed-off-by: Armin Kuster <akuster@mvista.com> > + > +--- > + 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 3288609a5..537c5e94b 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/meta/recipes-bsp/grub/files/CVE-2021-20233.patch b/meta/recipes-bsp/grub/files/CVE-2021-20233.patch > new file mode 100644 > index 0000000000..3f0abe0bde > --- /dev/null > +++ b/meta/recipes-bsp/grub/files/CVE-2021-20233.patch > @@ -0,0 +1,50 @@ > +From e8813743f74b8ac23bf40ed9ee86b759d0475666 Mon Sep 17 00:00:00 2001 > +From: Daniel Axtens <dja@axtens.net> > +Date: Fri, 22 Jan 2021 17:10:48 +1100 > +Subject: 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 <dja@axtens.net> > +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> > + > +Patch-Name: 2021-02-security/063-commands-menuentry-Fix-quoting-in-setparams_prefix.patch > + > +Upstream-Status: Backport > +CVE: CVE-2021-20233 > +Signed-off-by: Armin Kuster <akuster@mvista.com> > + > +--- > + 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 9164df744..720e6d8ea 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/meta/recipes-bsp/grub/grub2.inc b/meta/recipes-bsp/grub/grub2.inc > index 180e3752f8..d8c4337cf3 100644 > --- a/meta/recipes-bsp/grub/grub2.inc > +++ b/meta/recipes-bsp/grub/grub2.inc > @@ -31,6 +31,22 @@ SRC_URI = "${GNU_MIRROR}/grub/grub-${PV}.tar.gz \ > file://CVE-2020-15706-script-Avoid-a-use-after-free-when-redefining-a-func.patch \ > file://CVE-2020-15707-linux-Fix-integer-overflows-in-initrd-size-handling.patch \ > file://determinism.patch \ > + file://CVE-2020-25632.patch \ > + file://CVE-2020-25647.patch \ > + file://CVE-2020-14372_p1.patch \ > + file://CVE-2020-14372_p2.patch \ > + file://CVE-2020-14372_p3.patch \ > + file://CVE-2020-14372_p4.patch \ > + file://CVE-2020-14372.patch \ > + file://CVE-2020-27779.patch \ > + file://CVE-2021-20225.patch \ > + file://CVE-2021-20233.patch \ > + file://CVE-2020-27749_1.patch \ > + file://CVE-2020-27749_2.patch \ > + file://CVE-2020-27749_3.patch \ > + file://CVE-2020-27749_4.patch \ > + file://CVE-2020-27749_5.patch \ > + file://CVE-2020-27749_6.patch \ > " > SRC_URI[md5sum] = "5ce674ca6b2612d8939b9e6abed32934" > SRC_URI[sha256sum] = "f10c85ae3e204dbaec39ae22fa3c5e99f0665417e91c2cb49b7e5031658ba6ea" > -- > 2.25.1 > > > > ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [OE-core] [dunfell][PATCH 2/2] grub2: Several cve fixes 2021-09-06 17:28 ` [OE-core] " Steve Sakoman @ 2021-09-06 23:58 ` Armin Kuster 0 siblings, 0 replies; 4+ messages in thread From: Armin Kuster @ 2021-09-06 23:58 UTC (permalink / raw) To: Steve Sakoman Cc: Patches and discussions about the oe-core layer, Armin Kuster On 9/6/21 10:28 AM, Steve Sakoman wrote: > On Sun, Sep 5, 2021 at 12:58 PM Armin Kuster <akuster808@gmail.com> wrote: >> From: Armin Kuster <akuster@mvista.com> >> >> Source: Debian.org >> MR: 109156, 109169, 109336, 109349, 109362, 109375, 109388 >> Type: Security Fix https://sources.debian.org/patches/grub2/2.04-20/ >> Disposition: Backport from >> ChangeID: f87f309a172004f21ac28870b85477cb90438d50 >> Description: >> >> Affects < 2.06 >> >> Fixes these CVE's: >> CVE-2020-14372 >> CVE-2020-25632 >> CVE-2020-25647 >> CVE-2020-27749 >> CVE-2020-27779 >> CVE-2021-20225 >> CVE-2021-20233 > This patch is causing autobuilder errors of this type: > > https://errors.yoctoproject.org/Errors/Details/603310/ ok. V2 out shortly. > > Dunfell's grub version seems to be missing grub_efi_secure_boot() > > Steve > >> Signed-off-by: Armin Kuster <akuster@mvista.com> >> --- >> .../grub/files/CVE-2020-14372.patch | 79 ++++ >> .../grub/files/CVE-2020-14372_p1.patch | 432 ++++++++++++++++++ >> .../grub/files/CVE-2020-14372_p2.patch | 60 +++ >> .../grub/files/CVE-2020-14372_p3.patch | 57 +++ >> .../grub/files/CVE-2020-14372_p4.patch | 168 +++++++ >> .../grub/files/CVE-2020-25632.patch | 90 ++++ >> .../grub/files/CVE-2020-25647.patch | 117 +++++ >> .../grub/files/CVE-2020-27749_1.patch | 80 ++++ >> .../grub/files/CVE-2020-27749_2.patch | 123 +++++ >> .../grub/files/CVE-2020-27749_3.patch | 69 +++ >> .../grub/files/CVE-2020-27749_4.patch | 97 ++++ >> .../grub/files/CVE-2020-27749_5.patch | 311 +++++++++++++ >> .../grub/files/CVE-2020-27749_6.patch | 254 ++++++++++ >> .../grub/files/CVE-2020-27779.patch | 72 +++ >> .../grub/files/CVE-2021-20225.patch | 57 +++ >> .../grub/files/CVE-2021-20233.patch | 50 ++ >> meta/recipes-bsp/grub/grub2.inc | 16 + >> 17 files changed, 2132 insertions(+) >> create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-14372.patch >> create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-14372_p1.patch >> create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-14372_p2.patch >> create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-14372_p3.patch >> create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-14372_p4.patch >> create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-25632.patch >> create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-25647.patch >> create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27749_1.patch >> create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27749_2.patch >> create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27749_3.patch >> create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27749_4.patch >> create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27749_5.patch >> create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27749_6.patch >> create mode 100644 meta/recipes-bsp/grub/files/CVE-2020-27779.patch >> create mode 100644 meta/recipes-bsp/grub/files/CVE-2021-20225.patch >> create mode 100644 meta/recipes-bsp/grub/files/CVE-2021-20233.patch >> >> diff --git a/meta/recipes-bsp/grub/files/CVE-2020-14372.patch b/meta/recipes-bsp/grub/files/CVE-2020-14372.patch >> new file mode 100644 >> index 0000000000..cb51686ca5 >> --- /dev/null >> +++ b/meta/recipes-bsp/grub/files/CVE-2020-14372.patch >> @@ -0,0 +1,79 @@ >> +From b62501e6d869aa0968a17c8cb2379bde475dab20 Mon Sep 17 00:00:00 2001 >> +From: Javier Martinez Canillas <javierm@redhat.com> >> +Date: Mon, 28 Sep 2020 20:08:41 +0200 >> +Subject: 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 <km@mkukri.xyz> >> +Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> >> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> >> + >> +Patch-Name: 2021-02-security/006-acpi-Don-t-register-the-acpi-command-when-locked-down.patch >> + >> +Upstream-Status: Backport >> +CVE: CVE-2020-14372 >> +Signed-off-by: Armin Kuster <akuster@mvista.com> >> + >> +--- >> + docs/grub.texi | 5 +++++ >> + grub-core/commands/acpi.c | 15 ++++++++------- >> + 2 files changed, 13 insertions(+), 7 deletions(-) >> + >> +Index: grub-2.04/docs/grub.texi >> +=================================================================== >> +--- grub-2.04.orig/docs/grub.texi >> ++++ grub-2.04/docs/grub.texi >> +@@ -3986,6 +3986,11 @@ Normally, this command will replace the >> + (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 >> + >> + >> +Index: grub-2.04/grub-core/commands/acpi.c >> +=================================================================== >> +--- grub-2.04.orig/grub-core/commands/acpi.c >> ++++ grub-2.04/grub-core/commands/acpi.c >> +@@ -27,6 +27,7 @@ >> + #include <grub/mm.h> >> + #include <grub/memory.h> >> + #include <grub/i18n.h> >> ++#include <grub/lockdown.h> >> + >> + #ifdef GRUB_MACHINE_EFI >> + #include <grub/efi/efi.h> >> +@@ -775,13 +776,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/meta/recipes-bsp/grub/files/CVE-2020-14372_p1.patch b/meta/recipes-bsp/grub/files/CVE-2020-14372_p1.patch >> new file mode 100644 >> index 0000000000..47bbc594dc >> --- /dev/null >> +++ b/meta/recipes-bsp/grub/files/CVE-2020-14372_p1.patch >> @@ -0,0 +1,432 @@ >> +From 4484c5c41f65b0975c0b300015764c0980765f0b Mon Sep 17 00:00:00 2001 >> +From: Javier Martinez Canillas <javierm@redhat.com> >> +Date: Mon, 28 Sep 2020 20:08:02 +0200 >> +Subject: 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 <javierm@redhat.com> >> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> >> + >> +Patch-Name: 2021-02-security/002-kern-Add-lockdown-support.patch >> + >> +Upstream-Status: Backport >> +CVE: CVE-2020-14372 Patch #1 >> +Signed-off-by: Armin Kuster <akuster@mvista.com> >> + >> +--- >> + conf/Makefile.common | 2 + >> + docs/grub-dev.texi | 27 +++++++++++++ >> + docs/grub.texi | 8 ++++ >> + grub-core/Makefile.am | 5 ++- >> + grub-core/Makefile.core.def | 1 + >> + grub-core/commands/extcmd.c | 23 +++++++++++ >> + grub-core/kern/command.c | 24 +++++++++++ >> + grub-core/kern/lockdown.c | 80 +++++++++++++++++++++++++++++++++++++ >> + include/grub/command.h | 5 +++ >> + include/grub/extcmd.h | 7 ++++ >> + include/grub/lockdown.h | 44 ++++++++++++++++++++ >> + 11 files changed, 225 insertions(+), 1 deletion(-) >> + create mode 100644 grub-core/kern/lockdown.c >> + create mode 100644 include/grub/lockdown.h >> + >> +Index: grub-2.04/conf/Makefile.common >> +=================================================================== >> +--- grub-2.04.orig/conf/Makefile.common >> ++++ grub-2.04/conf/Makefile.common >> +@@ -84,7 +84,9 @@ CPPFLAGS_PARTTOOL_LIST = -Dgrub_parttool >> + 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_FDT_LIST := '-Dgrub_fdtbus_register(...)=FDT_DRIVER_LIST_MARKER(__VA_ARGS__)' >> + CPPFLAGS_MARKER = $(CPPFLAGS_FS_LIST) $(CPPFLAGS_VIDEO_LIST) \ >> +Index: grub-2.04/docs/grub-dev.texi >> +=================================================================== >> +--- grub-2.04.orig/docs/grub-dev.texi >> ++++ grub-2.04/docs/grub-dev.texi >> +@@ -86,6 +86,7 @@ This edition documents version @value{VE >> + * PFF2 Font File Format:: >> + * Graphical Menu Software Design:: >> + * Verifiers framework:: >> ++* Lockdown framework:: >> + * Copying This Manual:: Copying This Manual >> + * Index:: >> + @end menu >> +@@ -2086,6 +2087,32 @@ Optionally at the end of the file @samp{ >> + the context. If you return no error during any of @samp{init}, @samp{write} and >> + @samp{fini} then the file is considered as having succeded verification. >> + >> ++@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 >> + >> +Index: grub-2.04/docs/grub.texi >> +=================================================================== >> +--- grub-2.04.orig/docs/grub.texi >> ++++ grub-2.04/docs/grub.texi >> +@@ -5581,6 +5581,7 @@ environment variables and commands are l >> + * Using digital signatures:: Booting digitally signed code >> + * UEFI secure boot and shim:: Booting digitally signed PE files >> + * Measured Boot:: Measuring boot components >> ++* Lockdown:: Lockdown when booting on a secure setup >> + @end menu >> + >> + @node Authentication and authorisation >> +@@ -5794,6 +5795,13 @@ into @file{core.img} in order to avoid a >> + >> + Measured boot is currently only supported on EFI platforms. >> + >> ++@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 >> + >> +Index: grub-2.04/grub-core/Makefile.am >> +=================================================================== >> +--- grub-2.04.orig/grub-core/Makefile.am >> ++++ grub-2.04/grub-core/Makefile.am >> +@@ -79,6 +79,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/inc >> + 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 >> + if COND_emu >> + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/compiler-rt-emu.h >> +@@ -375,8 +376,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 >> +Index: grub-2.04/grub-core/Makefile.core.def >> +=================================================================== >> +--- grub-2.04.orig/grub-core/Makefile.core.def >> ++++ grub-2.04/grub-core/Makefile.core.def >> +@@ -203,6 +203,7 @@ kernel = { >> + efi = term/efi/console.c; >> + efi = kern/acpi.c; >> + efi = kern/efi/acpi.c; >> ++ efi = kern/lockdown.c; >> + i386_coreboot = kern/i386/pc/acpi.c; >> + i386_multiboot = kern/i386/pc/acpi.c; >> + i386_coreboot = kern/acpi.c; >> +Index: grub-2.04/grub-core/commands/extcmd.c >> +=================================================================== >> +--- grub-2.04.orig/grub-core/commands/extcmd.c >> ++++ grub-2.04/grub-core/commands/extcmd.c >> +@@ -19,6 +19,7 @@ >> + >> + #include <grub/mm.h> >> + #include <grub/list.h> >> ++#include <grub/lockdown.h> >> + #include <grub/misc.h> >> + #include <grub/extcmd.h> >> + #include <grub/script_sh.h> >> +@@ -110,6 +111,28 @@ grub_register_extcmd (const char *name, >> + 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) >> + { >> +Index: grub-2.04/grub-core/kern/command.c >> +=================================================================== >> +--- grub-2.04.orig/grub-core/kern/command.c >> ++++ grub-2.04/grub-core/kern/command.c >> +@@ -17,6 +17,7 @@ >> + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. >> + */ >> + >> ++#include <grub/lockdown.h> >> + #include <grub/mm.h> >> + #include <grub/command.h> >> + >> +@@ -77,6 +78,29 @@ grub_register_command_prio (const char * >> + 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) >> + { >> +Index: grub-2.04/grub-core/kern/lockdown.c >> +=================================================================== >> +--- /dev/null >> ++++ grub-2.04/grub-core/kern/lockdown.c >> +@@ -0,0 +1,80 @@ >> ++/* >> ++ * 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 <http://www.gnu.org/licenses/>. >> ++ * >> ++ */ >> ++ >> ++#include <grub/dl.h> >> ++#include <grub/file.h> >> ++#include <grub/lockdown.h> >> ++#include <grub/verify.h> >> ++ >> ++static int lockdown = GRUB_LOCKDOWN_DISABLED; >> ++ >> ++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, >> ++ }; >> ++ >> ++void >> ++grub_lockdown (void) >> ++{ >> ++ lockdown = GRUB_LOCKDOWN_ENABLED; >> ++ >> ++ grub_verifier_register (&lockdown_verifier); >> ++} >> ++ >> ++int >> ++grub_is_lockdown (void) >> ++{ >> ++ return lockdown; >> ++} >> +Index: grub-2.04/include/grub/command.h >> +=================================================================== >> +--- grub-2.04.orig/include/grub/command.h >> ++++ grub-2.04/include/grub/command.h >> +@@ -86,6 +86,11 @@ EXPORT_FUNC(grub_register_command_prio) >> + 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 >> +Index: grub-2.04/include/grub/extcmd.h >> +=================================================================== >> +--- grub-2.04.orig/include/grub/extcmd.h >> ++++ grub-2.04/include/grub/extcmd.h >> +@@ -62,6 +62,13 @@ grub_extcmd_t EXPORT_FUNC(grub_register_ >> + 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, >> +Index: grub-2.04/include/grub/lockdown.h >> +=================================================================== >> +--- /dev/null >> ++++ grub-2.04/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 <http://www.gnu.org/licenses/>. >> ++ */ >> ++ >> ++#ifndef GRUB_LOCKDOWN_H >> ++#define GRUB_LOCKDOWN_H 1 >> ++ >> ++#include <grub/symbol.h> >> ++ >> ++#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/meta/recipes-bsp/grub/files/CVE-2020-14372_p2.patch b/meta/recipes-bsp/grub/files/CVE-2020-14372_p2.patch >> new file mode 100644 >> index 0000000000..5dffbb1506 >> --- /dev/null >> +++ b/meta/recipes-bsp/grub/files/CVE-2020-14372_p2.patch >> @@ -0,0 +1,60 @@ >> +From fbcb8c44aa9136f9421f60d4d0bb9d055dc8c2eb Mon Sep 17 00:00:00 2001 >> +From: Javier Martinez Canillas <javierm@redhat.com> >> +Date: Tue, 2 Feb 2021 19:59:48 +0100 >> +Subject: 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 <xnox@ubuntu.com> >> +Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> >> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> >> + >> +Patch-Name: 2021-02-security/003-kern-lockdown-Set-a-variable-if-the-GRUB-is-locked-down.patch >> + >> +Upstream-Status: Backport >> +CVE: CVE-2020-14372 Patch #2 >> +Signed-off-by: Armin Kuster <akuster@mvista.com> >> + >> +--- >> + docs/grub.texi | 3 +++ >> + grub-core/kern/lockdown.c | 4 ++++ >> + 2 files changed, 7 insertions(+) >> + >> +Index: grub-2.04/docs/grub.texi >> +=================================================================== >> +--- grub-2.04.orig/docs/grub.texi >> ++++ grub-2.04/docs/grub.texi >> +@@ -5802,6 +5802,9 @@ The GRUB can be locked down when booted >> + 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 >> + >> +Index: grub-2.04/grub-core/kern/lockdown.c >> +=================================================================== >> +--- grub-2.04.orig/grub-core/kern/lockdown.c >> ++++ grub-2.04/grub-core/kern/lockdown.c >> +@@ -18,6 +18,7 @@ >> + */ >> + >> + #include <grub/dl.h> >> ++#include <grub/env.h> >> + #include <grub/file.h> >> + #include <grub/lockdown.h> >> + #include <grub/verify.h> >> +@@ -71,6 +72,9 @@ grub_lockdown (void) >> + lockdown = GRUB_LOCKDOWN_ENABLED; >> + >> + grub_verifier_register (&lockdown_verifier); >> ++ >> ++ grub_env_set ("lockdown", "y"); >> ++ grub_env_export ("lockdown"); >> + } >> + >> + int >> diff --git a/meta/recipes-bsp/grub/files/CVE-2020-14372_p3.patch b/meta/recipes-bsp/grub/files/CVE-2020-14372_p3.patch >> new file mode 100644 >> index 0000000000..2a8f1ed6d6 >> --- /dev/null >> +++ b/meta/recipes-bsp/grub/files/CVE-2020-14372_p3.patch >> @@ -0,0 +1,57 @@ >> +From 0260afe3d0b3fe07a2c55eaf3582a21a35bfd4f5 Mon Sep 17 00:00:00 2001 >> +From: Javier Martinez Canillas <javierm@redhat.com> >> +Date: Mon, 28 Sep 2020 20:08:29 +0200 >> +Subject: 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 <javierm@redhat.com> >> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> >> + >> +Patch-Name: 2021-02-security/004-efi-Lockdown-the-GRUB-when-the-UEFI-Secure-Boot-is-enabled.patch >> +Upstream-Status: Backport >> +CVE: CVE-2020-14372 Patch #3 >> +Signed-off-by: Armin Kuster <akuster@mvista.com> >> + >> +--- >> + grub-core/kern/efi/init.c | 18 ++++++++++++++++++ >> + 1 file changed, 18 insertions(+) >> + >> +diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c >> +index 2c31847bf..811692054 100644 >> +--- a/grub-core/kern/efi/init.c >> ++++ b/grub-core/kern/efi/init.c >> +@@ -20,6 +20,7 @@ >> + #include <grub/efi/efi.h> >> + #include <grub/efi/console.h> >> + #include <grub/efi/disk.h> >> ++#include <grub/lockdown.h> >> + #include <grub/term.h> >> + #include <grub/misc.h> >> + #include <grub/env.h> >> +@@ -39,6 +40,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 Debian 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/meta/recipes-bsp/grub/files/CVE-2020-14372_p4.patch b/meta/recipes-bsp/grub/files/CVE-2020-14372_p4.patch >> new file mode 100644 >> index 0000000000..486c9f76aa >> --- /dev/null >> +++ b/meta/recipes-bsp/grub/files/CVE-2020-14372_p4.patch >> @@ -0,0 +1,168 @@ >> +From bcffa66a873f72f337eb79d4ce673b2db8b3e7b0 Mon Sep 17 00:00:00 2001 >> +From: Javier Martinez Canillas <javierm@redhat.com> >> +Date: Mon, 28 Sep 2020 20:08:33 +0200 >> +Subject: 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 <javierm@redhat.com> >> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> >> + >> +Patch-Name: 2021-02-security/005-efi-Use-grub_is_lockdown-instead-of-hardcoding-a-disabled-modules-list.patch >> + >> +Upstream-Status: Backport >> +CVE: CVE-2020-14372 Patch #4 >> +Signed-off-by: Armin Kuster <akuster@mvista.com> >> + >> +--- >> + docs/grub.texi | 17 ++++++++++------- >> + grub-core/commands/i386/wrmsr.c | 5 +++-- >> + grub-core/commands/iorw.c | 19 ++++++++++--------- >> + grub-core/commands/memrw.c | 19 ++++++++++--------- >> + 4 files changed, 33 insertions(+), 27 deletions(-) >> + >> +Index: grub-2.04/docs/grub.texi >> +=================================================================== >> +--- grub-2.04.orig/docs/grub.texi >> ++++ grub-2.04/docs/grub.texi >> +@@ -5256,6 +5256,9 @@ only applies to the particular cpu/core/ >> + Also, if you specify a reserved or unimplemented MSR address, it will >> + cause a general protection exception (which is not currently being handled) >> + and the system will reboot. >> ++ >> ++Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}). >> ++ This is done to prevent subverting various security mechanisms. >> + @end deffn >> + >> + @node xen_hypervisor >> +@@ -5750,13 +5753,13 @@ secure boot chain. >> + The GRUB, except the @command{chainloader} command, works with the UEFI secure >> + boot and the shim. This functionality is provided by the shim_lock module. It >> + is recommend to build in this and other required modules into the @file{core.img}. >> +-All modules not stored in the @file{core.img} and the ACPI tables for the >> +-@command{acpi} command have to be signed, e.g. using PGP. Additionally, the >> +-@command{iorw}, the @command{memrw} and the @command{wrmsr} commands are >> +-prohibited if the UEFI secure boot is enabled. This is done due to >> +-security reasons. All above mentioned requirements are enforced by the >> +-shim_lock module. And itself it is a persistent module which means that >> +-it cannot be unloaded if it was loaded into the memory. >> ++ >> ++All GRUB modules not stored in the @file{core.img}, OS kernels, ACPI tables, >> ++Device Trees, etc. have to be signed, e.g, using PGP. Additionally, the commands >> ++that can be used to subvert the UEFI secure boot mechanism, such as @command{iorw} >> ++and @command{memrw} will not be available when the UEFI secure boot is enabled. >> ++This is done for security reasons and are enforced by the GRUB Lockdown mechanism >> ++(@pxref{Lockdown}). >> + >> + @node Measured Boot >> + @section Measuring boot components >> +Index: grub-2.04/grub-core/commands/i386/wrmsr.c >> +=================================================================== >> +--- grub-2.04.orig/grub-core/commands/i386/wrmsr.c >> ++++ grub-2.04/grub-core/commands/i386/wrmsr.c >> +@@ -24,6 +24,7 @@ >> + #include <grub/env.h> >> + #include <grub/command.h> >> + #include <grub/extcmd.h> >> ++#include <grub/lockdown.h> >> + #include <grub/i18n.h> >> + #include <grub/i386/cpuid.h> >> + #include <grub/i386/wrmsr.h> >> +@@ -83,8 +84,8 @@ grub_cmd_msr_write (grub_command_t cmd _ >> + >> + GRUB_MOD_INIT(wrmsr) >> + { >> +- cmd_write = grub_register_command ("wrmsr", grub_cmd_msr_write, N_("ADDR VALUE"), >> +- N_("Write a value to a CPU model specific register.")); >> ++ cmd_write = grub_register_command_lockdown ("wrmsr", grub_cmd_msr_write, N_("ADDR VALUE"), >> ++ N_("Write a value to a CPU model specific register.")); >> + } >> + >> + GRUB_MOD_FINI(wrmsr) >> +Index: grub-2.04/grub-core/commands/iorw.c >> +=================================================================== >> +--- grub-2.04.orig/grub-core/commands/iorw.c >> ++++ grub-2.04/grub-core/commands/iorw.c >> +@@ -23,6 +23,7 @@ >> + #include <grub/env.h> >> + #include <grub/cpu/io.h> >> + #include <grub/i18n.h> >> ++#include <grub/lockdown.h> >> + >> + GRUB_MOD_LICENSE ("GPLv3+"); >> + >> +@@ -131,17 +132,17 @@ 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) >> +Index: grub-2.04/grub-core/commands/memrw.c >> +=================================================================== >> +--- grub-2.04.orig/grub-core/commands/memrw.c >> ++++ grub-2.04/grub-core/commands/memrw.c >> +@@ -22,6 +22,7 @@ >> + #include <grub/extcmd.h> >> + #include <grub/env.h> >> + #include <grub/i18n.h> >> ++#include <grub/lockdown.h> >> + >> + GRUB_MOD_LICENSE ("GPLv3+"); >> + >> +@@ -133,17 +134,17 @@ 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) >> diff --git a/meta/recipes-bsp/grub/files/CVE-2020-25632.patch b/meta/recipes-bsp/grub/files/CVE-2020-25632.patch >> new file mode 100644 >> index 0000000000..30a6997185 >> --- /dev/null >> +++ b/meta/recipes-bsp/grub/files/CVE-2020-25632.patch >> @@ -0,0 +1,90 @@ >> +From 1e3203e7ec93ba725eb27bd28210a42430bf6539 Mon Sep 17 00:00:00 2001 >> +From: Javier Martinez Canillas <javierm@redhat.com> >> +Date: Tue, 29 Sep 2020 14:08:55 +0200 >> +Subject: 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 <chris.coulson@canonical.com> >> +Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> >> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> >> + >> +Patch-Name: 2021-02-security/014-dl-Only-allow-unloading-modules-that-are-not-dependencies.patch >> + >> +Upstream-Status: Backport >> +CVE: CVE-2020-25632 >> +Signed-off-by: Armin Kuster <akuster@mvista.com> >> + >> +--- >> + grub-core/commands/minicmd.c | 7 +++++-- >> + grub-core/kern/dl.c | 9 +++++++++ >> + include/grub/dl.h | 8 +++++--- >> + 3 files changed, 19 insertions(+), 5 deletions(-) >> + >> +Index: grub-2.04/grub-core/commands/minicmd.c >> +=================================================================== >> +--- grub-2.04.orig/grub-core/commands/minicmd.c >> ++++ grub-2.04/grub-core/commands/minicmd.c >> +@@ -140,8 +140,11 @@ grub_mini_cmd_rmmod (struct grub_command >> + if (grub_dl_is_persistent (mod)) >> + return grub_error (GRUB_ERR_BAD_ARGUMENT, "cannot unload persistent 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; >> + } >> +Index: grub-2.04/grub-core/kern/dl.c >> +=================================================================== >> +--- grub-2.04.orig/grub-core/kern/dl.c >> ++++ grub-2.04/grub-core/kern/dl.c >> +@@ -549,6 +549,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) >> + { >> +Index: grub-2.04/include/grub/dl.h >> +=================================================================== >> +--- grub-2.04.orig/include/grub/dl.h >> ++++ grub-2.04/include/grub/dl.h >> +@@ -203,9 +203,11 @@ grub_dl_t EXPORT_FUNC(grub_dl_load) (con >> + 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/meta/recipes-bsp/grub/files/CVE-2020-25647.patch b/meta/recipes-bsp/grub/files/CVE-2020-25647.patch >> new file mode 100644 >> index 0000000000..73b2abadf3 >> --- /dev/null >> +++ b/meta/recipes-bsp/grub/files/CVE-2020-25647.patch >> @@ -0,0 +1,117 @@ >> +From 98a777237f96dcf82a01d42c887015f6bc45174f Mon Sep 17 00:00:00 2001 >> +From: Javier Martinez Canillas <javierm@redhat.com> >> +Date: Fri, 11 Dec 2020 19:19:21 +0100 >> +Subject: 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 <ivansprundel@ioactive.com> >> +Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> >> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> >> + >> +Patch-Name: 2021-02-security/015-usb-Avoid-possible-out-of-bound-accesses-caused-by-malicious-devices.patch >> + >> +Upstream-Status: Backport >> +CVE: CVE-2020-25647 >> +Signed-off-by: Armin Kuster <akuster@mvista.com> >> +--- >> + 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 8da5e4c74..7cb3cc230 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 512ae1dd0..6475c552f 100644 >> +--- a/include/grub/usb.h >> ++++ b/include/grub/usb.h >> +@@ -23,6 +23,10 @@ >> + #include <grub/usbdesc.h> >> + #include <grub/usbtrans.h> >> + >> ++#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/meta/recipes-bsp/grub/files/CVE-2020-27749_1.patch b/meta/recipes-bsp/grub/files/CVE-2020-27749_1.patch >> new file mode 100644 >> index 0000000000..2cc07186f7 >> --- /dev/null >> +++ b/meta/recipes-bsp/grub/files/CVE-2020-27749_1.patch >> @@ -0,0 +1,80 @@ >> +From 8d06222bb8fb5d610dcdadb221d1846e7de88980 Mon Sep 17 00:00:00 2001 >> +From: Chris Coulson <chris.coulson@canonical.com> >> +Date: Wed, 18 Nov 2020 00:59:24 +0000 >> +Subject: 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 <chris.coulson@canonical.com> >> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> >> + >> +Patch-Name: 2021-02-security/093-kern-parser-Fix-a-memory-leak.patch >> + >> +Upstream-Status: Backport >> +CVE: CVE-2020-27749 patch#1 >> +Signed-off-by: Armin Kuster <akuster@mvista.com> >> + >> +--- >> + grub-core/kern/parser.c | 20 ++++++++++++++++---- >> + 1 file changed, 16 insertions(+), 4 deletions(-) >> + >> +Index: grub-2.04/grub-core/kern/parser.c >> +=================================================================== >> +--- grub-2.04.orig/grub-core/kern/parser.c >> ++++ grub-2.04/grub-core/kern/parser.c >> +@@ -140,6 +140,7 @@ grub_parser_split_cmdline (const char *c >> + char buffer[1024]; >> + char *bp = buffer; >> + char *rd = (char *) cmdline; >> ++ char *rp = rd; >> + char varname[200]; >> + char *vp = varname; >> + char *args; >> +@@ -148,10 +149,18 @@ grub_parser_split_cmdline (const char *c >> + *argc = 0; >> + 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; >> + } >> +@@ -159,12 +168,12 @@ grub_parser_split_cmdline (const char *c >> + 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 >> +@@ -197,6 +206,9 @@ grub_parser_split_cmdline (const char *c >> + } >> + 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/meta/recipes-bsp/grub/files/CVE-2020-27749_2.patch b/meta/recipes-bsp/grub/files/CVE-2020-27749_2.patch >> new file mode 100644 >> index 0000000000..88a780bcec >> --- /dev/null >> +++ b/meta/recipes-bsp/grub/files/CVE-2020-27749_2.patch >> @@ -0,0 +1,123 @@ >> +From 45812770ce81194ede99bba4c868b3a244fc37ee Mon Sep 17 00:00:00 2001 >> +From: Chris Coulson <chris.coulson@canonical.com> >> +Date: Tue, 5 Jan 2021 22:17:28 +0000 >> +Subject: 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 <chris.coulson@canonical.com> >> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> >> + >> +Patch-Name: 2021-02-security/094-kern-parser-Introduce-process_char-helper.patch >> + >> +Upstream-Status: Backport >> +CVE: CVE-2020-27749 patch#2 >> +Signed-off-by: Armin Kuster <akuster@mvista.com> >> + >> +--- >> + grub-core/kern/parser.c | 74 +++++++++++++++++++++++++---------------- >> + 1 file changed, 46 insertions(+), 28 deletions(-) >> + >> +Index: grub-2.04/grub-core/kern/parser.c >> +=================================================================== >> +--- grub-2.04.orig/grub-core/kern/parser.c >> ++++ grub-2.04/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 >> + *((*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, >> +@@ -171,35 +211,13 @@ grub_parser_split_cmdline (const char *c >> + 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/meta/recipes-bsp/grub/files/CVE-2020-27749_3.patch b/meta/recipes-bsp/grub/files/CVE-2020-27749_3.patch >> new file mode 100644 >> index 0000000000..ff211a9bd4 >> --- /dev/null >> +++ b/meta/recipes-bsp/grub/files/CVE-2020-27749_3.patch >> @@ -0,0 +1,69 @@ >> +From a93ec88ea67b578c495113663a7312777de22df3 Mon Sep 17 00:00:00 2001 >> +From: Chris Coulson <chris.coulson@canonical.com> >> +Date: Thu, 7 Jan 2021 19:53:55 +0000 >> +Subject: 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 <chris.coulson@canonical.com> >> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> >> + >> +Patch-Name: 2021-02-security/095-kern-parser-Introduce-terminate_arg-helper.patch >> + >> +Upstream-Status: Backport >> +CVE: CVE-2020-27749 patch#3 >> +Signed-off-by: Armin Kuster <akuster@mvista.com> >> + >> +--- >> + grub-core/kern/parser.c | 23 +++++++++++++---------- >> + 1 file changed, 13 insertions(+), 10 deletions(-) >> + >> +Index: grub-2.04/grub-core/kern/parser.c >> +=================================================================== >> +--- grub-2.04.orig/grub-core/kern/parser.c >> ++++ grub-2.04/grub-core/kern/parser.c >> +@@ -129,6 +129,16 @@ add_var (char *varname, char **bp, char >> + *((*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 >> + * 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; >> +@@ -231,11 +237,8 @@ grub_parser_split_cmdline (const char *c >> + 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); >> + >> + /* Reserve memory for the return values. */ >> + args = grub_malloc (bp - buffer); >> diff --git a/meta/recipes-bsp/grub/files/CVE-2020-27749_4.patch b/meta/recipes-bsp/grub/files/CVE-2020-27749_4.patch >> new file mode 100644 >> index 0000000000..ac18909ce9 >> --- /dev/null >> +++ b/meta/recipes-bsp/grub/files/CVE-2020-27749_4.patch >> @@ -0,0 +1,97 @@ >> +From d5d6b0d72ef3ae571720c443210b4222122cf9eb Mon Sep 17 00:00:00 2001 >> +From: Chris Coulson <chris.coulson@canonical.com> >> +Date: Wed, 6 Jan 2021 13:54:26 +0000 >> +Subject: 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 <chris.coulson@canonical.com> >> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> >> + >> +Patch-Name: 2021-02-security/096-kern-parser-Refactor-grub_parser_split_cmdline-cleanup.patch >> + >> +Upstream-Status: Backport >> +CVE: CVE-2020-27749 patch#4 >> +Signed-off-by: Armin Kuster <akuster@mvista.com> >> + >> +--- >> + grub-core/kern/parser.c | 35 ++++++++++++++++++++--------------- >> + 1 file changed, 20 insertions(+), 15 deletions(-) >> + >> +Index: grub-2.04/grub-core/kern/parser.c >> +=================================================================== >> +--- grub-2.04.orig/grub-core/kern/parser.c >> ++++ grub-2.04/grub-core/kern/parser.c >> +@@ -220,38 +220,37 @@ grub_parser_split_cmdline (const char *c >> + >> + 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); >> + >> ++ /* If there are no args, then we're done. */ >> ++ if (!*argc) >> ++ { >> ++ grub_errno = GRUB_ERR_NONE; >> ++ goto out; >> ++ } >> ++ >> + /* Ensure that the last argument is terminated. */ >> ++ >> + terminate_arg (buffer, &bp, argc); >> + >> + /* 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. */ >> +@@ -264,7 +263,18 @@ grub_parser_split_cmdline (const char *c >> + 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/meta/recipes-bsp/grub/files/CVE-2020-27749_5.patch b/meta/recipes-bsp/grub/files/CVE-2020-27749_5.patch >> new file mode 100644 >> index 0000000000..e6917c606b >> --- /dev/null >> +++ b/meta/recipes-bsp/grub/files/CVE-2020-27749_5.patch >> @@ -0,0 +1,311 @@ >> +From 4f38583d8066b81dcc04eadd2d29700f58991547 Mon Sep 17 00:00:00 2001 >> +From: Chris Coulson <chris.coulson@canonical.com> >> +Date: Thu, 7 Jan 2021 15:15:43 +0000 >> +Subject: 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 <chris.coulson@canonical.com> >> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> >> + >> +Patch-Name: 2021-02-security/097-kern-buffer-Add-variable-sized-heap-buffer.patch >> + >> +Upstream-Status: Backport >> +CVE: CVE-2020-27749 patch#5 >> +Signed-off-by: Armin Kuster <akuster@mvista.com> >> + >> +--- >> + 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 e7e4d3cf5..248835aca 100644 >> +--- a/grub-core/Makefile.core.def >> ++++ b/grub-core/Makefile.core.def >> +@@ -123,6 +123,7 @@ kernel = { >> + riscv32_efi_startup = kern/riscv/efi/startup.S; >> + riscv64_efi_startup = kern/riscv/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 000000000..9f5f8b867 >> +--- /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 <http://www.gnu.org/licenses/>. >> ++ */ >> ++ >> ++#include <grub/buffer.h> >> ++#include <grub/err.h> >> ++#include <grub/misc.h> >> ++#include <grub/mm.h> >> ++#include <grub/safemath.h> >> ++#include <grub/types.h> >> ++ >> ++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 000000000..f4b10cf28 >> +--- /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 <http://www.gnu.org/licenses/>. >> ++ */ >> ++ >> ++#ifndef GRUB_BUFFER_H >> ++#define GRUB_BUFFER_H 1 >> ++ >> ++#include <grub/err.h> >> ++#include <grub/misc.h> >> ++#include <grub/mm.h> >> ++#include <grub/safemath.h> >> ++#include <grub/types.h> >> ++ >> ++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/meta/recipes-bsp/grub/files/CVE-2020-27749_6.patch b/meta/recipes-bsp/grub/files/CVE-2020-27749_6.patch >> new file mode 100644 >> index 0000000000..8e21c948ce >> --- /dev/null >> +++ b/meta/recipes-bsp/grub/files/CVE-2020-27749_6.patch >> @@ -0,0 +1,254 @@ >> +From e44c6dbbb5c344aaca6bf20967f3b2a2f9a25eba Mon Sep 17 00:00:00 2001 >> +From: Chris Coulson <chris.coulson@canonical.com> >> +Date: Thu, 7 Jan 2021 19:21:03 +0000 >> +Subject: 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 <chris.coulson@canonical.com> >> +Signed-off-by: Chris Coulson <chris.coulson@canonical.com> >> +Signed-off-by: Darren Kenny <darren.kenny@oracle.com> >> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> >> + >> +Patch-Name: 2021-02-security/098-kern-parser-Fix-a-stack-buffer-overflow.patch >> + >> +Upstream-Status: Backport >> +CVE: CVE-2020-27749 patch#6 >> +Signed-off-by: Armin Kuster <akuster@mvista.com> >> + >> +--- >> + grub-core/kern/parser.c | 110 ++++++++++++++++++++++++---------------- >> + 1 file changed, 67 insertions(+), 43 deletions(-) >> + >> +Index: grub-2.04/grub-core/kern/parser.c >> +=================================================================== >> +--- grub-2.04.orig/grub-core/kern/parser.c >> ++++ grub-2.04/grub-core/kern/parser.c >> +@@ -18,6 +18,7 @@ >> + */ >> + >> + #include <grub/parser.h> >> ++#include <grub/buffer.h> >> + #include <grub/env.h> >> + #include <grub/misc.h> >> + #include <grub/mm.h> >> +@@ -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 >> + /* 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; >> ++ >> ++ if (grub_buffer_append_char (varname, '\0') != GRUB_ERR_NONE) >> ++ return grub_errno; >> + >> +- *((*vp)++) = '\0'; >> +- val = grub_env_get (varname); >> +- *vp = varname; >> ++ 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 >> + * 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 >> + * 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,18 +193,21 @@ grub_parser_split_cmdline (const char *c >> + 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; >> ++ >> ++ 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') >> +@@ -218,7 +233,7 @@ grub_parser_split_cmdline (const char *c >> + { >> + 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; >> + >> +@@ -229,7 +244,13 @@ grub_parser_split_cmdline (const char *c >> + >> + /* 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. */ >> ++ >> ++ if (terminate_arg (buffer, argc) != GRUB_ERR_NONE) >> ++ goto fail; >> + >> + /* If there are no args, then we're done. */ >> + if (!*argc) >> +@@ -238,15 +259,6 @@ grub_parser_split_cmdline (const char *c >> + goto out; >> + } >> + >> +- /* Ensure that the last argument is terminated. */ >> +- >> +- terminate_arg (buffer, &bp, argc); >> +- >> +- /* 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) >> +@@ -254,26 +266,39 @@ grub_parser_split_cmdline (const char *c >> + >> + /* 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/meta/recipes-bsp/grub/files/CVE-2020-27779.patch b/meta/recipes-bsp/grub/files/CVE-2020-27779.patch >> new file mode 100644 >> index 0000000000..cf489a5468 >> --- /dev/null >> +++ b/meta/recipes-bsp/grub/files/CVE-2020-27779.patch >> @@ -0,0 +1,72 @@ >> +From 4ad34d7d0aff5467cc2a2b3e0c55750856c19545 Mon Sep 17 00:00:00 2001 >> +From: Javier Martinez Canillas <javierm@redhat.com> >> +Date: Wed, 14 Oct 2020 16:33:42 +0200 >> +Subject: 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 <teddy.reed@gmail.com> >> +Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> >> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> >> + >> +Patch-Name: 2021-02-security/007-mmap-Don-t-register-cutmem-and-badram-commands-when-lockdown-is-enforced.patch >> + >> +Upstream-Status: Backport >> +CVE: CVE-2020-27779 >> +Signed-off-by: Armin Kuster <akuster@mvista.com> >> +--- >> + docs/grub.texi | 4 ++++ >> + grub-core/mmap/mmap.c | 13 +++++++------ >> + 2 files changed, 11 insertions(+), 6 deletions(-) >> + >> +Index: grub-2.04/docs/grub.texi >> +=================================================================== >> +--- grub-2.04.orig/docs/grub.texi >> ++++ grub-2.04/docs/grub.texi >> +@@ -4051,6 +4051,10 @@ this page is to be filtered. This synta >> + 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 >> + >> +Index: grub-2.04/grub-core/mmap/mmap.c >> +=================================================================== >> +--- grub-2.04.orig/grub-core/mmap/mmap.c >> ++++ grub-2.04/grub-core/mmap/mmap.c >> +@@ -20,6 +20,7 @@ >> + #include <grub/memory.h> >> + #include <grub/machine/memory.h> >> + #include <grub/err.h> >> ++#include <grub/lockdown.h> >> + #include <grub/misc.h> >> + #include <grub/mm.h> >> + #include <grub/command.h> >> +@@ -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/meta/recipes-bsp/grub/files/CVE-2021-20225.patch b/meta/recipes-bsp/grub/files/CVE-2021-20225.patch >> new file mode 100644 >> index 0000000000..e7b213868e >> --- /dev/null >> +++ b/meta/recipes-bsp/grub/files/CVE-2021-20225.patch >> @@ -0,0 +1,57 @@ >> +From e46927de3e5bac21bc91986099c6b7ae014a4016 Mon Sep 17 00:00:00 2001 >> +From: Daniel Axtens <dja@axtens.net> >> +Date: Fri, 22 Jan 2021 16:07:29 +1100 >> +Subject: 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 <dja@axtens.net> >> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> >> + >> +Patch-Name: 2021-02-security/061-lib-arg-Block-repeated-short-options-that-require-an-argument.patch >> + >> +Upstream-Status: Backport >> +CVE: CVE-2021-20225 >> +Signed-off-by: Armin Kuster <akuster@mvista.com> >> + >> +--- >> + 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 3288609a5..537c5e94b 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/meta/recipes-bsp/grub/files/CVE-2021-20233.patch b/meta/recipes-bsp/grub/files/CVE-2021-20233.patch >> new file mode 100644 >> index 0000000000..3f0abe0bde >> --- /dev/null >> +++ b/meta/recipes-bsp/grub/files/CVE-2021-20233.patch >> @@ -0,0 +1,50 @@ >> +From e8813743f74b8ac23bf40ed9ee86b759d0475666 Mon Sep 17 00:00:00 2001 >> +From: Daniel Axtens <dja@axtens.net> >> +Date: Fri, 22 Jan 2021 17:10:48 +1100 >> +Subject: 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 <dja@axtens.net> >> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> >> + >> +Patch-Name: 2021-02-security/063-commands-menuentry-Fix-quoting-in-setparams_prefix.patch >> + >> +Upstream-Status: Backport >> +CVE: CVE-2021-20233 >> +Signed-off-by: Armin Kuster <akuster@mvista.com> >> + >> +--- >> + 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 9164df744..720e6d8ea 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/meta/recipes-bsp/grub/grub2.inc b/meta/recipes-bsp/grub/grub2.inc >> index 180e3752f8..d8c4337cf3 100644 >> --- a/meta/recipes-bsp/grub/grub2.inc >> +++ b/meta/recipes-bsp/grub/grub2.inc >> @@ -31,6 +31,22 @@ SRC_URI = "${GNU_MIRROR}/grub/grub-${PV}.tar.gz \ >> file://CVE-2020-15706-script-Avoid-a-use-after-free-when-redefining-a-func.patch \ >> file://CVE-2020-15707-linux-Fix-integer-overflows-in-initrd-size-handling.patch \ >> file://determinism.patch \ >> + file://CVE-2020-25632.patch \ >> + file://CVE-2020-25647.patch \ >> + file://CVE-2020-14372_p1.patch \ >> + file://CVE-2020-14372_p2.patch \ >> + file://CVE-2020-14372_p3.patch \ >> + file://CVE-2020-14372_p4.patch \ >> + file://CVE-2020-14372.patch \ >> + file://CVE-2020-27779.patch \ >> + file://CVE-2021-20225.patch \ >> + file://CVE-2021-20233.patch \ >> + file://CVE-2020-27749_1.patch \ >> + file://CVE-2020-27749_2.patch \ >> + file://CVE-2020-27749_3.patch \ >> + file://CVE-2020-27749_4.patch \ >> + file://CVE-2020-27749_5.patch \ >> + file://CVE-2020-27749_6.patch \ >> " >> SRC_URI[md5sum] = "5ce674ca6b2612d8939b9e6abed32934" >> SRC_URI[sha256sum] = "f10c85ae3e204dbaec39ae22fa3c5e99f0665417e91c2cb49b7e5031658ba6ea" >> -- >> 2.25.1 >> >> >> >> ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-09-06 23:58 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-09-05 22:58 [dunfell][PATCH 1/2] gdk-pixbuf: fix CVE-2021-20240 Armin Kuster 2021-09-05 22:58 ` [dunfell][PATCH 2/2] grub2: Several cve fixes Armin Kuster 2021-09-06 17:28 ` [OE-core] " Steve Sakoman 2021-09-06 23:58 ` Armin Kuster
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.