summaryrefslogtreecommitdiffstats
path: root/meta/recipes-bsp/grub/files/CVE-2020-14372_2.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-bsp/grub/files/CVE-2020-14372_2.patch')
-rw-r--r--meta/recipes-bsp/grub/files/CVE-2020-14372_2.patch431
1 files changed, 431 insertions, 0 deletions
diff --git a/meta/recipes-bsp/grub/files/CVE-2020-14372_2.patch b/meta/recipes-bsp/grub/files/CVE-2020-14372_2.patch
new file mode 100644
index 0000000000..a98b5d0455
--- /dev/null
+++ b/meta/recipes-bsp/grub/files/CVE-2020-14372_2.patch
@@ -0,0 +1,431 @@
+From d8aac4517fef0f0188a60a2a8ff9cafdd9c7ca42 Mon Sep 17 00:00:00 2001
+From: Javier Martinez Canillas <javierm@redhat.com>
+Date: Mon, 28 Sep 2020 20:08:02 +0200
+Subject: [PATCH] kern: Add lockdown support
+
+When the GRUB starts on a secure boot platform, some commands can be
+used to subvert the protections provided by the verification mechanism and
+could lead to booting untrusted system.
+
+To prevent that situation, allow GRUB to be locked down. That way the code
+may check if GRUB has been locked down and further restrict the commands
+that are registered or what subset of their functionality could be used.
+
+The lockdown support adds the following components:
+
+* The grub_lockdown() function which can be used to lockdown GRUB if,
+ e.g., UEFI Secure Boot is enabled.
+
+* The grub_is_lockdown() function which can be used to check if the GRUB
+ was locked down.
+
+* A verifier that flags OS kernels, the GRUB modules, Device Trees and ACPI
+ tables as GRUB_VERIFY_FLAGS_DEFER_AUTH to defer verification to other
+ verifiers. These files are only successfully verified if another registered
+ verifier returns success. Otherwise, the whole verification process fails.
+
+ For example, PE/COFF binaries verification can be done by the shim_lock
+ verifier which validates the signatures using the shim_lock protocol.
+ However, the verification is not deferred directly to the shim_lock verifier.
+ The shim_lock verifier is hooked into the verification process instead.
+
+* A set of grub_{command,extcmd}_lockdown functions that can be used by
+ code registering command handlers, to only register unsafe commands if
+ the GRUB has not been locked down.
+
+Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+
+Upstream-Status: Backport [https://git.savannah.gnu.org/cgit/grub.git/commit/?id=578c95298bcc46e0296f4c786db64c2ff26ce2cc]
+CVE: CVE-2020-14372
+Signed-off-by: Marta Rybczynska <marta.rybczynska@huawei.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
+
+diff --git a/conf/Makefile.common b/conf/Makefile.common
+index 6cd71cb..2a1a886 100644
+--- a/conf/Makefile.common
++++ b/conf/Makefile.common
+@@ -84,7 +84,9 @@ CPPFLAGS_PARTTOOL_LIST = -Dgrub_parttool_register=PARTTOOL_LIST_MARKER
+ CPPFLAGS_TERMINAL_LIST = '-Dgrub_term_register_input(...)=INPUT_TERMINAL_LIST_MARKER(__VA_ARGS__)'
+ CPPFLAGS_TERMINAL_LIST += '-Dgrub_term_register_output(...)=OUTPUT_TERMINAL_LIST_MARKER(__VA_ARGS__)'
+ CPPFLAGS_COMMAND_LIST = '-Dgrub_register_command(...)=COMMAND_LIST_MARKER(__VA_ARGS__)'
++CPPFLAGS_COMMAND_LIST += '-Dgrub_register_command_lockdown(...)=COMMAND_LOCKDOWN_LIST_MARKER(__VA_ARGS__)'
+ CPPFLAGS_COMMAND_LIST += '-Dgrub_register_extcmd(...)=EXTCOMMAND_LIST_MARKER(__VA_ARGS__)'
++CPPFLAGS_COMMAND_LIST += '-Dgrub_register_extcmd_lockdown(...)=EXTCOMMAND_LOCKDOWN_LIST_MARKER(__VA_ARGS__)'
+ CPPFLAGS_COMMAND_LIST += '-Dgrub_register_command_p1(...)=P1COMMAND_LIST_MARKER(__VA_ARGS__)'
+ CPPFLAGS_FDT_LIST := '-Dgrub_fdtbus_register(...)=FDT_DRIVER_LIST_MARKER(__VA_ARGS__)'
+ CPPFLAGS_MARKER = $(CPPFLAGS_FS_LIST) $(CPPFLAGS_VIDEO_LIST) \
+diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi
+index ee389fd..635ec72 100644
+--- a/docs/grub-dev.texi
++++ b/docs/grub-dev.texi
+@@ -86,6 +86,7 @@ This edition documents version @value{VERSION}.
+ * 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{fini}, if it exists, is called with just
+ 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
+
+diff --git a/docs/grub.texi b/docs/grub.texi
+index 8779507..d778bfb 100644
+--- a/docs/grub.texi
++++ b/docs/grub.texi
+@@ -5581,6 +5581,7 @@ environment variables and commands are listed in the same order.
+ * 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 potential gap in measurement between
+
+ 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
+
+diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
+index 375c30d..3096241 100644
+--- a/grub-core/Makefile.am
++++ b/grub-core/Makefile.am
+@@ -79,6 +79,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fs.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i18n.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/kernel.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/list.h
++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lockdown.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/misc.h
+ if COND_emu
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/compiler-rt-emu.h
+@@ -376,8 +377,10 @@ command.lst: $(MARKER_FILES)
+ b=`basename $$pp .marker`; \
+ sed -n \
+ -e "/EXTCOMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \
++ -e "/EXTCOMMAND_LOCKDOWN_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \
+ -e "/P1COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \
+- -e "/COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \
++ -e "/COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" \
++ -e "/COMMAND_LOCKDOWN_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \
+ done) | sort -u > $@
+ platform_DATA += command.lst
+ CLEANFILES += command.lst
+diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
+index cff02f2..651ea2a 100644
+--- a/grub-core/Makefile.core.def
++++ b/grub-core/Makefile.core.def
+@@ -204,6 +204,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;
+diff --git a/grub-core/commands/extcmd.c b/grub-core/commands/extcmd.c
+index 69574e2..90a5ca2 100644
+--- a/grub-core/commands/extcmd.c
++++ b/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, grub_extcmd_func_t func,
+ summary, description, parser, 1);
+ }
+
++static grub_err_t
++grub_extcmd_lockdown (grub_extcmd_context_t ctxt __attribute__ ((unused)),
++ int argc __attribute__ ((unused)),
++ char **argv __attribute__ ((unused)))
++{
++ return grub_error (GRUB_ERR_ACCESS_DENIED,
++ N_("%s: the command is not allowed when lockdown is enforced"),
++ ctxt->extcmd->cmd->name);
++}
++
++grub_extcmd_t
++grub_register_extcmd_lockdown (const char *name, grub_extcmd_func_t func,
++ grub_command_flags_t flags, const char *summary,
++ const char *description,
++ const struct grub_arg_option *parser)
++{
++ if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED)
++ func = grub_extcmd_lockdown;
++
++ return grub_register_extcmd (name, func, flags, summary, description, parser);
++}
++
+ void
+ grub_unregister_extcmd (grub_extcmd_t ext)
+ {
+diff --git a/grub-core/kern/command.c b/grub-core/kern/command.c
+index acd7218..4aabcd4 100644
+--- a/grub-core/kern/command.c
++++ b/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 *name,
+ return cmd;
+ }
+
++static grub_err_t
++grub_cmd_lockdown (grub_command_t cmd __attribute__ ((unused)),
++ int argc __attribute__ ((unused)),
++ char **argv __attribute__ ((unused)))
++
++{
++ return grub_error (GRUB_ERR_ACCESS_DENIED,
++ N_("%s: the command is not allowed when lockdown is enforced"),
++ cmd->name);
++}
++
++grub_command_t
++grub_register_command_lockdown (const char *name,
++ grub_command_func_t func,
++ const char *summary,
++ const char *description)
++{
++ if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED)
++ func = grub_cmd_lockdown;
++
++ return grub_register_command_prio (name, func, summary, description, 0);
++}
++
+ void
+ grub_unregister_command (grub_command_t cmd)
+ {
+diff --git a/grub-core/kern/lockdown.c b/grub-core/kern/lockdown.c
+new file mode 100644
+index 0000000..1e56c0b
+--- /dev/null
++++ b/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;
++}
+diff --git a/include/grub/command.h b/include/grub/command.h
+index eee4e84..2a6f7f8 100644
+--- a/include/grub/command.h
++++ b/include/grub/command.h
+@@ -86,6 +86,11 @@ EXPORT_FUNC(grub_register_command_prio) (const char *name,
+ const char *summary,
+ const char *description,
+ int prio);
++grub_command_t
++EXPORT_FUNC(grub_register_command_lockdown) (const char *name,
++ grub_command_func_t func,
++ const char *summary,
++ const char *description);
+ void EXPORT_FUNC(grub_unregister_command) (grub_command_t cmd);
+
+ static inline grub_command_t
+diff --git a/include/grub/extcmd.h b/include/grub/extcmd.h
+index 19fe592..fe9248b 100644
+--- a/include/grub/extcmd.h
++++ b/include/grub/extcmd.h
+@@ -62,6 +62,13 @@ grub_extcmd_t EXPORT_FUNC(grub_register_extcmd) (const char *name,
+ const char *description,
+ const struct grub_arg_option *parser);
+
++grub_extcmd_t EXPORT_FUNC(grub_register_extcmd_lockdown) (const char *name,
++ grub_extcmd_func_t func,
++ grub_command_flags_t flags,
++ const char *summary,
++ const char *description,
++ const struct grub_arg_option *parser);
++
+ grub_extcmd_t EXPORT_FUNC(grub_register_extcmd_prio) (const char *name,
+ grub_extcmd_func_t func,
+ grub_command_flags_t flags,
+diff --git a/include/grub/lockdown.h b/include/grub/lockdown.h
+new file mode 100644
+index 0000000..40531fa
+--- /dev/null
++++ b/include/grub/lockdown.h
+@@ -0,0 +1,44 @@
++/*
++ * GRUB -- GRand Unified Bootloader
++ * Copyright (C) 2020 Free Software Foundation, Inc.
++ *
++ * GRUB is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation, either version 3 of the License, or
++ * (at your option) any later version.
++ *
++ * GRUB is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with GRUB. If not, see <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 */