Accepting request 876327 from Base:System
OBS-URL: https://build.opensuse.org/request/show/876327 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/grub2?expand=0&rev=234
This commit is contained in:
parent
f2623d53c7
commit
39206e6e67
@ -0,0 +1,39 @@
|
||||
From f756ab3eac93346c3945eeb254773436ea3e1607 Mon Sep 17 00:00:00 2001
|
||||
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Date: Thu, 3 Dec 2020 16:01:43 +0100
|
||||
Subject: [PATCH 01/46] include/grub/i386/linux.h: Include missing
|
||||
<grub/types.h> header
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This header uses types defined in <grub/types.h> but does not include it,
|
||||
which leads to compile errors like the following:
|
||||
|
||||
In file included from ../include/grub/cpu/linux.h:19,
|
||||
from kern/efi/sb.c:21:
|
||||
../include/grub/i386/linux.h:80:3: error: unknown type name ‘grub_uint64_t’
|
||||
80 | grub_uint64_t addr;
|
||||
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
include/grub/i386/linux.h | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h
|
||||
index ce30e7fb0..6da5f030f 100644
|
||||
--- a/include/grub/i386/linux.h
|
||||
+++ b/include/grub/i386/linux.h
|
||||
@@ -19,6 +19,8 @@
|
||||
#ifndef GRUB_I386_LINUX_HEADER
|
||||
#define GRUB_I386_LINUX_HEADER 1
|
||||
|
||||
+#include <grub/types.h>
|
||||
+
|
||||
#define GRUB_LINUX_I386_MAGIC_SIGNATURE 0x53726448 /* "HdrS" */
|
||||
#define GRUB_LINUX_DEFAULT_SETUP_SECTS 4
|
||||
#define GRUB_LINUX_INITRD_MAX_ADDRESS 0x37FFFFFF
|
||||
--
|
||||
2.26.2
|
||||
|
@ -1,53 +0,0 @@
|
||||
From 1b4f4b2f5cd9b804a5bb66861b659d05d9a4f35a Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 17 Aug 2020 17:09:01 +0800
|
||||
Subject: [PATCH 1/2] linuxefi: fail kernel validation without shim protocol.
|
||||
|
||||
If certificates that signed grub are installed into db, grub can be
|
||||
booted directly. It will then boot any kernel without signature
|
||||
validation. The booted kernel will think it was booted in secureboot
|
||||
mode and will implement lockdown, yet it could have been tampered.
|
||||
|
||||
This version of the patch skips calling verification, when booted
|
||||
without secureboot.
|
||||
|
||||
CVE-2020-15705
|
||||
|
||||
Reported-by: Mathieu Trudel-Lapierre <cyphermox@ubuntu.com>
|
||||
Also-by: Dimitri John Ledkov <xnox@ubuntu.com>
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/loader/i386/efi/linux.c | 17 +++++++++++++++++
|
||||
1 file changed, 17 insertions(+)
|
||||
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
||||
index 61b2d5177..8017e8c05 100644
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -172,6 +172,23 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ if (grub_efi_secure_boot())
|
||||
+ {
|
||||
+ grub_dl_t mod;
|
||||
+
|
||||
+ mod = grub_dl_get ("shim_lock");
|
||||
+ if (!mod)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("shim_lock module is not loaded"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ if (!grub_dl_is_persistent (mod))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("shim_lock protocol is not available"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
|
||||
if (! file)
|
||||
goto fail;
|
||||
--
|
||||
2.26.2
|
||||
|
@ -1,41 +0,0 @@
|
||||
From a60cfeacdeefb21215d35c4cad025e57de900352 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 27 Aug 2020 13:18:25 +0800
|
||||
Subject: [PATCH] shim_lock: Disable GRUB_VERIFY_FLAGS_DEFER_AUTH if secure
|
||||
boot off
|
||||
|
||||
The GRUB_VERIFY_FLAGS_DEFER_AUTH is enabled regardless secure boot
|
||||
status that will cause error [1] on loading external grub modules if
|
||||
secure boot turned off in which shim protocol itself did not verify
|
||||
images so should not request verification for external modules either.
|
||||
|
||||
This patch fixed the problem by adding the secure boot status check
|
||||
before requesting other verifiers to verify external module, therefore
|
||||
external module loading can work after shim_lock module loaded and
|
||||
secure boot turned off.
|
||||
|
||||
[1] error: verification requested but nobody cares:
|
||||
(hd0,gpt10)/boot/grub2/x86_64-efi/linux.mod.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/efi/shim_lock.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/commands/efi/shim_lock.c b/grub-core/commands/efi/shim_lock.c
|
||||
index 764098cfc..18d121297 100644
|
||||
--- a/grub-core/commands/efi/shim_lock.c
|
||||
+++ b/grub-core/commands/efi/shim_lock.c
|
||||
@@ -82,7 +82,8 @@ shim_lock_init (grub_file_t io, enum grub_file_type type,
|
||||
|
||||
case GRUB_FILE_TYPE_ACPI_TABLE:
|
||||
case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE:
|
||||
- *flags = GRUB_VERIFY_FLAGS_DEFER_AUTH;
|
||||
+ if (grub_efi_secure_boot())
|
||||
+ *flags = GRUB_VERIFY_FLAGS_DEFER_AUTH;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
--
|
||||
2.26.2
|
||||
|
96
0002-efi-Make-shim_lock-GUID-and-protocol-type-public.patch
Normal file
96
0002-efi-Make-shim_lock-GUID-and-protocol-type-public.patch
Normal file
@ -0,0 +1,96 @@
|
||||
From 3b60f205de1450ed6bbe8655bfb59ea0dac4ad78 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Date: Thu, 3 Dec 2020 16:01:45 +0100
|
||||
Subject: [PATCH 02/46] efi: Make shim_lock GUID and protocol type public
|
||||
|
||||
The GUID will be used to properly detect and report UEFI Secure Boot
|
||||
status to the x86 Linux kernel. The functionality will be added by
|
||||
subsequent patches. The shim_lock protocol type is made public for
|
||||
completeness.
|
||||
|
||||
Additionally, fix formatting of four preceding GUIDs.
|
||||
|
||||
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/commands/efi/shim_lock.c | 12 ------------
|
||||
include/grub/efi/api.h | 19 +++++++++++++++----
|
||||
2 files changed, 15 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/efi/shim_lock.c b/grub-core/commands/efi/shim_lock.c
|
||||
index 764098cfc..d8f52d721 100644
|
||||
--- a/grub-core/commands/efi/shim_lock.c
|
||||
+++ b/grub-core/commands/efi/shim_lock.c
|
||||
@@ -27,18 +27,6 @@
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
-#define GRUB_EFI_SHIM_LOCK_GUID \
|
||||
- { 0x605dab50, 0xe046, 0x4300, \
|
||||
- { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } \
|
||||
- }
|
||||
-
|
||||
-struct grub_efi_shim_lock_protocol
|
||||
-{
|
||||
- grub_efi_status_t
|
||||
- (*verify) (void *buffer, grub_uint32_t size);
|
||||
-};
|
||||
-typedef struct grub_efi_shim_lock_protocol grub_efi_shim_lock_protocol_t;
|
||||
-
|
||||
static grub_efi_guid_t shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID;
|
||||
static grub_efi_shim_lock_protocol_t *sl;
|
||||
|
||||
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
|
||||
index 21efee3f3..b5cef9a88 100644
|
||||
--- a/include/grub/efi/api.h
|
||||
+++ b/include/grub/efi/api.h
|
||||
@@ -316,22 +316,27 @@
|
||||
|
||||
#define GRUB_EFI_SAL_TABLE_GUID \
|
||||
{ 0xeb9d2d32, 0x2d88, 0x11d3, \
|
||||
- { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
|
||||
+ { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
|
||||
}
|
||||
|
||||
#define GRUB_EFI_HCDP_TABLE_GUID \
|
||||
{ 0xf951938d, 0x620b, 0x42ef, \
|
||||
- { 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 } \
|
||||
+ { 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 } \
|
||||
}
|
||||
|
||||
#define GRUB_EFI_DEVICE_TREE_GUID \
|
||||
{ 0xb1b621d5, 0xf19c, 0x41a5, \
|
||||
- { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } \
|
||||
+ { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } \
|
||||
}
|
||||
|
||||
#define GRUB_EFI_VENDOR_APPLE_GUID \
|
||||
{ 0x2B0585EB, 0xD8B8, 0x49A9, \
|
||||
- { 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } \
|
||||
+ { 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } \
|
||||
+ }
|
||||
+
|
||||
+#define GRUB_EFI_SHIM_LOCK_GUID \
|
||||
+ { 0x605dab50, 0xe046, 0x4300, \
|
||||
+ { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } \
|
||||
}
|
||||
|
||||
#define GRUB_EFI_IP4_CONFIG2_PROTOCOL_GUID \
|
||||
@@ -1970,6 +1975,12 @@ struct grub_efi_ip6_config_manual_address {
|
||||
};
|
||||
typedef struct grub_efi_ip6_config_manual_address grub_efi_ip6_config_manual_address_t;
|
||||
|
||||
+struct grub_efi_shim_lock_protocol
|
||||
+{
|
||||
+ grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size);
|
||||
+};
|
||||
+typedef struct grub_efi_shim_lock_protocol grub_efi_shim_lock_protocol_t;
|
||||
+
|
||||
#if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \
|
||||
|| defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \
|
||||
|| defined(__riscv)
|
||||
--
|
||||
2.26.2
|
||||
|
146
0003-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch
Normal file
146
0003-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch
Normal file
@ -0,0 +1,146 @@
|
||||
From 10ee52fd565c9a88d9428a837c7f753a6c7fac5b Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Date: Thu, 3 Dec 2020 16:01:46 +0100
|
||||
Subject: [PATCH 03/46] efi: Return grub_efi_status_t from
|
||||
grub_efi_get_variable()
|
||||
|
||||
This is needed to properly detect and report UEFI Secure Boot status
|
||||
to the x86 Linux kernel. The functionality will be added by subsequent
|
||||
patches.
|
||||
|
||||
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/commands/efi/efifwsetup.c | 8 ++++----
|
||||
grub-core/kern/efi/efi.c | 16 +++++++++-------
|
||||
grub-core/video/efi_gop.c | 2 +-
|
||||
include/grub/efi/efi.h | 7 ++++---
|
||||
4 files changed, 18 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/efi/efifwsetup.c b/grub-core/commands/efi/efifwsetup.c
|
||||
index 7a137a72a..eaca03283 100644
|
||||
--- a/grub-core/commands/efi/efifwsetup.c
|
||||
+++ b/grub-core/commands/efi/efifwsetup.c
|
||||
@@ -38,8 +38,8 @@ grub_cmd_fwsetup (grub_command_t cmd __attribute__ ((unused)),
|
||||
grub_size_t oi_size;
|
||||
grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID;
|
||||
|
||||
- old_os_indications = grub_efi_get_variable ("OsIndications", &global,
|
||||
- &oi_size);
|
||||
+ grub_efi_get_variable ("OsIndications", &global, &oi_size,
|
||||
+ (void **) &old_os_indications);
|
||||
|
||||
if (old_os_indications != NULL && oi_size == sizeof (os_indications))
|
||||
os_indications |= *old_os_indications;
|
||||
@@ -63,8 +63,8 @@ efifwsetup_is_supported (void)
|
||||
grub_size_t oi_size = 0;
|
||||
grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID;
|
||||
|
||||
- os_indications_supported = grub_efi_get_variable ("OsIndicationsSupported",
|
||||
- &global, &oi_size);
|
||||
+ grub_efi_get_variable ("OsIndicationsSupported", &global, &oi_size,
|
||||
+ (void **) &os_indications_supported);
|
||||
|
||||
if (!os_indications_supported)
|
||||
return 0;
|
||||
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
|
||||
index 02d298b0c..9fd136694 100644
|
||||
--- a/grub-core/kern/efi/efi.c
|
||||
+++ b/grub-core/kern/efi/efi.c
|
||||
@@ -222,9 +222,9 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid,
|
||||
return grub_error (GRUB_ERR_IO, "could not set EFI variable `%s'", var);
|
||||
}
|
||||
|
||||
-void *
|
||||
+grub_efi_status_t
|
||||
grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
||||
- grub_size_t *datasize_out)
|
||||
+ grub_size_t *datasize_out, void **data_out)
|
||||
{
|
||||
grub_efi_status_t status;
|
||||
grub_efi_uintn_t datasize = 0;
|
||||
@@ -233,13 +233,14 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
||||
void *data;
|
||||
grub_size_t len, len16;
|
||||
|
||||
+ *data_out = NULL;
|
||||
*datasize_out = 0;
|
||||
|
||||
len = grub_strlen (var);
|
||||
len16 = len * GRUB_MAX_UTF16_PER_UTF8;
|
||||
var16 = grub_calloc (len16 + 1, sizeof (var16[0]));
|
||||
if (!var16)
|
||||
- return NULL;
|
||||
+ return GRUB_EFI_OUT_OF_RESOURCES;
|
||||
len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL);
|
||||
var16[len16] = 0;
|
||||
|
||||
@@ -250,14 +251,14 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
||||
if (status != GRUB_EFI_BUFFER_TOO_SMALL || !datasize)
|
||||
{
|
||||
grub_free (var16);
|
||||
- return NULL;
|
||||
+ return status;
|
||||
}
|
||||
|
||||
data = grub_malloc (datasize);
|
||||
if (!data)
|
||||
{
|
||||
grub_free (var16);
|
||||
- return NULL;
|
||||
+ return GRUB_EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, data);
|
||||
@@ -265,12 +266,13 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
||||
|
||||
if (status == GRUB_EFI_SUCCESS)
|
||||
{
|
||||
+ *data_out = data;
|
||||
*datasize_out = datasize;
|
||||
- return data;
|
||||
+ return status;
|
||||
}
|
||||
|
||||
grub_free (data);
|
||||
- return NULL;
|
||||
+ return status;
|
||||
}
|
||||
|
||||
grub_efi_boolean_t
|
||||
diff --git a/grub-core/video/efi_gop.c b/grub-core/video/efi_gop.c
|
||||
index df29853f0..962f0eb8f 100644
|
||||
--- a/grub-core/video/efi_gop.c
|
||||
+++ b/grub-core/video/efi_gop.c
|
||||
@@ -310,7 +310,7 @@ grub_video_gop_get_edid (struct grub_video_edid_info *edid_info)
|
||||
char edidname[] = "agp-internal-edid";
|
||||
grub_size_t datasize;
|
||||
grub_uint8_t *data;
|
||||
- data = grub_efi_get_variable (edidname, &efi_var_guid, &datasize);
|
||||
+ grub_efi_get_variable (edidname, &efi_var_guid, &datasize, (void **) &data);
|
||||
if (data && datasize > 16)
|
||||
{
|
||||
copy_size = datasize - 16;
|
||||
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
|
||||
index 085ee0524..f27d3a365 100644
|
||||
--- a/include/grub/efi/efi.h
|
||||
+++ b/include/grub/efi/efi.h
|
||||
@@ -77,9 +77,10 @@ grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) (grub_efi_uintn_t memo
|
||||
grub_efi_uintn_t descriptor_size,
|
||||
grub_efi_uint32_t descriptor_version,
|
||||
grub_efi_memory_descriptor_t *virtual_map);
|
||||
-void *EXPORT_FUNC (grub_efi_get_variable) (const char *variable,
|
||||
- const grub_efi_guid_t *guid,
|
||||
- grub_size_t *datasize_out);
|
||||
+grub_efi_status_t EXPORT_FUNC (grub_efi_get_variable) (const char *variable,
|
||||
+ const grub_efi_guid_t *guid,
|
||||
+ grub_size_t *datasize_out,
|
||||
+ void **data_out);
|
||||
grub_err_t
|
||||
EXPORT_FUNC (grub_efi_set_variable) (const char *var,
|
||||
const grub_efi_guid_t *guid,
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,79 @@
|
||||
From 5f2d71f71bc62c5cffbe27a9ee247803a77dc032 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Date: Thu, 3 Dec 2020 16:01:47 +0100
|
||||
Subject: [PATCH 04/46] efi: Add a function to read EFI variables with
|
||||
attributes
|
||||
|
||||
It will be used to properly detect and report UEFI Secure Boot status to
|
||||
the x86 Linux kernel. The functionality will be added by subsequent patches.
|
||||
|
||||
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
|
||||
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/kern/efi/efi.c | 16 +++++++++++++---
|
||||
include/grub/efi/efi.h | 5 +++++
|
||||
2 files changed, 18 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
|
||||
index 9fd136694..92e99b441 100644
|
||||
--- a/grub-core/kern/efi/efi.c
|
||||
+++ b/grub-core/kern/efi/efi.c
|
||||
@@ -223,8 +223,11 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid,
|
||||
}
|
||||
|
||||
grub_efi_status_t
|
||||
-grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
||||
- grub_size_t *datasize_out, void **data_out)
|
||||
+grub_efi_get_variable_with_attributes (const char *var,
|
||||
+ const grub_efi_guid_t *guid,
|
||||
+ grub_size_t *datasize_out,
|
||||
+ void **data_out,
|
||||
+ grub_efi_uint32_t *attributes)
|
||||
{
|
||||
grub_efi_status_t status;
|
||||
grub_efi_uintn_t datasize = 0;
|
||||
@@ -261,7 +264,7 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
||||
return GRUB_EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
- status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, data);
|
||||
+ status = efi_call_5 (r->get_variable, var16, guid, attributes, &datasize, data);
|
||||
grub_free (var16);
|
||||
|
||||
if (status == GRUB_EFI_SUCCESS)
|
||||
@@ -303,6 +306,13 @@ grub_efi_secure_boot (void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+grub_efi_status_t
|
||||
+grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
||||
+ grub_size_t *datasize_out, void **data_out)
|
||||
+{
|
||||
+ return grub_efi_get_variable_with_attributes (var, guid, datasize_out, data_out, NULL);
|
||||
+}
|
||||
+
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
|
||||
/* Search the mods section from the PE32/PE32+ image. This code uses
|
||||
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
|
||||
index f27d3a365..568d80030 100644
|
||||
--- a/include/grub/efi/efi.h
|
||||
+++ b/include/grub/efi/efi.h
|
||||
@@ -77,6 +77,11 @@ grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) (grub_efi_uintn_t memo
|
||||
grub_efi_uintn_t descriptor_size,
|
||||
grub_efi_uint32_t descriptor_version,
|
||||
grub_efi_memory_descriptor_t *virtual_map);
|
||||
+grub_efi_status_t EXPORT_FUNC (grub_efi_get_variable_with_attributes) (const char *variable,
|
||||
+ const grub_efi_guid_t *guid,
|
||||
+ grub_size_t *datasize_out,
|
||||
+ void **data_out,
|
||||
+ grub_efi_uint32_t *attributes);
|
||||
grub_efi_status_t EXPORT_FUNC (grub_efi_get_variable) (const char *variable,
|
||||
const grub_efi_guid_t *guid,
|
||||
grub_size_t *datasize_out,
|
||||
--
|
||||
2.26.2
|
||||
|
210
0005-efi-Add-secure-boot-detection.patch
Normal file
210
0005-efi-Add-secure-boot-detection.patch
Normal file
@ -0,0 +1,210 @@
|
||||
From 12650d0953372674fb587c2e6331257fc7a90a94 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Date: Thu, 3 Dec 2020 16:01:48 +0100
|
||||
Subject: [PATCH 05/46] efi: Add secure boot detection
|
||||
|
||||
Introduce grub_efi_get_secureboot() function which returns whether
|
||||
UEFI Secure Boot is enabled or not on UEFI systems.
|
||||
|
||||
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
|
||||
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/Makefile.am | 1 +
|
||||
grub-core/Makefile.core.def | 1 +
|
||||
grub-core/kern/efi/sb.c | 109 ++++++++++++++++++++++++++++++++++++
|
||||
include/grub/efi/sb.h | 40 +++++++++++++
|
||||
4 files changed, 151 insertions(+)
|
||||
create mode 100644 grub-core/kern/efi/sb.c
|
||||
create mode 100644 include/grub/efi/sb.h
|
||||
|
||||
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
|
||||
index ede596170..5ff3afd62 100644
|
||||
--- a/grub-core/Makefile.am
|
||||
+++ b/grub-core/Makefile.am
|
||||
@@ -71,6 +71,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 ce4f71ebe..072b1628c 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/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/efi/sb.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/kern/efi/sb.c b/grub-core/kern/efi/sb.c
|
||||
new file mode 100644
|
||||
index 000000000..19658d962
|
||||
--- /dev/null
|
||||
+++ b/grub-core/kern/efi/sb.c
|
||||
@@ -0,0 +1,109 @@
|
||||
+/*
|
||||
+ * 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/>.
|
||||
+ *
|
||||
+ * UEFI Secure Boot related checkings.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/efi/efi.h>
|
||||
+#include <grub/efi/pe32.h>
|
||||
+#include <grub/efi/sb.h>
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/i386/linux.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/types.h>
|
||||
+
|
||||
+/*
|
||||
+ * Determine whether we're in secure boot mode.
|
||||
+ *
|
||||
+ * Please keep the logic in sync with the Linux kernel,
|
||||
+ * drivers/firmware/efi/libstub/secureboot.c:efi_get_secureboot().
|
||||
+ */
|
||||
+grub_uint8_t
|
||||
+grub_efi_get_secureboot (void)
|
||||
+{
|
||||
+ static grub_efi_guid_t efi_variable_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID;
|
||||
+ static grub_efi_guid_t efi_shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID;
|
||||
+ grub_efi_status_t status;
|
||||
+ grub_efi_uint32_t attr = 0;
|
||||
+ grub_size_t size = 0;
|
||||
+ grub_uint8_t *secboot = NULL;
|
||||
+ grub_uint8_t *setupmode = NULL;
|
||||
+ grub_uint8_t *moksbstate = NULL;
|
||||
+ grub_uint8_t secureboot = GRUB_EFI_SECUREBOOT_MODE_UNKNOWN;
|
||||
+ const char *secureboot_str = "UNKNOWN";
|
||||
+
|
||||
+ status = grub_efi_get_variable ("SecureBoot", &efi_variable_guid,
|
||||
+ &size, (void **) &secboot);
|
||||
+
|
||||
+ if (status == GRUB_EFI_NOT_FOUND)
|
||||
+ {
|
||||
+ secureboot = GRUB_EFI_SECUREBOOT_MODE_DISABLED;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (status != GRUB_EFI_SUCCESS)
|
||||
+ goto out;
|
||||
+
|
||||
+ status = grub_efi_get_variable ("SetupMode", &efi_variable_guid,
|
||||
+ &size, (void **) &setupmode);
|
||||
+
|
||||
+ if (status != GRUB_EFI_SUCCESS)
|
||||
+ goto out;
|
||||
+
|
||||
+ if ((*secboot == 0) || (*setupmode == 1))
|
||||
+ {
|
||||
+ secureboot = GRUB_EFI_SECUREBOOT_MODE_DISABLED;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * See if a user has put the shim into insecure mode. If so, and if the
|
||||
+ * variable doesn't have the runtime attribute set, we might as well
|
||||
+ * honor that.
|
||||
+ */
|
||||
+ status = grub_efi_get_variable_with_attributes ("MokSBState", &efi_shim_lock_guid,
|
||||
+ &size, (void **) &moksbstate, &attr);
|
||||
+
|
||||
+ /* If it fails, we don't care why. Default to secure. */
|
||||
+ if (status != GRUB_EFI_SUCCESS)
|
||||
+ {
|
||||
+ secureboot = GRUB_EFI_SECUREBOOT_MODE_ENABLED;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (!(attr & GRUB_EFI_VARIABLE_RUNTIME_ACCESS) && *moksbstate == 1)
|
||||
+ {
|
||||
+ secureboot = GRUB_EFI_SECUREBOOT_MODE_DISABLED;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ secureboot = GRUB_EFI_SECUREBOOT_MODE_ENABLED;
|
||||
+
|
||||
+ out:
|
||||
+ grub_free (moksbstate);
|
||||
+ grub_free (setupmode);
|
||||
+ grub_free (secboot);
|
||||
+
|
||||
+ if (secureboot == GRUB_EFI_SECUREBOOT_MODE_DISABLED)
|
||||
+ secureboot_str = "Disabled";
|
||||
+ else if (secureboot == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
|
||||
+ secureboot_str = "Enabled";
|
||||
+
|
||||
+ grub_dprintf ("efi", "UEFI Secure Boot state: %s\n", secureboot_str);
|
||||
+
|
||||
+ return secureboot;
|
||||
+}
|
||||
diff --git a/include/grub/efi/sb.h b/include/grub/efi/sb.h
|
||||
new file mode 100644
|
||||
index 000000000..a33d985e3
|
||||
--- /dev/null
|
||||
+++ b/include/grub/efi/sb.h
|
||||
@@ -0,0 +1,40 @@
|
||||
+/*
|
||||
+ * 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_EFI_SB_H
|
||||
+#define GRUB_EFI_SB_H 1
|
||||
+
|
||||
+#include <grub/types.h>
|
||||
+#include <grub/dl.h>
|
||||
+
|
||||
+#define GRUB_EFI_SECUREBOOT_MODE_UNSET 0
|
||||
+#define GRUB_EFI_SECUREBOOT_MODE_UNKNOWN 1
|
||||
+#define GRUB_EFI_SECUREBOOT_MODE_DISABLED 2
|
||||
+#define GRUB_EFI_SECUREBOOT_MODE_ENABLED 3
|
||||
+
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+extern grub_uint8_t
|
||||
+EXPORT_FUNC (grub_efi_get_secureboot) (void);
|
||||
+#else
|
||||
+static inline grub_uint8_t
|
||||
+grub_efi_get_secureboot (void)
|
||||
+{
|
||||
+ return GRUB_EFI_SECUREBOOT_MODE_UNSET;
|
||||
+}
|
||||
+#endif
|
||||
+#endif /* GRUB_EFI_SB_H */
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,90 @@
|
||||
From a0659724e8fb6ddc9b6db68973e50637cf781605 Mon Sep 17 00:00:00 2001
|
||||
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Date: Thu, 3 Dec 2020 16:01:49 +0100
|
||||
Subject: [PATCH 06/46] efi: Only register shim_lock verifier if shim_lock
|
||||
protocol is found and SB enabled
|
||||
|
||||
The shim_lock module registers a verifier to call shim's verify, but the
|
||||
handler is registered even when the shim_lock protocol was not installed.
|
||||
|
||||
This doesn't cause a NULL pointer dereference in shim_lock_write() because
|
||||
the shim_lock_init() function just returns GRUB_ERR_NONE if sl isn't set.
|
||||
|
||||
But in that case there's no point to even register the shim_lock verifier
|
||||
since won't do anything. Additionally, it is only useful when Secure Boot
|
||||
is enabled.
|
||||
|
||||
Finally, don't assume that the shim_lock protocol will always be present
|
||||
when the shim_lock_write() function is called, and check for it on every
|
||||
call to this function.
|
||||
|
||||
Reported-by: Michael Chang <mchang@suse.com>
|
||||
Reported-by: Peter Jones <pjones@redhat.com>
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/commands/efi/shim_lock.c | 17 ++++++++++-------
|
||||
1 file changed, 10 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/efi/shim_lock.c b/grub-core/commands/efi/shim_lock.c
|
||||
index d8f52d721..f7f3109d6 100644
|
||||
--- a/grub-core/commands/efi/shim_lock.c
|
||||
+++ b/grub-core/commands/efi/shim_lock.c
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <grub/dl.h>
|
||||
#include <grub/efi/efi.h>
|
||||
+#include <grub/efi/sb.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/misc.h>
|
||||
@@ -28,7 +29,6 @@
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static grub_efi_guid_t shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID;
|
||||
-static grub_efi_shim_lock_protocol_t *sl;
|
||||
|
||||
/* List of modules which cannot be loaded if UEFI secure boot mode is enabled. */
|
||||
static const char * const disabled_mods[] = {"iorw", "memrw", "wrmsr", NULL};
|
||||
@@ -43,9 +43,6 @@ shim_lock_init (grub_file_t io, enum grub_file_type type,
|
||||
|
||||
*flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
|
||||
|
||||
- if (!sl)
|
||||
- return GRUB_ERR_NONE;
|
||||
-
|
||||
switch (type & GRUB_FILE_TYPE_MASK)
|
||||
{
|
||||
case GRUB_FILE_TYPE_GRUB_MODULE:
|
||||
@@ -100,6 +97,11 @@ shim_lock_init (grub_file_t io, enum grub_file_type type,
|
||||
static grub_err_t
|
||||
shim_lock_write (void *context __attribute__ ((unused)), void *buf, grub_size_t size)
|
||||
{
|
||||
+ grub_efi_shim_lock_protocol_t *sl = grub_efi_locate_protocol (&shim_lock_guid, 0);
|
||||
+
|
||||
+ if (sl == NULL)
|
||||
+ return grub_error (GRUB_ERR_ACCESS_DENIED, N_("shim_lock protocol not found"));
|
||||
+
|
||||
if (sl->verify (buf, size) != GRUB_EFI_SUCCESS)
|
||||
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad shim signature"));
|
||||
|
||||
@@ -115,12 +117,13 @@ struct grub_file_verifier shim_lock =
|
||||
|
||||
GRUB_MOD_INIT(shim_lock)
|
||||
{
|
||||
- sl = grub_efi_locate_protocol (&shim_lock_guid, 0);
|
||||
- grub_verifier_register (&shim_lock);
|
||||
+ grub_efi_shim_lock_protocol_t *sl = grub_efi_locate_protocol (&shim_lock_guid, 0);
|
||||
|
||||
- if (!sl)
|
||||
+ if (sl == NULL || grub_efi_get_secureboot () != GRUB_EFI_SECUREBOOT_MODE_ENABLED)
|
||||
return;
|
||||
|
||||
+ grub_verifier_register (&shim_lock);
|
||||
+
|
||||
grub_dl_set_persistent (mod);
|
||||
}
|
||||
|
||||
--
|
||||
2.26.2
|
||||
|
@ -1,97 +0,0 @@
|
||||
From 496890ebd2605eb1ff15f8d96c30b5d617f1bb85 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 6 Nov 2020 11:19:06 +0000
|
||||
Subject: [PATCH 7/9] linuxefi: fail kernel validation without shim protocol.
|
||||
|
||||
If certificates that signed grub are installed into db, grub can be
|
||||
booted directly. It will then boot any kernel without signature
|
||||
validation. The booted kernel will think it was booted in secureboot
|
||||
mode and will implement lockdown, yet it could have been tampered.
|
||||
|
||||
This version of the patch skips calling verification, when booted
|
||||
without secureboot. And is indented with gnu ident.
|
||||
|
||||
CVE-2020-15705
|
||||
|
||||
Reported-by: Mathieu Trudel-Lapierre <cyphermox@ubuntu.com>
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/loader/arm64/efi/linux.c | 38 +++++++++++++++++++++++-------
|
||||
1 file changed, 29 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/arm64/efi/linux.c b/grub-core/loader/arm64/efi/linux.c
|
||||
index a4041be5c..0e5782caa 100644
|
||||
--- a/grub-core/loader/arm64/efi/linux.c
|
||||
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||
@@ -58,21 +58,35 @@ struct grub_efi_shim_lock
|
||||
};
|
||||
typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
|
||||
|
||||
-static grub_efi_boolean_t
|
||||
+// Returns 1 on success, -1 on error, 0 when not available
|
||||
+static int
|
||||
grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
|
||||
{
|
||||
grub_efi_guid_t guid = SHIM_LOCK_GUID;
|
||||
grub_efi_shim_lock_t *shim_lock;
|
||||
+ grub_efi_status_t status;
|
||||
|
||||
shim_lock = grub_efi_locate_protocol(&guid, NULL);
|
||||
-
|
||||
+ grub_dprintf ("secureboot", "shim_lock: %p\n", shim_lock);
|
||||
if (!shim_lock)
|
||||
- return 1;
|
||||
+ {
|
||||
+ grub_dprintf ("secureboot", "shim not available\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
|
||||
- if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS)
|
||||
- return 1;
|
||||
+ grub_dprintf ("secureboot", "Asking shim to verify kernel signature\n");
|
||||
+ status = shim_lock->verify (data, size);
|
||||
+ grub_dprintf ("secureboot", "shim_lock->verify(): %ld\n", (long int)status);
|
||||
+ if (status == GRUB_EFI_SUCCESS)
|
||||
+ {
|
||||
+ grub_dprintf ("secureboot", "Kernel signature verification passed\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
|
||||
- return 0;
|
||||
+ grub_dprintf ("secureboot", "Kernel signature verification failed (0x%lx)\n",
|
||||
+ (unsigned long) status);
|
||||
+
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
@@ -399,6 +413,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
struct linux_arch_kernel_header lh;
|
||||
struct grub_armxx_linux_pe_header *pe;
|
||||
grub_err_t err;
|
||||
+ int rc;
|
||||
|
||||
grub_dl_ref (my_mod);
|
||||
|
||||
@@ -443,10 +458,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
|
||||
grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
|
||||
|
||||
- if (!grub_linuxefi_secure_validate (kernel_addr, kernel_size))
|
||||
+ if (grub_efi_secure_boot ())
|
||||
{
|
||||
- grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
|
||||
- goto fail;
|
||||
+ rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size);
|
||||
+ if (rc <= 0)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_INVALID_COMMAND,
|
||||
+ N_("%s has invalid signature"), argv[0]);
|
||||
+ goto fail;
|
||||
+ }
|
||||
}
|
||||
|
||||
pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
|
||||
--
|
||||
2.26.2
|
||||
|
129
0007-verifiers-Move-verifiers-API-to-kernel-image.patch
Normal file
129
0007-verifiers-Move-verifiers-API-to-kernel-image.patch
Normal file
@ -0,0 +1,129 @@
|
||||
From ea5950d8597278ba9066f24d7abcee403f825668 Mon Sep 17 00:00:00 2001
|
||||
From: Marco A Benatto <mbenatto@redhat.com>
|
||||
Date: Wed, 23 Sep 2020 11:33:33 -0400
|
||||
Subject: [PATCH 07/46] verifiers: Move verifiers API to kernel image
|
||||
|
||||
Move verifiers API from a module to the kernel image, so it can be
|
||||
used there as well. There are no functional changes in this patch.
|
||||
|
||||
Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/Makefile.am | 1 +
|
||||
grub-core/Makefile.core.def | 6 +-----
|
||||
grub-core/kern/main.c | 4 ++++
|
||||
grub-core/{commands => kern}/verifiers.c | 8 ++------
|
||||
include/grub/verify.h | 9 ++++++---
|
||||
5 files changed, 14 insertions(+), 14 deletions(-)
|
||||
rename grub-core/{commands => kern}/verifiers.c (97%)
|
||||
|
||||
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
|
||||
index 5ff3afd62..3569b7101 100644
|
||||
--- a/grub-core/Makefile.am
|
||||
+++ b/grub-core/Makefile.am
|
||||
@@ -91,6 +91,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
|
||||
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/verify.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index 072b1628c..5cb869f5b 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -140,6 +140,7 @@ kernel = {
|
||||
common = kern/rescue_parser.c;
|
||||
common = kern/rescue_reader.c;
|
||||
common = kern/term.c;
|
||||
+ common = kern/verifiers.c;
|
||||
|
||||
noemu = kern/compiler-rt.c;
|
||||
noemu = kern/mm.c;
|
||||
@@ -943,11 +944,6 @@ module = {
|
||||
cppflags = '-I$(srcdir)/lib/posix_wrap';
|
||||
};
|
||||
|
||||
-module = {
|
||||
- name = verifiers;
|
||||
- common = commands/verifiers.c;
|
||||
-};
|
||||
-
|
||||
module = {
|
||||
name = shim_lock;
|
||||
common = commands/efi/shim_lock.c;
|
||||
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
|
||||
index 9cad0c448..73967e2f5 100644
|
||||
--- a/grub-core/kern/main.c
|
||||
+++ b/grub-core/kern/main.c
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <grub/command.h>
|
||||
#include <grub/reader.h>
|
||||
#include <grub/parser.h>
|
||||
+#include <grub/verify.h>
|
||||
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
#include <grub/machine/memory.h>
|
||||
@@ -274,6 +275,9 @@ grub_main (void)
|
||||
grub_printf ("Welcome to GRUB!\n\n");
|
||||
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
|
||||
|
||||
+ /* Init verifiers API. */
|
||||
+ grub_verifiers_init ();
|
||||
+
|
||||
grub_load_config ();
|
||||
|
||||
grub_boot_time ("Before loading embedded modules.");
|
||||
diff --git a/grub-core/commands/verifiers.c b/grub-core/kern/verifiers.c
|
||||
similarity index 97%
|
||||
rename from grub-core/commands/verifiers.c
|
||||
rename to grub-core/kern/verifiers.c
|
||||
index 7b9297cd3..3d19bffd1 100644
|
||||
--- a/grub-core/commands/verifiers.c
|
||||
+++ b/grub-core/kern/verifiers.c
|
||||
@@ -218,12 +218,8 @@ grub_verify_string (char *str, enum grub_verify_string_type type)
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
-GRUB_MOD_INIT(verifiers)
|
||||
+void
|
||||
+grub_verifiers_init (void)
|
||||
{
|
||||
grub_file_filter_register (GRUB_FILE_FILTER_VERIFY, grub_verifiers_open);
|
||||
}
|
||||
-
|
||||
-GRUB_MOD_FINI(verifiers)
|
||||
-{
|
||||
- grub_file_filter_unregister (GRUB_FILE_FILTER_VERIFY);
|
||||
-}
|
||||
diff --git a/include/grub/verify.h b/include/grub/verify.h
|
||||
index ea0491433..cd129c398 100644
|
||||
--- a/include/grub/verify.h
|
||||
+++ b/include/grub/verify.h
|
||||
@@ -64,7 +64,10 @@ struct grub_file_verifier
|
||||
grub_err_t (*verify_string) (char *str, enum grub_verify_string_type type);
|
||||
};
|
||||
|
||||
-extern struct grub_file_verifier *grub_file_verifiers;
|
||||
+extern struct grub_file_verifier *EXPORT_VAR (grub_file_verifiers);
|
||||
+
|
||||
+extern void
|
||||
+grub_verifiers_init (void);
|
||||
|
||||
static inline void
|
||||
grub_verifier_register (struct grub_file_verifier *ver)
|
||||
@@ -78,7 +81,7 @@ grub_verifier_unregister (struct grub_file_verifier *ver)
|
||||
grub_list_remove (GRUB_AS_LIST (ver));
|
||||
}
|
||||
|
||||
-grub_err_t
|
||||
-grub_verify_string (char *str, enum grub_verify_string_type type);
|
||||
+extern grub_err_t
|
||||
+EXPORT_FUNC (grub_verify_string) (char *str, enum grub_verify_string_type type);
|
||||
|
||||
#endif /* ! GRUB_VERIFY_HEADER */
|
||||
--
|
||||
2.26.2
|
||||
|
368
0008-efi-Move-the-shim_lock-verifier-to-the-GRUB-core.patch
Normal file
368
0008-efi-Move-the-shim_lock-verifier-to-the-GRUB-core.patch
Normal file
@ -0,0 +1,368 @@
|
||||
From b16919b634129e377431e96bc3252179fed83a40 Mon Sep 17 00:00:00 2001
|
||||
From: Marco A Benatto <mbenatto@redhat.com>
|
||||
Date: Wed, 23 Sep 2020 14:21:14 -0400
|
||||
Subject: [PATCH 08/46] efi: Move the shim_lock verifier to the GRUB core
|
||||
|
||||
Move the shim_lock verifier from its own module into the core image. The
|
||||
Secure Boot lockdown mechanism has the intent to prevent the load of any
|
||||
unsigned code or binary when Secure Boot is enabled.
|
||||
|
||||
The reason is that GRUB must be able to prevent executing untrusted code
|
||||
if UEFI Secure Boot is enabled, without depending on external modules.
|
||||
|
||||
Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
docs/grub.texi | 9 +-
|
||||
grub-core/Makefile.core.def | 6 --
|
||||
grub-core/commands/efi/shim_lock.c | 133 -----------------------------
|
||||
grub-core/kern/efi/init.c | 4 +
|
||||
grub-core/kern/efi/sb.c | 105 +++++++++++++++++++++++
|
||||
include/grub/efi/sb.h | 3 +
|
||||
6 files changed, 117 insertions(+), 143 deletions(-)
|
||||
delete mode 100644 grub-core/commands/efi/shim_lock.c
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index bd0e02057..d3fbc81db 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -5764,15 +5764,16 @@ secure boot chain.
|
||||
@section UEFI secure boot and shim support
|
||||
|
||||
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}.
|
||||
+boot and the shim. This functionality is provided by the shim_lock verifier. It
|
||||
+is built into the @file{core.img} and is registered if the UEFI secure boot is
|
||||
+enabled.
|
||||
+
|
||||
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.
|
||||
+shim_lock verifier logic.
|
||||
|
||||
@node Measured Boot
|
||||
@section Measuring boot components
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index 5cb869f5b..8c8f8c579 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -944,12 +944,6 @@ module = {
|
||||
cppflags = '-I$(srcdir)/lib/posix_wrap';
|
||||
};
|
||||
|
||||
-module = {
|
||||
- name = shim_lock;
|
||||
- common = commands/efi/shim_lock.c;
|
||||
- enable = x86_64_efi;
|
||||
-};
|
||||
-
|
||||
module = {
|
||||
name = hdparm;
|
||||
common = commands/hdparm.c;
|
||||
diff --git a/grub-core/commands/efi/shim_lock.c b/grub-core/commands/efi/shim_lock.c
|
||||
deleted file mode 100644
|
||||
index f7f3109d6..000000000
|
||||
--- a/grub-core/commands/efi/shim_lock.c
|
||||
+++ /dev/null
|
||||
@@ -1,133 +0,0 @@
|
||||
-/*
|
||||
- * GRUB -- GRand Unified Bootloader
|
||||
- * Copyright (C) 2017 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/>.
|
||||
- *
|
||||
- * EFI shim lock verifier.
|
||||
- */
|
||||
-
|
||||
-#include <grub/dl.h>
|
||||
-#include <grub/efi/efi.h>
|
||||
-#include <grub/efi/sb.h>
|
||||
-#include <grub/err.h>
|
||||
-#include <grub/file.h>
|
||||
-#include <grub/misc.h>
|
||||
-#include <grub/verify.h>
|
||||
-
|
||||
-GRUB_MOD_LICENSE ("GPLv3+");
|
||||
-
|
||||
-static grub_efi_guid_t shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID;
|
||||
-
|
||||
-/* List of modules which cannot be loaded if UEFI secure boot mode is enabled. */
|
||||
-static const char * const disabled_mods[] = {"iorw", "memrw", "wrmsr", NULL};
|
||||
-
|
||||
-static grub_err_t
|
||||
-shim_lock_init (grub_file_t io, enum grub_file_type type,
|
||||
- void **context __attribute__ ((unused)),
|
||||
- enum grub_verify_flags *flags)
|
||||
-{
|
||||
- const char *b, *e;
|
||||
- int i;
|
||||
-
|
||||
- *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
|
||||
-
|
||||
- switch (type & GRUB_FILE_TYPE_MASK)
|
||||
- {
|
||||
- case GRUB_FILE_TYPE_GRUB_MODULE:
|
||||
- /* Establish GRUB module name. */
|
||||
- b = grub_strrchr (io->name, '/');
|
||||
- e = grub_strrchr (io->name, '.');
|
||||
-
|
||||
- b = b ? (b + 1) : io->name;
|
||||
- e = e ? e : io->name + grub_strlen (io->name);
|
||||
- e = (e > b) ? e : io->name + grub_strlen (io->name);
|
||||
-
|
||||
- for (i = 0; disabled_mods[i]; i++)
|
||||
- if (!grub_strncmp (b, disabled_mods[i], grub_strlen (b) - grub_strlen (e)))
|
||||
- {
|
||||
- grub_error (GRUB_ERR_ACCESS_DENIED,
|
||||
- N_("module cannot be loaded in UEFI secure boot mode: %s"),
|
||||
- io->name);
|
||||
- return GRUB_ERR_ACCESS_DENIED;
|
||||
- }
|
||||
-
|
||||
- /* Fall through. */
|
||||
-
|
||||
- case GRUB_FILE_TYPE_ACPI_TABLE:
|
||||
- case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE:
|
||||
- *flags = GRUB_VERIFY_FLAGS_DEFER_AUTH;
|
||||
-
|
||||
- return GRUB_ERR_NONE;
|
||||
-
|
||||
- case GRUB_FILE_TYPE_LINUX_KERNEL:
|
||||
- case GRUB_FILE_TYPE_MULTIBOOT_KERNEL:
|
||||
- case GRUB_FILE_TYPE_BSD_KERNEL:
|
||||
- case GRUB_FILE_TYPE_XNU_KERNEL:
|
||||
- case GRUB_FILE_TYPE_PLAN9_KERNEL:
|
||||
- for (i = 0; disabled_mods[i]; i++)
|
||||
- if (grub_dl_get (disabled_mods[i]))
|
||||
- {
|
||||
- grub_error (GRUB_ERR_ACCESS_DENIED,
|
||||
- N_("cannot boot due to dangerous module in memory: %s"),
|
||||
- disabled_mods[i]);
|
||||
- return GRUB_ERR_ACCESS_DENIED;
|
||||
- }
|
||||
-
|
||||
- *flags = GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
|
||||
-
|
||||
- /* Fall through. */
|
||||
-
|
||||
- default:
|
||||
- return GRUB_ERR_NONE;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static grub_err_t
|
||||
-shim_lock_write (void *context __attribute__ ((unused)), void *buf, grub_size_t size)
|
||||
-{
|
||||
- grub_efi_shim_lock_protocol_t *sl = grub_efi_locate_protocol (&shim_lock_guid, 0);
|
||||
-
|
||||
- if (sl == NULL)
|
||||
- return grub_error (GRUB_ERR_ACCESS_DENIED, N_("shim_lock protocol not found"));
|
||||
-
|
||||
- if (sl->verify (buf, size) != GRUB_EFI_SUCCESS)
|
||||
- return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad shim signature"));
|
||||
-
|
||||
- return GRUB_ERR_NONE;
|
||||
-}
|
||||
-
|
||||
-struct grub_file_verifier shim_lock =
|
||||
- {
|
||||
- .name = "shim_lock",
|
||||
- .init = shim_lock_init,
|
||||
- .write = shim_lock_write
|
||||
- };
|
||||
-
|
||||
-GRUB_MOD_INIT(shim_lock)
|
||||
-{
|
||||
- grub_efi_shim_lock_protocol_t *sl = grub_efi_locate_protocol (&shim_lock_guid, 0);
|
||||
-
|
||||
- if (sl == NULL || grub_efi_get_secureboot () != GRUB_EFI_SECUREBOOT_MODE_ENABLED)
|
||||
- return;
|
||||
-
|
||||
- grub_verifier_register (&shim_lock);
|
||||
-
|
||||
- grub_dl_set_persistent (mod);
|
||||
-}
|
||||
-
|
||||
-GRUB_MOD_FINI(shim_lock)
|
||||
-{
|
||||
- grub_verifier_unregister (&shim_lock);
|
||||
-}
|
||||
diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
|
||||
index 5c7876e42..9c143eed7 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/efi/sb.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/env.h>
|
||||
@@ -40,6 +41,9 @@ grub_efi_init (void)
|
||||
/* Initialize the memory management system. */
|
||||
grub_efi_mm_init ();
|
||||
|
||||
+ /* Register the shim_lock verifier if UEFI Secure Boot is enabled. */
|
||||
+ grub_shim_lock_verifier_setup ();
|
||||
+
|
||||
efi_call_4 (grub_efi_system_table->boot_services->set_watchdog_timer,
|
||||
0, 0, 0, NULL);
|
||||
|
||||
diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c
|
||||
index 19658d962..8bd5e936d 100644
|
||||
--- a/grub-core/kern/efi/sb.c
|
||||
+++ b/grub-core/kern/efi/sb.c
|
||||
@@ -22,9 +22,16 @@
|
||||
#include <grub/efi/pe32.h>
|
||||
#include <grub/efi/sb.h>
|
||||
#include <grub/err.h>
|
||||
+#include <grub/file.h>
|
||||
#include <grub/i386/linux.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/types.h>
|
||||
+#include <grub/verify.h>
|
||||
+
|
||||
+static grub_efi_guid_t shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID;
|
||||
+
|
||||
+/* List of modules which cannot be loaded if UEFI secure boot mode is enabled. */
|
||||
+static const char * const disabled_mods[] = {"iorw", "memrw", "wrmsr", NULL};
|
||||
|
||||
/*
|
||||
* Determine whether we're in secure boot mode.
|
||||
@@ -107,3 +114,101 @@ grub_efi_get_secureboot (void)
|
||||
|
||||
return secureboot;
|
||||
}
|
||||
+
|
||||
+static grub_err_t
|
||||
+shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)),
|
||||
+ enum grub_file_type type,
|
||||
+ void **context __attribute__ ((unused)),
|
||||
+ enum grub_verify_flags *flags)
|
||||
+{
|
||||
+ const char *b, *e;
|
||||
+ int i;
|
||||
+
|
||||
+ *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
|
||||
+
|
||||
+ switch (type & GRUB_FILE_TYPE_MASK)
|
||||
+ {
|
||||
+ case GRUB_FILE_TYPE_GRUB_MODULE:
|
||||
+ /* Establish GRUB module name. */
|
||||
+ b = grub_strrchr (io->name, '/');
|
||||
+ e = grub_strrchr (io->name, '.');
|
||||
+
|
||||
+ b = b ? (b + 1) : io->name;
|
||||
+ e = e ? e : io->name + grub_strlen (io->name);
|
||||
+ e = (e > b) ? e : io->name + grub_strlen (io->name);
|
||||
+
|
||||
+ for (i = 0; disabled_mods[i]; i++)
|
||||
+ if (!grub_strncmp (b, disabled_mods[i], grub_strlen (b) - grub_strlen (e)))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED,
|
||||
+ N_("module cannot be loaded in UEFI secure boot mode: %s"),
|
||||
+ io->name);
|
||||
+ return GRUB_ERR_ACCESS_DENIED;
|
||||
+ }
|
||||
+
|
||||
+ /* Fall through. */
|
||||
+
|
||||
+ case GRUB_FILE_TYPE_ACPI_TABLE:
|
||||
+ case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE:
|
||||
+ *flags = GRUB_VERIFY_FLAGS_DEFER_AUTH;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ case GRUB_FILE_TYPE_LINUX_KERNEL:
|
||||
+ case GRUB_FILE_TYPE_MULTIBOOT_KERNEL:
|
||||
+ case GRUB_FILE_TYPE_BSD_KERNEL:
|
||||
+ case GRUB_FILE_TYPE_XNU_KERNEL:
|
||||
+ case GRUB_FILE_TYPE_PLAN9_KERNEL:
|
||||
+ for (i = 0; disabled_mods[i]; i++)
|
||||
+ if (grub_dl_get (disabled_mods[i]))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED,
|
||||
+ N_("cannot boot due to dangerous module in memory: %s"),
|
||||
+ disabled_mods[i]);
|
||||
+ return GRUB_ERR_ACCESS_DENIED;
|
||||
+ }
|
||||
+
|
||||
+ *flags = GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
|
||||
+
|
||||
+ /* Fall through. */
|
||||
+
|
||||
+ default:
|
||||
+ return GRUB_ERR_NONE;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+shim_lock_verifier_write (void *context __attribute__ ((unused)), void *buf, grub_size_t size)
|
||||
+{
|
||||
+ grub_efi_shim_lock_protocol_t *sl = grub_efi_locate_protocol (&shim_lock_guid, 0);
|
||||
+
|
||||
+ if (!sl)
|
||||
+ return grub_error (GRUB_ERR_ACCESS_DENIED, N_("shim_lock protocol not found"));
|
||||
+
|
||||
+ if (sl->verify (buf, size) != GRUB_EFI_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad shim signature"));
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+struct grub_file_verifier shim_lock_verifier =
|
||||
+ {
|
||||
+ .name = "shim_lock_verifier",
|
||||
+ .init = shim_lock_verifier_init,
|
||||
+ .write = shim_lock_verifier_write
|
||||
+ };
|
||||
+
|
||||
+void
|
||||
+grub_shim_lock_verifier_setup (void)
|
||||
+{
|
||||
+ grub_efi_shim_lock_protocol_t *sl =
|
||||
+ grub_efi_locate_protocol (&shim_lock_guid, 0);
|
||||
+
|
||||
+ if (!sl)
|
||||
+ return;
|
||||
+
|
||||
+ if (grub_efi_get_secureboot () != GRUB_EFI_SECUREBOOT_MODE_ENABLED)
|
||||
+ return;
|
||||
+
|
||||
+ grub_verifier_register (&shim_lock_verifier);
|
||||
+}
|
||||
diff --git a/include/grub/efi/sb.h b/include/grub/efi/sb.h
|
||||
index a33d985e3..30c4335bb 100644
|
||||
--- a/include/grub/efi/sb.h
|
||||
+++ b/include/grub/efi/sb.h
|
||||
@@ -30,6 +30,9 @@
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
extern grub_uint8_t
|
||||
EXPORT_FUNC (grub_efi_get_secureboot) (void);
|
||||
+
|
||||
+extern void
|
||||
+grub_shim_lock_verifier_setup (void);
|
||||
#else
|
||||
static inline grub_uint8_t
|
||||
grub_efi_get_secureboot (void)
|
||||
--
|
||||
2.26.2
|
||||
|
430
0009-kern-Add-lockdown-support.patch
Normal file
430
0009-kern-Add-lockdown-support.patch
Normal file
@ -0,0 +1,430 @@
|
||||
From 1aebb5645e749917034444b24b88825ea557cae9 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 09/46] 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>
|
||||
---
|
||||
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 6cd71cbb2..2a1a886f6 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 ee389fd83..635ec7231 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 d3fbc81db..a459a71e4 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -5598,6 +5598,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
|
||||
@@ -5812,6 +5813,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 3569b7101..6b2e5e139 100644
|
||||
--- a/grub-core/Makefile.am
|
||||
+++ b/grub-core/Makefile.am
|
||||
@@ -80,6 +80,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fs.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i18n.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/list.h
|
||||
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lockdown.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/misc.h
|
||||
if COND_emu
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/compiler-rt-emu.h
|
||||
@@ -378,8 +379,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 8c8f8c579..a00e7f983 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -205,6 +205,7 @@ kernel = {
|
||||
efi = kern/acpi.c;
|
||||
efi = kern/efi/acpi.c;
|
||||
efi = kern/efi/sb.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 69574e2b0..90a5ca24a 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 acd721879..4aabcd4b5 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 000000000..1e56c0b80
|
||||
--- /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 eee4e847e..2a6f7f846 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 19fe59266..fe9248b8b 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 000000000..40531fa82
|
||||
--- /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 */
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,57 @@
|
||||
From 959db537b12c5e76c244ccc51cbbed7f27b0abe2 Mon Sep 17 00:00:00 2001
|
||||
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Date: Tue, 2 Feb 2021 19:59:48 +0100
|
||||
Subject: [PATCH 10/46] 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>
|
||||
---
|
||||
docs/grub.texi | 3 +++
|
||||
grub-core/kern/lockdown.c | 4 ++++
|
||||
2 files changed, 7 insertions(+)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index a459a71e4..3a4d18e06 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -5820,6 +5820,9 @@ The GRUB can be locked down when booted on a secure boot environment, for exampl
|
||||
if the UEFI secure boot is enabled. On a locked down configuration, the GRUB will
|
||||
be restricted and some operations/commands cannot be executed.
|
||||
|
||||
+The @samp{lockdown} variable is set to @samp{y} when the GRUB is locked down.
|
||||
+Otherwise it does not exit.
|
||||
+
|
||||
@node Platform limitations
|
||||
@chapter Platform limitations
|
||||
|
||||
diff --git a/grub-core/kern/lockdown.c b/grub-core/kern/lockdown.c
|
||||
index 1e56c0b80..0bc70fd42 100644
|
||||
--- a/grub-core/kern/lockdown.c
|
||||
+++ b/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
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,49 @@
|
||||
From a255fd33e08015335aeac619348536b5fda8303e Mon Sep 17 00:00:00 2001
|
||||
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Date: Mon, 28 Sep 2020 20:08:29 +0200
|
||||
Subject: [PATCH 11/46] 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>
|
||||
---
|
||||
grub-core/kern/efi/init.c | 12 ++++++++++--
|
||||
1 file changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
|
||||
index 9c143eed7..08ef2b8f4 100644
|
||||
--- a/grub-core/kern/efi/init.c
|
||||
+++ b/grub-core/kern/efi/init.c
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <grub/efi/console.h>
|
||||
#include <grub/efi/disk.h>
|
||||
#include <grub/efi/sb.h>
|
||||
+#include <grub/lockdown.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/env.h>
|
||||
@@ -41,8 +42,15 @@ grub_efi_init (void)
|
||||
/* Initialize the memory management system. */
|
||||
grub_efi_mm_init ();
|
||||
|
||||
- /* Register the shim_lock verifier if UEFI Secure Boot is enabled. */
|
||||
- grub_shim_lock_verifier_setup ();
|
||||
+ /*
|
||||
+ * Lockdown the GRUB and register the shim_lock verifier
|
||||
+ * if the UEFI Secure Boot is enabled.
|
||||
+ */
|
||||
+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
|
||||
+ {
|
||||
+ grub_lockdown ();
|
||||
+ grub_shim_lock_verifier_setup ();
|
||||
+ }
|
||||
|
||||
efi_call_4 (grub_efi_system_table->boot_services->set_watchdog_timer,
|
||||
0, 0, 0, NULL);
|
||||
--
|
||||
2.26.2
|
||||
|
231
0012-efi-Use-grub_is_lockdown-instead-of-hardcoding-a-dis.patch
Normal file
231
0012-efi-Use-grub_is_lockdown-instead-of-hardcoding-a-dis.patch
Normal file
@ -0,0 +1,231 @@
|
||||
From fd04f7a20cffb4bde9deb688f4e33e5ff2c80181 Mon Sep 17 00:00:00 2001
|
||||
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Date: Mon, 28 Sep 2020 20:08:33 +0200
|
||||
Subject: [PATCH 12/46] 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>
|
||||
---
|
||||
docs/grub.texi | 15 +++++++-----
|
||||
grub-core/commands/i386/wrmsr.c | 5 ++--
|
||||
grub-core/commands/iorw.c | 19 +++++++--------
|
||||
grub-core/commands/memrw.c | 19 +++++++--------
|
||||
grub-core/kern/efi/sb.c | 41 ---------------------------------
|
||||
5 files changed, 32 insertions(+), 67 deletions(-)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index 3a4d18e06..6d8d32b0b 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -5256,6 +5256,9 @@ only applies to the particular cpu/core/thread that runs the command.
|
||||
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
|
||||
@@ -5769,12 +5772,12 @@ boot and the shim. This functionality is provided by the shim_lock verifier. It
|
||||
is built into the @file{core.img} and is registered if the UEFI secure boot is
|
||||
enabled.
|
||||
|
||||
-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 verifier logic.
|
||||
+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
|
||||
diff --git a/grub-core/commands/i386/wrmsr.c b/grub-core/commands/i386/wrmsr.c
|
||||
index 9c5e510eb..56a29c29f 100644
|
||||
--- a/grub-core/commands/i386/wrmsr.c
|
||||
+++ b/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 __attribute__ ((unused)), int argc, char
|
||||
|
||||
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)
|
||||
diff --git a/grub-core/commands/iorw.c b/grub-core/commands/iorw.c
|
||||
index a0c164e54..584baec8f 100644
|
||||
--- a/grub-core/commands/iorw.c
|
||||
+++ b/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)
|
||||
diff --git a/grub-core/commands/memrw.c b/grub-core/commands/memrw.c
|
||||
index 98769eadb..d401a6db0 100644
|
||||
--- a/grub-core/commands/memrw.c
|
||||
+++ b/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/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c
|
||||
index 8bd5e936d..5d7210a82 100644
|
||||
--- a/grub-core/kern/efi/sb.c
|
||||
+++ b/grub-core/kern/efi/sb.c
|
||||
@@ -30,9 +30,6 @@
|
||||
|
||||
static grub_efi_guid_t shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID;
|
||||
|
||||
-/* List of modules which cannot be loaded if UEFI secure boot mode is enabled. */
|
||||
-static const char * const disabled_mods[] = {"iorw", "memrw", "wrmsr", NULL};
|
||||
-
|
||||
/*
|
||||
* Determine whether we're in secure boot mode.
|
||||
*
|
||||
@@ -121,53 +118,15 @@ shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)),
|
||||
void **context __attribute__ ((unused)),
|
||||
enum grub_verify_flags *flags)
|
||||
{
|
||||
- const char *b, *e;
|
||||
- int i;
|
||||
-
|
||||
*flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
|
||||
|
||||
switch (type & GRUB_FILE_TYPE_MASK)
|
||||
{
|
||||
- case GRUB_FILE_TYPE_GRUB_MODULE:
|
||||
- /* Establish GRUB module name. */
|
||||
- b = grub_strrchr (io->name, '/');
|
||||
- e = grub_strrchr (io->name, '.');
|
||||
-
|
||||
- b = b ? (b + 1) : io->name;
|
||||
- e = e ? e : io->name + grub_strlen (io->name);
|
||||
- e = (e > b) ? e : io->name + grub_strlen (io->name);
|
||||
-
|
||||
- for (i = 0; disabled_mods[i]; i++)
|
||||
- if (!grub_strncmp (b, disabled_mods[i], grub_strlen (b) - grub_strlen (e)))
|
||||
- {
|
||||
- grub_error (GRUB_ERR_ACCESS_DENIED,
|
||||
- N_("module cannot be loaded in UEFI secure boot mode: %s"),
|
||||
- io->name);
|
||||
- return GRUB_ERR_ACCESS_DENIED;
|
||||
- }
|
||||
-
|
||||
- /* Fall through. */
|
||||
-
|
||||
- case GRUB_FILE_TYPE_ACPI_TABLE:
|
||||
- case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE:
|
||||
- *flags = GRUB_VERIFY_FLAGS_DEFER_AUTH;
|
||||
-
|
||||
- return GRUB_ERR_NONE;
|
||||
-
|
||||
case GRUB_FILE_TYPE_LINUX_KERNEL:
|
||||
case GRUB_FILE_TYPE_MULTIBOOT_KERNEL:
|
||||
case GRUB_FILE_TYPE_BSD_KERNEL:
|
||||
case GRUB_FILE_TYPE_XNU_KERNEL:
|
||||
case GRUB_FILE_TYPE_PLAN9_KERNEL:
|
||||
- for (i = 0; disabled_mods[i]; i++)
|
||||
- if (grub_dl_get (disabled_mods[i]))
|
||||
- {
|
||||
- grub_error (GRUB_ERR_ACCESS_DENIED,
|
||||
- N_("cannot boot due to dangerous module in memory: %s"),
|
||||
- disabled_mods[i]);
|
||||
- return GRUB_ERR_ACCESS_DENIED;
|
||||
- }
|
||||
-
|
||||
*flags = GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
|
||||
|
||||
/* Fall through. */
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,75 @@
|
||||
From 08c63ad119ce0c0d0de56d9878f0be6811f623d4 Mon Sep 17 00:00:00 2001
|
||||
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Date: Mon, 28 Sep 2020 20:08:41 +0200
|
||||
Subject: [PATCH 13/46] 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>
|
||||
---
|
||||
docs/grub.texi | 5 +++++
|
||||
grub-core/commands/acpi.c | 15 ++++++++-------
|
||||
2 files changed, 13 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index 6d8d32b0b..2ee8721a1 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -3986,6 +3986,11 @@ Normally, this command will replace the Root System Description Pointer
|
||||
(RSDP) in the Extended BIOS Data Area to point to the new tables. If the
|
||||
@option{--no-ebda} option is used, the new tables will be known only to
|
||||
GRUB, but may be used by GRUB's EFI emulation.
|
||||
+
|
||||
+Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}).
|
||||
+ Otherwise an attacker can instruct the GRUB to load an SSDT table to
|
||||
+ overwrite the kernel lockdown configuration and later load and execute
|
||||
+ unsigned code.
|
||||
@end deffn
|
||||
|
||||
|
||||
diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c
|
||||
index 5a1499aa0..1215f2a62 100644
|
||||
--- a/grub-core/commands/acpi.c
|
||||
+++ b/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)
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,69 @@
|
||||
From cbd4d630728847bcc3eb82c4a1667fc7ba6de73a Mon Sep 17 00:00:00 2001
|
||||
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Date: Wed, 14 Oct 2020 16:33:42 +0200
|
||||
Subject: [PATCH 14/46] 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>
|
||||
---
|
||||
docs/grub.texi | 4 ++++
|
||||
grub-core/mmap/mmap.c | 13 +++++++------
|
||||
2 files changed, 11 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index 2ee8721a1..70bf91f40 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -4051,6 +4051,10 @@ this page is to be filtered. This syntax makes it easy to represent patterns
|
||||
that are often result of memory damage, due to physical distribution of memory
|
||||
cells.
|
||||
|
||||
+Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}).
|
||||
+ This prevents removing EFI memory regions to potentially subvert the
|
||||
+ security mechanisms provided by the UEFI secure boot.
|
||||
+
|
||||
@node blocklist
|
||||
@subsection blocklist
|
||||
|
||||
diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c
|
||||
index 57b4e9a72..7ebf32e1e 100644
|
||||
--- a/grub-core/mmap/mmap.c
|
||||
+++ b/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."));
|
||||
|
||||
}
|
||||
|
||||
--
|
||||
2.26.2
|
||||
|
104
0015-commands-Restrict-commands-that-can-load-BIOS-or-DT-.patch
Normal file
104
0015-commands-Restrict-commands-that-can-load-BIOS-or-DT-.patch
Normal file
@ -0,0 +1,104 @@
|
||||
From d1a40f870dbcb55280f57673c1d9c2c7110df42a Mon Sep 17 00:00:00 2001
|
||||
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Date: Wed, 24 Feb 2021 09:00:05 +0100
|
||||
Subject: [PATCH 15/46] commands: Restrict commands that can load BIOS or DT
|
||||
blobs when locked down
|
||||
|
||||
There are some more commands that should be restricted when the GRUB is
|
||||
locked down. Following is the list of commands and reasons to restrict:
|
||||
|
||||
* fakebios: creates BIOS-like structures for backward compatibility with
|
||||
existing OSes. This should not be allowed when locked down.
|
||||
|
||||
* loadbios: reads a BIOS dump from storage and loads it. This action
|
||||
should not be allowed when locked down.
|
||||
|
||||
* devicetree: loads a Device Tree blob and passes it to the OS. It replaces
|
||||
any Device Tree provided by the firmware. This also should
|
||||
not be allowed when locked down.
|
||||
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
docs/grub.texi | 3 +++
|
||||
grub-core/commands/efi/loadbios.c | 16 ++++++++--------
|
||||
grub-core/loader/arm/linux.c | 6 +++---
|
||||
grub-core/loader/efi/fdt.c | 4 ++--
|
||||
4 files changed, 16 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index 70bf91f40..cf29a1797 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -4236,6 +4236,9 @@ Load a device tree blob (.dtb) from a filesystem, for later use by a Linux
|
||||
kernel. Does not perform merging with any device tree supplied by firmware,
|
||||
but rather replaces it completely.
|
||||
@ref{GNU/Linux}.
|
||||
+
|
||||
+Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}).
|
||||
+ This is done to prevent subverting various security mechanisms.
|
||||
@end deffn
|
||||
|
||||
@node distrust
|
||||
diff --git a/grub-core/commands/efi/loadbios.c b/grub-core/commands/efi/loadbios.c
|
||||
index d41d521a4..5c7725f8b 100644
|
||||
--- a/grub-core/commands/efi/loadbios.c
|
||||
+++ b/grub-core/commands/efi/loadbios.c
|
||||
@@ -205,14 +205,14 @@ static grub_command_t cmd_fakebios, cmd_loadbios;
|
||||
|
||||
GRUB_MOD_INIT(loadbios)
|
||||
{
|
||||
- cmd_fakebios = grub_register_command ("fakebios", grub_cmd_fakebios,
|
||||
- 0, N_("Create BIOS-like structures for"
|
||||
- " backward compatibility with"
|
||||
- " existing OS."));
|
||||
-
|
||||
- cmd_loadbios = grub_register_command ("loadbios", grub_cmd_loadbios,
|
||||
- N_("BIOS_DUMP [INT10_DUMP]"),
|
||||
- N_("Load BIOS dump."));
|
||||
+ cmd_fakebios = grub_register_command_lockdown ("fakebios", grub_cmd_fakebios,
|
||||
+ 0, N_("Create BIOS-like structures for"
|
||||
+ " backward compatibility with"
|
||||
+ " existing OS."));
|
||||
+
|
||||
+ cmd_loadbios = grub_register_command_lockdown ("loadbios", grub_cmd_loadbios,
|
||||
+ N_("BIOS_DUMP [INT10_DUMP]"),
|
||||
+ N_("Load BIOS dump."));
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(loadbios)
|
||||
diff --git a/grub-core/loader/arm/linux.c b/grub-core/loader/arm/linux.c
|
||||
index d70c17486..ed23dc71e 100644
|
||||
--- a/grub-core/loader/arm/linux.c
|
||||
+++ b/grub-core/loader/arm/linux.c
|
||||
@@ -493,9 +493,9 @@ GRUB_MOD_INIT (linux)
|
||||
0, N_("Load Linux."));
|
||||
cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
|
||||
0, N_("Load initrd."));
|
||||
- cmd_devicetree = grub_register_command ("devicetree", grub_cmd_devicetree,
|
||||
- /* TRANSLATORS: DTB stands for device tree blob. */
|
||||
- 0, N_("Load DTB file."));
|
||||
+ cmd_devicetree = grub_register_command_lockdown ("devicetree", grub_cmd_devicetree,
|
||||
+ /* TRANSLATORS: DTB stands for device tree blob. */
|
||||
+ 0, N_("Load DTB file."));
|
||||
my_mod = mod;
|
||||
current_fdt = (const void *) grub_arm_firmware_get_boot_data ();
|
||||
machine_type = grub_arm_firmware_get_machine_type ();
|
||||
diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c
|
||||
index ee9c5592c..003d07cd8 100644
|
||||
--- a/grub-core/loader/efi/fdt.c
|
||||
+++ b/grub-core/loader/efi/fdt.c
|
||||
@@ -165,8 +165,8 @@ static grub_command_t cmd_devicetree;
|
||||
GRUB_MOD_INIT (fdt)
|
||||
{
|
||||
cmd_devicetree =
|
||||
- grub_register_command ("devicetree", grub_cmd_devicetree, 0,
|
||||
- N_("Load DTB file."));
|
||||
+ grub_register_command_lockdown ("devicetree", grub_cmd_devicetree, 0,
|
||||
+ N_("Load DTB file."));
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI (fdt)
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,37 @@
|
||||
From 3e5b0593346fde8d92dd4e87ce15ff07e0cacf88 Mon Sep 17 00:00:00 2001
|
||||
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Date: Wed, 24 Feb 2021 22:59:59 +0100
|
||||
Subject: [PATCH 16/46] commands/setpci: Restrict setpci command when locked
|
||||
down
|
||||
|
||||
This command can set PCI devices register values, which makes it dangerous
|
||||
in a locked down configuration. Restrict it so can't be used on this setup.
|
||||
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/commands/setpci.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/setpci.c b/grub-core/commands/setpci.c
|
||||
index d5bc97d60..fa2ba7d89 100644
|
||||
--- a/grub-core/commands/setpci.c
|
||||
+++ b/grub-core/commands/setpci.c
|
||||
@@ -329,10 +329,10 @@ static grub_extcmd_t cmd;
|
||||
|
||||
GRUB_MOD_INIT(setpci)
|
||||
{
|
||||
- cmd = grub_register_extcmd ("setpci", grub_cmd_setpci, 0,
|
||||
- N_("[-s POSITION] [-d DEVICE] [-v VAR] "
|
||||
- "REGISTER[=VALUE[:MASK]]"),
|
||||
- N_("Manipulate PCI devices."), options);
|
||||
+ cmd = grub_register_extcmd_lockdown ("setpci", grub_cmd_setpci, 0,
|
||||
+ N_("[-s POSITION] [-d DEVICE] [-v VAR] "
|
||||
+ "REGISTER[=VALUE[:MASK]]"),
|
||||
+ N_("Manipulate PCI devices."), options);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(setpci)
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,35 @@
|
||||
From 75dd393392f16194904c8958a22fe12034f915a3 Mon Sep 17 00:00:00 2001
|
||||
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Date: Wed, 24 Feb 2021 12:59:29 +0100
|
||||
Subject: [PATCH 17/46] commands/hdparm: Restrict hdparm command when locked
|
||||
down
|
||||
|
||||
The command can be used to get/set ATA disk parameters. Some of these can
|
||||
be dangerous since change the disk behavior. Restrict it when locked down.
|
||||
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/commands/hdparm.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/hdparm.c b/grub-core/commands/hdparm.c
|
||||
index d3fa9661e..2e2319e64 100644
|
||||
--- a/grub-core/commands/hdparm.c
|
||||
+++ b/grub-core/commands/hdparm.c
|
||||
@@ -436,9 +436,9 @@ static grub_extcmd_t cmd;
|
||||
|
||||
GRUB_MOD_INIT(hdparm)
|
||||
{
|
||||
- cmd = grub_register_extcmd ("hdparm", grub_cmd_hdparm, 0,
|
||||
- N_("[OPTIONS] DISK"),
|
||||
- N_("Get/set ATA disk parameters."), options);
|
||||
+ cmd = grub_register_extcmd_lockdown ("hdparm", grub_cmd_hdparm, 0,
|
||||
+ N_("[OPTIONS] DISK"),
|
||||
+ N_("Get/set ATA disk parameters."), options);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(hdparm)
|
||||
--
|
||||
2.26.2
|
||||
|
61
0018-gdb-Restrict-GDB-access-when-locked-down.patch
Normal file
61
0018-gdb-Restrict-GDB-access-when-locked-down.patch
Normal file
@ -0,0 +1,61 @@
|
||||
From a4df9a0d74376aa4fc82f8c86c280cb087de01be Mon Sep 17 00:00:00 2001
|
||||
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Date: Wed, 24 Feb 2021 15:03:26 +0100
|
||||
Subject: [PATCH 18/46] gdb: Restrict GDB access when locked down
|
||||
|
||||
The gdbstub* commands allow to start and control a GDB stub running on
|
||||
local host that can be used to connect from a remote debugger. Restrict
|
||||
this functionality when the GRUB is locked down.
|
||||
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/gdb/gdb.c | 32 ++++++++++++++++++--------------
|
||||
1 file changed, 18 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/grub-core/gdb/gdb.c b/grub-core/gdb/gdb.c
|
||||
index 847a1e1e3..1818cb6f8 100644
|
||||
--- a/grub-core/gdb/gdb.c
|
||||
+++ b/grub-core/gdb/gdb.c
|
||||
@@ -75,20 +75,24 @@ static grub_command_t cmd, cmd_stop, cmd_break;
|
||||
GRUB_MOD_INIT (gdb)
|
||||
{
|
||||
grub_gdb_idtinit ();
|
||||
- cmd = grub_register_command ("gdbstub", grub_cmd_gdbstub,
|
||||
- N_("PORT"),
|
||||
- /* TRANSLATORS: GDB stub is a small part of
|
||||
- GDB functionality running on local host
|
||||
- which allows remote debugger to
|
||||
- connect to it. */
|
||||
- N_("Start GDB stub on given port"));
|
||||
- cmd_break = grub_register_command ("gdbstub_break", grub_cmd_gdb_break,
|
||||
- /* TRANSLATORS: this refers to triggering
|
||||
- a breakpoint so that the user will land
|
||||
- into GDB. */
|
||||
- 0, N_("Break into GDB"));
|
||||
- cmd_stop = grub_register_command ("gdbstub_stop", grub_cmd_gdbstop,
|
||||
- 0, N_("Stop GDB stub"));
|
||||
+ cmd = grub_register_command_lockdown ("gdbstub", grub_cmd_gdbstub,
|
||||
+ N_("PORT"),
|
||||
+ /*
|
||||
+ * TRANSLATORS: GDB stub is a small part of
|
||||
+ * GDB functionality running on local host
|
||||
+ * which allows remote debugger to
|
||||
+ * connect to it.
|
||||
+ */
|
||||
+ N_("Start GDB stub on given port"));
|
||||
+ cmd_break = grub_register_command_lockdown ("gdbstub_break", grub_cmd_gdb_break,
|
||||
+ /*
|
||||
+ * TRANSLATORS: this refers to triggering
|
||||
+ * a breakpoint so that the user will land
|
||||
+ * into GDB.
|
||||
+ */
|
||||
+ 0, N_("Break into GDB"));
|
||||
+ cmd_stop = grub_register_command_lockdown ("gdbstub_stop", grub_cmd_gdbstop,
|
||||
+ 0, N_("Stop GDB stub"));
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI (gdb)
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,60 @@
|
||||
From da75051bd36ce97b94254f17a6a94b5cbdf77d48 Mon Sep 17 00:00:00 2001
|
||||
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Date: Wed, 24 Feb 2021 14:44:38 +0100
|
||||
Subject: [PATCH 19/46] loader/xnu: Don't allow loading extension and packages
|
||||
when locked down
|
||||
|
||||
The shim_lock verifier validates the XNU kernels but no its extensions
|
||||
and packages. Prevent these to be loaded when the GRUB is locked down.
|
||||
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/loader/xnu.c | 31 +++++++++++++++++--------------
|
||||
1 file changed, 17 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c
|
||||
index 77d7060e1..07232d2a1 100644
|
||||
--- a/grub-core/loader/xnu.c
|
||||
+++ b/grub-core/loader/xnu.c
|
||||
@@ -1482,20 +1482,23 @@ GRUB_MOD_INIT(xnu)
|
||||
N_("Load XNU image."));
|
||||
cmd_kernel64 = grub_register_command ("xnu_kernel64", grub_cmd_xnu_kernel64,
|
||||
0, N_("Load 64-bit XNU image."));
|
||||
- cmd_mkext = grub_register_command ("xnu_mkext", grub_cmd_xnu_mkext, 0,
|
||||
- N_("Load XNU extension package."));
|
||||
- cmd_kext = grub_register_command ("xnu_kext", grub_cmd_xnu_kext, 0,
|
||||
- N_("Load XNU extension."));
|
||||
- cmd_kextdir = grub_register_command ("xnu_kextdir", grub_cmd_xnu_kextdir,
|
||||
- /* TRANSLATORS: OSBundleRequired is a
|
||||
- variable name in xnu extensions
|
||||
- manifests. It behaves mostly like
|
||||
- GNU/Linux runlevels.
|
||||
- */
|
||||
- N_("DIRECTORY [OSBundleRequired]"),
|
||||
- /* TRANSLATORS: There are many extensions
|
||||
- in extension directory. */
|
||||
- N_("Load XNU extension directory."));
|
||||
+ cmd_mkext = grub_register_command_lockdown ("xnu_mkext", grub_cmd_xnu_mkext, 0,
|
||||
+ N_("Load XNU extension package."));
|
||||
+ cmd_kext = grub_register_command_lockdown ("xnu_kext", grub_cmd_xnu_kext, 0,
|
||||
+ N_("Load XNU extension."));
|
||||
+ cmd_kextdir = grub_register_command_lockdown ("xnu_kextdir", grub_cmd_xnu_kextdir,
|
||||
+ /*
|
||||
+ * TRANSLATORS: OSBundleRequired is
|
||||
+ * a variable name in xnu extensions
|
||||
+ * manifests. It behaves mostly like
|
||||
+ * GNU/Linux runlevels.
|
||||
+ */
|
||||
+ N_("DIRECTORY [OSBundleRequired]"),
|
||||
+ /*
|
||||
+ * TRANSLATORS: There are many extensions
|
||||
+ * in extension directory.
|
||||
+ */
|
||||
+ N_("Load XNU extension directory."));
|
||||
cmd_ramdisk = grub_register_command ("xnu_ramdisk", grub_cmd_xnu_ramdisk, 0,
|
||||
/* TRANSLATORS: ramdisk here isn't identifier. It can be translated. */
|
||||
N_("Load XNU ramdisk. "
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,87 @@
|
||||
From 01df3544dd3ea226e2832735c0284fc6d9157347 Mon Sep 17 00:00:00 2001
|
||||
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Date: Tue, 29 Sep 2020 14:08:55 +0200
|
||||
Subject: [PATCH 20/46] 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>
|
||||
---
|
||||
grub-core/commands/minicmd.c | 7 +++++--
|
||||
grub-core/kern/dl.c | 9 +++++++++
|
||||
include/grub/dl.h | 8 +++++---
|
||||
3 files changed, 19 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c
|
||||
index 6bbce3128..fa498931e 100644
|
||||
--- a/grub-core/commands/minicmd.c
|
||||
+++ b/grub-core/commands/minicmd.c
|
||||
@@ -140,8 +140,11 @@ grub_mini_cmd_rmmod (struct grub_command *cmd __attribute__ ((unused)),
|
||||
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;
|
||||
}
|
||||
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
|
||||
index 2a8372e14..e02f2afc5 100644
|
||||
--- a/grub-core/kern/dl.c
|
||||
+++ b/grub-core/kern/dl.c
|
||||
@@ -553,6 +553,15 @@ grub_dl_unref (grub_dl_t mod)
|
||||
return --mod->ref_count;
|
||||
}
|
||||
|
||||
+int
|
||||
+grub_dl_ref_count (grub_dl_t mod)
|
||||
+{
|
||||
+ if (mod == NULL)
|
||||
+ return 0;
|
||||
+
|
||||
+ return mod->ref_count;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
grub_dl_flush_cache (grub_dl_t mod)
|
||||
{
|
||||
diff --git a/include/grub/dl.h b/include/grub/dl.h
|
||||
index f03c03561..b3753c9ca 100644
|
||||
--- a/include/grub/dl.h
|
||||
+++ b/include/grub/dl.h
|
||||
@@ -203,9 +203,11 @@ grub_dl_t EXPORT_FUNC(grub_dl_load) (const char *name);
|
||||
grub_dl_t grub_dl_load_core (void *addr, grub_size_t size);
|
||||
grub_dl_t EXPORT_FUNC(grub_dl_load_core_noinit) (void *addr, grub_size_t size);
|
||||
int EXPORT_FUNC(grub_dl_unload) (grub_dl_t mod);
|
||||
-void grub_dl_unload_unneeded (void);
|
||||
-int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod);
|
||||
-int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod);
|
||||
+extern void grub_dl_unload_unneeded (void);
|
||||
+extern int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod);
|
||||
+extern int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod);
|
||||
+extern int EXPORT_FUNC(grub_dl_ref_count) (grub_dl_t mod);
|
||||
+
|
||||
extern grub_dl_t EXPORT_VAR(grub_dl_head);
|
||||
|
||||
#ifndef GRUB_UTIL
|
||||
--
|
||||
2.26.2
|
||||
|
115
0021-usb-Avoid-possible-out-of-bound-accesses-caused-by-m.patch
Normal file
115
0021-usb-Avoid-possible-out-of-bound-accesses-caused-by-m.patch
Normal file
@ -0,0 +1,115 @@
|
||||
From 6f8f29ca383eaa60a0eab00d4a934a072190c128 Mon Sep 17 00:00:00 2001
|
||||
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Date: Fri, 11 Dec 2020 19:19:21 +0100
|
||||
Subject: [PATCH 21/46] 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>
|
||||
---
|
||||
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;
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,54 @@
|
||||
From fafede32c0ed3bc1953c5663b58036a58fb7b6bd Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
Date: Fri, 22 Jan 2021 16:07:29 +1100
|
||||
Subject: [PATCH 22/46] 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>
|
||||
---
|
||||
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;
|
||||
}
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,46 @@
|
||||
From 833324355ed1c88b509a2c5e8632a190ce11bf40 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
Date: Fri, 22 Jan 2021 17:10:48 +1100
|
||||
Subject: [PATCH 23/46] 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>
|
||||
---
|
||||
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 348d72dac..c36913752 100644
|
||||
--- a/grub-core/commands/menuentry.c
|
||||
+++ b/grub-core/commands/menuentry.c
|
||||
@@ -233,7 +233,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);
|
||||
--
|
||||
2.26.2
|
||||
|
50
0024-kern-parser-Fix-resource-leak-if-argc-0.patch
Normal file
50
0024-kern-parser-Fix-resource-leak-if-argc-0.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From 61aebf1dd8213cd8e3d4b3493f4bb4c221331c17 Mon Sep 17 00:00:00 2001
|
||||
From: Darren Kenny <darren.kenny@oracle.com>
|
||||
Date: Fri, 22 Jan 2021 12:32:41 +0000
|
||||
Subject: [PATCH 24/46] kern/parser: Fix resource leak if argc == 0
|
||||
|
||||
After processing the command-line yet arriving at the point where we are
|
||||
setting argv, we are allocating memory, even if argc == 0, which makes
|
||||
no sense since we never put anything into the allocated argv.
|
||||
|
||||
The solution is to simply return that we've successfully processed the
|
||||
arguments but that argc == 0, and also ensure that argv is NULL when
|
||||
we're not allocating anything in it.
|
||||
|
||||
There are only 2 callers of this function, and both are handling a zero
|
||||
value in argc assuming nothing is allocated in argv.
|
||||
|
||||
Fixes: CID 96680
|
||||
|
||||
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/kern/parser.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c
|
||||
index 619db3122..d1cf061ad 100644
|
||||
--- a/grub-core/kern/parser.c
|
||||
+++ b/grub-core/kern/parser.c
|
||||
@@ -146,6 +146,7 @@ grub_parser_split_cmdline (const char *cmdline,
|
||||
int i;
|
||||
|
||||
*argc = 0;
|
||||
+ *argv = NULL;
|
||||
do
|
||||
{
|
||||
if (!rd || !*rd)
|
||||
@@ -207,6 +208,10 @@ grub_parser_split_cmdline (const char *cmdline,
|
||||
(*argc)++;
|
||||
}
|
||||
|
||||
+ /* If there are no args, then we're done. */
|
||||
+ if (!*argc)
|
||||
+ return 0;
|
||||
+
|
||||
/* Reserve memory for the return values. */
|
||||
args = grub_malloc (bp - buffer);
|
||||
if (!args)
|
||||
--
|
||||
2.26.2
|
||||
|
76
0025-kern-parser-Fix-a-memory-leak.patch
Normal file
76
0025-kern-parser-Fix-a-memory-leak.patch
Normal file
@ -0,0 +1,76 @@
|
||||
From b6e9ddb100e90665d090d7f92cdc69f03f0a6498 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Coulson <chris.coulson@canonical.com>
|
||||
Date: Wed, 18 Nov 2020 00:59:24 +0000
|
||||
Subject: [PATCH 25/46] 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>
|
||||
---
|
||||
grub-core/kern/parser.c | 20 ++++++++++++++++----
|
||||
1 file changed, 16 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c
|
||||
index d1cf061ad..39e4df65b 100644
|
||||
--- a/grub-core/kern/parser.c
|
||||
+++ b/grub-core/kern/parser.c
|
||||
@@ -140,6 +140,7 @@ grub_parser_split_cmdline (const char *cmdline,
|
||||
char buffer[1024];
|
||||
char *bp = buffer;
|
||||
char *rd = (char *) cmdline;
|
||||
+ char *rp = rd;
|
||||
char varname[200];
|
||||
char *vp = varname;
|
||||
char *args;
|
||||
@@ -149,10 +150,18 @@ grub_parser_split_cmdline (const char *cmdline,
|
||||
*argv = NULL;
|
||||
do
|
||||
{
|
||||
- if (!rd || !*rd)
|
||||
+ if (rp == NULL || *rp == '\0')
|
||||
{
|
||||
+ if (rd != cmdline)
|
||||
+ {
|
||||
+ grub_free (rd);
|
||||
+ rd = rp = NULL;
|
||||
+ }
|
||||
if (getline)
|
||||
- getline (&rd, 1, getline_data);
|
||||
+ {
|
||||
+ getline (&rd, 1, getline_data);
|
||||
+ rp = rd;
|
||||
+ }
|
||||
else
|
||||
break;
|
||||
}
|
||||
@@ -160,12 +169,12 @@ grub_parser_split_cmdline (const char *cmdline,
|
||||
if (!rd)
|
||||
break;
|
||||
|
||||
- for (; *rd; rd++)
|
||||
+ for (; *rp != '\0'; rp++)
|
||||
{
|
||||
grub_parser_state_t newstate;
|
||||
char use;
|
||||
|
||||
- newstate = grub_parser_cmdline_state (state, *rd, &use);
|
||||
+ newstate = grub_parser_cmdline_state (state, *rp, &use);
|
||||
|
||||
/* If a variable was being processed and this character does
|
||||
not describe the variable anymore, write the variable to
|
||||
@@ -198,6 +207,9 @@ grub_parser_split_cmdline (const char *cmdline,
|
||||
}
|
||||
while (state != GRUB_PARSER_STATE_TEXT && !check_varstate (state));
|
||||
|
||||
+ if (rd != cmdline)
|
||||
+ grub_free (rd);
|
||||
+
|
||||
/* A special case for when the last character was part of a
|
||||
variable. */
|
||||
add_var (varname, &bp, &vp, state, GRUB_PARSER_STATE_TEXT);
|
||||
--
|
||||
2.26.2
|
||||
|
119
0026-kern-parser-Introduce-process_char-helper.patch
Normal file
119
0026-kern-parser-Introduce-process_char-helper.patch
Normal file
@ -0,0 +1,119 @@
|
||||
From 80b048e51705c78638afecac539e53e80647f8bd Mon Sep 17 00:00:00 2001
|
||||
From: Chris Coulson <chris.coulson@canonical.com>
|
||||
Date: Tue, 5 Jan 2021 22:17:28 +0000
|
||||
Subject: [PATCH 26/46] 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>
|
||||
---
|
||||
grub-core/kern/parser.c | 74 +++++++++++++++++++++++++----------------
|
||||
1 file changed, 46 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c
|
||||
index 39e4df65b..0d3582bd8 100644
|
||||
--- a/grub-core/kern/parser.c
|
||||
+++ b/grub-core/kern/parser.c
|
||||
@@ -1,7 +1,7 @@
|
||||
/* parser.c - the part of the parser that can return partial tokens */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
- * Copyright (C) 2005,2007,2009 Free Software Foundation, Inc.
|
||||
+ * Copyright (C) 2005,2007,2009,2021 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -129,6 +129,46 @@ add_var (char *varname, char **bp, char **vp,
|
||||
*((*bp)++) = *val;
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+process_char (char c, char *buffer, char **bp, char *varname, char **vp,
|
||||
+ grub_parser_state_t state, int *argc,
|
||||
+ grub_parser_state_t *newstate)
|
||||
+{
|
||||
+ char use;
|
||||
+
|
||||
+ *newstate = grub_parser_cmdline_state (state, c, &use);
|
||||
+
|
||||
+ /*
|
||||
+ * If a variable was being processed and this character does
|
||||
+ * not describe the variable anymore, write the variable to
|
||||
+ * the buffer.
|
||||
+ */
|
||||
+ add_var (varname, bp, vp, state, *newstate);
|
||||
+
|
||||
+ if (check_varstate (*newstate))
|
||||
+ {
|
||||
+ if (use)
|
||||
+ *((*vp)++) = use;
|
||||
+ }
|
||||
+ else if (*newstate == GRUB_PARSER_STATE_TEXT &&
|
||||
+ state != GRUB_PARSER_STATE_ESC && grub_isspace (use))
|
||||
+ {
|
||||
+ /*
|
||||
+ * Don't add more than one argument if multiple
|
||||
+ * spaces are used.
|
||||
+ */
|
||||
+ if (*bp != buffer && *((*bp) - 1) != '\0')
|
||||
+ {
|
||||
+ *((*bp)++) = '\0';
|
||||
+ (*argc)++;
|
||||
+ }
|
||||
+ }
|
||||
+ else if (use)
|
||||
+ *((*bp)++) = use;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
grub_err_t
|
||||
grub_parser_split_cmdline (const char *cmdline,
|
||||
grub_reader_getline_t getline, void *getline_data,
|
||||
@@ -172,35 +212,13 @@ grub_parser_split_cmdline (const char *cmdline,
|
||||
for (; *rp != '\0'; rp++)
|
||||
{
|
||||
grub_parser_state_t newstate;
|
||||
- char use;
|
||||
-
|
||||
- newstate = grub_parser_cmdline_state (state, *rp, &use);
|
||||
|
||||
- /* If a variable was being processed and this character does
|
||||
- not describe the variable anymore, write the variable to
|
||||
- the buffer. */
|
||||
- add_var (varname, &bp, &vp, state, newstate);
|
||||
-
|
||||
- if (check_varstate (newstate))
|
||||
- {
|
||||
- if (use)
|
||||
- *(vp++) = use;
|
||||
- }
|
||||
- else
|
||||
+ if (process_char (*rp, buffer, &bp, varname, &vp, state, argc,
|
||||
+ &newstate) != GRUB_ERR_NONE)
|
||||
{
|
||||
- if (newstate == GRUB_PARSER_STATE_TEXT
|
||||
- && state != GRUB_PARSER_STATE_ESC && grub_isspace (use))
|
||||
- {
|
||||
- /* Don't add more than one argument if multiple
|
||||
- spaces are used. */
|
||||
- if (bp != buffer && *(bp - 1))
|
||||
- {
|
||||
- *(bp++) = '\0';
|
||||
- (*argc)++;
|
||||
- }
|
||||
- }
|
||||
- else if (use)
|
||||
- *(bp++) = use;
|
||||
+ if (rd != cmdline)
|
||||
+ grub_free (rd);
|
||||
+ return grub_errno;
|
||||
}
|
||||
state = newstate;
|
||||
}
|
||||
--
|
||||
2.26.2
|
||||
|
65
0027-kern-parser-Introduce-terminate_arg-helper.patch
Normal file
65
0027-kern-parser-Introduce-terminate_arg-helper.patch
Normal file
@ -0,0 +1,65 @@
|
||||
From b4086b4baa1412fc962b9f88aa5e2a982afee0da Mon Sep 17 00:00:00 2001
|
||||
From: Chris Coulson <chris.coulson@canonical.com>
|
||||
Date: Thu, 7 Jan 2021 19:53:55 +0000
|
||||
Subject: [PATCH 27/46] 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>
|
||||
---
|
||||
grub-core/kern/parser.c | 23 +++++++++++++----------
|
||||
1 file changed, 13 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c
|
||||
index 0d3582bd8..572c67089 100644
|
||||
--- a/grub-core/kern/parser.c
|
||||
+++ b/grub-core/kern/parser.c
|
||||
@@ -129,6 +129,16 @@ add_var (char *varname, char **bp, char **vp,
|
||||
*((*bp)++) = *val;
|
||||
}
|
||||
|
||||
+static void
|
||||
+terminate_arg (char *buffer, char **bp, int *argc)
|
||||
+{
|
||||
+ if (*bp != buffer && *((*bp) - 1) != '\0')
|
||||
+ {
|
||||
+ *((*bp)++) = '\0';
|
||||
+ (*argc)++;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
process_char (char c, char *buffer, char **bp, char *varname, char **vp,
|
||||
grub_parser_state_t state, int *argc,
|
||||
@@ -157,11 +167,7 @@ process_char (char c, char *buffer, char **bp, char *varname, char **vp,
|
||||
* Don't add more than one argument if multiple
|
||||
* spaces are used.
|
||||
*/
|
||||
- if (*bp != buffer && *((*bp) - 1) != '\0')
|
||||
- {
|
||||
- *((*bp)++) = '\0';
|
||||
- (*argc)++;
|
||||
- }
|
||||
+ terminate_arg (buffer, bp, argc);
|
||||
}
|
||||
else if (use)
|
||||
*((*bp)++) = use;
|
||||
@@ -232,11 +238,8 @@ grub_parser_split_cmdline (const char *cmdline,
|
||||
variable. */
|
||||
add_var (varname, &bp, &vp, state, GRUB_PARSER_STATE_TEXT);
|
||||
|
||||
- if (bp != buffer && *(bp - 1))
|
||||
- {
|
||||
- *(bp++) = '\0';
|
||||
- (*argc)++;
|
||||
- }
|
||||
+ /* Ensure that the last argument is terminated. */
|
||||
+ terminate_arg (buffer, &bp, argc);
|
||||
|
||||
/* If there are no args, then we're done. */
|
||||
if (!*argc)
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,92 @@
|
||||
From 550c0e6582b6be09b0af2fb2775a149f51c51bbc Mon Sep 17 00:00:00 2001
|
||||
From: Chris Coulson <chris.coulson@canonical.com>
|
||||
Date: Wed, 6 Jan 2021 13:54:26 +0000
|
||||
Subject: [PATCH 28/46] 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>
|
||||
---
|
||||
grub-core/kern/parser.c | 35 ++++++++++++++++++++---------------
|
||||
1 file changed, 20 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c
|
||||
index 572c67089..e010eaa1f 100644
|
||||
--- a/grub-core/kern/parser.c
|
||||
+++ b/grub-core/kern/parser.c
|
||||
@@ -221,19 +221,13 @@ grub_parser_split_cmdline (const char *cmdline,
|
||||
|
||||
if (process_char (*rp, buffer, &bp, varname, &vp, state, argc,
|
||||
&newstate) != GRUB_ERR_NONE)
|
||||
- {
|
||||
- if (rd != cmdline)
|
||||
- grub_free (rd);
|
||||
- return grub_errno;
|
||||
- }
|
||||
+ goto fail;
|
||||
+
|
||||
state = newstate;
|
||||
}
|
||||
}
|
||||
while (state != GRUB_PARSER_STATE_TEXT && !check_varstate (state));
|
||||
|
||||
- if (rd != cmdline)
|
||||
- grub_free (rd);
|
||||
-
|
||||
/* A special case for when the last character was part of a
|
||||
variable. */
|
||||
add_var (varname, &bp, &vp, state, GRUB_PARSER_STATE_TEXT);
|
||||
@@ -243,20 +237,20 @@ grub_parser_split_cmdline (const char *cmdline,
|
||||
|
||||
/* If there are no args, then we're done. */
|
||||
if (!*argc)
|
||||
- return 0;
|
||||
+ {
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
/* Reserve memory for the return values. */
|
||||
args = grub_malloc (bp - buffer);
|
||||
if (!args)
|
||||
- return grub_errno;
|
||||
+ goto fail;
|
||||
grub_memcpy (args, buffer, bp - buffer);
|
||||
|
||||
*argv = grub_calloc (*argc + 1, sizeof (char *));
|
||||
if (!*argv)
|
||||
- {
|
||||
- grub_free (args);
|
||||
- return grub_errno;
|
||||
- }
|
||||
+ goto fail;
|
||||
|
||||
/* The arguments are separated with 0's, setup argv so it points to
|
||||
the right values. */
|
||||
@@ -269,7 +263,18 @@ grub_parser_split_cmdline (const char *cmdline,
|
||||
bp++;
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+
|
||||
+ out:
|
||||
+ if (rd != cmdline)
|
||||
+ grub_free (rd);
|
||||
+
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ fail:
|
||||
+ grub_free (*argv);
|
||||
+ grub_free (args);
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
/* Helper for grub_parser_execute. */
|
||||
--
|
||||
2.26.2
|
||||
|
307
0029-kern-buffer-Add-variable-sized-heap-buffer.patch
Normal file
307
0029-kern-buffer-Add-variable-sized-heap-buffer.patch
Normal file
@ -0,0 +1,307 @@
|
||||
From 6fa7584551965d6e444ca1a934839c6538646d0d Mon Sep 17 00:00:00 2001
|
||||
From: Chris Coulson <chris.coulson@canonical.com>
|
||||
Date: Thu, 7 Jan 2021 15:15:43 +0000
|
||||
Subject: [PATCH 29/46] 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>
|
||||
---
|
||||
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 a00e7f983..eac42a7b7 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 */
|
||||
--
|
||||
2.26.2
|
||||
|
247
0030-kern-parser-Fix-a-stack-buffer-overflow.patch
Normal file
247
0030-kern-parser-Fix-a-stack-buffer-overflow.patch
Normal file
@ -0,0 +1,247 @@
|
||||
From e26b56b819c65d251d12175dd82fab4679cfbc87 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Coulson <chris.coulson@canonical.com>
|
||||
Date: Thu, 7 Jan 2021 19:21:03 +0000
|
||||
Subject: [PATCH 30/46] 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>
|
||||
---
|
||||
grub-core/kern/parser.c | 110 ++++++++++++++++++++++++----------------
|
||||
1 file changed, 67 insertions(+), 43 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c
|
||||
index e010eaa1f..6ab7aa427 100644
|
||||
--- a/grub-core/kern/parser.c
|
||||
+++ b/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 **vp,
|
||||
/* Check if a variable was being read in and the end of the name
|
||||
was reached. */
|
||||
if (!(check_varstate (state) && !check_varstate (newstate)))
|
||||
- return;
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ 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 **bp, char *varname, char **vp,
|
||||
* not describe the variable anymore, write the variable to
|
||||
* the buffer.
|
||||
*/
|
||||
- add_var (varname, bp, vp, state, *newstate);
|
||||
+ if (add_var (varname, buffer, state, *newstate) != GRUB_ERR_NONE)
|
||||
+ return grub_errno;
|
||||
|
||||
if (check_varstate (*newstate))
|
||||
{
|
||||
if (use)
|
||||
- *((*vp)++) = use;
|
||||
+ return grub_buffer_append_char (varname, use);
|
||||
}
|
||||
else if (*newstate == GRUB_PARSER_STATE_TEXT &&
|
||||
state != GRUB_PARSER_STATE_ESC && grub_isspace (use))
|
||||
@@ -167,10 +179,10 @@ process_char (char c, char *buffer, char **bp, char *varname, char **vp,
|
||||
* Don't add more than one argument if multiple
|
||||
* spaces are used.
|
||||
*/
|
||||
- terminate_arg (buffer, bp, argc);
|
||||
+ return terminate_arg (buffer, argc);
|
||||
}
|
||||
else if (use)
|
||||
- *((*bp)++) = use;
|
||||
+ return grub_buffer_append_char (buffer, use);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
@@ -181,19 +193,22 @@ grub_parser_split_cmdline (const char *cmdline,
|
||||
int *argc, char ***argv)
|
||||
{
|
||||
grub_parser_state_t state = GRUB_PARSER_STATE_TEXT;
|
||||
- /* XXX: Fixed size buffer, perhaps this buffer should be dynamically
|
||||
- allocated. */
|
||||
- char buffer[1024];
|
||||
- char *bp = buffer;
|
||||
+ grub_buffer_t buffer, varname;
|
||||
char *rd = (char *) cmdline;
|
||||
char *rp = rd;
|
||||
- char varname[200];
|
||||
- char *vp = varname;
|
||||
- char *args;
|
||||
int i;
|
||||
|
||||
*argc = 0;
|
||||
*argv = NULL;
|
||||
+
|
||||
+ buffer = grub_buffer_new (1024);
|
||||
+ if (buffer == NULL)
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ varname = grub_buffer_new (200);
|
||||
+ if (varname == NULL)
|
||||
+ goto fail;
|
||||
+
|
||||
do
|
||||
{
|
||||
if (rp == NULL || *rp == '\0')
|
||||
@@ -219,7 +234,7 @@ grub_parser_split_cmdline (const char *cmdline,
|
||||
{
|
||||
grub_parser_state_t newstate;
|
||||
|
||||
- if (process_char (*rp, buffer, &bp, varname, &vp, state, argc,
|
||||
+ if (process_char (*rp, buffer, varname, state, argc,
|
||||
&newstate) != GRUB_ERR_NONE)
|
||||
goto fail;
|
||||
|
||||
@@ -230,10 +245,12 @@ grub_parser_split_cmdline (const char *cmdline,
|
||||
|
||||
/* A special case for when the last character was part of a
|
||||
variable. */
|
||||
- add_var (varname, &bp, &vp, state, GRUB_PARSER_STATE_TEXT);
|
||||
+ if (add_var (varname, buffer, state, GRUB_PARSER_STATE_TEXT) != GRUB_ERR_NONE)
|
||||
+ goto fail;
|
||||
|
||||
/* Ensure that the last argument is terminated. */
|
||||
- terminate_arg (buffer, &bp, argc);
|
||||
+ if (terminate_arg (buffer, argc) != GRUB_ERR_NONE)
|
||||
+ goto fail;
|
||||
|
||||
/* If there are no args, then we're done. */
|
||||
if (!*argc)
|
||||
@@ -242,38 +259,45 @@ grub_parser_split_cmdline (const char *cmdline,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- /* Reserve memory for the return values. */
|
||||
- args = grub_malloc (bp - buffer);
|
||||
- if (!args)
|
||||
- goto fail;
|
||||
- grub_memcpy (args, buffer, bp - buffer);
|
||||
-
|
||||
*argv = grub_calloc (*argc + 1, sizeof (char *));
|
||||
if (!*argv)
|
||||
goto fail;
|
||||
|
||||
/* The arguments are separated with 0's, setup argv so it points to
|
||||
the right values. */
|
||||
- bp = args;
|
||||
for (i = 0; i < *argc; i++)
|
||||
{
|
||||
- (*argv)[i] = bp;
|
||||
- while (*bp)
|
||||
- bp++;
|
||||
- bp++;
|
||||
+ char *arg;
|
||||
+
|
||||
+ if (i > 0)
|
||||
+ {
|
||||
+ if (grub_buffer_advance_read_pos (buffer, 1) != GRUB_ERR_NONE)
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ arg = (char *) grub_buffer_peek_data (buffer);
|
||||
+ if (arg == NULL ||
|
||||
+ grub_buffer_advance_read_pos (buffer, grub_strlen (arg)) != GRUB_ERR_NONE)
|
||||
+ goto fail;
|
||||
+
|
||||
+ (*argv)[i] = arg;
|
||||
}
|
||||
|
||||
+ /* Keep memory for the return values. */
|
||||
+ grub_buffer_take_data (buffer);
|
||||
+
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
||||
out:
|
||||
if (rd != cmdline)
|
||||
grub_free (rd);
|
||||
+ grub_buffer_free (buffer);
|
||||
+ grub_buffer_free (varname);
|
||||
|
||||
return grub_errno;
|
||||
|
||||
fail:
|
||||
grub_free (*argv);
|
||||
- grub_free (args);
|
||||
goto out;
|
||||
}
|
||||
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,60 @@
|
||||
From 88862305f889d23a176c936ff337a8f3ec492efd Mon Sep 17 00:00:00 2001
|
||||
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Date: Thu, 11 Feb 2021 17:06:49 +0100
|
||||
Subject: [PATCH 31/46] util/mkimage: Remove unused code to add BSS section
|
||||
|
||||
The code is compiled out so there is no reason to keep it.
|
||||
|
||||
Additionally, don't set bss_size field since we do not add a BSS section.
|
||||
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
util/mkimage.c | 17 -----------------
|
||||
1 file changed, 17 deletions(-)
|
||||
|
||||
diff --git a/util/mkimage.c b/util/mkimage.c
|
||||
index 37d6249f1..32bb8ea68 100644
|
||||
--- a/util/mkimage.c
|
||||
+++ b/util/mkimage.c
|
||||
@@ -1304,7 +1304,6 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
o->code_size = grub_host_to_target32 (layout.exec_size);
|
||||
o->data_size = grub_cpu_to_le32 (reloc_addr - layout.exec_size
|
||||
- header_size);
|
||||
- o->bss_size = grub_cpu_to_le32 (layout.bss_size);
|
||||
o->entry_addr = grub_cpu_to_le32 (layout.start_address);
|
||||
o->code_base = grub_cpu_to_le32 (header_size);
|
||||
|
||||
@@ -1342,7 +1341,6 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
o->code_size = grub_host_to_target32 (layout.exec_size);
|
||||
o->data_size = grub_cpu_to_le32 (reloc_addr - layout.exec_size
|
||||
- header_size);
|
||||
- o->bss_size = grub_cpu_to_le32 (layout.bss_size);
|
||||
o->entry_addr = grub_cpu_to_le32 (layout.start_address);
|
||||
o->code_base = grub_cpu_to_le32 (header_size);
|
||||
o->image_base = 0;
|
||||
@@ -1387,21 +1385,6 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
= grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
|
||||
| GRUB_PE32_SCN_MEM_READ
|
||||
| GRUB_PE32_SCN_MEM_WRITE);
|
||||
-
|
||||
-#if 0
|
||||
- bss_section = data_section + 1;
|
||||
- strcpy (bss_section->name, ".bss");
|
||||
- bss_section->virtual_size = grub_cpu_to_le32 (layout.bss_size);
|
||||
- bss_section->virtual_address = grub_cpu_to_le32 (header_size + layout.kernel_size);
|
||||
- bss_section->raw_data_size = 0;
|
||||
- bss_section->raw_data_offset = 0;
|
||||
- bss_section->characteristics
|
||||
- = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_MEM_READ
|
||||
- | GRUB_PE32_SCN_MEM_WRITE
|
||||
- | GRUB_PE32_SCN_ALIGN_64BYTES
|
||||
- | GRUB_PE32_SCN_CNT_INITIALIZED_DATA
|
||||
- | 0x80);
|
||||
-#endif
|
||||
|
||||
mods_section = data_section + 1;
|
||||
strcpy (mods_section->name, "mods");
|
||||
--
|
||||
2.26.2
|
||||
|
112
0032-util-mkimage-Use-grub_host_to_target32-instead-of-gr.patch
Normal file
112
0032-util-mkimage-Use-grub_host_to_target32-instead-of-gr.patch
Normal file
@ -0,0 +1,112 @@
|
||||
From 6e003a43373e87683f3c5b783cdc8e423e1a6bc3 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Mon, 15 Feb 2021 13:59:21 +0100
|
||||
Subject: [PATCH 32/46] util/mkimage: Use grub_host_to_target32() instead of
|
||||
grub_cpu_to_le32()
|
||||
|
||||
The latter doesn't take into account the target image endianness. There is
|
||||
a grub_cpu_to_le32_compile_time() but no compile time variant for function
|
||||
grub_host_to_target32(). So, let's keep using the other one for this case.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
util/mkimage.c | 44 ++++++++++++++++++++++----------------------
|
||||
1 file changed, 22 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/util/mkimage.c b/util/mkimage.c
|
||||
index 32bb8ea68..02944f28e 100644
|
||||
--- a/util/mkimage.c
|
||||
+++ b/util/mkimage.c
|
||||
@@ -1302,10 +1302,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
+ sizeof (struct grub_pe32_coff_header));
|
||||
o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC);
|
||||
o->code_size = grub_host_to_target32 (layout.exec_size);
|
||||
- o->data_size = grub_cpu_to_le32 (reloc_addr - layout.exec_size
|
||||
+ o->data_size = grub_host_to_target32 (reloc_addr - layout.exec_size
|
||||
- header_size);
|
||||
- o->entry_addr = grub_cpu_to_le32 (layout.start_address);
|
||||
- o->code_base = grub_cpu_to_le32 (header_size);
|
||||
+ o->entry_addr = grub_host_to_target32 (layout.start_address);
|
||||
+ o->code_base = grub_host_to_target32 (header_size);
|
||||
|
||||
o->data_base = grub_host_to_target32 (header_size + layout.exec_size);
|
||||
|
||||
@@ -1339,10 +1339,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
+ sizeof (struct grub_pe32_coff_header));
|
||||
o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC);
|
||||
o->code_size = grub_host_to_target32 (layout.exec_size);
|
||||
- o->data_size = grub_cpu_to_le32 (reloc_addr - layout.exec_size
|
||||
+ o->data_size = grub_host_to_target32 (reloc_addr - layout.exec_size
|
||||
- header_size);
|
||||
- o->entry_addr = grub_cpu_to_le32 (layout.start_address);
|
||||
- o->code_base = grub_cpu_to_le32 (header_size);
|
||||
+ o->entry_addr = grub_host_to_target32 (layout.start_address);
|
||||
+ o->code_base = grub_host_to_target32 (header_size);
|
||||
o->image_base = 0;
|
||||
o->section_alignment = grub_host_to_target32 (image_target->section_align);
|
||||
o->file_alignment = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT);
|
||||
@@ -1366,10 +1366,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
/* The sections. */
|
||||
text_section = sections;
|
||||
strcpy (text_section->name, ".text");
|
||||
- text_section->virtual_size = grub_cpu_to_le32 (layout.exec_size);
|
||||
- text_section->virtual_address = grub_cpu_to_le32 (header_size);
|
||||
- text_section->raw_data_size = grub_cpu_to_le32 (layout.exec_size);
|
||||
- text_section->raw_data_offset = grub_cpu_to_le32 (header_size);
|
||||
+ text_section->virtual_size = grub_host_to_target32 (layout.exec_size);
|
||||
+ text_section->virtual_address = grub_host_to_target32 (header_size);
|
||||
+ text_section->raw_data_size = grub_host_to_target32 (layout.exec_size);
|
||||
+ text_section->raw_data_offset = grub_host_to_target32 (header_size);
|
||||
text_section->characteristics = grub_cpu_to_le32_compile_time (
|
||||
GRUB_PE32_SCN_CNT_CODE
|
||||
| GRUB_PE32_SCN_MEM_EXECUTE
|
||||
@@ -1377,10 +1377,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
|
||||
data_section = text_section + 1;
|
||||
strcpy (data_section->name, ".data");
|
||||
- data_section->virtual_size = grub_cpu_to_le32 (layout.kernel_size - layout.exec_size);
|
||||
- data_section->virtual_address = grub_cpu_to_le32 (header_size + layout.exec_size);
|
||||
- data_section->raw_data_size = grub_cpu_to_le32 (layout.kernel_size - layout.exec_size);
|
||||
- data_section->raw_data_offset = grub_cpu_to_le32 (header_size + layout.exec_size);
|
||||
+ data_section->virtual_size = grub_host_to_target32 (layout.kernel_size - layout.exec_size);
|
||||
+ data_section->virtual_address = grub_host_to_target32 (header_size + layout.exec_size);
|
||||
+ data_section->raw_data_size = grub_host_to_target32 (layout.kernel_size - layout.exec_size);
|
||||
+ data_section->raw_data_offset = grub_host_to_target32 (header_size + layout.exec_size);
|
||||
data_section->characteristics
|
||||
= grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
|
||||
| GRUB_PE32_SCN_MEM_READ
|
||||
@@ -1388,10 +1388,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
|
||||
mods_section = data_section + 1;
|
||||
strcpy (mods_section->name, "mods");
|
||||
- mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - layout.kernel_size - header_size);
|
||||
- mods_section->virtual_address = grub_cpu_to_le32 (header_size + layout.kernel_size + layout.bss_size);
|
||||
- mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - layout.kernel_size - header_size);
|
||||
- mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + layout.kernel_size);
|
||||
+ mods_section->virtual_size = grub_host_to_target32 (reloc_addr - layout.kernel_size - header_size);
|
||||
+ mods_section->virtual_address = grub_host_to_target32 (header_size + layout.kernel_size + layout.bss_size);
|
||||
+ mods_section->raw_data_size = grub_host_to_target32 (reloc_addr - layout.kernel_size - header_size);
|
||||
+ mods_section->raw_data_offset = grub_host_to_target32 (header_size + layout.kernel_size);
|
||||
mods_section->characteristics
|
||||
= grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
|
||||
| GRUB_PE32_SCN_MEM_READ
|
||||
@@ -1399,10 +1399,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
|
||||
reloc_section = mods_section + 1;
|
||||
strcpy (reloc_section->name, ".reloc");
|
||||
- reloc_section->virtual_size = grub_cpu_to_le32 (layout.reloc_size);
|
||||
- reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + layout.bss_size);
|
||||
- reloc_section->raw_data_size = grub_cpu_to_le32 (layout.reloc_size);
|
||||
- reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr);
|
||||
+ reloc_section->virtual_size = grub_host_to_target32 (layout.reloc_size);
|
||||
+ reloc_section->virtual_address = grub_host_to_target32 (reloc_addr + layout.bss_size);
|
||||
+ reloc_section->raw_data_size = grub_host_to_target32 (layout.reloc_size);
|
||||
+ reloc_section->raw_data_offset = grub_host_to_target32 (reloc_addr);
|
||||
reloc_section->characteristics
|
||||
= grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
|
||||
| GRUB_PE32_SCN_MEM_DISCARDABLE
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,38 @@
|
||||
From 4bf74d11396e0adde218a3129599f145459852f3 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Mon, 15 Feb 2021 14:14:24 +0100
|
||||
Subject: [PATCH 33/46] util/mkimage: Always use grub_host_to_target32() to
|
||||
initialize PE stack and heap stuff
|
||||
|
||||
This change does not impact final result of initialization itself.
|
||||
However, it eases PE code unification in subsequent patches.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
util/mkimage.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/util/mkimage.c b/util/mkimage.c
|
||||
index 02944f28e..b94bfb781 100644
|
||||
--- a/util/mkimage.c
|
||||
+++ b/util/mkimage.c
|
||||
@@ -1351,10 +1351,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION);
|
||||
|
||||
/* Do these really matter? */
|
||||
- o->stack_reserve_size = grub_host_to_target64 (0x10000);
|
||||
- o->stack_commit_size = grub_host_to_target64 (0x10000);
|
||||
- o->heap_reserve_size = grub_host_to_target64 (0x10000);
|
||||
- o->heap_commit_size = grub_host_to_target64 (0x10000);
|
||||
+ o->stack_reserve_size = grub_host_to_target32 (0x10000);
|
||||
+ o->stack_commit_size = grub_host_to_target32 (0x10000);
|
||||
+ o->heap_reserve_size = grub_host_to_target32 (0x10000);
|
||||
+ o->heap_commit_size = grub_host_to_target32 (0x10000);
|
||||
|
||||
o->num_data_directories
|
||||
= grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
|
||||
--
|
||||
2.26.2
|
||||
|
169
0034-util-mkimage-Unify-more-of-the-PE32-and-PE32-header-.patch
Normal file
169
0034-util-mkimage-Unify-more-of-the-PE32-and-PE32-header-.patch
Normal file
@ -0,0 +1,169 @@
|
||||
From 17db90317938d492561af63f0cc7356c6dadb46a Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Mon, 15 Feb 2021 14:19:31 +0100
|
||||
Subject: [PATCH 34/46] util/mkimage: Unify more of the PE32 and PE32+ header
|
||||
set-up
|
||||
|
||||
There's quite a bit of code duplication in the code that sets the optional
|
||||
header for PE32 and PE32+. The two are very similar with the exception of
|
||||
a few fields that have type grub_uint64_t instead of grub_uint32_t.
|
||||
|
||||
Factor out the common code and add a PE_OHDR() macro that simplifies the
|
||||
set-up and make the code more readable.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
util/mkimage.c | 111 +++++++++++++++++++++++--------------------------
|
||||
1 file changed, 51 insertions(+), 60 deletions(-)
|
||||
|
||||
diff --git a/util/mkimage.c b/util/mkimage.c
|
||||
index b94bfb781..a039039db 100644
|
||||
--- a/util/mkimage.c
|
||||
+++ b/util/mkimage.c
|
||||
@@ -816,6 +816,21 @@ grub_install_get_image_targets_string (void)
|
||||
return formats;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * tmp_ is just here so the compiler knows we'll never derefernce a NULL.
|
||||
+ * It should get fully optimized away.
|
||||
+ */
|
||||
+#define PE_OHDR(o32, o64, field) (*( \
|
||||
+{ \
|
||||
+ __typeof__((o64)->field) tmp_; \
|
||||
+ __typeof__((o64)->field) *ret_ = &tmp_; \
|
||||
+ if (o32) \
|
||||
+ ret_ = (void *)(&((o32)->field)); \
|
||||
+ else if (o64) \
|
||||
+ ret_ = (void *)(&((o64)->field)); \
|
||||
+ ret_; \
|
||||
+}))
|
||||
+
|
||||
void
|
||||
grub_install_generate_image (const char *dir, const char *prefix,
|
||||
FILE *out, const char *outname, char *mods[],
|
||||
@@ -1252,6 +1267,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB;
|
||||
int header_size;
|
||||
int reloc_addr;
|
||||
+ struct grub_pe32_optional_header *o32 = NULL;
|
||||
+ struct grub_pe64_optional_header *o64 = NULL;
|
||||
|
||||
if (image_target->voidp_sizeof == 4)
|
||||
header_size = EFI32_HEADER_SIZE;
|
||||
@@ -1293,76 +1310,50 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
/* The PE Optional header. */
|
||||
if (image_target->voidp_sizeof == 4)
|
||||
{
|
||||
- struct grub_pe32_optional_header *o;
|
||||
-
|
||||
c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header));
|
||||
|
||||
- o = (struct grub_pe32_optional_header *)
|
||||
- (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE
|
||||
- + sizeof (struct grub_pe32_coff_header));
|
||||
- o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC);
|
||||
- o->code_size = grub_host_to_target32 (layout.exec_size);
|
||||
- o->data_size = grub_host_to_target32 (reloc_addr - layout.exec_size
|
||||
- - header_size);
|
||||
- o->entry_addr = grub_host_to_target32 (layout.start_address);
|
||||
- o->code_base = grub_host_to_target32 (header_size);
|
||||
-
|
||||
- o->data_base = grub_host_to_target32 (header_size + layout.exec_size);
|
||||
-
|
||||
- o->image_base = 0;
|
||||
- o->section_alignment = grub_host_to_target32 (image_target->section_align);
|
||||
- o->file_alignment = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT);
|
||||
- o->image_size = grub_host_to_target32 (pe_size);
|
||||
- o->header_size = grub_host_to_target32 (header_size);
|
||||
- o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION);
|
||||
-
|
||||
- /* Do these really matter? */
|
||||
- o->stack_reserve_size = grub_host_to_target32 (0x10000);
|
||||
- o->stack_commit_size = grub_host_to_target32 (0x10000);
|
||||
- o->heap_reserve_size = grub_host_to_target32 (0x10000);
|
||||
- o->heap_commit_size = grub_host_to_target32 (0x10000);
|
||||
-
|
||||
- o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
|
||||
+ o32 = (struct grub_pe32_optional_header *)
|
||||
+ (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE +
|
||||
+ sizeof (struct grub_pe32_coff_header));
|
||||
+ o32->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC);
|
||||
+ o32->data_base = grub_host_to_target32 (header_size + layout.exec_size);
|
||||
|
||||
- o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr);
|
||||
- o->base_relocation_table.size = grub_host_to_target32 (layout.reloc_size);
|
||||
- sections = o + 1;
|
||||
+ sections = o32 + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
- struct grub_pe64_optional_header *o;
|
||||
-
|
||||
c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe64_optional_header));
|
||||
|
||||
- o = (struct grub_pe64_optional_header *)
|
||||
- (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE
|
||||
- + sizeof (struct grub_pe32_coff_header));
|
||||
- o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC);
|
||||
- o->code_size = grub_host_to_target32 (layout.exec_size);
|
||||
- o->data_size = grub_host_to_target32 (reloc_addr - layout.exec_size
|
||||
- - header_size);
|
||||
- o->entry_addr = grub_host_to_target32 (layout.start_address);
|
||||
- o->code_base = grub_host_to_target32 (header_size);
|
||||
- o->image_base = 0;
|
||||
- o->section_alignment = grub_host_to_target32 (image_target->section_align);
|
||||
- o->file_alignment = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT);
|
||||
- o->image_size = grub_host_to_target32 (pe_size);
|
||||
- o->header_size = grub_host_to_target32 (header_size);
|
||||
- o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION);
|
||||
-
|
||||
- /* Do these really matter? */
|
||||
- o->stack_reserve_size = grub_host_to_target32 (0x10000);
|
||||
- o->stack_commit_size = grub_host_to_target32 (0x10000);
|
||||
- o->heap_reserve_size = grub_host_to_target32 (0x10000);
|
||||
- o->heap_commit_size = grub_host_to_target32 (0x10000);
|
||||
-
|
||||
- o->num_data_directories
|
||||
- = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
|
||||
+ o64 = (struct grub_pe64_optional_header *)
|
||||
+ (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE +
|
||||
+ sizeof (struct grub_pe32_coff_header));
|
||||
+ o64->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC);
|
||||
|
||||
- o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr);
|
||||
- o->base_relocation_table.size = grub_host_to_target32 (layout.reloc_size);
|
||||
- sections = o + 1;
|
||||
+ sections = o64 + 1;
|
||||
}
|
||||
+
|
||||
+ PE_OHDR (o32, o64, code_size) = grub_host_to_target32 (layout.exec_size);
|
||||
+ PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (reloc_addr - layout.exec_size - header_size);
|
||||
+ PE_OHDR (o32, o64, entry_addr) = grub_host_to_target32 (layout.start_address);
|
||||
+ PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (header_size);
|
||||
+
|
||||
+ PE_OHDR (o32, o64, image_base) = 0;
|
||||
+ PE_OHDR (o32, o64, section_alignment) = grub_host_to_target32 (image_target->section_align);
|
||||
+ PE_OHDR (o32, o64, file_alignment) = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT);
|
||||
+ PE_OHDR (o32, o64, image_size) = grub_host_to_target32 (pe_size);
|
||||
+ PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size);
|
||||
+ PE_OHDR (o32, o64, subsystem) = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION);
|
||||
+
|
||||
+ /* Do these really matter? */
|
||||
+ PE_OHDR (o32, o64, stack_reserve_size) = grub_host_to_target32 (0x10000);
|
||||
+ PE_OHDR (o32, o64, stack_commit_size) = grub_host_to_target32 (0x10000);
|
||||
+ PE_OHDR (o32, o64, heap_reserve_size) = grub_host_to_target32 (0x10000);
|
||||
+ PE_OHDR (o32, o64, heap_commit_size) = grub_host_to_target32 (0x10000);
|
||||
+
|
||||
+ PE_OHDR (o32, o64, num_data_directories) = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
|
||||
+ PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (reloc_addr);
|
||||
+ PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (layout.reloc_size);
|
||||
+
|
||||
/* The sections. */
|
||||
text_section = sections;
|
||||
strcpy (text_section->name, ".text");
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,72 @@
|
||||
From fbacfa8211adbd1acaf264f7b1292781121a7195 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Mon, 15 Feb 2021 14:21:48 +0100
|
||||
Subject: [PATCH 35/46] util/mkimage: Reorder PE optional header fields set-up
|
||||
|
||||
This makes the PE32 and PE32+ header fields set-up easier to follow by
|
||||
setting them closer to the initialization of their related sections.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
util/mkimage.c | 16 ++++++++--------
|
||||
1 file changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/util/mkimage.c b/util/mkimage.c
|
||||
index a039039db..deaef5666 100644
|
||||
--- a/util/mkimage.c
|
||||
+++ b/util/mkimage.c
|
||||
@@ -1332,16 +1332,12 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
sections = o64 + 1;
|
||||
}
|
||||
|
||||
- PE_OHDR (o32, o64, code_size) = grub_host_to_target32 (layout.exec_size);
|
||||
- PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (reloc_addr - layout.exec_size - header_size);
|
||||
+ PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size);
|
||||
PE_OHDR (o32, o64, entry_addr) = grub_host_to_target32 (layout.start_address);
|
||||
- PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (header_size);
|
||||
-
|
||||
PE_OHDR (o32, o64, image_base) = 0;
|
||||
+ PE_OHDR (o32, o64, image_size) = grub_host_to_target32 (pe_size);
|
||||
PE_OHDR (o32, o64, section_alignment) = grub_host_to_target32 (image_target->section_align);
|
||||
PE_OHDR (o32, o64, file_alignment) = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT);
|
||||
- PE_OHDR (o32, o64, image_size) = grub_host_to_target32 (pe_size);
|
||||
- PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size);
|
||||
PE_OHDR (o32, o64, subsystem) = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION);
|
||||
|
||||
/* Do these really matter? */
|
||||
@@ -1351,10 +1347,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
PE_OHDR (o32, o64, heap_commit_size) = grub_host_to_target32 (0x10000);
|
||||
|
||||
PE_OHDR (o32, o64, num_data_directories) = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
|
||||
- PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (reloc_addr);
|
||||
- PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (layout.reloc_size);
|
||||
|
||||
/* The sections. */
|
||||
+ PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (header_size);
|
||||
+ PE_OHDR (o32, o64, code_size) = grub_host_to_target32 (layout.exec_size);
|
||||
text_section = sections;
|
||||
strcpy (text_section->name, ".text");
|
||||
text_section->virtual_size = grub_host_to_target32 (layout.exec_size);
|
||||
@@ -1366,6 +1362,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
| GRUB_PE32_SCN_MEM_EXECUTE
|
||||
| GRUB_PE32_SCN_MEM_READ);
|
||||
|
||||
+ PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (reloc_addr - layout.exec_size - header_size);
|
||||
+
|
||||
data_section = text_section + 1;
|
||||
strcpy (data_section->name, ".data");
|
||||
data_section->virtual_size = grub_host_to_target32 (layout.kernel_size - layout.exec_size);
|
||||
@@ -1388,6 +1386,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
| GRUB_PE32_SCN_MEM_READ
|
||||
| GRUB_PE32_SCN_MEM_WRITE);
|
||||
|
||||
+ PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (reloc_addr);
|
||||
+ PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (layout.reloc_size);
|
||||
reloc_section = mods_section + 1;
|
||||
strcpy (reloc_section->name, ".reloc");
|
||||
reloc_section->virtual_size = grub_host_to_target32 (layout.reloc_size);
|
||||
--
|
||||
2.26.2
|
||||
|
49
0036-util-mkimage-Improve-data_size-value-calculation.patch
Normal file
49
0036-util-mkimage-Improve-data_size-value-calculation.patch
Normal file
@ -0,0 +1,49 @@
|
||||
From 805d58de7a06687572fba8f8d0f4110204246f2d Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Thu, 11 Feb 2021 17:07:33 +0100
|
||||
Subject: [PATCH 36/46] util/mkimage: Improve data_size value calculation
|
||||
|
||||
According to "Microsoft Portable Executable and Common Object File Format
|
||||
Specification", the Optional Header SizeOfInitializedData field contains:
|
||||
|
||||
Size of the initialized data section, or the sum of all such sections if
|
||||
there are multiple data sections.
|
||||
|
||||
Make this explicit by adding the GRUB kernel data size to the sum of all
|
||||
the modules sizes. The ALIGN_UP() is not required by the PE spec but do
|
||||
it to avoid alignment issues.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
util/mkimage.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/util/mkimage.c b/util/mkimage.c
|
||||
index deaef5666..853a52179 100644
|
||||
--- a/util/mkimage.c
|
||||
+++ b/util/mkimage.c
|
||||
@@ -1260,6 +1260,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
void *pe_img;
|
||||
grub_uint8_t *header;
|
||||
void *sections;
|
||||
+ size_t scn_size;
|
||||
size_t pe_size;
|
||||
struct grub_pe32_coff_header *c;
|
||||
struct grub_pe32_section_table *text_section, *data_section;
|
||||
@@ -1362,7 +1363,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
| GRUB_PE32_SCN_MEM_EXECUTE
|
||||
| GRUB_PE32_SCN_MEM_READ);
|
||||
|
||||
- PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (reloc_addr - layout.exec_size - header_size);
|
||||
+ scn_size = ALIGN_UP (layout.kernel_size - layout.exec_size, GRUB_PE32_FILE_ALIGNMENT);
|
||||
+ PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size +
|
||||
+ ALIGN_UP (total_module_size,
|
||||
+ GRUB_PE32_FILE_ALIGNMENT));
|
||||
|
||||
data_section = text_section + 1;
|
||||
strcpy (data_section->name, ".data");
|
||||
--
|
||||
2.26.2
|
||||
|
220
0037-util-mkimage-Refactor-section-setup-to-use-a-helper.patch
Normal file
220
0037-util-mkimage-Refactor-section-setup-to-use-a-helper.patch
Normal file
@ -0,0 +1,220 @@
|
||||
From aa25aa5d9ce91e862cc951225c5aabc78c4d4366 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Mon, 15 Feb 2021 14:58:06 +0100
|
||||
Subject: [PATCH 37/46] util/mkimage: Refactor section setup to use a helper
|
||||
|
||||
Add a init_pe_section() helper function to setup PE sections. This makes
|
||||
the code simpler and easier to read.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
util/mkimage.c | 143 ++++++++++++++++++++++++++-----------------------
|
||||
1 file changed, 77 insertions(+), 66 deletions(-)
|
||||
|
||||
diff --git a/util/mkimage.c b/util/mkimage.c
|
||||
index 853a52179..8b475a691 100644
|
||||
--- a/util/mkimage.c
|
||||
+++ b/util/mkimage.c
|
||||
@@ -816,6 +816,38 @@ grub_install_get_image_targets_string (void)
|
||||
return formats;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * The image_target parameter is used by the grub_host_to_target32() macro.
|
||||
+ */
|
||||
+static struct grub_pe32_section_table *
|
||||
+init_pe_section(const struct grub_install_image_target_desc *image_target,
|
||||
+ struct grub_pe32_section_table *section,
|
||||
+ const char * const name,
|
||||
+ grub_uint32_t *vma, grub_uint32_t vsz, grub_uint32_t valign,
|
||||
+ grub_uint32_t *rda, grub_uint32_t rsz,
|
||||
+ grub_uint32_t characteristics)
|
||||
+{
|
||||
+ size_t len = strlen (name);
|
||||
+
|
||||
+ if (len > sizeof (section->name))
|
||||
+ grub_util_error (_("section name %s length is bigger than %lu"),
|
||||
+ name, (unsigned long) sizeof (section->name));
|
||||
+
|
||||
+ memcpy (section->name, name, len);
|
||||
+
|
||||
+ section->virtual_address = grub_host_to_target32 (*vma);
|
||||
+ section->virtual_size = grub_host_to_target32 (vsz);
|
||||
+ (*vma) = ALIGN_UP (*vma + vsz, valign);
|
||||
+
|
||||
+ section->raw_data_offset = grub_host_to_target32 (*rda);
|
||||
+ section->raw_data_size = grub_host_to_target32 (rsz);
|
||||
+ (*rda) = ALIGN_UP (*rda + rsz, GRUB_PE32_FILE_ALIGNMENT);
|
||||
+
|
||||
+ section->characteristics = grub_host_to_target32 (characteristics);
|
||||
+
|
||||
+ return section + 1;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* tmp_ is just here so the compiler knows we'll never derefernce a NULL.
|
||||
* It should get fully optimized away.
|
||||
@@ -1257,17 +1289,13 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
break;
|
||||
case IMAGE_EFI:
|
||||
{
|
||||
- void *pe_img;
|
||||
- grub_uint8_t *header;
|
||||
- void *sections;
|
||||
+ char *pe_img, *header;
|
||||
+ struct grub_pe32_section_table *section;
|
||||
size_t scn_size;
|
||||
- size_t pe_size;
|
||||
+ grub_uint32_t vma, raw_data;
|
||||
+ size_t pe_size, header_size;
|
||||
struct grub_pe32_coff_header *c;
|
||||
- struct grub_pe32_section_table *text_section, *data_section;
|
||||
- struct grub_pe32_section_table *mods_section, *reloc_section;
|
||||
static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB;
|
||||
- int header_size;
|
||||
- int reloc_addr;
|
||||
struct grub_pe32_optional_header *o32 = NULL;
|
||||
struct grub_pe64_optional_header *o64 = NULL;
|
||||
|
||||
@@ -1276,17 +1304,12 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
else
|
||||
header_size = EFI64_HEADER_SIZE;
|
||||
|
||||
- reloc_addr = ALIGN_UP (header_size + core_size,
|
||||
- GRUB_PE32_FILE_ALIGNMENT);
|
||||
+ vma = raw_data = header_size;
|
||||
+ pe_size = ALIGN_UP (header_size + core_size, GRUB_PE32_FILE_ALIGNMENT) +
|
||||
+ ALIGN_UP (layout.reloc_size, GRUB_PE32_FILE_ALIGNMENT);
|
||||
+ header = pe_img = xcalloc (1, pe_size);
|
||||
|
||||
- pe_size = ALIGN_UP (reloc_addr + layout.reloc_size,
|
||||
- GRUB_PE32_FILE_ALIGNMENT);
|
||||
- pe_img = xmalloc (reloc_addr + layout.reloc_size);
|
||||
- memset (pe_img, 0, header_size);
|
||||
- memcpy ((char *) pe_img + header_size, core_img, core_size);
|
||||
- memset ((char *) pe_img + header_size + core_size, 0, reloc_addr - (header_size + core_size));
|
||||
- memcpy ((char *) pe_img + reloc_addr, layout.reloc_section, layout.reloc_size);
|
||||
- header = pe_img;
|
||||
+ memcpy (pe_img + raw_data, core_img, core_size);
|
||||
|
||||
/* The magic. */
|
||||
memcpy (header, stub, GRUB_PE32_MSDOS_STUB_SIZE);
|
||||
@@ -1319,18 +1342,17 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
o32->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC);
|
||||
o32->data_base = grub_host_to_target32 (header_size + layout.exec_size);
|
||||
|
||||
- sections = o32 + 1;
|
||||
+ section = (struct grub_pe32_section_table *)(o32 + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe64_optional_header));
|
||||
-
|
||||
o64 = (struct grub_pe64_optional_header *)
|
||||
(header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE +
|
||||
sizeof (struct grub_pe32_coff_header));
|
||||
o64->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC);
|
||||
|
||||
- sections = o64 + 1;
|
||||
+ section = (struct grub_pe32_section_table *)(o64 + 1);
|
||||
}
|
||||
|
||||
PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size);
|
||||
@@ -1350,58 +1372,47 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
PE_OHDR (o32, o64, num_data_directories) = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
|
||||
|
||||
/* The sections. */
|
||||
- PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (header_size);
|
||||
+ PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (vma);
|
||||
PE_OHDR (o32, o64, code_size) = grub_host_to_target32 (layout.exec_size);
|
||||
- text_section = sections;
|
||||
- strcpy (text_section->name, ".text");
|
||||
- text_section->virtual_size = grub_host_to_target32 (layout.exec_size);
|
||||
- text_section->virtual_address = grub_host_to_target32 (header_size);
|
||||
- text_section->raw_data_size = grub_host_to_target32 (layout.exec_size);
|
||||
- text_section->raw_data_offset = grub_host_to_target32 (header_size);
|
||||
- text_section->characteristics = grub_cpu_to_le32_compile_time (
|
||||
- GRUB_PE32_SCN_CNT_CODE
|
||||
- | GRUB_PE32_SCN_MEM_EXECUTE
|
||||
- | GRUB_PE32_SCN_MEM_READ);
|
||||
+ section = init_pe_section (image_target, section, ".text",
|
||||
+ &vma, layout.exec_size,
|
||||
+ image_target->section_align,
|
||||
+ &raw_data, layout.exec_size,
|
||||
+ GRUB_PE32_SCN_CNT_CODE |
|
||||
+ GRUB_PE32_SCN_MEM_EXECUTE |
|
||||
+ GRUB_PE32_SCN_MEM_READ);
|
||||
|
||||
scn_size = ALIGN_UP (layout.kernel_size - layout.exec_size, GRUB_PE32_FILE_ALIGNMENT);
|
||||
PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size +
|
||||
ALIGN_UP (total_module_size,
|
||||
GRUB_PE32_FILE_ALIGNMENT));
|
||||
|
||||
- data_section = text_section + 1;
|
||||
- strcpy (data_section->name, ".data");
|
||||
- data_section->virtual_size = grub_host_to_target32 (layout.kernel_size - layout.exec_size);
|
||||
- data_section->virtual_address = grub_host_to_target32 (header_size + layout.exec_size);
|
||||
- data_section->raw_data_size = grub_host_to_target32 (layout.kernel_size - layout.exec_size);
|
||||
- data_section->raw_data_offset = grub_host_to_target32 (header_size + layout.exec_size);
|
||||
- data_section->characteristics
|
||||
- = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
|
||||
- | GRUB_PE32_SCN_MEM_READ
|
||||
- | GRUB_PE32_SCN_MEM_WRITE);
|
||||
-
|
||||
- mods_section = data_section + 1;
|
||||
- strcpy (mods_section->name, "mods");
|
||||
- mods_section->virtual_size = grub_host_to_target32 (reloc_addr - layout.kernel_size - header_size);
|
||||
- mods_section->virtual_address = grub_host_to_target32 (header_size + layout.kernel_size + layout.bss_size);
|
||||
- mods_section->raw_data_size = grub_host_to_target32 (reloc_addr - layout.kernel_size - header_size);
|
||||
- mods_section->raw_data_offset = grub_host_to_target32 (header_size + layout.kernel_size);
|
||||
- mods_section->characteristics
|
||||
- = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
|
||||
- | GRUB_PE32_SCN_MEM_READ
|
||||
- | GRUB_PE32_SCN_MEM_WRITE);
|
||||
-
|
||||
- PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (reloc_addr);
|
||||
- PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (layout.reloc_size);
|
||||
- reloc_section = mods_section + 1;
|
||||
- strcpy (reloc_section->name, ".reloc");
|
||||
- reloc_section->virtual_size = grub_host_to_target32 (layout.reloc_size);
|
||||
- reloc_section->virtual_address = grub_host_to_target32 (reloc_addr + layout.bss_size);
|
||||
- reloc_section->raw_data_size = grub_host_to_target32 (layout.reloc_size);
|
||||
- reloc_section->raw_data_offset = grub_host_to_target32 (reloc_addr);
|
||||
- reloc_section->characteristics
|
||||
- = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
|
||||
- | GRUB_PE32_SCN_MEM_DISCARDABLE
|
||||
- | GRUB_PE32_SCN_MEM_READ);
|
||||
+ section = init_pe_section (image_target, section, ".data",
|
||||
+ &vma, scn_size, image_target->section_align,
|
||||
+ &raw_data, scn_size,
|
||||
+ GRUB_PE32_SCN_CNT_INITIALIZED_DATA |
|
||||
+ GRUB_PE32_SCN_MEM_READ |
|
||||
+ GRUB_PE32_SCN_MEM_WRITE);
|
||||
+
|
||||
+ scn_size = pe_size - layout.reloc_size - raw_data;
|
||||
+ section = init_pe_section (image_target, section, "mods",
|
||||
+ &vma, scn_size, image_target->section_align,
|
||||
+ &raw_data, scn_size,
|
||||
+ GRUB_PE32_SCN_CNT_INITIALIZED_DATA |
|
||||
+ GRUB_PE32_SCN_MEM_READ |
|
||||
+ GRUB_PE32_SCN_MEM_WRITE);
|
||||
+
|
||||
+ scn_size = layout.reloc_size;
|
||||
+ PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (vma);
|
||||
+ PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (scn_size);
|
||||
+ memcpy (pe_img + raw_data, layout.reloc_section, scn_size);
|
||||
+ init_pe_section (image_target, section, ".reloc",
|
||||
+ &vma, scn_size, image_target->section_align,
|
||||
+ &raw_data, scn_size,
|
||||
+ GRUB_PE32_SCN_CNT_INITIALIZED_DATA |
|
||||
+ GRUB_PE32_SCN_MEM_DISCARDABLE |
|
||||
+ GRUB_PE32_SCN_MEM_READ);
|
||||
+
|
||||
free (core_img);
|
||||
core_img = pe_img;
|
||||
core_size = pe_size;
|
||||
--
|
||||
2.26.2
|
||||
|
263
0038-util-mkimage-Add-an-option-to-import-SBAT-metadata-i.patch
Normal file
263
0038-util-mkimage-Add-an-option-to-import-SBAT-metadata-i.patch
Normal file
@ -0,0 +1,263 @@
|
||||
From c128817e4493836b9877e573820782036dea2163 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Mon, 15 Feb 2021 17:07:00 +0100
|
||||
Subject: [PATCH 38/46] util/mkimage: Add an option to import SBAT metadata
|
||||
into a .sbat section
|
||||
|
||||
Add a --sbat option to the grub-mkimage tool which allows us to import
|
||||
an SBAT metadata formatted as a CSV file into a .sbat section of the
|
||||
EFI binary.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
docs/grub.texi | 19 ++++++++++++++++
|
||||
include/grub/util/install.h | 3 ++-
|
||||
include/grub/util/mkimage.h | 1 +
|
||||
util/grub-install-common.c | 2 +-
|
||||
util/grub-mkimage.c | 15 ++++++++++++-
|
||||
util/mkimage.c | 43 +++++++++++++++++++++++++++++++------
|
||||
6 files changed, 73 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index cf29a1797..fa0b49737 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -5612,6 +5612,7 @@ environment variables and commands are listed in the same order.
|
||||
* Authentication and authorisation:: Users and access control
|
||||
* Using digital signatures:: Booting digitally signed code
|
||||
* UEFI secure boot and shim:: Booting digitally signed PE files
|
||||
+* Secure Boot Advanced Targeting:: Embedded information for generation number based revocation
|
||||
* Measured Boot:: Measuring boot components
|
||||
* Lockdown:: Lockdown when booting on a secure setup
|
||||
@end menu
|
||||
@@ -5791,6 +5792,24 @@ 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 Secure Boot Advanced Targeting
|
||||
+@section Embedded information for generation number based revocation
|
||||
+
|
||||
+The Secure Boot Advanced Targeting (SBAT) is a mechanism to allow the revocation
|
||||
+of components in the boot path by using generation numbers embedded into the EFI
|
||||
+binaries. The SBAT metadata is located in an .sbat data section that has set of
|
||||
+UTF-8 strings as comma-separated values (CSV). See
|
||||
+@uref{https://github.com/rhboot/shim/blob/main/SBAT.md} for more details.
|
||||
+
|
||||
+To add a data section containing the SBAT information into the binary, the
|
||||
+@option{--sbat} option of @command{grub-mkimage} command should be used. The content
|
||||
+of a CSV file, encoded with UTF-8, is copied as is to the .sbat data section into
|
||||
+the generated EFI binary. The CSV file can be stored anywhere on the file system.
|
||||
+
|
||||
+@example
|
||||
+grub-mkimage -O x86_64-efi -o grubx64.efi -p '(tftp)/grub' --sbat sbat.csv efinet tftp
|
||||
+@end example
|
||||
+
|
||||
@node Measured Boot
|
||||
@section Measuring boot components
|
||||
|
||||
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
|
||||
index 1541ee233..6ee3b4516 100644
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -184,7 +184,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
char *config_path,
|
||||
const struct grub_install_image_target_desc *image_target,
|
||||
int note,
|
||||
- grub_compression_t comp, const char *dtb_file);
|
||||
+ grub_compression_t comp, const char *dtb_file,
|
||||
+ const char *sbat_path);
|
||||
|
||||
const struct grub_install_image_target_desc *
|
||||
grub_install_get_image_target (const char *arg);
|
||||
diff --git a/include/grub/util/mkimage.h b/include/grub/util/mkimage.h
|
||||
index ba9f568f6..3819a6744 100644
|
||||
--- a/include/grub/util/mkimage.h
|
||||
+++ b/include/grub/util/mkimage.h
|
||||
@@ -24,6 +24,7 @@ struct grub_mkimage_layout
|
||||
size_t exec_size;
|
||||
size_t kernel_size;
|
||||
size_t bss_size;
|
||||
+ size_t sbat_size;
|
||||
grub_uint64_t start_address;
|
||||
void *reloc_section;
|
||||
size_t reloc_size;
|
||||
diff --git a/util/grub-install-common.c b/util/grub-install-common.c
|
||||
index d1894f7c1..052f3ef3d 100644
|
||||
--- a/util/grub-install-common.c
|
||||
+++ b/util/grub-install-common.c
|
||||
@@ -546,7 +546,7 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
|
||||
grub_install_generate_image (dir, prefix, fp, outname,
|
||||
modules.entries, memdisk_path,
|
||||
pubkeys, npubkeys, config_path, tgt,
|
||||
- note, compression, dtb);
|
||||
+ note, compression, dtb, NULL);
|
||||
while (dc--)
|
||||
grub_install_pop_module ();
|
||||
}
|
||||
diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c
|
||||
index 912564e36..75b884710 100644
|
||||
--- a/util/grub-mkimage.c
|
||||
+++ b/util/grub-mkimage.c
|
||||
@@ -81,6 +81,7 @@ static struct argp_option options[] = {
|
||||
{"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0},
|
||||
{"format", 'O', N_("FORMAT"), 0, 0, 0},
|
||||
{"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use for core image"), 0},
|
||||
+ {"sbat", 's', N_("FILE"), 0, N_("SBAT metadata"), 0},
|
||||
{"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
|
||||
{ 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
@@ -123,6 +124,7 @@ struct arguments
|
||||
size_t npubkeys;
|
||||
char *font;
|
||||
char *config;
|
||||
+ char *sbat;
|
||||
int note;
|
||||
const struct grub_install_image_target_desc *image_target;
|
||||
grub_compression_t comp;
|
||||
@@ -224,6 +226,13 @@ argp_parser (int key, char *arg, struct argp_state *state)
|
||||
arguments->prefix = xstrdup (arg);
|
||||
break;
|
||||
|
||||
+ case 's':
|
||||
+ if (arguments->sbat)
|
||||
+ free (arguments->sbat);
|
||||
+
|
||||
+ arguments->sbat = xstrdup (arg);
|
||||
+ break;
|
||||
+
|
||||
case 'v':
|
||||
verbosity++;
|
||||
break;
|
||||
@@ -309,7 +318,8 @@ main (int argc, char *argv[])
|
||||
arguments.memdisk, arguments.pubkeys,
|
||||
arguments.npubkeys, arguments.config,
|
||||
arguments.image_target, arguments.note,
|
||||
- arguments.comp, arguments.dtb);
|
||||
+ arguments.comp, arguments.dtb,
|
||||
+ arguments.sbat);
|
||||
|
||||
if (grub_util_file_sync (fp) < 0)
|
||||
grub_util_error (_("cannot sync `%s': %s"), arguments.output ? : "stdout",
|
||||
@@ -328,5 +338,8 @@ main (int argc, char *argv[])
|
||||
if (arguments.output)
|
||||
free (arguments.output);
|
||||
|
||||
+ if (arguments.sbat)
|
||||
+ free (arguments.sbat);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
diff --git a/util/mkimage.c b/util/mkimage.c
|
||||
index 8b475a691..b354ec1d9 100644
|
||||
--- a/util/mkimage.c
|
||||
+++ b/util/mkimage.c
|
||||
@@ -869,12 +869,13 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
char *memdisk_path, char **pubkey_paths,
|
||||
size_t npubkeys, char *config_path,
|
||||
const struct grub_install_image_target_desc *image_target,
|
||||
- int note, grub_compression_t comp, const char *dtb_path)
|
||||
+ int note, grub_compression_t comp, const char *dtb_path,
|
||||
+ const char *sbat_path)
|
||||
{
|
||||
char *kernel_img, *core_img;
|
||||
size_t total_module_size, core_size;
|
||||
size_t memdisk_size = 0, config_size = 0;
|
||||
- size_t prefix_size = 0, dtb_size = 0;
|
||||
+ size_t prefix_size = 0, dtb_size = 0, sbat_size = 0;
|
||||
char *kernel_path;
|
||||
size_t offset;
|
||||
struct grub_util_path_list *path_list, *p;
|
||||
@@ -925,6 +926,9 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
total_module_size += dtb_size + sizeof (struct grub_module_header);
|
||||
}
|
||||
|
||||
+ if (sbat_path != NULL && image_target->id != IMAGE_EFI)
|
||||
+ grub_util_error (_(".sbat section can be embedded into EFI images only"));
|
||||
+
|
||||
if (config_path)
|
||||
{
|
||||
config_size = ALIGN_ADDR (grub_util_get_image_size (config_path) + 1);
|
||||
@@ -1289,8 +1293,9 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
break;
|
||||
case IMAGE_EFI:
|
||||
{
|
||||
- char *pe_img, *header;
|
||||
+ char *pe_img, *pe_sbat, *header;
|
||||
struct grub_pe32_section_table *section;
|
||||
+ size_t n_sections = 4;
|
||||
size_t scn_size;
|
||||
grub_uint32_t vma, raw_data;
|
||||
size_t pe_size, header_size;
|
||||
@@ -1305,8 +1310,15 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
header_size = EFI64_HEADER_SIZE;
|
||||
|
||||
vma = raw_data = header_size;
|
||||
+
|
||||
+ if (sbat_path != NULL)
|
||||
+ {
|
||||
+ sbat_size = ALIGN_ADDR (grub_util_get_image_size (sbat_path));
|
||||
+ sbat_size = ALIGN_UP (sbat_size, GRUB_PE32_FILE_ALIGNMENT);
|
||||
+ }
|
||||
+
|
||||
pe_size = ALIGN_UP (header_size + core_size, GRUB_PE32_FILE_ALIGNMENT) +
|
||||
- ALIGN_UP (layout.reloc_size, GRUB_PE32_FILE_ALIGNMENT);
|
||||
+ ALIGN_UP (layout.reloc_size, GRUB_PE32_FILE_ALIGNMENT) + sbat_size;
|
||||
header = pe_img = xcalloc (1, pe_size);
|
||||
|
||||
memcpy (pe_img + raw_data, core_img, core_size);
|
||||
@@ -1321,7 +1333,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
+ GRUB_PE32_SIGNATURE_SIZE);
|
||||
c->machine = grub_host_to_target16 (image_target->pe_target);
|
||||
|
||||
- c->num_sections = grub_host_to_target16 (4);
|
||||
+ if (sbat_path != NULL)
|
||||
+ n_sections++;
|
||||
+
|
||||
+ c->num_sections = grub_host_to_target16 (n_sections);
|
||||
c->time = grub_host_to_target32 (STABLE_EMBEDDING_TIMESTAMP);
|
||||
c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE
|
||||
| GRUB_PE32_LINE_NUMS_STRIPPED
|
||||
@@ -1383,7 +1398,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
GRUB_PE32_SCN_MEM_READ);
|
||||
|
||||
scn_size = ALIGN_UP (layout.kernel_size - layout.exec_size, GRUB_PE32_FILE_ALIGNMENT);
|
||||
- PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size +
|
||||
+ /* ALIGN_UP (sbat_size, GRUB_PE32_FILE_ALIGNMENT) is done earlier. */
|
||||
+ PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size + sbat_size +
|
||||
ALIGN_UP (total_module_size,
|
||||
GRUB_PE32_FILE_ALIGNMENT));
|
||||
|
||||
@@ -1394,7 +1410,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
GRUB_PE32_SCN_MEM_READ |
|
||||
GRUB_PE32_SCN_MEM_WRITE);
|
||||
|
||||
- scn_size = pe_size - layout.reloc_size - raw_data;
|
||||
+ scn_size = pe_size - layout.reloc_size - sbat_size - raw_data;
|
||||
section = init_pe_section (image_target, section, "mods",
|
||||
&vma, scn_size, image_target->section_align,
|
||||
&raw_data, scn_size,
|
||||
@@ -1402,6 +1418,19 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
GRUB_PE32_SCN_MEM_READ |
|
||||
GRUB_PE32_SCN_MEM_WRITE);
|
||||
|
||||
+ if (sbat_path != NULL)
|
||||
+ {
|
||||
+ pe_sbat = pe_img + raw_data;
|
||||
+ grub_util_load_image (sbat_path, pe_sbat);
|
||||
+
|
||||
+ section = init_pe_section (image_target, section, ".sbat",
|
||||
+ &vma, sbat_size,
|
||||
+ image_target->section_align,
|
||||
+ &raw_data, sbat_size,
|
||||
+ GRUB_PE32_SCN_CNT_INITIALIZED_DATA |
|
||||
+ GRUB_PE32_SCN_MEM_READ);
|
||||
+ }
|
||||
+
|
||||
scn_size = layout.reloc_size;
|
||||
PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (vma);
|
||||
PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (scn_size);
|
||||
--
|
||||
2.26.2
|
||||
|
84
0039-grub-install-common-Add-sbat-option.patch
Normal file
84
0039-grub-install-common-Add-sbat-option.patch
Normal file
@ -0,0 +1,84 @@
|
||||
From 427bbc05c7fe8c01872cdba3d1d59d27fc1b9e5b Mon Sep 17 00:00:00 2001
|
||||
From: Dimitri John Ledkov <xnox@ubuntu.com>
|
||||
Date: Mon, 22 Feb 2021 17:05:25 +0000
|
||||
Subject: [PATCH 39/46] grub-install-common: Add --sbat option
|
||||
|
||||
Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
include/grub/util/install.h | 5 ++++-
|
||||
util/grub-install-common.c | 12 ++++++++++--
|
||||
2 files changed, 14 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
|
||||
index 6ee3b4516..2207b54d7 100644
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -63,6 +63,8 @@
|
||||
/* TRANSLATORS: "embed" is a verb (command description). "*/ \
|
||||
{ "pubkey", 'k', N_("FILE"), 0, \
|
||||
N_("embed FILE as public key for signature checking"), 0}, \
|
||||
+ { "sbat", GRUB_INSTALL_OPTIONS_SBAT, N_("FILE"), 0, \
|
||||
+ N_("SBAT metadata"), 0 }, \
|
||||
{ "verbose", 'v', 0, 0, \
|
||||
N_("print verbose messages."), 1 }
|
||||
|
||||
@@ -123,7 +125,8 @@ enum grub_install_options {
|
||||
GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY,
|
||||
GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE,
|
||||
GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS,
|
||||
- GRUB_INSTALL_OPTIONS_DTB
|
||||
+ GRUB_INSTALL_OPTIONS_DTB,
|
||||
+ GRUB_INSTALL_OPTIONS_SBAT
|
||||
};
|
||||
|
||||
extern char *grub_install_source_directory;
|
||||
diff --git a/util/grub-install-common.c b/util/grub-install-common.c
|
||||
index 052f3ef3d..4efee002f 100644
|
||||
--- a/util/grub-install-common.c
|
||||
+++ b/util/grub-install-common.c
|
||||
@@ -342,6 +342,7 @@ handle_install_list (struct install_list *il, const char *val,
|
||||
|
||||
static char **pubkeys;
|
||||
static size_t npubkeys;
|
||||
+static char *sbat;
|
||||
static grub_compression_t compression;
|
||||
|
||||
int
|
||||
@@ -372,6 +373,12 @@ grub_install_parse (int key, char *arg)
|
||||
* (npubkeys + 1));
|
||||
pubkeys[npubkeys++] = xstrdup (arg);
|
||||
return 1;
|
||||
+ case GRUB_INSTALL_OPTIONS_SBAT:
|
||||
+ if (sbat)
|
||||
+ free (sbat);
|
||||
+
|
||||
+ sbat = xstrdup (arg);
|
||||
+ return 1;
|
||||
|
||||
case GRUB_INSTALL_OPTIONS_VERBOSITY:
|
||||
verbosity++;
|
||||
@@ -533,9 +540,10 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
|
||||
grub_util_info ("grub-mkimage --directory '%s' --prefix '%s'"
|
||||
" --output '%s' "
|
||||
" --dtb '%s' "
|
||||
+ "--sbat '%s' "
|
||||
"--format '%s' --compression '%s' %s %s\n",
|
||||
dir, prefix,
|
||||
- outname, dtb ? : "", mkimage_target,
|
||||
+ outname, dtb ? : "", sbat ? : "", mkimage_target,
|
||||
compnames[compression], note ? "--note" : "", s);
|
||||
free (s);
|
||||
|
||||
@@ -546,7 +554,7 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
|
||||
grub_install_generate_image (dir, prefix, fp, outname,
|
||||
modules.entries, memdisk_path,
|
||||
pubkeys, npubkeys, config_path, tgt,
|
||||
- note, compression, dtb, NULL);
|
||||
+ note, compression, dtb, sbat);
|
||||
while (dc--)
|
||||
grub_install_pop_module ();
|
||||
}
|
||||
--
|
||||
2.26.2
|
||||
|
268
0040-shim_lock-Only-skip-loading-shim_lock-verifier-with-.patch
Normal file
268
0040-shim_lock-Only-skip-loading-shim_lock-verifier-with-.patch
Normal file
@ -0,0 +1,268 @@
|
||||
From d9f12b9f37280aa54e8ef4b8c2a2163721d28360 Mon Sep 17 00:00:00 2001
|
||||
From: Dimitri John Ledkov <xnox@ubuntu.com>
|
||||
Date: Sat, 20 Feb 2021 17:10:34 +0000
|
||||
Subject: [PATCH 40/46] shim_lock: Only skip loading shim_lock verifier with
|
||||
explicit consent
|
||||
|
||||
Commit 32ddc42c (efi: Only register shim_lock verifier if shim_lock
|
||||
protocol is found and SB enabled) reintroduced CVE-2020-15705 which
|
||||
previously only existed in the out-of-tree linuxefi patches and was
|
||||
fixed as part of the BootHole patch series.
|
||||
|
||||
Under Secure Boot enforce loading shim_lock verifier. Allow skipping
|
||||
shim_lock verifier if SecureBoot/MokSBState EFI variables indicate
|
||||
skipping validations, or if GRUB image is built with --disable-shim-lock.
|
||||
|
||||
Fixes: 132ddc42c (efi: Only register shim_lock verifier if shim_lock
|
||||
protocol is found and SB enabled)
|
||||
Fixes: CVE-2020-15705
|
||||
|
||||
Reported-by: Dimitri John Ledkov <xnox@ubuntu.com>
|
||||
Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
docs/grub.texi | 5 ++++-
|
||||
grub-core/kern/efi/sb.c | 17 ++++++++++++++++-
|
||||
include/grub/kernel.h | 3 ++-
|
||||
include/grub/util/install.h | 7 +++++--
|
||||
util/grub-install-common.c | 12 +++++++++---
|
||||
util/grub-mkimage.c | 8 +++++++-
|
||||
util/mkimage.c | 15 ++++++++++++++-
|
||||
7 files changed, 57 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index fa0b49737..b82f32382 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -5783,7 +5783,10 @@ 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 verifier. It
|
||||
is built into the @file{core.img} and is registered if the UEFI secure boot is
|
||||
-enabled.
|
||||
+enabled. The @samp{shim_lock} variable is set to @samp{y} when shim_lock verifier
|
||||
+is registered. If it is desired to use UEFI secure boot without shim, one can
|
||||
+disable shim_lock by disabling shim verification with MokSbState UEFI variable
|
||||
+or by building grub image with @samp{--disable-shim-lock} option.
|
||||
|
||||
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
|
||||
diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c
|
||||
index 5d7210a82..41dadcd14 100644
|
||||
--- a/grub-core/kern/efi/sb.c
|
||||
+++ b/grub-core/kern/efi/sb.c
|
||||
@@ -21,9 +21,11 @@
|
||||
#include <grub/efi/efi.h>
|
||||
#include <grub/efi/pe32.h>
|
||||
#include <grub/efi/sb.h>
|
||||
+#include <grub/env.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/i386/linux.h>
|
||||
+#include <grub/kernel.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/verify.h>
|
||||
@@ -160,14 +162,27 @@ struct grub_file_verifier shim_lock_verifier =
|
||||
void
|
||||
grub_shim_lock_verifier_setup (void)
|
||||
{
|
||||
+ struct grub_module_header *header;
|
||||
grub_efi_shim_lock_protocol_t *sl =
|
||||
grub_efi_locate_protocol (&shim_lock_guid, 0);
|
||||
|
||||
+ /* shim_lock is missing, check if GRUB image is built with --disable-shim-lock. */
|
||||
if (!sl)
|
||||
- return;
|
||||
+ {
|
||||
+ FOR_MODULES (header)
|
||||
+ {
|
||||
+ if (header->type == OBJ_TYPE_DISABLE_SHIM_LOCK)
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
+ /* Secure Boot is off. Do not load shim_lock. */
|
||||
if (grub_efi_get_secureboot () != GRUB_EFI_SECUREBOOT_MODE_ENABLED)
|
||||
return;
|
||||
|
||||
+ /* Enforce shim_lock_verifier. */
|
||||
grub_verifier_register (&shim_lock_verifier);
|
||||
+
|
||||
+ grub_env_set ("shim_lock", "y");
|
||||
+ grub_env_export ("shim_lock");
|
||||
}
|
||||
diff --git a/include/grub/kernel.h b/include/grub/kernel.h
|
||||
index 133a37c8d..abbca5ea3 100644
|
||||
--- a/include/grub/kernel.h
|
||||
+++ b/include/grub/kernel.h
|
||||
@@ -29,7 +29,8 @@ enum
|
||||
OBJ_TYPE_CONFIG,
|
||||
OBJ_TYPE_PREFIX,
|
||||
OBJ_TYPE_PUBKEY,
|
||||
- OBJ_TYPE_DTB
|
||||
+ OBJ_TYPE_DTB,
|
||||
+ OBJ_TYPE_DISABLE_SHIM_LOCK
|
||||
};
|
||||
|
||||
/* The module header. */
|
||||
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
|
||||
index 2207b54d7..0992aecbe 100644
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -65,6 +65,8 @@
|
||||
N_("embed FILE as public key for signature checking"), 0}, \
|
||||
{ "sbat", GRUB_INSTALL_OPTIONS_SBAT, N_("FILE"), 0, \
|
||||
N_("SBAT metadata"), 0 }, \
|
||||
+ { "disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, \
|
||||
+ N_("disable shim_lock verifier"), 0 }, \
|
||||
{ "verbose", 'v', 0, 0, \
|
||||
N_("print verbose messages."), 1 }
|
||||
|
||||
@@ -126,7 +128,8 @@ enum grub_install_options {
|
||||
GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE,
|
||||
GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS,
|
||||
GRUB_INSTALL_OPTIONS_DTB,
|
||||
- GRUB_INSTALL_OPTIONS_SBAT
|
||||
+ GRUB_INSTALL_OPTIONS_SBAT,
|
||||
+ GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK
|
||||
};
|
||||
|
||||
extern char *grub_install_source_directory;
|
||||
@@ -188,7 +191,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
const struct grub_install_image_target_desc *image_target,
|
||||
int note,
|
||||
grub_compression_t comp, const char *dtb_file,
|
||||
- const char *sbat_path);
|
||||
+ const char *sbat_path, const int disable_shim_lock);
|
||||
|
||||
const struct grub_install_image_target_desc *
|
||||
grub_install_get_image_target (const char *arg);
|
||||
diff --git a/util/grub-install-common.c b/util/grub-install-common.c
|
||||
index 4efee002f..c7b824789 100644
|
||||
--- a/util/grub-install-common.c
|
||||
+++ b/util/grub-install-common.c
|
||||
@@ -343,6 +343,7 @@ handle_install_list (struct install_list *il, const char *val,
|
||||
static char **pubkeys;
|
||||
static size_t npubkeys;
|
||||
static char *sbat;
|
||||
+static int disable_shim_lock;
|
||||
static grub_compression_t compression;
|
||||
|
||||
int
|
||||
@@ -379,6 +380,9 @@ grub_install_parse (int key, char *arg)
|
||||
|
||||
sbat = xstrdup (arg);
|
||||
return 1;
|
||||
+ case GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK:
|
||||
+ disable_shim_lock = 1;
|
||||
+ return 1;
|
||||
|
||||
case GRUB_INSTALL_OPTIONS_VERBOSITY:
|
||||
verbosity++;
|
||||
@@ -541,10 +545,11 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
|
||||
" --output '%s' "
|
||||
" --dtb '%s' "
|
||||
"--sbat '%s' "
|
||||
- "--format '%s' --compression '%s' %s %s\n",
|
||||
+ "--format '%s' --compression '%s' %s %s %s\n",
|
||||
dir, prefix,
|
||||
outname, dtb ? : "", sbat ? : "", mkimage_target,
|
||||
- compnames[compression], note ? "--note" : "", s);
|
||||
+ compnames[compression], note ? "--note" : "",
|
||||
+ disable_shim_lock ? "--disable-shim-lock" : "", s);
|
||||
free (s);
|
||||
|
||||
tgt = grub_install_get_image_target (mkimage_target);
|
||||
@@ -554,7 +559,8 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
|
||||
grub_install_generate_image (dir, prefix, fp, outname,
|
||||
modules.entries, memdisk_path,
|
||||
pubkeys, npubkeys, config_path, tgt,
|
||||
- note, compression, dtb, sbat);
|
||||
+ note, compression, dtb, sbat,
|
||||
+ disable_shim_lock);
|
||||
while (dc--)
|
||||
grub_install_pop_module ();
|
||||
}
|
||||
diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c
|
||||
index 75b884710..c0d559937 100644
|
||||
--- a/util/grub-mkimage.c
|
||||
+++ b/util/grub-mkimage.c
|
||||
@@ -82,6 +82,7 @@ static struct argp_option options[] = {
|
||||
{"format", 'O', N_("FORMAT"), 0, 0, 0},
|
||||
{"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use for core image"), 0},
|
||||
{"sbat", 's', N_("FILE"), 0, N_("SBAT metadata"), 0},
|
||||
+ {"disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, N_("disable shim_lock verifier"), 0},
|
||||
{"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
|
||||
{ 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
@@ -126,6 +127,7 @@ struct arguments
|
||||
char *config;
|
||||
char *sbat;
|
||||
int note;
|
||||
+ int disable_shim_lock;
|
||||
const struct grub_install_image_target_desc *image_target;
|
||||
grub_compression_t comp;
|
||||
};
|
||||
@@ -233,6 +235,10 @@ argp_parser (int key, char *arg, struct argp_state *state)
|
||||
arguments->sbat = xstrdup (arg);
|
||||
break;
|
||||
|
||||
+ case GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK:
|
||||
+ arguments->disable_shim_lock = 1;
|
||||
+ break;
|
||||
+
|
||||
case 'v':
|
||||
verbosity++;
|
||||
break;
|
||||
@@ -319,7 +325,7 @@ main (int argc, char *argv[])
|
||||
arguments.npubkeys, arguments.config,
|
||||
arguments.image_target, arguments.note,
|
||||
arguments.comp, arguments.dtb,
|
||||
- arguments.sbat);
|
||||
+ arguments.sbat, arguments.disable_shim_lock);
|
||||
|
||||
if (grub_util_file_sync (fp) < 0)
|
||||
grub_util_error (_("cannot sync `%s': %s"), arguments.output ? : "stdout",
|
||||
diff --git a/util/mkimage.c b/util/mkimage.c
|
||||
index b354ec1d9..a26cf76f7 100644
|
||||
--- a/util/mkimage.c
|
||||
+++ b/util/mkimage.c
|
||||
@@ -870,7 +870,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
size_t npubkeys, char *config_path,
|
||||
const struct grub_install_image_target_desc *image_target,
|
||||
int note, grub_compression_t comp, const char *dtb_path,
|
||||
- const char *sbat_path)
|
||||
+ const char *sbat_path, int disable_shim_lock)
|
||||
{
|
||||
char *kernel_img, *core_img;
|
||||
size_t total_module_size, core_size;
|
||||
@@ -929,6 +929,9 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
if (sbat_path != NULL && image_target->id != IMAGE_EFI)
|
||||
grub_util_error (_(".sbat section can be embedded into EFI images only"));
|
||||
|
||||
+ if (disable_shim_lock)
|
||||
+ total_module_size += sizeof (struct grub_module_header);
|
||||
+
|
||||
if (config_path)
|
||||
{
|
||||
config_size = ALIGN_ADDR (grub_util_get_image_size (config_path) + 1);
|
||||
@@ -1065,6 +1068,16 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
offset += dtb_size;
|
||||
}
|
||||
|
||||
+ if (disable_shim_lock)
|
||||
+ {
|
||||
+ struct grub_module_header *header;
|
||||
+
|
||||
+ header = (struct grub_module_header *) (kernel_img + offset);
|
||||
+ header->type = grub_host_to_target32 (OBJ_TYPE_DISABLE_SHIM_LOCK);
|
||||
+ header->size = grub_host_to_target32 (sizeof (*header));
|
||||
+ offset += sizeof (*header);
|
||||
+ }
|
||||
+
|
||||
if (config_path)
|
||||
{
|
||||
struct grub_module_header *header;
|
||||
--
|
||||
2.26.2
|
||||
|
92
0041-squash-Add-secureboot-support-on-efi-chainloader.patch
Normal file
92
0041-squash-Add-secureboot-support-on-efi-chainloader.patch
Normal file
@ -0,0 +1,92 @@
|
||||
From 50f063f61eec3a99565db5f964970a872b642b27 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 11 Dec 2020 22:33:52 +0800
|
||||
Subject: [PATCH 41/46] squash! Add secureboot support on efi chainloader
|
||||
|
||||
Use grub_efi_get_secureboot to get secure boot status
|
||||
---
|
||||
grub-core/loader/efi/chainloader.c | 54 ++----------------------------
|
||||
1 file changed, 2 insertions(+), 52 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
|
||||
index 8272df3cd..559247abf 100644
|
||||
--- a/grub-core/loader/efi/chainloader.c
|
||||
+++ b/grub-core/loader/efi/chainloader.c
|
||||
@@ -46,6 +46,7 @@
|
||||
|
||||
#ifdef SUPPORT_SECURE_BOOT
|
||||
#include <grub/efi/pe32.h>
|
||||
+#include <grub/efi/sb.h>
|
||||
#endif
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
@@ -282,57 +283,6 @@ grub_secure_validate (void *data, grub_efi_uint32_t size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static grub_efi_boolean_t
|
||||
-grub_secure_mode (void)
|
||||
-{
|
||||
- grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID;
|
||||
- grub_uint8_t *data;
|
||||
- grub_size_t datasize;
|
||||
-
|
||||
- data = grub_efi_get_variable ("SecureBoot", &efi_var_guid, &datasize);
|
||||
-
|
||||
- if (data)
|
||||
- {
|
||||
- grub_dprintf ("chain", "SecureBoot: %d, datasize %d\n", (int)*data, (int)datasize);
|
||||
- }
|
||||
-
|
||||
- if (data && (datasize == 1))
|
||||
- {
|
||||
- if (*data != 1)
|
||||
- {
|
||||
- grub_dprintf ("chain", "secure boot not enabled\n");
|
||||
- return 0;
|
||||
- }
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- grub_dprintf ("chain", "unknown secure boot status\n");
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- grub_free (data);
|
||||
-
|
||||
- data = grub_efi_get_variable ("SetupMode", &efi_var_guid, &datasize);
|
||||
-
|
||||
- if (data)
|
||||
- {
|
||||
- grub_dprintf ("chain", "SetupMode: %d, datasize %d\n", (int)*data, (int)datasize);
|
||||
- }
|
||||
-
|
||||
- if (data && (datasize == 1))
|
||||
- {
|
||||
- if (*data == 1)
|
||||
- {
|
||||
- grub_dprintf ("chain", "platform in setup mode\n");
|
||||
- return 0;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- grub_free (data);
|
||||
-
|
||||
- return 1;
|
||||
-}
|
||||
-
|
||||
static grub_efi_boolean_t
|
||||
read_header (void *data, grub_efi_uint32_t size, pe_coff_loader_image_context_t *context)
|
||||
{
|
||||
@@ -837,7 +787,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||
|
||||
#ifdef SUPPORT_SECURE_BOOT
|
||||
/* FIXME is secure boot possible also with universal binaries? */
|
||||
- if (debug_secureboot || (grub_secure_mode() && grub_secure_validate ((void *)address, fsize)))
|
||||
+ if (debug_secureboot || (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED && grub_secure_validate ((void *)address, fsize)))
|
||||
{
|
||||
grub_file_close (file);
|
||||
grub_loader_set (grub_secureboot_chainloader_boot, grub_secureboot_chainloader_unload, 0);
|
||||
--
|
||||
2.26.2
|
||||
|
26
0042-squash-grub2-efi-chainload-harder.patch
Normal file
26
0042-squash-grub2-efi-chainload-harder.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From 5673c583f3987350a51e39b64260a84342d9592a Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 11 Dec 2020 22:39:54 +0800
|
||||
Subject: [PATCH 42/46] squash! grub2-efi-chainload-harder
|
||||
|
||||
Use grub_efi_get_secureboot to get secure boot status
|
||||
---
|
||||
grub-core/loader/efi/chainloader.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
|
||||
index 559247abf..7a910db44 100644
|
||||
--- a/grub-core/loader/efi/chainloader.c
|
||||
+++ b/grub-core/loader/efi/chainloader.c
|
||||
@@ -799,7 +799,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||
boot_image, fsize,
|
||||
&image_handle);
|
||||
#ifdef SUPPORT_SECURE_BOOT
|
||||
- if (status == GRUB_EFI_SECURITY_VIOLATION && !grub_secure_mode())
|
||||
+ if (status == GRUB_EFI_SECURITY_VIOLATION && grub_efi_get_secureboot () != GRUB_EFI_SECUREBOOT_MODE_ENABLED)
|
||||
{
|
||||
/* If it failed with security violation while not in secure boot mode,
|
||||
the firmware might be broken. We try to workaround on that by forcing
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,88 @@
|
||||
From 768ab190a7c0a412bbec6142d12000655324daa0 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 11 Dec 2020 23:01:59 +0800
|
||||
Subject: [PATCH 43/46] squash! Don't allow insmod when secure boot is enabled.
|
||||
|
||||
Use grub_efi_get_secureboot to get secure boot status
|
||||
---
|
||||
grub-core/kern/dl.c | 4 ++--
|
||||
grub-core/kern/efi/efi.c | 28 ----------------------------
|
||||
include/grub/efi/efi.h | 1 -
|
||||
3 files changed, 2 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
|
||||
index e02f2afc5..93f08dfce 100644
|
||||
--- a/grub-core/kern/dl.c
|
||||
+++ b/grub-core/kern/dl.c
|
||||
@@ -39,7 +39,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
-#include <grub/efi/efi.h>
|
||||
+#include <grub/efi/sb.h>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -702,7 +702,7 @@ grub_dl_load_file (const char *filename)
|
||||
grub_boot_time ("Loading module %s", filename);
|
||||
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
- if (grub_efi_secure_boot ())
|
||||
+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
|
||||
{
|
||||
#if 0
|
||||
/* This is an error, but grub2-mkconfig still generates a pile of
|
||||
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
|
||||
index 92e99b441..32f1b2ec7 100644
|
||||
--- a/grub-core/kern/efi/efi.c
|
||||
+++ b/grub-core/kern/efi/efi.c
|
||||
@@ -278,34 +278,6 @@ grub_efi_get_variable_with_attributes (const char *var,
|
||||
return status;
|
||||
}
|
||||
|
||||
-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;
|
||||
-}
|
||||
-
|
||||
grub_efi_status_t
|
||||
grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
||||
grub_size_t *datasize_out, void **data_out)
|
||||
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
|
||||
index 568d80030..08f6ee00a 100644
|
||||
--- a/include/grub/efi/efi.h
|
||||
+++ b/include/grub/efi/efi.h
|
||||
@@ -91,7 +91,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);
|
||||
--
|
||||
2.26.2
|
||||
|
115
0044-squash-kern-Add-lockdown-support.patch
Normal file
115
0044-squash-kern-Add-lockdown-support.patch
Normal file
@ -0,0 +1,115 @@
|
||||
From 3c612287086a5f590f80d874e8c5c6042bf7f6a0 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Wed, 24 Feb 2021 23:51:38 +0800
|
||||
Subject: [PATCH 44/46] squash! kern: Add lockdown support
|
||||
|
||||
Since the lockdown feature is efi specific, the
|
||||
grub_{command,extcmd}_lockdown functions can be removed from other
|
||||
platform for not taking up space in kernel image.
|
||||
---
|
||||
grub-core/commands/extcmd.c | 2 ++
|
||||
grub-core/kern/command.c | 2 ++
|
||||
include/grub/command.h | 11 +++++++++++
|
||||
include/grub/extcmd.h | 13 +++++++++++++
|
||||
4 files changed, 28 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/extcmd.c b/grub-core/commands/extcmd.c
|
||||
index 90a5ca24a..4ac111a99 100644
|
||||
--- a/grub-core/commands/extcmd.c
|
||||
+++ b/grub-core/commands/extcmd.c
|
||||
@@ -111,6 +111,7 @@ grub_register_extcmd (const char *name, grub_extcmd_func_t func,
|
||||
summary, description, parser, 1);
|
||||
}
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
static grub_err_t
|
||||
grub_extcmd_lockdown (grub_extcmd_context_t ctxt __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
@@ -132,6 +133,7 @@ grub_register_extcmd_lockdown (const char *name, grub_extcmd_func_t func,
|
||||
|
||||
return grub_register_extcmd (name, func, flags, summary, description, parser);
|
||||
}
|
||||
+#endif
|
||||
|
||||
void
|
||||
grub_unregister_extcmd (grub_extcmd_t ext)
|
||||
diff --git a/grub-core/kern/command.c b/grub-core/kern/command.c
|
||||
index 4aabcd4b5..17363af7b 100644
|
||||
--- a/grub-core/kern/command.c
|
||||
+++ b/grub-core/kern/command.c
|
||||
@@ -78,6 +78,7 @@ grub_register_command_prio (const char *name,
|
||||
return cmd;
|
||||
}
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
static grub_err_t
|
||||
grub_cmd_lockdown (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
@@ -100,6 +101,7 @@ grub_register_command_lockdown (const char *name,
|
||||
|
||||
return grub_register_command_prio (name, func, summary, description, 0);
|
||||
}
|
||||
+#endif
|
||||
|
||||
void
|
||||
grub_unregister_command (grub_command_t cmd)
|
||||
diff --git a/include/grub/command.h b/include/grub/command.h
|
||||
index 2a6f7f846..b518e262e 100644
|
||||
--- a/include/grub/command.h
|
||||
+++ b/include/grub/command.h
|
||||
@@ -86,11 +86,22 @@ EXPORT_FUNC(grub_register_command_prio) (const char *name,
|
||||
const char *summary,
|
||||
const char *description,
|
||||
int prio);
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
grub_command_t
|
||||
EXPORT_FUNC(grub_register_command_lockdown) (const char *name,
|
||||
grub_command_func_t func,
|
||||
const char *summary,
|
||||
const char *description);
|
||||
+#else
|
||||
+static inline grub_command_t
|
||||
+grub_register_command_lockdown (const char *name,
|
||||
+ grub_command_func_t func,
|
||||
+ const char *summary,
|
||||
+ const char *description)
|
||||
+{
|
||||
+ return grub_register_command_prio (name, func, summary, description, 0);
|
||||
+}
|
||||
+#endif
|
||||
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 fe9248b8b..fa1328ea5 100644
|
||||
--- a/include/grub/extcmd.h
|
||||
+++ b/include/grub/extcmd.h
|
||||
@@ -62,12 +62,25 @@ grub_extcmd_t EXPORT_FUNC(grub_register_extcmd) (const char *name,
|
||||
const char *description,
|
||||
const struct grub_arg_option *parser);
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
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);
|
||||
+#else
|
||||
+static inline 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)
|
||||
+{
|
||||
+ return grub_register_extcmd (name, func, flags, summary, description, parser);
|
||||
+}
|
||||
+#endif
|
||||
|
||||
grub_extcmd_t EXPORT_FUNC(grub_register_extcmd_prio) (const char *name,
|
||||
grub_extcmd_func_t func,
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,68 @@
|
||||
From 601c838c4cf3e6bd3e8e19b9e7aa4331cac0dc25 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 25 Feb 2021 20:44:58 +0800
|
||||
Subject: [PATCH 45/46] squash! Add support for Linux EFI stub loading on
|
||||
aarch64.
|
||||
|
||||
The efi shim_lock verifier has been moved to grub core so local
|
||||
shim_lock protocol is no longer needed here for aarch64 efi to verify
|
||||
the loaded kernel image. From now on the framework will take care the
|
||||
verificaion, consolidating the integration of various security verifiers
|
||||
like secure boot, gpg and tpm.
|
||||
---
|
||||
grub-core/loader/arm64/efi/linux.c | 32 ------------------------------
|
||||
1 file changed, 32 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/arm64/efi/linux.c b/grub-core/loader/arm64/efi/linux.c
|
||||
index 8549e555b..b73105347 100644
|
||||
--- a/grub-core/loader/arm64/efi/linux.c
|
||||
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||
@@ -49,32 +49,6 @@ static grub_uint32_t cmdline_size;
|
||||
static grub_addr_t initrd_start;
|
||||
static grub_addr_t initrd_end;
|
||||
|
||||
-#define SHIM_LOCK_GUID \
|
||||
- { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }
|
||||
-
|
||||
-struct grub_efi_shim_lock
|
||||
-{
|
||||
- grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size);
|
||||
-};
|
||||
-typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
|
||||
-
|
||||
-static grub_efi_boolean_t
|
||||
-grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
|
||||
-{
|
||||
- grub_efi_guid_t guid = SHIM_LOCK_GUID;
|
||||
- grub_efi_shim_lock_t *shim_lock;
|
||||
-
|
||||
- shim_lock = grub_efi_locate_protocol(&guid, NULL);
|
||||
-
|
||||
- if (!shim_lock)
|
||||
- return 1;
|
||||
-
|
||||
- if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS)
|
||||
- return 1;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
|
||||
@@ -443,12 +417,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
|
||||
grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
|
||||
|
||||
- if (!grub_linuxefi_secure_validate (kernel_addr, kernel_size))
|
||||
- {
|
||||
- grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
|
||||
- goto fail;
|
||||
- }
|
||||
-
|
||||
pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
|
||||
handover_offset = pe->opt.entry_addr;
|
||||
|
||||
--
|
||||
2.26.2
|
||||
|
153
0046-squash-verifiers-Move-verifiers-API-to-kernel-image.patch
Normal file
153
0046-squash-verifiers-Move-verifiers-API-to-kernel-image.patch
Normal file
@ -0,0 +1,153 @@
|
||||
From 59ac440754a43c6e964e924a086af066e04e753e Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 26 Feb 2021 19:43:14 +0800
|
||||
Subject: [PATCH 46/46] squash! verifiers: Move verifiers API to kernel image
|
||||
|
||||
In case there's broken i386-pc setup running inconsistent installs for
|
||||
module in filesystem and core image on the disk, keeping the verifiers
|
||||
as module for i386-pc to avoid potential issue of looking up symbols.
|
||||
---
|
||||
configure.ac | 1 +
|
||||
grub-core/Makefile.am | 2 ++
|
||||
grub-core/Makefile.core.def | 8 +++++++-
|
||||
grub-core/kern/main.c | 4 ++++
|
||||
grub-core/kern/verifiers.c | 11 +++++++++++
|
||||
include/grub/verify.h | 9 +++++++++
|
||||
6 files changed, 34 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index c39e8379f..530da4b01 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -1913,6 +1913,7 @@ AM_CONDITIONAL([COND_real_platform], [test x$platform != xnone])
|
||||
AM_CONDITIONAL([COND_emu], [test x$platform = xemu])
|
||||
AM_CONDITIONAL([COND_NOT_emu], [test x$platform != xemu])
|
||||
AM_CONDITIONAL([COND_i386_pc], [test x$target_cpu = xi386 -a x$platform = xpc])
|
||||
+AM_CONDITIONAL([COND_NOT_i386_pc], [test x$target_cpu != xi386 -o x$platform != xpc])
|
||||
AM_CONDITIONAL([COND_i386_efi], [test x$target_cpu = xi386 -a x$platform = xefi])
|
||||
AM_CONDITIONAL([COND_ia64_efi], [test x$target_cpu = xia64 -a x$platform = xefi])
|
||||
AM_CONDITIONAL([COND_i386_qemu], [test x$target_cpu = xi386 -a x$platform = xqemu])
|
||||
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
|
||||
index 6b2e5e139..47c91e35d 100644
|
||||
--- a/grub-core/Makefile.am
|
||||
+++ b/grub-core/Makefile.am
|
||||
@@ -92,7 +92,9 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
|
||||
+if COND_NOT_i386_pc
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/verify.h
|
||||
+endif
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index eac42a7b7..893044538 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -141,7 +141,7 @@ kernel = {
|
||||
common = kern/rescue_parser.c;
|
||||
common = kern/rescue_reader.c;
|
||||
common = kern/term.c;
|
||||
- common = kern/verifiers.c;
|
||||
+ nopc = kern/verifiers.c;
|
||||
|
||||
noemu = kern/compiler-rt.c;
|
||||
noemu = kern/mm.c;
|
||||
@@ -946,6 +946,12 @@ module = {
|
||||
cppflags = '-I$(srcdir)/lib/posix_wrap';
|
||||
};
|
||||
|
||||
+module = {
|
||||
+ name = verifiers;
|
||||
+ common = kern/verifiers.c;
|
||||
+ enable = i386_pc;
|
||||
+};
|
||||
+
|
||||
module = {
|
||||
name = hdparm;
|
||||
common = commands/hdparm.c;
|
||||
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
|
||||
index 73967e2f5..c7c6d2d0b 100644
|
||||
--- a/grub-core/kern/main.c
|
||||
+++ b/grub-core/kern/main.c
|
||||
@@ -29,7 +29,9 @@
|
||||
#include <grub/command.h>
|
||||
#include <grub/reader.h>
|
||||
#include <grub/parser.h>
|
||||
+#ifndef GRUB_MACHINE_PCBIOS
|
||||
#include <grub/verify.h>
|
||||
+#endif
|
||||
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
#include <grub/machine/memory.h>
|
||||
@@ -275,8 +277,10 @@ grub_main (void)
|
||||
grub_printf ("Welcome to GRUB!\n\n");
|
||||
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
|
||||
|
||||
+#ifndef GRUB_MACHINE_PCBIOS
|
||||
/* Init verifiers API. */
|
||||
grub_verifiers_init ();
|
||||
+#endif
|
||||
|
||||
grub_load_config ();
|
||||
|
||||
diff --git a/grub-core/kern/verifiers.c b/grub-core/kern/verifiers.c
|
||||
index 3d19bffd1..479253351 100644
|
||||
--- a/grub-core/kern/verifiers.c
|
||||
+++ b/grub-core/kern/verifiers.c
|
||||
@@ -218,8 +218,19 @@ grub_verify_string (char *str, enum grub_verify_string_type type)
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
+#ifdef GRUB_MACHINE_PCBIOS
|
||||
+GRUB_MOD_INIT(verifiers)
|
||||
+#else
|
||||
void
|
||||
grub_verifiers_init (void)
|
||||
+#endif
|
||||
{
|
||||
grub_file_filter_register (GRUB_FILE_FILTER_VERIFY, grub_verifiers_open);
|
||||
}
|
||||
+
|
||||
+#ifdef GRUB_MACHINE_PCBIOS
|
||||
+GRUB_MOD_FINI(verifiers)
|
||||
+{
|
||||
+ grub_file_filter_unregister (GRUB_FILE_FILTER_VERIFY);
|
||||
+}
|
||||
+#endif
|
||||
diff --git a/include/grub/verify.h b/include/grub/verify.h
|
||||
index cd129c398..6fde244fc 100644
|
||||
--- a/include/grub/verify.h
|
||||
+++ b/include/grub/verify.h
|
||||
@@ -64,10 +64,14 @@ struct grub_file_verifier
|
||||
grub_err_t (*verify_string) (char *str, enum grub_verify_string_type type);
|
||||
};
|
||||
|
||||
+#ifdef GRUB_MACHINE_PCBIOS
|
||||
+extern struct grub_file_verifier *grub_file_verifiers;
|
||||
+#else
|
||||
extern struct grub_file_verifier *EXPORT_VAR (grub_file_verifiers);
|
||||
|
||||
extern void
|
||||
grub_verifiers_init (void);
|
||||
+#endif
|
||||
|
||||
static inline void
|
||||
grub_verifier_register (struct grub_file_verifier *ver)
|
||||
@@ -81,7 +85,12 @@ grub_verifier_unregister (struct grub_file_verifier *ver)
|
||||
grub_list_remove (GRUB_AS_LIST (ver));
|
||||
}
|
||||
|
||||
+#ifdef GRUB_MACHINE_PCBIOS
|
||||
+grub_err_t
|
||||
+grub_verify_string (char *str, enum grub_verify_string_type type);
|
||||
+#else
|
||||
extern grub_err_t
|
||||
EXPORT_FUNC (grub_verify_string) (char *str, enum grub_verify_string_type type);
|
||||
+#endif
|
||||
|
||||
#endif /* ! GRUB_VERIFY_HEADER */
|
||||
--
|
||||
2.26.2
|
||||
|
@ -1,3 +1,67 @@
|
||||
-------------------------------------------------------------------
|
||||
Fri Feb 26 06:52:18 UTC 2021 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- VUL-0: grub2,shim: implement new SBAT method (bsc#1182057)
|
||||
* 0031-util-mkimage-Remove-unused-code-to-add-BSS-section.patch
|
||||
* 0032-util-mkimage-Use-grub_host_to_target32-instead-of-gr.patch
|
||||
* 0033-util-mkimage-Always-use-grub_host_to_target32-to-ini.patch
|
||||
* 0034-util-mkimage-Unify-more-of-the-PE32-and-PE32-header-.patch
|
||||
* 0035-util-mkimage-Reorder-PE-optional-header-fields-set-u.patch
|
||||
* 0036-util-mkimage-Improve-data_size-value-calculation.patch
|
||||
* 0037-util-mkimage-Refactor-section-setup-to-use-a-helper.patch
|
||||
* 0038-util-mkimage-Add-an-option-to-import-SBAT-metadata-i.patch
|
||||
* 0039-grub-install-common-Add-sbat-option.patch
|
||||
- Fix CVE-2021-20225 (bsc#1182262)
|
||||
* 0022-lib-arg-Block-repeated-short-options-that-require-an.patch
|
||||
- Fix CVE-2020-27749 (bsc#1179264)
|
||||
* 0024-kern-parser-Fix-resource-leak-if-argc-0.patch
|
||||
* 0025-kern-parser-Fix-a-memory-leak.patch
|
||||
* 0026-kern-parser-Introduce-process_char-helper.patch
|
||||
* 0027-kern-parser-Introduce-terminate_arg-helper.patch
|
||||
* 0028-kern-parser-Refactor-grub_parser_split_cmdline-clean.patch
|
||||
* 0029-kern-buffer-Add-variable-sized-heap-buffer.patch
|
||||
* 0030-kern-parser-Fix-a-stack-buffer-overflow.patch
|
||||
- Fix CVE-2021-20233 (bsc#1182263)
|
||||
* 0023-commands-menuentry-Fix-quoting-in-setparams_prefix.patch
|
||||
- Fix CVE-2020-25647 (bsc#1177883)
|
||||
* 0021-usb-Avoid-possible-out-of-bound-accesses-caused-by-m.patch
|
||||
- Fix CVE-2020-25632 (bsc#1176711)
|
||||
* 0020-dl-Only-allow-unloading-modules-that-are-not-depende.patch
|
||||
- Fix CVE-2020-27779, CVE-2020-14372 (bsc#1179265) (bsc#1175970)
|
||||
* 0001-include-grub-i386-linux.h-Include-missing-grub-types.patch
|
||||
* 0002-efi-Make-shim_lock-GUID-and-protocol-type-public.patch
|
||||
* 0003-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch
|
||||
* 0004-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch
|
||||
* 0005-efi-Add-secure-boot-detection.patch
|
||||
* 0006-efi-Only-register-shim_lock-verifier-if-shim_lock-pr.patch
|
||||
* 0007-verifiers-Move-verifiers-API-to-kernel-image.patch
|
||||
* 0008-efi-Move-the-shim_lock-verifier-to-the-GRUB-core.patch
|
||||
* 0009-kern-Add-lockdown-support.patch
|
||||
* 0010-kern-lockdown-Set-a-variable-if-the-GRUB-is-locked-d.patch
|
||||
* 0011-efi-Lockdown-the-GRUB-when-the-UEFI-Secure-Boot-is-e.patch
|
||||
* 0012-efi-Use-grub_is_lockdown-instead-of-hardcoding-a-dis.patch
|
||||
* 0013-acpi-Don-t-register-the-acpi-command-when-locked-dow.patch
|
||||
* 0014-mmap-Don-t-register-cutmem-and-badram-commands-when-.patch
|
||||
* 0015-commands-Restrict-commands-that-can-load-BIOS-or-DT-.patch
|
||||
* 0016-commands-setpci-Restrict-setpci-command-when-locked-.patch
|
||||
* 0017-commands-hdparm-Restrict-hdparm-command-when-locked-.patch
|
||||
* 0018-gdb-Restrict-GDB-access-when-locked-down.patch
|
||||
* 0019-loader-xnu-Don-t-allow-loading-extension-and-package.patch
|
||||
* 0040-shim_lock-Only-skip-loading-shim_lock-verifier-with-.patch
|
||||
* 0041-squash-Add-secureboot-support-on-efi-chainloader.patch
|
||||
* 0042-squash-grub2-efi-chainload-harder.patch
|
||||
* 0043-squash-Don-t-allow-insmod-when-secure-boot-is-enable.patch
|
||||
* 0044-squash-kern-Add-lockdown-support.patch
|
||||
* 0045-squash-Add-support-for-Linux-EFI-stub-loading-on-aar.patch
|
||||
* 0046-squash-verifiers-Move-verifiers-API-to-kernel-image.patch
|
||||
- Drop patch supersceded by the new backport
|
||||
* 0001-linuxefi-fail-kernel-validation-without-shim-protoco.patch
|
||||
* 0001-shim_lock-Disable-GRUB_VERIFY_FLAGS_DEFER_AUTH-if-se.patch
|
||||
* 0007-linuxefi-fail-kernel-validation-without-shim-protoco.patch
|
||||
- Add SBAT metadata section to grub.efi
|
||||
- Drop shim_lock module as it is part of core of grub.efi
|
||||
* grub2.spec
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Feb 22 12:49:48 UTC 2021 - Michael Chang <mchang@suse.com>
|
||||
|
||||
|
121
grub2.spec
121
grub2.spec
@ -321,16 +321,12 @@ Patch712: 0009-script-Avoid-a-use-after-free-when-redefining-a-func.patch
|
||||
# overflows in initrd size handling
|
||||
Patch713: 0010-linux-Fix-integer-overflows-in-initrd-size-handling.patch
|
||||
Patch714: 0001-kern-mm.c-Make-grub_calloc-inline.patch
|
||||
# bsc#1174421 VUL-0: CVE-2020-15705: grub2: linuxefi: fail kernel validation
|
||||
# without shim protocol
|
||||
Patch715: 0001-linuxefi-fail-kernel-validation-without-shim-protoco.patch
|
||||
Patch716: 0002-cmdline-Provide-cmdline-functions-as-module.patch
|
||||
# bsc#1172745 L3: SLES 12 SP4 - Slow boot of system after updated kernel -
|
||||
# takes 45 minutes after grub to start loading kernel
|
||||
Patch717: 0001-ieee1275-powerpc-implements-fibre-channel-discovery-.patch
|
||||
Patch718: 0002-ieee1275-powerpc-enables-device-mapper-discovery.patch
|
||||
Patch719: 0001-Unify-the-check-to-enable-btrfs-relative-path.patch
|
||||
Patch720: 0001-shim_lock-Disable-GRUB_VERIFY_FLAGS_DEFER_AUTH-if-se.patch
|
||||
Patch721: 0001-efi-linux-provide-linux-command.patch
|
||||
# Improve the error handling when grub2-install fails with short mbr gap
|
||||
# (bsc#1176062)
|
||||
@ -343,11 +339,57 @@ Patch732: 0003-Make-grub_error-more-verbose.patch
|
||||
Patch733: 0004-arm-arm64-loader-Better-memory-allocation-and-error-.patch
|
||||
Patch734: 0005-Make-linux_arm_kernel_header.hdr_offset-be-at-the-ri.patch
|
||||
Patch735: 0006-efi-Set-image-base-address-before-jumping-to-the-PE-.patch
|
||||
Patch736: 0007-linuxefi-fail-kernel-validation-without-shim-protoco.patch
|
||||
Patch737: 0008-squash-Add-support-for-Linux-EFI-stub-loading-on-aar.patch
|
||||
Patch738: 0009-squash-Add-support-for-linuxefi.patch
|
||||
Patch739: 0001-Fix-build-error-in-binutils-2.36.patch
|
||||
Patch740: 0001-emu-fix-executable-stack-marking.patch
|
||||
# Boothole2
|
||||
Patch741: 0001-include-grub-i386-linux.h-Include-missing-grub-types.patch
|
||||
Patch742: 0002-efi-Make-shim_lock-GUID-and-protocol-type-public.patch
|
||||
Patch743: 0003-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch
|
||||
Patch744: 0004-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch
|
||||
Patch745: 0005-efi-Add-secure-boot-detection.patch
|
||||
Patch746: 0006-efi-Only-register-shim_lock-verifier-if-shim_lock-pr.patch
|
||||
Patch747: 0007-verifiers-Move-verifiers-API-to-kernel-image.patch
|
||||
Patch748: 0008-efi-Move-the-shim_lock-verifier-to-the-GRUB-core.patch
|
||||
Patch749: 0009-kern-Add-lockdown-support.patch
|
||||
Patch750: 0010-kern-lockdown-Set-a-variable-if-the-GRUB-is-locked-d.patch
|
||||
Patch751: 0011-efi-Lockdown-the-GRUB-when-the-UEFI-Secure-Boot-is-e.patch
|
||||
Patch752: 0012-efi-Use-grub_is_lockdown-instead-of-hardcoding-a-dis.patch
|
||||
Patch753: 0013-acpi-Don-t-register-the-acpi-command-when-locked-dow.patch
|
||||
Patch754: 0014-mmap-Don-t-register-cutmem-and-badram-commands-when-.patch
|
||||
Patch755: 0015-commands-Restrict-commands-that-can-load-BIOS-or-DT-.patch
|
||||
Patch756: 0016-commands-setpci-Restrict-setpci-command-when-locked-.patch
|
||||
Patch757: 0017-commands-hdparm-Restrict-hdparm-command-when-locked-.patch
|
||||
Patch758: 0018-gdb-Restrict-GDB-access-when-locked-down.patch
|
||||
Patch759: 0019-loader-xnu-Don-t-allow-loading-extension-and-package.patch
|
||||
Patch760: 0020-dl-Only-allow-unloading-modules-that-are-not-depende.patch
|
||||
Patch761: 0021-usb-Avoid-possible-out-of-bound-accesses-caused-by-m.patch
|
||||
Patch762: 0022-lib-arg-Block-repeated-short-options-that-require-an.patch
|
||||
Patch763: 0023-commands-menuentry-Fix-quoting-in-setparams_prefix.patch
|
||||
Patch764: 0024-kern-parser-Fix-resource-leak-if-argc-0.patch
|
||||
Patch765: 0025-kern-parser-Fix-a-memory-leak.patch
|
||||
Patch766: 0026-kern-parser-Introduce-process_char-helper.patch
|
||||
Patch767: 0027-kern-parser-Introduce-terminate_arg-helper.patch
|
||||
Patch768: 0028-kern-parser-Refactor-grub_parser_split_cmdline-clean.patch
|
||||
Patch769: 0029-kern-buffer-Add-variable-sized-heap-buffer.patch
|
||||
Patch770: 0030-kern-parser-Fix-a-stack-buffer-overflow.patch
|
||||
Patch771: 0031-util-mkimage-Remove-unused-code-to-add-BSS-section.patch
|
||||
Patch772: 0032-util-mkimage-Use-grub_host_to_target32-instead-of-gr.patch
|
||||
Patch773: 0033-util-mkimage-Always-use-grub_host_to_target32-to-ini.patch
|
||||
Patch774: 0034-util-mkimage-Unify-more-of-the-PE32-and-PE32-header-.patch
|
||||
Patch775: 0035-util-mkimage-Reorder-PE-optional-header-fields-set-u.patch
|
||||
Patch776: 0036-util-mkimage-Improve-data_size-value-calculation.patch
|
||||
Patch777: 0037-util-mkimage-Refactor-section-setup-to-use-a-helper.patch
|
||||
Patch778: 0038-util-mkimage-Add-an-option-to-import-SBAT-metadata-i.patch
|
||||
Patch779: 0039-grub-install-common-Add-sbat-option.patch
|
||||
Patch780: 0040-shim_lock-Only-skip-loading-shim_lock-verifier-with-.patch
|
||||
Patch781: 0041-squash-Add-secureboot-support-on-efi-chainloader.patch
|
||||
Patch782: 0042-squash-grub2-efi-chainload-harder.patch
|
||||
Patch783: 0043-squash-Don-t-allow-insmod-when-secure-boot-is-enable.patch
|
||||
Patch784: 0044-squash-kern-Add-lockdown-support.patch
|
||||
Patch785: 0045-squash-Add-support-for-Linux-EFI-stub-loading-on-aar.patch
|
||||
Patch786: 0046-squash-verifiers-Move-verifiers-API-to-kernel-image.patch
|
||||
|
||||
Requires: gettext-runtime
|
||||
%if 0%{?suse_version} >= 1140
|
||||
@ -664,12 +706,10 @@ swap partition while in resuming
|
||||
%patch712 -p1
|
||||
%patch713 -p1
|
||||
%patch714 -p1
|
||||
%patch715 -p1
|
||||
%patch716 -p1
|
||||
%patch717 -p1
|
||||
%patch718 -p1
|
||||
%patch719 -p1
|
||||
%patch720 -p1
|
||||
%patch721 -p1
|
||||
%patch722 -p1
|
||||
%patch723 -p1
|
||||
@ -679,11 +719,56 @@ swap partition while in resuming
|
||||
%patch733 -p1
|
||||
%patch734 -p1
|
||||
%patch735 -p1
|
||||
%patch736 -p1
|
||||
%patch737 -p1
|
||||
%patch738 -p1
|
||||
%patch739 -p1
|
||||
%patch740 -p1
|
||||
%patch741 -p1
|
||||
%patch742 -p1
|
||||
%patch743 -p1
|
||||
%patch744 -p1
|
||||
%patch745 -p1
|
||||
%patch746 -p1
|
||||
%patch747 -p1
|
||||
%patch748 -p1
|
||||
%patch749 -p1
|
||||
%patch750 -p1
|
||||
%patch751 -p1
|
||||
%patch752 -p1
|
||||
%patch753 -p1
|
||||
%patch754 -p1
|
||||
%patch755 -p1
|
||||
%patch756 -p1
|
||||
%patch757 -p1
|
||||
%patch758 -p1
|
||||
%patch759 -p1
|
||||
%patch760 -p1
|
||||
%patch761 -p1
|
||||
%patch762 -p1
|
||||
%patch763 -p1
|
||||
%patch764 -p1
|
||||
%patch765 -p1
|
||||
%patch766 -p1
|
||||
%patch767 -p1
|
||||
%patch768 -p1
|
||||
%patch769 -p1
|
||||
%patch770 -p1
|
||||
%patch771 -p1
|
||||
%patch772 -p1
|
||||
%patch773 -p1
|
||||
%patch774 -p1
|
||||
%patch775 -p1
|
||||
%patch776 -p1
|
||||
%patch777 -p1
|
||||
%patch778 -p1
|
||||
%patch779 -p1
|
||||
%patch780 -p1
|
||||
%patch781 -p1
|
||||
%patch782 -p1
|
||||
%patch783 -p1
|
||||
%patch784 -p1
|
||||
%patch785 -p1
|
||||
%patch786 -p1
|
||||
|
||||
%build
|
||||
# collect evidence to debug spurious build failure on SLE15
|
||||
@ -789,16 +874,30 @@ PXE_MODULES="efinet tftp http"
|
||||
CRYPTO_MODULES="luks gcry_rijndael gcry_sha1 gcry_sha256"
|
||||
|
||||
%ifarch x86_64
|
||||
CD_MODULES="${CD_MODULES} shim_lock linuxefi"
|
||||
CD_MODULES="${CD_MODULES} linuxefi"
|
||||
%else
|
||||
CD_MODULES="${CD_MODULES} linux"
|
||||
%endif
|
||||
|
||||
# SBAT metadata
|
||||
%if 0%{?is_opensuse} == 1
|
||||
distro_id="opensuse"
|
||||
distro_name="The openSUSE Project"
|
||||
%else
|
||||
distro_id="sle"
|
||||
distro_name="SUSE Linux Enterprise"
|
||||
%endif
|
||||
upstream_sbat=1
|
||||
distro_sbat=1
|
||||
echo "sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md" > sbat.csv
|
||||
echo "grub,${upstream_sbat},Free Software Foundation,grub,%{version},https://www.gnu.org/software/grub/" >> sbat.csv
|
||||
echo "grub.${distro_id},${distro_sbat},${distro_name},%{name},%{version},mail:security-team@suse.de" >> sbat.csv
|
||||
|
||||
GRUB_MODULES="${CD_MODULES} ${FS_MODULES} ${PXE_MODULES} ${CRYPTO_MODULES} mdraid09 mdraid1x lvm serial"
|
||||
./grub-mkimage -O %{grubefiarch} -o grub.efi --prefix= \
|
||||
./grub-mkimage -O %{grubefiarch} -o grub.efi --prefix= --sbat sbat.csv \
|
||||
-d grub-core ${GRUB_MODULES}
|
||||
%ifarch x86_64
|
||||
./grub-mkimage -O %{grubefiarch} -o grub-tpm.efi --prefix= \
|
||||
./grub-mkimage -O %{grubefiarch} -o grub-tpm.efi --prefix= --sbat sbat.csv \
|
||||
-d grub-core ${GRUB_MODULES} tpm
|
||||
%endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user