From a28fc78d531ea309d59d085ce89bcc292f35774e Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 6 Oct 2015 16:09:25 -0400 Subject: [PATCH 221/261] Make any of the loaders that link in efi mode honor secure boot. And in this case "honor" means "even if somebody does link this in, they won't register commands if SB is enabled." Signed-off-by: Peter Jones --- grub-core/Makefile.am | 1 + grub-core/Makefile.core.def | 2 ++ grub-core/commands/iorw.c | 7 +++++ grub-core/commands/memrw.c | 7 +++++ grub-core/kern/efi/efi.c | 28 ------------------ grub-core/kern/efi/sb.c | 58 ++++++++++++++++++++++++++++++++++++++ grub-core/loader/efi/appleloader.c | 7 +++++ grub-core/loader/efi/chainloader.c | 1 + grub-core/loader/i386/bsd.c | 7 +++++ grub-core/loader/i386/linux.c | 7 +++++ grub-core/loader/i386/pc/linux.c | 7 +++++ grub-core/loader/multiboot.c | 7 +++++ grub-core/loader/xnu.c | 7 +++++ include/grub/efi/efi.h | 1 - include/grub/efi/sb.h | 29 +++++++++++++++++++ include/grub/ia64/linux.h | 0 include/grub/mips/linux.h | 0 include/grub/powerpc/linux.h | 0 include/grub/sparc64/linux.h | 0 19 files changed, 147 insertions(+), 29 deletions(-) create mode 100644 grub-core/kern/efi/sb.c create mode 100644 include/grub/efi/sb.h create mode 100644 include/grub/ia64/linux.h create mode 100644 include/grub/mips/linux.h create mode 100644 include/grub/powerpc/linux.h create mode 100644 include/grub/sparc64/linux.h diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index cb7fd9f98..be29e327f 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -67,6 +67,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/command.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/device.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/disk.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/dl.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/sb.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env_private.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/err.h diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 4fc743933..b340ceeec 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -175,6 +175,8 @@ kernel = { efi = term/efi/console.c; efi = lib/envblk.c; + common = kern/efi/sb.c; + x86 = kern/i386/tsc.c; i386_efi = kern/i386/efi/init.c; diff --git a/grub-core/commands/iorw.c b/grub-core/commands/iorw.c index a0c164e54..41a7f3f04 100644 --- a/grub-core/commands/iorw.c +++ b/grub-core/commands/iorw.c @@ -23,6 +23,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -118,6 +119,9 @@ grub_cmd_write (grub_command_t cmd, int argc, char **argv) GRUB_MOD_INIT(memrw) { + if (grub_efi_secure_boot()) + return; + cmd_read_byte = grub_register_extcmd ("inb", grub_cmd_read, 0, N_("PORT"), N_("Read 8-bit value from PORT."), @@ -146,6 +150,9 @@ GRUB_MOD_INIT(memrw) GRUB_MOD_FINI(memrw) { + if (grub_efi_secure_boot()) + return; + grub_unregister_extcmd (cmd_read_byte); grub_unregister_extcmd (cmd_read_word); grub_unregister_extcmd (cmd_read_dword); diff --git a/grub-core/commands/memrw.c b/grub-core/commands/memrw.c index 98769eadb..088cbe9e2 100644 --- a/grub-core/commands/memrw.c +++ b/grub-core/commands/memrw.c @@ -22,6 +22,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -120,6 +121,9 @@ grub_cmd_write (grub_command_t cmd, int argc, char **argv) GRUB_MOD_INIT(memrw) { + if (grub_efi_secure_boot()) + return; + cmd_read_byte = grub_register_extcmd ("read_byte", grub_cmd_read, 0, N_("ADDR"), N_("Read 8-bit value from ADDR."), @@ -148,6 +152,9 @@ GRUB_MOD_INIT(memrw) GRUB_MOD_FINI(memrw) { + if (grub_efi_secure_boot()) + return; + grub_unregister_extcmd (cmd_read_byte); grub_unregister_extcmd (cmd_read_word); grub_unregister_extcmd (cmd_read_dword); diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c index c80d85b67..7dfe2ef14 100644 --- a/grub-core/kern/efi/efi.c +++ b/grub-core/kern/efi/efi.c @@ -260,34 +260,6 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, return NULL; } -grub_efi_boolean_t -grub_efi_secure_boot (void) -{ - grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID; - grub_size_t datasize; - char *secure_boot = NULL; - char *setup_mode = NULL; - grub_efi_boolean_t ret = 0; - - secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize); - - if (datasize != 1 || !secure_boot) - goto out; - - setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize); - - if (datasize != 1 || !setup_mode) - goto out; - - if (*secure_boot && !*setup_mode) - ret = 1; - - out: - grub_free (secure_boot); - grub_free (setup_mode); - return ret; -} - #pragma GCC diagnostic ignored "-Wcast-align" /* Search the mods section from the PE32/PE32+ image. This code uses diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c new file mode 100644 index 000000000..a41b6c5b8 --- /dev/null +++ b/grub-core/kern/efi/sb.c @@ -0,0 +1,58 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2014 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int +grub_efi_secure_boot (void) +{ +#ifdef GRUB_MACHINE_EFI + grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID; + grub_size_t datasize; + char *secure_boot = NULL; + char *setup_mode = NULL; + grub_efi_boolean_t ret = 0; + + secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize); + + if (datasize != 1 || !secure_boot) + goto out; + + setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize); + + if (datasize != 1 || !setup_mode) + goto out; + + if (*secure_boot && !*setup_mode) + ret = 1; + + out: + grub_free (secure_boot); + grub_free (setup_mode); + return ret; +#else + return 0; +#endif +} diff --git a/grub-core/loader/efi/appleloader.c b/grub-core/loader/efi/appleloader.c index 74888c463..69c2a10d3 100644 --- a/grub-core/loader/efi/appleloader.c +++ b/grub-core/loader/efi/appleloader.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -227,6 +228,9 @@ static grub_command_t cmd; GRUB_MOD_INIT(appleloader) { + if (grub_efi_secure_boot()) + return; + cmd = grub_register_command ("appleloader", grub_cmd_appleloader, N_("[OPTS]"), /* TRANSLATORS: This command is used on EFI to @@ -238,5 +242,8 @@ GRUB_MOD_INIT(appleloader) GRUB_MOD_FINI(appleloader) { + if (grub_efi_secure_boot()) + return; + grub_unregister_command (cmd); } diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c index 87a91e16f..aee8e6bec 100644 --- a/grub-core/loader/efi/chainloader.c +++ b/grub-core/loader/efi/chainloader.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c index 8f691e0e2..b671f59b6 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -38,6 +38,7 @@ #ifdef GRUB_MACHINE_PCBIOS #include #endif +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -2111,6 +2112,9 @@ static grub_command_t cmd_netbsd_module_elf, cmd_openbsd_ramdisk; GRUB_MOD_INIT (bsd) { + if (grub_efi_secure_boot()) + return; + /* Net and OpenBSD kernels are often compressed. */ grub_dl_load ("gzio"); @@ -2150,6 +2154,9 @@ GRUB_MOD_INIT (bsd) GRUB_MOD_FINI (bsd) { + if (grub_efi_secure_boot()) + return; + grub_unregister_extcmd (cmd_freebsd); grub_unregister_extcmd (cmd_openbsd); grub_unregister_extcmd (cmd_netbsd); diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index 2ae176315..bd37c69b5 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -35,6 +35,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -1137,6 +1138,9 @@ static grub_command_t cmd_linux, cmd_initrd; GRUB_MOD_INIT(linux) { + if (grub_efi_secure_boot()) + return; + cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0, N_("Load Linux.")); cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, @@ -1146,6 +1150,9 @@ GRUB_MOD_INIT(linux) GRUB_MOD_FINI(linux) { + if (grub_efi_secure_boot()) + return; + grub_unregister_command (cmd_linux); grub_unregister_command (cmd_initrd); } diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c index b481e4668..b19527e8e 100644 --- a/grub-core/loader/i386/pc/linux.c +++ b/grub-core/loader/i386/pc/linux.c @@ -35,6 +35,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -469,6 +470,9 @@ static grub_command_t cmd_linux, cmd_initrd; GRUB_MOD_INIT(linux16) { + if (grub_efi_secure_boot()) + return; + cmd_linux = grub_register_command ("linux16", grub_cmd_linux, 0, N_("Load Linux.")); @@ -480,6 +484,9 @@ GRUB_MOD_INIT(linux16) GRUB_MOD_FINI(linux16) { + if (grub_efi_secure_boot()) + return; + grub_unregister_command (cmd_linux); grub_unregister_command (cmd_initrd); } diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c index 4b71f3363..e4e696e8f 100644 --- a/grub-core/loader/multiboot.c +++ b/grub-core/loader/multiboot.c @@ -42,6 +42,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -383,6 +384,9 @@ static grub_command_t cmd_multiboot, cmd_module; GRUB_MOD_INIT(multiboot) { + if (grub_efi_secure_boot()) + return; + cmd_multiboot = #ifdef GRUB_USE_MULTIBOOT2 grub_register_command ("multiboot2", grub_cmd_multiboot, @@ -403,6 +407,9 @@ GRUB_MOD_INIT(multiboot) GRUB_MOD_FINI(multiboot) { + if (grub_efi_secure_boot()) + return; + grub_unregister_command (cmd_multiboot); grub_unregister_command (cmd_module); } diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c index cdd9715ce..faffccc97 100644 --- a/grub-core/loader/xnu.c +++ b/grub-core/loader/xnu.c @@ -33,6 +33,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -1466,6 +1467,9 @@ static grub_extcmd_t cmd_splash; GRUB_MOD_INIT(xnu) { + if (grub_efi_secure_boot()) + return; + cmd_kernel = grub_register_command ("xnu_kernel", grub_cmd_xnu_kernel, 0, N_("Load XNU image.")); cmd_kernel64 = grub_register_command ("xnu_kernel64", grub_cmd_xnu_kernel64, @@ -1506,6 +1510,9 @@ GRUB_MOD_INIT(xnu) GRUB_MOD_FINI(xnu) { + if (grub_efi_secure_boot()) + return; + #ifndef GRUB_MACHINE_EMU grub_unregister_command (cmd_resume); #endif diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index 22456327e..9a2da0eb3 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -76,7 +76,6 @@ EXPORT_FUNC (grub_efi_set_variable) (const char *var, const grub_efi_guid_t *guid, void *data, grub_size_t datasize); -grub_efi_boolean_t EXPORT_FUNC (grub_efi_secure_boot) (void); int EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, const grub_efi_device_path_t *dp2); diff --git a/include/grub/efi/sb.h b/include/grub/efi/sb.h new file mode 100644 index 000000000..9629fbb0f --- /dev/null +++ b/include/grub/efi/sb.h @@ -0,0 +1,29 @@ +/* sb.h - declare functions for EFI Secure Boot support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_EFI_SB_HEADER +#define GRUB_EFI_SB_HEADER 1 + +#include +#include + +/* Functions. */ +int EXPORT_FUNC (grub_efi_secure_boot) (void); + +#endif /* ! GRUB_EFI_SB_HEADER */ diff --git a/include/grub/ia64/linux.h b/include/grub/ia64/linux.h new file mode 100644 index 000000000..e69de29bb diff --git a/include/grub/mips/linux.h b/include/grub/mips/linux.h new file mode 100644 index 000000000..e69de29bb diff --git a/include/grub/powerpc/linux.h b/include/grub/powerpc/linux.h new file mode 100644 index 000000000..e69de29bb diff --git a/include/grub/sparc64/linux.h b/include/grub/sparc64/linux.h new file mode 100644 index 000000000..e69de29bb -- 2.13.5