Compare commits
9 Commits
| Author | SHA256 | Date | |
|---|---|---|---|
| 8664a1b42d | |||
| 8e0047f3d6 | |||
| 662ffc3467 | |||
| faa532f0d4 | |||
| db6cd9e010 | |||
| 01d2deb451 | |||
| e8de5b5d4b | |||
| 64d637cf0c | |||
| 58b2f1d02d |
@@ -1,42 +0,0 @@
|
||||
From d7158116601881ec676de4c16d82653344ea617f Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 22 Jan 2026 18:19:23 +0800
|
||||
Subject: [PATCH] 00_header: Omit loading efi_uga on non-x86 EFI platforms
|
||||
|
||||
When booting the arm64-efi target, GRUB prints the error message that
|
||||
may disrupt the boot process:
|
||||
|
||||
error: ../../grub-core/fs/btrfs.c:find_path:2163:file
|
||||
`/boot/grub2/arm64-efi/efi_uga.mod' not found.
|
||||
|
||||
This is introduced by the commit:
|
||||
|
||||
ea0b76dc4 util/grub.d/00_header.in: Disable loading all_video for EFI
|
||||
|
||||
However the efi_uga module is only enabled for x86_64-efi and i386-efi.
|
||||
The script should therefore check the CPU target before attempting to
|
||||
load it.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
util/grub.d/00_header.in | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in
|
||||
index ffb50847f..63d8a1f38 100644
|
||||
--- a/util/grub.d/00_header.in
|
||||
+++ b/util/grub.d/00_header.in
|
||||
@@ -179,7 +179,9 @@ else # GRUB_FORCE_EFI_ALL_VIDEO is not set true
|
||||
cat <<EOF
|
||||
if [ x\$grub_platform = xefi ]; then
|
||||
insmod efi_gop
|
||||
- insmod efi_uga
|
||||
+ if [ x\$grub_cpu = xx86_64 -o x\$grub_cpu = xi386 ]; then
|
||||
+ insmod efi_uga
|
||||
+ fi
|
||||
elif [ x\$feature_all_video_module = xy ]; then
|
||||
EOF
|
||||
fi # end GRUB_FORCE_EFI_ALL_VIDEO
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@@ -13,6 +13,8 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
util/grub-editenv.c | 4 +---
|
||||
3 files changed, 14 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/lib/envblk.c b/grub-core/lib/envblk.c
|
||||
index 2e4e78b132..24efbe7ffa 100644
|
||||
--- a/grub-core/lib/envblk.c
|
||||
+++ b/grub-core/lib/envblk.c
|
||||
@@ -23,6 +23,18 @@
|
||||
@@ -34,9 +36,11 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
grub_envblk_t
|
||||
grub_envblk_open (char *buf, grub_size_t size)
|
||||
{
|
||||
diff --git a/include/grub/lib/envblk.h b/include/grub/lib/envblk.h
|
||||
index c3e6559217..83f3fcf841 100644
|
||||
--- a/include/grub/lib/envblk.h
|
||||
+++ b/include/grub/lib/envblk.h
|
||||
@@ -31,6 +31,7 @@
|
||||
@@ -31,6 +31,7 @@ struct grub_envblk
|
||||
};
|
||||
typedef struct grub_envblk *grub_envblk_t;
|
||||
|
||||
@@ -44,10 +48,12 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
grub_envblk_t grub_envblk_open (char *buf, grub_size_t size);
|
||||
int grub_envblk_set (grub_envblk_t envblk, const char *name, const char *value);
|
||||
void grub_envblk_delete (grub_envblk_t envblk, const char *name);
|
||||
diff --git a/util/grub-editenv.c b/util/grub-editenv.c
|
||||
index b8219335f7..a02d3f2a63 100644
|
||||
--- a/util/grub-editenv.c
|
||||
+++ b/util/grub-editenv.c
|
||||
@@ -255,9 +255,7 @@
|
||||
if (fp == NULL)
|
||||
@@ -210,9 +210,7 @@ create_envblk_fs (void)
|
||||
if (! fp)
|
||||
grub_util_error (_("cannot open `%s': %s"), device, strerror (errno));
|
||||
|
||||
- buf = xmalloc (size);
|
||||
@@ -57,3 +63,6 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
|
||||
if (fseek (fp, offset, SEEK_SET) < 0)
|
||||
grub_util_error (_("cannot seek `%s': %s"), device, strerror (errno));
|
||||
--
|
||||
2.34.1
|
||||
|
||||
|
||||
@@ -120,17 +120,17 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
if (nested)
|
||||
--- a/grub-core/normal/menu.c
|
||||
+++ b/grub-core/normal/menu.c
|
||||
@@ -33,6 +33,9 @@
|
||||
@@ -32,6 +32,9 @@
|
||||
#include <grub/script_sh.h>
|
||||
#include <grub/gfxterm.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/safemath.h>
|
||||
+#ifdef GRUB_MACHINE_IEEE1275
|
||||
+#include <grub/ieee1275/ieee1275.h>
|
||||
+#endif
|
||||
|
||||
/* Time to delay after displaying an error message about a default/fallback
|
||||
entry failing to boot. */
|
||||
@@ -318,8 +321,31 @@
|
||||
@@ -317,8 +320,31 @@
|
||||
grub_env_set ("default", ptr + 1);
|
||||
else
|
||||
grub_env_unset ("default");
|
||||
@@ -162,7 +162,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
|
||||
if (errs_before != grub_err_printed_errors)
|
||||
grub_wait_after_message ();
|
||||
@@ -327,8 +353,23 @@
|
||||
@@ -326,8 +352,23 @@
|
||||
errs_before = grub_err_printed_errors;
|
||||
|
||||
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
|
||||
@@ -312,7 +312,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
|
||||
/* Max digits for a char is 3 (0xFF is 255), similarly for an int it
|
||||
is sizeof (int) * 3, and one extra for a possible -ve sign. */
|
||||
@@ -903,10 +900,6 @@
|
||||
@@ -886,10 +883,6 @@
|
||||
grub_err_t ret = 0;
|
||||
struct grub_script *parsed_script;
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
include/grub/crypttab.h | 18 ++++++++++-------
|
||||
7 files changed, 61 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/crypttab.c b/grub-core/commands/crypttab.c
|
||||
index c2217ca980..9397bede9e 100644
|
||||
--- a/grub-core/commands/crypttab.c
|
||||
+++ b/grub-core/commands/crypttab.c
|
||||
@@ -9,17 +9,20 @@
|
||||
@@ -65,7 +67,7 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
if (!cur)
|
||||
cur = grub_zalloc (sizeof (*cur));
|
||||
if (!cur)
|
||||
@@ -44,21 +47,24 @@
|
||||
@@ -44,21 +47,24 @@ grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len,
|
||||
cur->path = grub_strdup (path);
|
||||
}
|
||||
|
||||
@@ -94,7 +96,7 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
{
|
||||
grub_list_remove (GRUB_AS_LIST (cur));
|
||||
grub_memset (cur->key, 0, cur->key_len);
|
||||
@@ -69,6 +75,20 @@
|
||||
@@ -69,6 +75,20 @@ grub_initrd_discard_key (void)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +117,7 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
static grub_err_t
|
||||
grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **argv)
|
||||
@@ -92,7 +112,7 @@
|
||||
@@ -92,7 +112,7 @@ grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
|
||||
/*FIXME: Validate UUID string*/
|
||||
@@ -124,9 +126,11 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index cb87d337ac..5fd68f4549 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1076,6 +1076,9 @@
|
||||
@@ -1071,6 +1071,9 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
struct cryptodisk_read_hook_ctx read_hook_data = {0};
|
||||
int askpass = 0;
|
||||
char *part = NULL;
|
||||
@@ -136,15 +140,15 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
|
||||
dev = grub_cryptodisk_get_by_source_disk (source);
|
||||
|
||||
@@ -1194,6 +1197,7 @@
|
||||
goto error;
|
||||
@@ -1185,6 +1188,7 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
goto error;
|
||||
#ifndef GRUB_UTIL
|
||||
grub_cli_set_auth_needed ();
|
||||
+ is_tpmkey = 1;
|
||||
#endif
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -1307,7 +1311,7 @@
|
||||
@@ -1247,7 +1251,7 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
|
||||
#ifndef GRUB_UTIL
|
||||
if (cargs->key_data && dev)
|
||||
@@ -153,7 +157,7 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
#endif
|
||||
if (askpass)
|
||||
{
|
||||
@@ -1890,6 +1894,10 @@
|
||||
@@ -1792,6 +1796,10 @@ grub_cryptodisk_erasesecrets (void)
|
||||
grub_cryptodisk_t i;
|
||||
grub_uint8_t *buf;
|
||||
|
||||
@@ -164,9 +168,11 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
buf = grub_zalloc (GRUB_CRYPTODISK_MAX_KEYLEN);
|
||||
if (buf == NULL)
|
||||
grub_fatal ("grub_cryptodisk_erasesecrets: cannot allocate memory");
|
||||
diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c
|
||||
index 9ee8f37907..e5e7929581 100644
|
||||
--- a/grub-core/loader/linux.c
|
||||
+++ b/grub-core/loader/linux.c
|
||||
@@ -226,13 +226,13 @@
|
||||
@@ -226,13 +226,13 @@ grub_initrd_init (int argc, char *argv[],
|
||||
int i;
|
||||
int newc = 0;
|
||||
struct dir *root = 0;
|
||||
@@ -182,7 +188,7 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
if (pk->key && pk->path)
|
||||
numkey++;
|
||||
|
||||
@@ -305,7 +305,7 @@
|
||||
@@ -305,7 +305,7 @@ grub_initrd_init (int argc, char *argv[],
|
||||
goto overflow;
|
||||
}
|
||||
|
||||
@@ -191,9 +197,11 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
if (pk->key && pk->path)
|
||||
{
|
||||
grub_initrd_component (pk->key, pk->key_len, pk->path, initrd_ctx);
|
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
|
||||
index 320adbe337..343cdbae2c 100644
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -599,7 +599,7 @@
|
||||
@@ -599,7 +599,7 @@ grub_cmdline_run (int nested, int force_auth)
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -202,17 +210,19 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
grub_normal_reader_init (nested);
|
||||
|
||||
while (1)
|
||||
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
|
||||
index f243c5e0bd..897da6abac 100644
|
||||
--- a/grub-core/normal/menu.c
|
||||
+++ b/grub-core/normal/menu.c
|
||||
@@ -33,6 +33,7 @@
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <grub/script_sh.h>
|
||||
#include <grub/gfxterm.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/safemath.h>
|
||||
+#include <grub/crypttab.h>
|
||||
#ifdef GRUB_MACHINE_IEEE1275
|
||||
#include <grub/ieee1275/ieee1275.h>
|
||||
#endif
|
||||
@@ -770,6 +771,7 @@
|
||||
@@ -769,6 +770,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot, int *notify_boot)
|
||||
if (grub_key_is_interrupt (key))
|
||||
{
|
||||
timeout = -1;
|
||||
@@ -220,7 +230,7 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -852,6 +854,11 @@
|
||||
@@ -851,6 +853,11 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot, int *notify_boot)
|
||||
clear_timeout ();
|
||||
}
|
||||
|
||||
@@ -232,9 +242,11 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
switch (c)
|
||||
{
|
||||
case GRUB_TERM_KEY_HOME:
|
||||
diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c
|
||||
index 38c958e657..bbd05e5638 100644
|
||||
--- a/grub-core/normal/menu_entry.c
|
||||
+++ b/grub-core/normal/menu_entry.c
|
||||
@@ -1331,7 +1331,7 @@
|
||||
@@ -1331,7 +1331,7 @@ grub_menu_entry_run (grub_menu_entry_t entry)
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -243,6 +255,8 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
|
||||
screen = make_screen (entry);
|
||||
if (! screen)
|
||||
diff --git a/include/grub/crypttab.h b/include/grub/crypttab.h
|
||||
index 113c53cfce..f86404686f 100644
|
||||
--- a/include/grub/crypttab.h
|
||||
+++ b/include/grub/crypttab.h
|
||||
@@ -4,21 +4,25 @@
|
||||
@@ -278,3 +292,6 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
+void
|
||||
+grub_cryptokey_tpmkey_discard (void);
|
||||
#endif /* ! GRUB_CRYPTTAB_HEADER */
|
||||
--
|
||||
2.49.0
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
From b50719d46a75da79b23d2eda4bb117bb1c9207fc Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 19 Jan 2026 14:27:49 +0800
|
||||
Subject: [PATCH 1/2] Revert "configure: Print a more helpful error if
|
||||
autoconf-archive is not installed"
|
||||
|
||||
This reverts commit ac042f3f58d33ce9cd5ff61750f06da1a1d7b0eb.
|
||||
---
|
||||
configure.ac | 5 -----
|
||||
1 file changed, 5 deletions(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 900e0626a..b4d4db944 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -1792,11 +1792,6 @@ LIBS=""
|
||||
# Defined in acinclude.m4.
|
||||
grub_ASM_USCORE
|
||||
grub_PROG_TARGET_CC
|
||||
-
|
||||
-# The error message produced by autoconf if autoconf-archive is not installed is
|
||||
-# quite misleading and not very helpful. So, try point people in the right direction.
|
||||
-m4_ifndef([AX_CHECK_LINK_FLAG], [m4_fatal([autoconf-archive is missing. You must install it to generate the configure script.])])
|
||||
-
|
||||
if test "x$TARGET_APPLE_LINKER" != x1 ; then
|
||||
AX_CHECK_LINK_FLAG([-Wl,--image-base,0x400000],
|
||||
[TARGET_IMG_BASE_LDOPT="-Wl,--image-base"],
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@@ -41,9 +41,30 @@ Signed-Off-by: Michael Chang <mchang@suse.com>
|
||||
include/grub/parser.h | 4 ++
|
||||
3 files changed, 90 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
|
||||
index cbe2a289e..e08f35817 100644
|
||||
--- a/grub-core/commands/blscfg.c
|
||||
+++ b/grub-core/commands/blscfg.c
|
||||
@@ -953,10 +953,14 @@ static void create_entry (struct bls_entry *entry)
|
||||
|
||||
const char *sdval = grub_env_get("save_default");
|
||||
bool savedefault = ((NULL != sdval) && (grub_strcmp(sdval, "true") == 0));
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+ src = grub_xasprintf ("%slinux %s%s%s%s\n"
|
||||
+#else
|
||||
src = grub_xasprintf ("%sload_video\n"
|
||||
"set gfxpayload=keep\n"
|
||||
"insmod gzio\n"
|
||||
"linux %s%s%s%s\n"
|
||||
+#endif
|
||||
"%s%s",
|
||||
savedefault ? "savedefault\n" : "",
|
||||
#ifdef GRUB_MACHINE_EMU
|
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
|
||||
index 03631f07a..8e58ced67 100644
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -113,6 +113,65 @@
|
||||
@@ -113,6 +113,65 @@ read_config_file_getline (char **line, int cont __attribute__ ((unused)),
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
@@ -109,7 +130,7 @@ Signed-Off-by: Michael Chang <mchang@suse.com>
|
||||
static grub_menu_t
|
||||
read_config_file (const char *config)
|
||||
{
|
||||
@@ -282,6 +341,26 @@
|
||||
@@ -282,6 +341,26 @@ grub_normal_execute (const char *config, int nested, int batch)
|
||||
|
||||
grub_boot_time ("Executing config file");
|
||||
|
||||
@@ -136,7 +157,7 @@ Signed-Off-by: Michael Chang <mchang@suse.com>
|
||||
if (config)
|
||||
{
|
||||
menu = read_config_file (config);
|
||||
@@ -307,6 +386,9 @@
|
||||
@@ -307,6 +386,9 @@ grub_normal_execute (const char *config, int nested, int batch)
|
||||
|
||||
grub_boot_time ("Executed config file");
|
||||
|
||||
@@ -146,9 +167,11 @@ Signed-Off-by: Michael Chang <mchang@suse.com>
|
||||
if (! batch)
|
||||
{
|
||||
if (menu && menu->size)
|
||||
diff --git a/include/grub/parser.h b/include/grub/parser.h
|
||||
index 64f9f5cc2..9d702571a 100644
|
||||
--- a/include/grub/parser.h
|
||||
+++ b/include/grub/parser.h
|
||||
@@ -86,7 +86,11 @@
|
||||
@@ -86,7 +86,11 @@ struct grub_parser
|
||||
};
|
||||
typedef struct grub_parser *grub_parser_t;
|
||||
|
||||
@@ -160,3 +183,6 @@ Signed-Off-by: Michael Chang <mchang@suse.com>
|
||||
|
||||
grub_err_t
|
||||
grub_rescue_parse_line (char *line,
|
||||
--
|
||||
2.46.0
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ V6:
|
||||
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -2456,6 +2456,12 @@
|
||||
@@ -2362,6 +2362,12 @@
|
||||
common = net/ethernet.c;
|
||||
common = net/arp.c;
|
||||
common = net/netbuff.c;
|
||||
@@ -233,7 +233,7 @@ V6:
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -346,7 +347,7 @@
|
||||
@@ -345,7 +346,7 @@
|
||||
}
|
||||
|
||||
static grub_efi_handle_t
|
||||
@@ -242,7 +242,7 @@ V6:
|
||||
grub_efi_device_path_t **r_device_path)
|
||||
{
|
||||
grub_efi_handle_t handle;
|
||||
@@ -499,6 +500,17 @@
|
||||
@@ -498,6 +499,17 @@
|
||||
|
||||
ldp = grub_efi_find_last_device_path (ddp);
|
||||
|
||||
@@ -260,7 +260,7 @@ V6:
|
||||
if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
|
||||
|| (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE
|
||||
&& GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE))
|
||||
@@ -766,6 +778,7 @@
|
||||
@@ -765,6 +777,7 @@
|
||||
if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
|
||||
|| (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE
|
||||
&& GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE
|
||||
@@ -268,7 +268,7 @@ V6:
|
||||
&& GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_URI_DEVICE_PATH_SUBTYPE))
|
||||
continue;
|
||||
dup_dp = grub_efi_duplicate_device_path (dp);
|
||||
@@ -781,6 +794,15 @@
|
||||
@@ -780,6 +793,15 @@
|
||||
}
|
||||
|
||||
dup_ldp = grub_efi_find_last_device_path (dup_dp);
|
||||
@@ -284,7 +284,7 @@ V6:
|
||||
dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
||||
dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||
dup_ldp->length = sizeof (*dup_ldp);
|
||||
@@ -870,6 +892,9 @@
|
||||
@@ -860,6 +882,9 @@
|
||||
|
||||
GRUB_MOD_INIT(efinet)
|
||||
{
|
||||
@@ -294,7 +294,7 @@ V6:
|
||||
grub_efinet_findcards ();
|
||||
grub_efi_net_config = grub_efi_net_config_real;
|
||||
}
|
||||
@@ -881,5 +906,7 @@
|
||||
@@ -871,5 +896,7 @@
|
||||
FOR_NET_CARDS_SAFE (card, next)
|
||||
if (card->driver == &efidriver)
|
||||
grub_net_card_unregister (card);
|
||||
@@ -3848,17 +3848,17 @@ V6:
|
||||
+
|
||||
--- a/grub-core/net/net.c
|
||||
+++ b/grub-core/net/net.c
|
||||
@@ -33,6 +33,9 @@
|
||||
@@ -32,6 +32,9 @@
|
||||
#include <grub/loader.h>
|
||||
#include <grub/bufio.h>
|
||||
#include <grub/kernel.h>
|
||||
#include <grub/safemath.h>
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+#include <grub/net/efi.h>
|
||||
+#endif
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -2079,8 +2082,49 @@
|
||||
@@ -2014,8 +2017,49 @@
|
||||
static grub_command_t cmd_setvlan, cmd_lsroutes, cmd_lscards;
|
||||
static grub_command_t cmd_lsaddr, cmd_slaac;
|
||||
|
||||
@@ -3908,7 +3908,7 @@ V6:
|
||||
grub_register_variable_hook ("net_default_server", defserver_get_env,
|
||||
defserver_set_env);
|
||||
grub_env_export ("net_default_server");
|
||||
@@ -2131,10 +2175,37 @@
|
||||
@@ -2066,10 +2110,37 @@
|
||||
grub_net_restore_hw,
|
||||
GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK);
|
||||
grub_net_poll_cards_idle = grub_net_poll_cards_idle_real;
|
||||
@@ -3945,8 +3945,8 @@ V6:
|
||||
+
|
||||
grub_register_variable_hook ("net_default_server", 0, 0);
|
||||
grub_register_variable_hook ("pxe_default_server", 0, 0);
|
||||
grub_register_variable_hook ("net_default_ip", 0, 0);
|
||||
@@ -2155,4 +2226,7 @@
|
||||
|
||||
@@ -2088,4 +2159,7 @@
|
||||
grub_net_fini_hw (0);
|
||||
grub_loader_unregister_preboot_hook (fini_hnd);
|
||||
grub_net_poll_cards_idle = NULL;
|
||||
@@ -3956,7 +3956,7 @@ V6:
|
||||
}
|
||||
--- a/include/grub/efi/api.h
|
||||
+++ b/include/grub/efi/api.h
|
||||
@@ -663,6 +663,23 @@
|
||||
@@ -653,6 +653,23 @@
|
||||
typedef grub_uint8_t grub_efi_ip_address_t[8] __attribute__ ((aligned(4)));
|
||||
typedef grub_efi_uint64_t grub_efi_physical_address_t;
|
||||
typedef grub_efi_uint64_t grub_efi_virtual_address_t;
|
||||
@@ -3980,7 +3980,7 @@ V6:
|
||||
|
||||
/* XXX although the spec does not specify the padding, this actually
|
||||
must have the padding! */
|
||||
@@ -912,6 +929,8 @@
|
||||
@@ -902,6 +919,8 @@
|
||||
grub_efi_uint16_t remote_port;
|
||||
grub_efi_uint16_t protocol;
|
||||
grub_efi_uint8_t static_ip_address;
|
||||
@@ -3989,7 +3989,7 @@ V6:
|
||||
} GRUB_PACKED;
|
||||
typedef struct grub_efi_ipv6_device_path grub_efi_ipv6_device_path_t;
|
||||
|
||||
@@ -970,6 +989,15 @@
|
||||
@@ -960,6 +979,15 @@
|
||||
} GRUB_PACKED;
|
||||
typedef struct grub_efi_uri_device_path grub_efi_uri_device_path_t;
|
||||
|
||||
@@ -4005,7 +4005,7 @@ V6:
|
||||
#define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE 10
|
||||
|
||||
/* Media Device Path. */
|
||||
@@ -1052,6 +1080,23 @@
|
||||
@@ -1042,6 +1070,23 @@
|
||||
} GRUB_PACKED;
|
||||
typedef struct grub_efi_bios_device_path grub_efi_bios_device_path_t;
|
||||
|
||||
@@ -4029,7 +4029,7 @@ V6:
|
||||
struct grub_efi_open_protocol_information_entry
|
||||
{
|
||||
grub_efi_handle_t agent_handle;
|
||||
@@ -1554,23 +1599,28 @@
|
||||
@@ -1544,23 +1589,28 @@
|
||||
|
||||
typedef grub_uint8_t grub_efi_pxe_packet_t[1472];
|
||||
|
||||
@@ -4072,7 +4072,7 @@ V6:
|
||||
|
||||
#define GRUB_EFI_PXE_BASE_CODE_MAX_IPCNT 8
|
||||
typedef struct {
|
||||
@@ -1620,18 +1670,32 @@
|
||||
@@ -1610,18 +1660,32 @@
|
||||
typedef struct grub_efi_pxe
|
||||
{
|
||||
grub_uint64_t rev;
|
||||
@@ -4117,7 +4117,7 @@ V6:
|
||||
struct grub_efi_pxe_mode *mode;
|
||||
} grub_efi_pxe_t;
|
||||
|
||||
@@ -1951,6 +2015,44 @@
|
||||
@@ -1921,6 +1985,44 @@
|
||||
};
|
||||
typedef struct grub_efi_ip4_config2_protocol grub_efi_ip4_config2_protocol_t;
|
||||
|
||||
@@ -4162,7 +4162,7 @@ V6:
|
||||
enum grub_efi_ip6_config_data_type {
|
||||
GRUB_EFI_IP6_CONFIG_DATA_TYPE_INTERFACEINFO,
|
||||
GRUB_EFI_IP6_CONFIG_DATA_TYPE_ALT_INTERFACEID,
|
||||
@@ -1985,4 +2087,47 @@
|
||||
@@ -1955,4 +2057,47 @@
|
||||
};
|
||||
typedef struct grub_efi_ip6_config_protocol grub_efi_ip6_config_protocol_t;
|
||||
|
||||
|
||||
82
0001-bli-Fix-crash-in-get_part_uuid.patch
Normal file
82
0001-bli-Fix-crash-in-get_part_uuid.patch
Normal file
@@ -0,0 +1,82 @@
|
||||
From 552a2de0642bb95dd38fcdb7894ea7e07171975e Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 15 Jul 2024 11:43:07 +0800
|
||||
Subject: [PATCH] bli: Fix crash in get_part_uuid
|
||||
|
||||
The get_part_uuid() function made an assumption that the target grub
|
||||
device is a partition device and accessed device->disk->partition
|
||||
without checking for NULL. There are four situations where this
|
||||
assumption is problematic:
|
||||
|
||||
1. The device is a net device instead of a disk.
|
||||
2. The device is an abstraction device, like LVM, RAID, or CRYPTO, which
|
||||
is mostly logical "disk" ((lvmid/<UUID>) and so on).
|
||||
3. Firmware RAID may present the ESP to grub as an EFI disk (hd0) device
|
||||
if it is contained within a Linux software RAID.
|
||||
4. When booting from a cdrom, the ESP is a vfat image indexed by the El
|
||||
Torito boot catalog. The boot device is set to (cd0), corresponding
|
||||
to the cdrom image mounted as an iso9660 filesystem.
|
||||
|
||||
As a result, get_part_uuid() could lead to a NULL pointer dereference
|
||||
and trigger a synchronous exception during boot if the ESP falls into
|
||||
one of these categories. This patch fixes the problem by adding the
|
||||
necessary checks to handle cases where the ESP is not a partition
|
||||
device.
|
||||
|
||||
Additionally, to avoid disrupting the boot process, this patch relaxes
|
||||
the severity of the errors in this context to non-critical. Errors will
|
||||
be logged, but they will not prevent the boot process from continuing.
|
||||
|
||||
Fixes: e0fa7dc84 (bli: Add a module for the Boot Loader Interface)
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
Reviewed-By: Oliver Steffen <osteffen@redhat.com>
|
||||
---
|
||||
grub-core/commands/bli.c | 20 +++++++++++++++++++-
|
||||
1 file changed, 19 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/commands/bli.c b/grub-core/commands/bli.c
|
||||
index e0d8a54f7..298c5f70a 100644
|
||||
--- a/grub-core/commands/bli.c
|
||||
+++ b/grub-core/commands/bli.c
|
||||
@@ -48,6 +48,22 @@ get_part_uuid (const char *device_name, char **part_uuid)
|
||||
if (device == NULL)
|
||||
return grub_error (grub_errno, N_("cannot open device: %s"), device_name);
|
||||
|
||||
+ if (device->disk == NULL)
|
||||
+ {
|
||||
+ grub_dprintf ("bli", "%s is not a disk device, partuuid skipped\n", device_name);
|
||||
+ *part_uuid = NULL;
|
||||
+ grub_device_close (device);
|
||||
+ return GRUB_ERR_NONE;
|
||||
+ }
|
||||
+
|
||||
+ if (device->disk->partition == NULL)
|
||||
+ {
|
||||
+ grub_dprintf ("bli", "%s has no partition, partuuid skipped\n", device_name);
|
||||
+ *part_uuid = NULL;
|
||||
+ grub_device_close (device);
|
||||
+ return GRUB_ERR_NONE;
|
||||
+ }
|
||||
+
|
||||
disk = grub_disk_open (device->disk->name);
|
||||
if (disk == NULL)
|
||||
{
|
||||
@@ -99,7 +115,7 @@ set_loader_device_part_uuid (void)
|
||||
|
||||
status = get_part_uuid (device_name, &part_uuid);
|
||||
|
||||
- if (status == GRUB_ERR_NONE)
|
||||
+ if (status == GRUB_ERR_NONE && part_uuid)
|
||||
status = grub_efi_set_variable_to_string ("LoaderDevicePartUUID", &bli_vendor_guid, part_uuid,
|
||||
GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
GRUB_EFI_VARIABLE_RUNTIME_ACCESS);
|
||||
@@ -117,4 +133,6 @@ GRUB_MOD_INIT (bli)
|
||||
GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
GRUB_EFI_VARIABLE_RUNTIME_ACCESS);
|
||||
set_loader_device_part_uuid ();
|
||||
+ /* No error here is critical, other than being logged */
|
||||
+ grub_print_error ();
|
||||
}
|
||||
--
|
||||
2.46.0
|
||||
|
||||
1613
0001-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch
Normal file
1613
0001-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -14,11 +14,13 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
grub-core/commands/blscfg.c | 164 ++++++++++++++++++++++--------------
|
||||
1 file changed, 103 insertions(+), 61 deletions(-)
|
||||
|
||||
--- a/grub-core/commands/blsuki.c
|
||||
+++ b/grub-core/commands/blsuki.c
|
||||
@@ -117,6 +117,16 @@
|
||||
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
|
||||
index 343c7ae989..10996722cf 100644
|
||||
--- a/grub-core/commands/blscfg.c
|
||||
+++ b/grub-core/commands/blscfg.c
|
||||
@@ -55,6 +55,15 @@ struct keyval
|
||||
|
||||
static grub_blsuki_entry_t *entries = NULL;
|
||||
static struct bls_entry *entries = NULL;
|
||||
|
||||
+struct bls_fragment
|
||||
+{
|
||||
@@ -27,39 +29,141 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
+ char *filename;
|
||||
+};
|
||||
+typedef struct bls_fragment *bls_fragment_t;
|
||||
+static bls_fragment_t fragments;
|
||||
+
|
||||
+static bls_fragment_t fragments = NULL;
|
||||
+
|
||||
#define FOR_BLSUKI_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries)
|
||||
#define FOR_BLS_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries)
|
||||
|
||||
/*
|
||||
@@ -645,6 +655,69 @@
|
||||
/* BLS appears to make paths relative to the filesystem that snippets are
|
||||
@@ -466,69 +475,41 @@ struct read_entry_info {
|
||||
grub_file_t file;
|
||||
};
|
||||
|
||||
-static int read_entry (
|
||||
- const char *filename,
|
||||
- const struct grub_dirhook_info *dirhook_info UNUSED,
|
||||
- void *data)
|
||||
+static int
|
||||
+read_entry (const char *filename)
|
||||
{
|
||||
grub_size_t m = 0, n, clip = 0;
|
||||
int rc = 0;
|
||||
char *p = NULL;
|
||||
grub_file_t f = NULL;
|
||||
struct bls_entry *entry;
|
||||
- struct read_entry_info *info = (struct read_entry_info *)data;
|
||||
-
|
||||
- grub_dprintf ("blscfg", "filename: \"%s\"\n", filename);
|
||||
+ char *slash;
|
||||
|
||||
- n = grub_strlen (filename);
|
||||
+ grub_dprintf ("blscfg", "read_entry: \"%s\"\n", filename);
|
||||
|
||||
- if (info->file)
|
||||
- {
|
||||
- f = info->file;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- if (filename[0] == '.')
|
||||
- return 0;
|
||||
+ f = grub_file_open (filename, GRUB_FILE_TYPE_CONFIG);
|
||||
|
||||
- if (n <= 5)
|
||||
- return 0;
|
||||
-
|
||||
- if (grub_strcmp (filename + n - 5, ".conf") != 0)
|
||||
- return 0;
|
||||
-
|
||||
- p = grub_xasprintf ("(%s)%s/%s", info->devid, info->dirname, filename);
|
||||
-
|
||||
- f = grub_file_open (p, GRUB_FILE_TYPE_CONFIG);
|
||||
- if (!f)
|
||||
- goto finish;
|
||||
- }
|
||||
+ if (!f)
|
||||
+ goto finish;
|
||||
|
||||
entry = grub_zalloc (sizeof (*entry));
|
||||
if (!entry)
|
||||
goto finish;
|
||||
|
||||
- if (info->file)
|
||||
- {
|
||||
- char *slash;
|
||||
+ /* Strip .conf */
|
||||
+ n = grub_strlen (filename);
|
||||
|
||||
- if (n > 5 && !grub_strcmp (filename + n - 5, ".conf") == 0)
|
||||
- clip = 5;
|
||||
+ if (n > 5 && !grub_strcmp (filename + n - 5, ".conf") == 0)
|
||||
+ clip = 5;
|
||||
|
||||
- slash = grub_strrchr (filename, '/');
|
||||
- if (!slash)
|
||||
- slash = grub_strrchr (filename, '\\');
|
||||
+ slash = grub_strrchr (filename, '/');
|
||||
+ if (!slash)
|
||||
+ slash = grub_strrchr (filename, '\\');
|
||||
|
||||
- while (*slash == '/' || *slash == '\\')
|
||||
- slash++;
|
||||
+ while (*slash == '/' || *slash == '\\')
|
||||
+ slash++;
|
||||
|
||||
- m = slash ? slash - filename : 0;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- m = 0;
|
||||
- clip = 5;
|
||||
- }
|
||||
+ m = slash ? slash - filename : 0;
|
||||
n -= m;
|
||||
|
||||
entry->filename = grub_strndup(filename + m, n - clip);
|
||||
@@ -573,10 +554,7 @@ static int read_entry (
|
||||
if (rc < 0)
|
||||
break;
|
||||
}
|
||||
-
|
||||
- if (info->devid)
|
||||
- entry->devid = grub_strdup(info->devid);
|
||||
-
|
||||
+ entry->devid = grub_file_get_device_name (filename);
|
||||
if (!rc)
|
||||
bls_add_entry(entry);
|
||||
|
||||
@@ -590,6 +568,73 @@ finish:
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int
|
||||
+collect_fragments (
|
||||
+ const char *filename,
|
||||
+ const struct grub_dirhook_info *dirhook_info __attribute__ ((__unused__)),
|
||||
+ void *data __attribute__ ((__unused__)))
|
||||
+ const struct grub_dirhook_info *dirhook_info UNUSED,
|
||||
+ void *data)
|
||||
+{
|
||||
+ grub_size_t n;
|
||||
+ char *p = NULL;
|
||||
+ struct read_entry_info *info = (struct read_entry_info *)data;
|
||||
+ bls_fragment_t fragment, f, last;
|
||||
+
|
||||
+ if (filename[0] == '.')
|
||||
+ return 0;
|
||||
+
|
||||
+ fragment = grub_zalloc (sizeof (*fragment));
|
||||
+ if (fragment == NULL)
|
||||
+ n = grub_strlen (filename);
|
||||
+ if (n <= 5)
|
||||
+ return 0;
|
||||
+
|
||||
+ fragment->filename = grub_strdup (filename);
|
||||
+ if (fragment->filename == NULL)
|
||||
+ {
|
||||
+ grub_free (fragment);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (grub_strcmp (filename + n - 5, ".conf") != 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (fragments == NULL)
|
||||
+ p = grub_xasprintf ("(%s)%s/%s", info->devid, info->dirname, filename);
|
||||
+
|
||||
+ fragment = grub_zalloc (sizeof (*fragment));
|
||||
+ fragment->filename = grub_strdup (p);
|
||||
+
|
||||
+ if (!fragments)
|
||||
+ {
|
||||
+ fragments = fragment;
|
||||
+ return 0;
|
||||
@@ -68,8 +172,8 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
+ FOR_LIST_ELEMENTS (f, fragments)
|
||||
+ {
|
||||
+ int rc;
|
||||
+ rc = grub_strcmp (fragment->filename, f->filename);
|
||||
+ if (rc == 0)
|
||||
+ rc = grub_strcmp(fragment->filename, f->filename);
|
||||
+ if (!rc)
|
||||
+ {
|
||||
+ grub_free (fragment);
|
||||
+ return 0;
|
||||
@@ -100,33 +204,56 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* This function returns a list of values that had the same key in the BLS
|
||||
* config file or UKI. The number of entries in this list is returned by the len
|
||||
@@ -1200,7 +1273,7 @@
|
||||
read_entry_info.devid = info->devid;
|
||||
read_entry_info.cmd_type = cmd_type;
|
||||
static grub_envblk_t saved_env = NULL;
|
||||
|
||||
- r = dir_fs->fs_dir (dir_dev, read_entry_info.dirname, blsuki_read_entry,
|
||||
+ r = dir_fs->fs_dir (dir_dev, read_entry_info.dirname, collect_fragments,
|
||||
&read_entry_info);
|
||||
if (r != 0)
|
||||
{
|
||||
@@ -1208,6 +1281,17 @@
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
static int UNUSED
|
||||
@@ -1007,6 +1052,7 @@ static int find_entry (struct find_entry_info *info)
|
||||
const char *blsdir = info->dirname;
|
||||
int fallback = 0;
|
||||
int r = 0;
|
||||
+ bls_fragment_t fragment;
|
||||
|
||||
+ while (fragments != NULL)
|
||||
+ {
|
||||
+ bls_fragment_t fragment = fragments;
|
||||
if (!blsdir) {
|
||||
blsdir = grub_env_get ("blsdir");
|
||||
@@ -1024,8 +1070,14 @@ static int find_entry (struct find_entry_info *info)
|
||||
read_entry_info.devid = info->devid;
|
||||
|
||||
read_fallback:
|
||||
- r = blsdir_fs->fs_dir (blsdir_dev, read_entry_info.dirname, read_entry,
|
||||
+ r = blsdir_fs->fs_dir (blsdir_dev, read_entry_info.dirname, collect_fragments,
|
||||
&read_entry_info);
|
||||
+ FOR_LIST_ELEMENTS (fragment, fragments)
|
||||
+ {
|
||||
+ grub_dprintf ("blscfg", "read_entry: %s\n", fragment->filename);
|
||||
+ read_entry (fragment->filename);
|
||||
+ }
|
||||
+
|
||||
+ fragments = fragments->next;
|
||||
+ grub_dprintf ("blsuki", "read_entry: %s\n", fragment->filename);
|
||||
+ blsuki_read_entry (fragment->filename, NULL, &read_entry_info);
|
||||
+ grub_free (fragment->filename);
|
||||
+ grub_free (fragment);
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* If we aren't able to find BLS entries in the directory given by info->dirname,
|
||||
* we can fallback to the default location of "/loader/entries/" and see if we
|
||||
if (r != 0) {
|
||||
grub_dprintf ("blscfg", "read_entry returned error\n");
|
||||
grub_err_t e;
|
||||
@@ -1060,21 +1112,11 @@ bls_load_entries (const char *path)
|
||||
.fs = NULL,
|
||||
.dirname = NULL,
|
||||
};
|
||||
- struct read_entry_info rei = {
|
||||
- .devid = NULL,
|
||||
- .dirname = NULL,
|
||||
- };
|
||||
|
||||
if (path) {
|
||||
len = grub_strlen (path);
|
||||
if (grub_strcmp (path + len - 5, ".conf") == 0) {
|
||||
- rei.file = grub_file_open (path, GRUB_FILE_TYPE_CONFIG);
|
||||
- if (!rei.file)
|
||||
- return grub_errno;
|
||||
- /*
|
||||
- * read_entry() closes the file
|
||||
- */
|
||||
- return read_entry(path, NULL, &rei);
|
||||
+ return read_entry (path);
|
||||
} else if (path[0] == '(') {
|
||||
devid = path + 1;
|
||||
|
||||
--
|
||||
2.49.0
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
From cc6749ca2fbe48c8624dbbea02b4bed89f046ef5 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 2 Feb 2026 18:40:01 +0800
|
||||
Subject: [PATCH] blsuki: Fix linux_cmd size calcution in bls_get_linux()
|
||||
|
||||
---
|
||||
grub-core/commands/blsuki.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/blsuki.c b/grub-core/commands/blsuki.c
|
||||
index 4da0464cf..531aac889 100644
|
||||
--- a/grub-core/commands/blsuki.c
|
||||
+++ b/grub-core/commands/blsuki.c
|
||||
@@ -958,6 +958,13 @@ bls_get_linux (grub_blsuki_entry_t *entry)
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Need one extra byte for '\n' */
|
||||
+ if (grub_add (size, 1, &size))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while calculating linux buffer size");
|
||||
+ goto finish;
|
||||
+ }
|
||||
+
|
||||
linux_cmd = grub_malloc (size);
|
||||
if (linux_cmd == NULL)
|
||||
goto finish;
|
||||
--
|
||||
2.52.0
|
||||
|
||||
374
0001-cli_lock-Add-build-option-to-block-command-line-inte.patch
Normal file
374
0001-cli_lock-Add-build-option-to-block-command-line-inte.patch
Normal file
@@ -0,0 +1,374 @@
|
||||
From c7dd3dd296592fef6166170121b54aafe634369f Mon Sep 17 00:00:00 2001
|
||||
From: Alec Brown <alec.r.brown@oracle.com>
|
||||
Date: Wed, 24 Jan 2024 06:26:37 +0000
|
||||
Subject: [PATCH 1/2] cli_lock: Add build option to block command line
|
||||
interface
|
||||
|
||||
Add functionality to disable command line interface access and editing of GRUB
|
||||
menu entries if GRUB image is built with --disable-cli.
|
||||
|
||||
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
|
||||
Reviewed-by: Vladimir Serbinenko <phcoder@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
docs/grub.texi | 6 ++++--
|
||||
grub-core/kern/main.c | 28 ++++++++++++++++++++++++++++
|
||||
grub-core/kern/rescue_reader.c | 13 +++++++++++++
|
||||
grub-core/normal/auth.c | 3 +++
|
||||
grub-core/normal/menu_text.c | 31 +++++++++++++++++--------------
|
||||
include/grub/kernel.h | 3 ++-
|
||||
include/grub/misc.h | 2 ++
|
||||
include/grub/util/install.h | 8 ++++++--
|
||||
util/grub-install-common.c | 11 ++++++++---
|
||||
util/grub-mkimage.c | 9 ++++++++-
|
||||
util/mkimage.c | 16 +++++++++++++++-
|
||||
11 files changed, 106 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index 00c5fdc44..e89007920 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -6523,8 +6523,10 @@ the GRUB command line, edit menu entries, and execute any menu entry. If
|
||||
@samp{superusers} is set, then use of the command line and editing of menu
|
||||
entries are automatically restricted to superusers. Setting @samp{superusers}
|
||||
to empty string effectively disables both access to CLI and editing of menu
|
||||
-entries. Note: The environment variable needs to be exported to also affect
|
||||
-the section defined by the @samp{submenu} command (@pxref{submenu}).
|
||||
+entries. Building a grub image with @samp{--disable-cli} option will also
|
||||
+disable access to CLI and editing of menu entries, as well as disabling rescue
|
||||
+mode. Note: The environment variable needs to be exported to also affect the
|
||||
+section defined by the @samp{submenu} command (@pxref{submenu}).
|
||||
|
||||
Other users may be allowed to execute specific menu entries by giving a list of
|
||||
usernames (as above) using the @option{--users} option to the
|
||||
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
|
||||
index 02df49206..07b6940d2 100644
|
||||
--- a/grub-core/kern/main.c
|
||||
+++ b/grub-core/kern/main.c
|
||||
@@ -30,11 +30,14 @@
|
||||
#include <grub/reader.h>
|
||||
#include <grub/parser.h>
|
||||
#include <grub/verify.h>
|
||||
+#include <grub/types.h>
|
||||
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
#include <grub/machine/memory.h>
|
||||
#endif
|
||||
|
||||
+static bool cli_disabled = false;
|
||||
+
|
||||
grub_addr_t
|
||||
grub_modules_get_end (void)
|
||||
{
|
||||
@@ -237,6 +240,28 @@ grub_load_normal_mode (void)
|
||||
grub_command_execute ("normal", 0, 0);
|
||||
}
|
||||
|
||||
+bool
|
||||
+grub_is_cli_disabled (void)
|
||||
+{
|
||||
+ return cli_disabled;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+check_is_cli_disabled (void)
|
||||
+{
|
||||
+ struct grub_module_header *header;
|
||||
+ header = 0;
|
||||
+
|
||||
+ FOR_MODULES (header)
|
||||
+ {
|
||||
+ if (header->type == OBJ_TYPE_DISABLE_CLI)
|
||||
+ {
|
||||
+ cli_disabled = true;
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void
|
||||
reclaim_module_space (void)
|
||||
{
|
||||
@@ -294,6 +319,9 @@ grub_main (void)
|
||||
|
||||
grub_boot_time ("After loading embedded modules.");
|
||||
|
||||
+ /* Check if the CLI should be disabled */
|
||||
+ check_is_cli_disabled ();
|
||||
+
|
||||
/* It is better to set the root device as soon as possible,
|
||||
for convenience. */
|
||||
grub_set_prefix_and_root ();
|
||||
diff --git a/grub-core/kern/rescue_reader.c b/grub-core/kern/rescue_reader.c
|
||||
index dcd7d4439..4259857ba 100644
|
||||
--- a/grub-core/kern/rescue_reader.c
|
||||
+++ b/grub-core/kern/rescue_reader.c
|
||||
@@ -78,6 +78,19 @@ grub_rescue_read_line (char **line, int cont,
|
||||
void __attribute__ ((noreturn))
|
||||
grub_rescue_run (void)
|
||||
{
|
||||
+ /* Stall if the CLI has been disabled */
|
||||
+ if (grub_is_cli_disabled ())
|
||||
+ {
|
||||
+ grub_printf ("Rescue mode has been disabled...\n");
|
||||
+
|
||||
+ do
|
||||
+ {
|
||||
+ /* Do not optimize out the loop. */
|
||||
+ asm volatile ("");
|
||||
+ }
|
||||
+ while (1);
|
||||
+ }
|
||||
+
|
||||
grub_printf ("Entering rescue mode...\n");
|
||||
|
||||
while (1)
|
||||
diff --git a/grub-core/normal/auth.c b/grub-core/normal/auth.c
|
||||
index 517fc623f..d94020186 100644
|
||||
--- a/grub-core/normal/auth.c
|
||||
+++ b/grub-core/normal/auth.c
|
||||
@@ -209,6 +209,9 @@ grub_auth_check_authentication (const char *userlist)
|
||||
char entered[GRUB_AUTH_MAX_PASSLEN];
|
||||
struct grub_auth_user *user;
|
||||
|
||||
+ if (grub_is_cli_disabled ())
|
||||
+ return GRUB_ACCESS_DENIED;
|
||||
+
|
||||
grub_memset (login, 0, sizeof (login));
|
||||
|
||||
if (is_authenticated (userlist))
|
||||
diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c
|
||||
index ae92050d7..56c6f7797 100644
|
||||
--- a/grub-core/normal/menu_text.c
|
||||
+++ b/grub-core/normal/menu_text.c
|
||||
@@ -194,21 +194,24 @@ command-line or ESC to discard edits and return to the GRUB menu."),
|
||||
grub_free (msg_translated);
|
||||
#endif
|
||||
|
||||
- if (nested)
|
||||
+ if (!grub_is_cli_disabled ())
|
||||
{
|
||||
- ret += grub_print_message_indented_real
|
||||
- (_("Press enter to boot the selected OS, "
|
||||
- "`e' to edit the commands before booting "
|
||||
- "or `c' for a command-line. ESC to return previous menu."),
|
||||
- STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- ret += grub_print_message_indented_real
|
||||
- (_("Press enter to boot the selected OS, "
|
||||
- "`e' to edit the commands before booting "
|
||||
- "or `c' for a command-line."),
|
||||
- STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
||||
+ if (nested)
|
||||
+ {
|
||||
+ ret += grub_print_message_indented_real
|
||||
+ (_("Press enter to boot the selected OS, "
|
||||
+ "`e' to edit the commands before booting "
|
||||
+ "or `c' for a command-line. ESC to return previous menu."),
|
||||
+ STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ ret += grub_print_message_indented_real
|
||||
+ (_("Press enter to boot the selected OS, "
|
||||
+ "`e' to edit the commands before booting "
|
||||
+ "or `c' for a command-line."),
|
||||
+ STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
diff --git a/include/grub/kernel.h b/include/grub/kernel.h
|
||||
index d3aafc884..9f3e2031f 100644
|
||||
--- a/include/grub/kernel.h
|
||||
+++ b/include/grub/kernel.h
|
||||
@@ -31,7 +31,8 @@ enum
|
||||
OBJ_TYPE_GPG_PUBKEY,
|
||||
OBJ_TYPE_X509_PUBKEY,
|
||||
OBJ_TYPE_DTB,
|
||||
- OBJ_TYPE_DISABLE_SHIM_LOCK
|
||||
+ OBJ_TYPE_DISABLE_SHIM_LOCK,
|
||||
+ OBJ_TYPE_DISABLE_CLI
|
||||
};
|
||||
|
||||
/* The module header. */
|
||||
diff --git a/include/grub/misc.h b/include/grub/misc.h
|
||||
index 1b35a167f..1578f36c3 100644
|
||||
--- a/include/grub/misc.h
|
||||
+++ b/include/grub/misc.h
|
||||
@@ -391,6 +391,8 @@ grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
|
||||
grub_uint64_t d,
|
||||
grub_uint64_t *r);
|
||||
|
||||
+extern bool EXPORT_FUNC(grub_is_cli_disabled) (void);
|
||||
+
|
||||
/* Must match softdiv group in gentpl.py. */
|
||||
#if !defined(GRUB_MACHINE_EMU) && (defined(__arm__) || defined(__ia64__) || \
|
||||
(defined(__riscv) && (__riscv_xlen == 32)))
|
||||
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
|
||||
index 38c6da73b..a4aac7b85 100644
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -72,6 +72,8 @@
|
||||
{ "appended-signature-size", GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,\
|
||||
"SIZE", 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), \
|
||||
1}, \
|
||||
+ { "disable-cli", GRUB_INSTALL_OPTIONS_DISABLE_CLI, 0, 0, \
|
||||
+ N_("disabled command line interface access"), 0 }, \
|
||||
{ "verbose", 'v', 0, 0, \
|
||||
N_("print verbose messages."), 1 }
|
||||
|
||||
@@ -136,7 +138,8 @@ enum grub_install_options {
|
||||
GRUB_INSTALL_OPTIONS_DTB,
|
||||
GRUB_INSTALL_OPTIONS_SBAT,
|
||||
GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK,
|
||||
- GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE
|
||||
+ GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,
|
||||
+ GRUB_INSTALL_OPTIONS_DISABLE_CLI
|
||||
};
|
||||
|
||||
extern char *grub_install_source_directory;
|
||||
@@ -199,7 +202,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
const struct grub_install_image_target_desc *image_target,
|
||||
int note, size_t appsig_size,
|
||||
grub_compression_t comp, const char *dtb_file,
|
||||
- const char *sbat_path, const int disable_shim_lock);
|
||||
+ const char *sbat_path, const int disable_shim_lock,
|
||||
+ const int disable_cli);
|
||||
|
||||
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 75fa03995..344dca664 100644
|
||||
--- a/util/grub-install-common.c
|
||||
+++ b/util/grub-install-common.c
|
||||
@@ -469,6 +469,7 @@ static char **x509keys;
|
||||
static size_t nx509keys;
|
||||
static grub_compression_t compression;
|
||||
static size_t appsig_size;
|
||||
+static int disable_cli;
|
||||
|
||||
int
|
||||
grub_install_parse (int key, char *arg)
|
||||
@@ -514,6 +515,9 @@ grub_install_parse (int key, char *arg)
|
||||
* (nx509keys + 1));
|
||||
x509keys[nx509keys++] = xstrdup (arg);
|
||||
return 1;
|
||||
+ case GRUB_INSTALL_OPTIONS_DISABLE_CLI:
|
||||
+ disable_cli = 1;
|
||||
+ return 1;
|
||||
|
||||
case GRUB_INSTALL_OPTIONS_VERBOSITY:
|
||||
verbosity++;
|
||||
@@ -707,12 +711,13 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
|
||||
|
||||
grub_util_info ("grub-mkimage --directory '%s' --prefix '%s' --output '%s'"
|
||||
" --format '%s' --compression '%s'"
|
||||
- " --appended-signature-size %zu%s%s%s\n",
|
||||
+ " --appended-signature-size %zu%s%s%s%s\n",
|
||||
dir, prefix, outname,
|
||||
mkimage_target, compnames[compression],
|
||||
appsig_size,
|
||||
note ? " --note" : "",
|
||||
- disable_shim_lock ? " --disable-shim-lock" : "", s);
|
||||
+ disable_shim_lock ? " --disable-shim-lock" : "",
|
||||
+ disable_cli ? " --disable-cli" : "", s);
|
||||
free (s);
|
||||
|
||||
tgt = grub_install_get_image_target (mkimage_target);
|
||||
@@ -724,7 +729,7 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
|
||||
pubkeys, npubkeys, x509keys, nx509keys,
|
||||
config_path, tgt,
|
||||
note, appsig_size, compression, dtb, sbat,
|
||||
- disable_shim_lock);
|
||||
+ disable_shim_lock, disable_cli);
|
||||
while (dc--)
|
||||
grub_install_pop_module ();
|
||||
}
|
||||
diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c
|
||||
index 7d61ef3ea..351a5e430 100644
|
||||
--- a/util/grub-mkimage.c
|
||||
+++ b/util/grub-mkimage.c
|
||||
@@ -84,6 +84,7 @@ static struct argp_option options[] = {
|
||||
{"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},
|
||||
+ {"disable-cli", GRUB_INSTALL_OPTIONS_DISABLE_CLI, 0, 0, N_("disable command line interface access"), 0},
|
||||
{"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
|
||||
{"appended-signature-size", 'S', N_("SIZE"), 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), 0},
|
||||
{ 0, 0, 0, 0, 0, 0 }
|
||||
@@ -133,6 +134,7 @@ struct arguments
|
||||
int note;
|
||||
int disable_shim_lock;
|
||||
size_t appsig_size;
|
||||
+ int disable_cli;
|
||||
const struct grub_install_image_target_desc *image_target;
|
||||
grub_compression_t comp;
|
||||
};
|
||||
@@ -259,6 +261,10 @@ argp_parser (int key, char *arg, struct argp_state *state)
|
||||
arguments->disable_shim_lock = 1;
|
||||
break;
|
||||
|
||||
+ case GRUB_INSTALL_OPTIONS_DISABLE_CLI:
|
||||
+ arguments->disable_cli = 1;
|
||||
+ break;
|
||||
+
|
||||
case 'v':
|
||||
verbosity++;
|
||||
break;
|
||||
@@ -347,7 +353,8 @@ main (int argc, char *argv[])
|
||||
arguments.image_target, arguments.note,
|
||||
arguments.appsig_size,
|
||||
arguments.comp, arguments.dtb,
|
||||
- arguments.sbat, arguments.disable_shim_lock);
|
||||
+ arguments.sbat, arguments.disable_shim_lock,
|
||||
+ arguments.disable_cli);
|
||||
|
||||
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 0737935fd..d6cc13475 100644
|
||||
--- a/util/mkimage.c
|
||||
+++ b/util/mkimage.c
|
||||
@@ -889,7 +889,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
const struct grub_install_image_target_desc *image_target,
|
||||
int note, size_t appsig_size, grub_compression_t comp,
|
||||
const char *dtb_path, const char *sbat_path,
|
||||
- int disable_shim_lock)
|
||||
+ int disable_shim_lock,
|
||||
+ int disable_cli)
|
||||
{
|
||||
char *kernel_img, *core_img;
|
||||
size_t total_module_size, core_size;
|
||||
@@ -964,6 +965,9 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
if (disable_shim_lock)
|
||||
total_module_size += sizeof (struct grub_module_header);
|
||||
|
||||
+ if (disable_cli)
|
||||
+ total_module_size += sizeof (struct grub_module_header);
|
||||
+
|
||||
if (config_path)
|
||||
{
|
||||
config_size = ALIGN_ADDR (grub_util_get_image_size (config_path) + 1);
|
||||
@@ -1130,6 +1134,16 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
offset += sizeof (*header);
|
||||
}
|
||||
|
||||
+ if (disable_cli)
|
||||
+ {
|
||||
+ struct grub_module_header *header;
|
||||
+
|
||||
+ header = (struct grub_module_header *) (kernel_img + offset);
|
||||
+ header->type = grub_host_to_target32 (OBJ_TYPE_DISABLE_CLI);
|
||||
+ header->size = grub_host_to_target32 (sizeof (*header));
|
||||
+ offset += sizeof (*header);
|
||||
+ }
|
||||
+
|
||||
if (config_path)
|
||||
{
|
||||
struct grub_module_header *header;
|
||||
--
|
||||
2.46.0
|
||||
|
||||
153
0001-disk-cryptodisk-Allow-user-to-retry-failed-passphras.patch
Normal file
153
0001-disk-cryptodisk-Allow-user-to-retry-failed-passphras.patch
Normal file
@@ -0,0 +1,153 @@
|
||||
From 386b59ddb42fa3f86ddfe557113b25c8fa16f88c Mon Sep 17 00:00:00 2001
|
||||
From: Forest <forestix@nom.one>
|
||||
Date: Mon, 6 May 2024 17:07:30 -0700
|
||||
Subject: [PATCH] disk/cryptodisk: Allow user to retry failed passphrase
|
||||
|
||||
Give the user a chance to re-enter their cryptodisk passphrase after a typo,
|
||||
rather than immediately failing (and likely dumping them into a GRUB shell).
|
||||
|
||||
By default, we allow 3 tries before giving up. A value in the
|
||||
cryptodisk_passphrase_tries environment variable will override this default.
|
||||
|
||||
The user can give up early by entering an empty passphrase, just as they
|
||||
could before this patch.
|
||||
|
||||
Signed-off-by: Forest <forestix@nom.one>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
docs/grub.texi | 9 +++++
|
||||
grub-core/disk/cryptodisk.c | 71 ++++++++++++++++++++++++++++---------
|
||||
2 files changed, 64 insertions(+), 16 deletions(-)
|
||||
|
||||
Index: grub-2.12/docs/grub.texi
|
||||
===================================================================
|
||||
--- grub-2.12.orig/docs/grub.texi
|
||||
+++ grub-2.12/docs/grub.texi
|
||||
@@ -3278,6 +3278,7 @@ These variables have special meaning to
|
||||
* color_normal::
|
||||
* config_directory::
|
||||
* config_file::
|
||||
+* cryptodisk_passphrase_tries::
|
||||
* debug::
|
||||
* default::
|
||||
* fallback::
|
||||
@@ -3450,6 +3451,14 @@ processed by commands @command{configfil
|
||||
(@pxref{normal}). It is restored to the previous value when command completes.
|
||||
|
||||
|
||||
+@node cryptodisk_passphrase_tries
|
||||
+@subsection cryptodisk_passphrase_tries
|
||||
+
|
||||
+When prompting the user for a cryptodisk passphrase, allow this many attempts
|
||||
+before giving up. Defaults to @samp{3} if unset or set to an invalid value.
|
||||
+(The user can give up early by entering an empty passphrase.)
|
||||
+
|
||||
+
|
||||
@node debug
|
||||
@subsection debug
|
||||
|
||||
Index: grub-2.12/grub-core/disk/cryptodisk.c
|
||||
===================================================================
|
||||
--- grub-2.12.orig/grub-core/disk/cryptodisk.c
|
||||
+++ grub-2.12/grub-core/disk/cryptodisk.c
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include <grub/cryptodisk.h>
|
||||
+#include <grub/env.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/dl.h>
|
||||
@@ -1202,37 +1203,76 @@ grub_cryptodisk_scan_device_real (const
|
||||
grub_free (part);
|
||||
}
|
||||
|
||||
- if (!cargs->key_len)
|
||||
+ if (cargs->key_len)
|
||||
{
|
||||
+ ret = cr->recover_key (source, dev, cargs);
|
||||
+ if (ret != GRUB_ERR_NONE)
|
||||
+ goto error;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /* Get the passphrase from the user, if no key data. */
|
||||
+ unsigned long tries = 3;
|
||||
+ const char *tries_env;
|
||||
+
|
||||
if (grub_errno)
|
||||
{
|
||||
grub_print_error ();
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
- /* Get the passphrase from the user, if no key data. */
|
||||
askpass = 1;
|
||||
- part = grub_partition_get_name (source->partition);
|
||||
- grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
|
||||
- source->partition != NULL ? "," : "",
|
||||
- part != NULL ? part : N_("UNKNOWN"), dev->uuid);
|
||||
- grub_free (part);
|
||||
-
|
||||
cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE);
|
||||
if (cargs->key_data == NULL)
|
||||
goto error;
|
||||
|
||||
- if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE))
|
||||
+ tries_env = grub_env_get ("cryptodisk_passphrase_tries");
|
||||
+ if (tries_env != NULL && tries_env[0] != '\0')
|
||||
{
|
||||
- grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied");
|
||||
- goto error;
|
||||
+ unsigned long tries_env_val;
|
||||
+ const char *p;
|
||||
+
|
||||
+ tries_env_val = grub_strtoul (tries_env, &p, 0);
|
||||
+ if (*p == '\0' && tries_env_val != ~0UL)
|
||||
+ tries = tries_env_val;
|
||||
+ else
|
||||
+ grub_printf_ (N_("Invalid cryptodisk_passphrase_tries value `%s'. Defaulting to %lu.\n"),
|
||||
+ tries_env,
|
||||
+ tries);
|
||||
}
|
||||
- cargs->key_len = grub_strlen ((char *) cargs->key_data);
|
||||
- }
|
||||
|
||||
- ret = cr->recover_key (source, dev, cargs);
|
||||
- if (ret != GRUB_ERR_NONE)
|
||||
- goto error;
|
||||
+ for (; tries > 0; tries--)
|
||||
+ {
|
||||
+ part = grub_partition_get_name (source->partition);
|
||||
+ grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
|
||||
+ source->partition != NULL ? "," : "",
|
||||
+ part != NULL ? part : N_("UNKNOWN"),
|
||||
+ dev->uuid);
|
||||
+ grub_free (part);
|
||||
+
|
||||
+ if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied");
|
||||
+ goto error;
|
||||
+ }
|
||||
+ cargs->key_len = grub_strlen ((char *) cargs->key_data);
|
||||
+
|
||||
+ ret = cr->recover_key (source, dev, cargs);
|
||||
+ if (ret == GRUB_ERR_NONE)
|
||||
+ break;
|
||||
+ if (ret != GRUB_ERR_ACCESS_DENIED || tries == 1)
|
||||
+ goto error;
|
||||
+ grub_puts_ (N_("Invalid passphrase."));
|
||||
+
|
||||
+ /*
|
||||
+ * Since recover_key() calls a function that returns grub_errno,
|
||||
+ * a leftover error value from a previously rejected passphrase
|
||||
+ * will trigger a phantom failure. We therefore clear it before
|
||||
+ * trying a new passphrase.
|
||||
+ */
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
ret = grub_cryptodisk_insert (dev, name, source);
|
||||
if (ret != GRUB_ERR_NONE)
|
||||
@@ -1,27 +0,0 @@
|
||||
From ad40cc47948a351a77bd0aa35286e1f1e66cc39f Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 24 Nov 2025 15:27:28 +0800
|
||||
Subject: [PATCH] editenv: create health_check_flag env var on RW raw block
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
util/grub-editenv.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/util/grub-editenv.c b/util/grub-editenv.c
|
||||
index ddecfab48..16ab32798 100644
|
||||
--- a/util/grub-editenv.c
|
||||
+++ b/util/grub-editenv.c
|
||||
@@ -468,7 +468,8 @@ set_variables (const char *name, int argc, char *argv[])
|
||||
|
||||
*(p++) = 0;
|
||||
|
||||
- if ((strcmp (argv[0], "next_entry") == 0) && envblk_on_block != NULL)
|
||||
+ if ((strcmp (argv[0], "next_entry") == 0 ||
|
||||
+ strcmp (argv[0], "health_checker_flag") == 0) && envblk_on_block != NULL)
|
||||
{
|
||||
if (grub_envblk_set (envblk_on_block, argv[0], p) == 0)
|
||||
grub_util_error ("%s", _("environment block too small"));
|
||||
--
|
||||
2.51.1
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
From 8b9234c7e482edd49a9b3377da8e48fbd54aab28 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 24 Sep 2024 18:59:34 +0800
|
||||
Subject: [PATCH] efinet: Skip virtual VLAN devices during card enumeration
|
||||
|
||||
Similar to the fix in commit "c52ae4057 efinet: skip virtual IPv4 and
|
||||
IPv6 devices during card enumeration", the UEFI PXE driver creates
|
||||
additional VLAN child devices when a VLAN ID is configured on a network
|
||||
interface associated with a physical NIC. These virtual VLAN devices
|
||||
must be skipped during card enumeration to ensure that the subsequent
|
||||
SNP exclusive open operation targets the correct physical card
|
||||
instances, otherwise packet transfer would fail.
|
||||
|
||||
Example device path with VLAN nodes:
|
||||
|
||||
/MAC(123456789ABC,0x1)/Vlan(20)/IPv4(0.0.0.0,0x0,DHCP,0.0.0.0,0.0.0.0,0.0.0.0)
|
||||
|
||||
Signed-Off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/net/drivers/efi/efinet.c | 12 +++++++++++-
|
||||
1 file changed, 11 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
|
||||
index 720b5d0e1..3d0bf34fa 100644
|
||||
--- a/grub-core/net/drivers/efi/efinet.c
|
||||
+++ b/grub-core/net/drivers/efi/efinet.c
|
||||
@@ -280,7 +280,8 @@ grub_efinet_findcards (void)
|
||||
|| GRUB_EFI_DEVICE_PATH_SUBTYPE (child) == GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)
|
||||
&& parent
|
||||
&& GRUB_EFI_DEVICE_PATH_TYPE (parent) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
|
||||
- && GRUB_EFI_DEVICE_PATH_SUBTYPE (parent) == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE)
|
||||
+ && (GRUB_EFI_DEVICE_PATH_SUBTYPE (parent) == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE
|
||||
+ || GRUB_EFI_DEVICE_PATH_SUBTYPE (parent) == GRUB_EFI_VLAN_DEVICE_PATH_SUBTYPE))
|
||||
continue;
|
||||
|
||||
net = grub_efi_open_protocol (*handle, &net_io_guid,
|
||||
@@ -810,6 +811,15 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
|
||||
dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
||||
dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||
dup_ldp->length = sizeof (*dup_ldp);
|
||||
+
|
||||
+ dup_ldp = grub_efi_find_last_device_path (dup_dp);
|
||||
+ if (GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_VLAN_DEVICE_PATH_SUBTYPE)
|
||||
+ {
|
||||
+ dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
||||
+ dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||
+ dup_ldp->length = sizeof (*dup_ldp);
|
||||
+ }
|
||||
+
|
||||
match = grub_efi_compare_device_paths (dup_dp, cdp) == 0;
|
||||
grub_free (dup_dp);
|
||||
if (!match)
|
||||
--
|
||||
2.46.1
|
||||
|
||||
48
0001-fix-grub-screen-filled-with-post-screen-artifects.patch
Normal file
48
0001-fix-grub-screen-filled-with-post-screen-artifects.patch
Normal file
@@ -0,0 +1,48 @@
|
||||
From 44f3c7978a8ac5cc94a5c885ac9e983ba2980f5e Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Wed, 29 May 2024 12:32:32 +0800
|
||||
Subject: [PATCH] fix grub screen filled with post screen artifects
|
||||
|
||||
---
|
||||
grub-core/normal/menu.c | 7 ++++---
|
||||
grub-core/term/efi/console.c | 2 +-
|
||||
2 files changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
|
||||
index 1df2638d7..b11b28e0d 100644
|
||||
--- a/grub-core/normal/menu.c
|
||||
+++ b/grub-core/normal/menu.c
|
||||
@@ -975,13 +975,14 @@ show_menu (grub_menu_t menu, int nested, int autobooted)
|
||||
if (! e)
|
||||
continue; /* Menu is empty. */
|
||||
|
||||
- grub_cls ();
|
||||
-
|
||||
if (auto_boot)
|
||||
grub_menu_execute_with_fallback (menu, e, autobooted,
|
||||
&execution_callback, ¬ify_boot);
|
||||
else
|
||||
- grub_menu_execute_entry (e, 0);
|
||||
+ {
|
||||
+ grub_cls ();
|
||||
+ grub_menu_execute_entry (e, 0);
|
||||
+ }
|
||||
if (autobooted)
|
||||
break;
|
||||
}
|
||||
diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c
|
||||
index bb587f39d..258b52737 100644
|
||||
--- a/grub-core/term/efi/console.c
|
||||
+++ b/grub-core/term/efi/console.c
|
||||
@@ -432,7 +432,7 @@ grub_console_cls (struct grub_term_output *term __attribute__ ((unused)))
|
||||
grub_efi_simple_text_output_interface_t *o;
|
||||
grub_efi_int32_t orig_attr;
|
||||
|
||||
- if (grub_efi_is_finished || text_mode != GRUB_TEXT_MODE_AVAILABLE)
|
||||
+ if (grub_prepare_for_text_output (term) != GRUB_ERR_NONE)
|
||||
return;
|
||||
|
||||
o = grub_efi_system_table->con_out;
|
||||
--
|
||||
2.45.1
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
From 7a8d9a29358fbe9eb5dcc70e63c417c4f3cd5068 Mon Sep 17 00:00:00 2001
|
||||
From: "Darrick J. Wong" <djwong@kernel.org>
|
||||
Date: Mon, 3 Feb 2025 15:41:22 -0800
|
||||
Subject: [PATCH 1/3] fs/xfs: Add new superblock features added in Linux
|
||||
6.12/6.13
|
||||
|
||||
The Linux port of XFS added a few new features in 2024. The existing
|
||||
GRUB driver doesn't attempt to read or write any of the new metadata,
|
||||
so, all three can be added to the incompat allowlist.
|
||||
|
||||
On the occasion align XFS_SB_FEAT_INCOMPAT_NREXT64 value.
|
||||
|
||||
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/fs/xfs.c | 19 +++++++++++++++++--
|
||||
1 file changed, 17 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
|
||||
index c17e54e447..e3a69fe498 100644
|
||||
--- a/grub-core/fs/xfs.c
|
||||
+++ b/grub-core/fs/xfs.c
|
||||
@@ -88,7 +88,10 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */
|
||||
#define XFS_SB_FEAT_INCOMPAT_BIGTIME (1 << 3) /* large timestamps */
|
||||
#define XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR (1 << 4) /* needs xfs_repair */
|
||||
-#define XFS_SB_FEAT_INCOMPAT_NREXT64 (1 << 5) /* large extent counters */
|
||||
+#define XFS_SB_FEAT_INCOMPAT_NREXT64 (1 << 5) /* large extent counters */
|
||||
+#define XFS_SB_FEAT_INCOMPAT_EXCHRANGE (1 << 6) /* exchangerange supported */
|
||||
+#define XFS_SB_FEAT_INCOMPAT_PARENT (1 << 7) /* parent pointers */
|
||||
+#define XFS_SB_FEAT_INCOMPAT_METADIR (1 << 8) /* metadata dir tree */
|
||||
|
||||
/*
|
||||
* Directory entries with ftype are explicitly handled by GRUB code.
|
||||
@@ -98,6 +101,15 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
*
|
||||
* We do not currently verify metadata UUID, so it is safe to read filesystems
|
||||
* with the XFS_SB_FEAT_INCOMPAT_META_UUID feature.
|
||||
+ *
|
||||
+ * We do not currently replay the log, so it is safe to read filesystems
|
||||
+ * with the XFS_SB_FEAT_INCOMPAT_EXCHRANGE feature.
|
||||
+ *
|
||||
+ * We do not currently read directory parent pointers, so it is safe to read
|
||||
+ * filesystems with the XFS_SB_FEAT_INCOMPAT_PARENT feature.
|
||||
+ *
|
||||
+ * We do not currently look at realtime or quota metadata, so it is safe to
|
||||
+ * read filesystems with the XFS_SB_FEAT_INCOMPAT_METADIR feature.
|
||||
*/
|
||||
#define XFS_SB_FEAT_INCOMPAT_SUPPORTED \
|
||||
(XFS_SB_FEAT_INCOMPAT_FTYPE | \
|
||||
@@ -105,7 +117,10 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
XFS_SB_FEAT_INCOMPAT_META_UUID | \
|
||||
XFS_SB_FEAT_INCOMPAT_BIGTIME | \
|
||||
XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR | \
|
||||
- XFS_SB_FEAT_INCOMPAT_NREXT64)
|
||||
+ XFS_SB_FEAT_INCOMPAT_NREXT64 | \
|
||||
+ XFS_SB_FEAT_INCOMPAT_EXCHRANGE | \
|
||||
+ XFS_SB_FEAT_INCOMPAT_PARENT | \
|
||||
+ XFS_SB_FEAT_INCOMPAT_METADIR)
|
||||
|
||||
struct grub_xfs_sblock
|
||||
{
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
From 045aae8fe7238aabc217700df4d17d83b7d891f3 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 23 Jan 2024 12:46:16 +0800
|
||||
Subject: [PATCH] fs/xfs: always verify the total number of entries is not zero
|
||||
|
||||
---
|
||||
grub-core/fs/xfs.c | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
|
||||
index bc2224dbb..1ce5fa4fc 100644
|
||||
--- a/grub-core/fs/xfs.c
|
||||
+++ b/grub-core/fs/xfs.c
|
||||
@@ -900,6 +900,8 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
{
|
||||
struct grub_xfs_dir2_entry *direntry =
|
||||
grub_xfs_first_de(dir->data, dirblock);
|
||||
+ struct grub_xfs_dirblock_tail *tail = grub_xfs_dir_tail (dir->data, dirblock);
|
||||
+
|
||||
int entries = -1;
|
||||
char *end = dirblock + dirblk_size;
|
||||
|
||||
@@ -918,18 +920,16 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
*/
|
||||
if (dir->inode.nextents == grub_cpu_to_be32_compile_time (1))
|
||||
{
|
||||
- struct grub_xfs_dirblock_tail *tail = grub_xfs_dir_tail (dir->data, dirblock);
|
||||
-
|
||||
end = (char *) tail;
|
||||
|
||||
/* Subtract the space used by leaf nodes. */
|
||||
end -= grub_be_to_cpu32 (tail->leaf_count) * sizeof (struct grub_xfs_dir_leaf_entry);
|
||||
+ }
|
||||
|
||||
- entries = grub_be_to_cpu32 (tail->leaf_count) - grub_be_to_cpu32 (tail->leaf_stale);
|
||||
+ entries = grub_be_to_cpu32 (tail->leaf_count) - grub_be_to_cpu32 (tail->leaf_stale);
|
||||
|
||||
- if (!entries)
|
||||
- continue;
|
||||
- }
|
||||
+ if (!entries)
|
||||
+ continue;
|
||||
|
||||
/* Iterate over all entries within this block. */
|
||||
while ((char *) direntry < (char *) end)
|
||||
--
|
||||
2.43.0
|
||||
|
||||
113
0001-ieee1275-Use-net-config-for-boot-location-instead-of.patch
Normal file
113
0001-ieee1275-Use-net-config-for-boot-location-instead-of.patch
Normal file
@@ -0,0 +1,113 @@
|
||||
From eae4fc64a16cb58733afca09e70a09e51d405a9d Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 30 Sep 2025 14:44:02 +0800
|
||||
Subject: [PATCH] ieee1275: Use net config for boot location instead of
|
||||
firmware bootpath
|
||||
|
||||
On network boots, grub_ieee1275_net_config() is used to determine the
|
||||
boot device, but the path continues to be taken from the Open Firmware
|
||||
/chosen/bootpath property. This assumes the device node follows the
|
||||
generic IEEE-1275 syntax, which is not always the case. Different
|
||||
drivers may extend or redefine the format, and GRUB may then
|
||||
misinterpret the argument as a filename and set $prefix incorrectly.
|
||||
|
||||
The generic Open Firmware device path format is:
|
||||
|
||||
device-name[:device-argument]
|
||||
device-argument := [partition][,[filename]]
|
||||
|
||||
For example, a bootpath such as:
|
||||
|
||||
/vdevice/l-lan@30000002:speed=auto,duplex=auto,1.2.243.345,,9.8.76.543,1.2.34.5,5,5,255.255.255.0,512
|
||||
|
||||
does not follow this form. The section after the colon (the
|
||||
device-argument) contains driver-specific options and network
|
||||
parameters, not a valid filename. GRUB interprets this string as a
|
||||
filename, which results in $prefix being set to "/", effectively losing
|
||||
the intended boot directory.
|
||||
|
||||
The firmware is not at fault here, since interpretation of device nodes
|
||||
is driver-specific. Instead, GRUB should use the filename provided in
|
||||
the cached DHCP packet, which is consistent and reliable. This is also
|
||||
the same mechanism already used on UEFI and legacy BIOS platforms.
|
||||
|
||||
This patch updates grub_machine_get_bootlocation() to prefer the result
|
||||
from grub_ieee1275_net_config() when complete, and only fall back to the
|
||||
firmware bootpath otherwise.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/kern/ieee1275/init.c | 28 +++++++++++++++++++++-------
|
||||
1 file changed, 21 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
|
||||
index 45f787eff..802a34f07 100644
|
||||
--- a/grub-core/kern/ieee1275/init.c
|
||||
+++ b/grub-core/kern/ieee1275/init.c
|
||||
@@ -153,9 +153,11 @@ void (*grub_ieee1275_net_config) (const char *dev, char **device, char **path,
|
||||
void
|
||||
grub_machine_get_bootlocation (char **device, char **path)
|
||||
{
|
||||
- char *bootpath;
|
||||
+ char *bootpath = NULL;
|
||||
char *filename;
|
||||
- char *type;
|
||||
+ char *type = NULL;
|
||||
+ char *ret_device = NULL;
|
||||
+ char *ret_path = NULL;
|
||||
|
||||
bootpath = grub_ieee1275_get_boot_dev ();
|
||||
if (! bootpath)
|
||||
@@ -171,7 +173,7 @@ grub_machine_get_bootlocation (char **device, char **path)
|
||||
dev = grub_ieee1275_get_aliasdevname (bootpath);
|
||||
canon = grub_ieee1275_canonicalise_devname (dev);
|
||||
if (! canon)
|
||||
- return;
|
||||
+ goto done;
|
||||
ptr = canon + grub_strlen (canon) - 1;
|
||||
while (ptr > canon && (*ptr == ',' || *ptr == ':'))
|
||||
ptr--;
|
||||
@@ -179,13 +181,17 @@ grub_machine_get_bootlocation (char **device, char **path)
|
||||
*ptr = 0;
|
||||
|
||||
if (grub_ieee1275_net_config)
|
||||
- grub_ieee1275_net_config (canon, device, path, bootpath);
|
||||
+ grub_ieee1275_net_config (canon, &ret_device, &ret_path, bootpath);
|
||||
grub_free (dev);
|
||||
grub_free (canon);
|
||||
+
|
||||
+ /* Use path from net config if it is provided by cached DHCP info */
|
||||
+ if (ret_path != NULL)
|
||||
+ goto done;
|
||||
+ /* Fall through to use firmware bootpath */
|
||||
}
|
||||
else
|
||||
- *device = grub_ieee1275_encode_devname (bootpath);
|
||||
- grub_free (type);
|
||||
+ ret_device = grub_ieee1275_encode_devname (bootpath);
|
||||
|
||||
filename = grub_ieee1275_get_filename (bootpath);
|
||||
if (filename)
|
||||
@@ -198,10 +204,18 @@ grub_machine_get_bootlocation (char **device, char **path)
|
||||
*lastslash = '\0';
|
||||
grub_translate_ieee1275_path (filename);
|
||||
|
||||
- *path = filename;
|
||||
+ ret_path = filename;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ done:
|
||||
+ grub_free (type);
|
||||
grub_free (bootpath);
|
||||
+
|
||||
+ if (device != NULL)
|
||||
+ *device = ret_device;
|
||||
+ if (path != NULL)
|
||||
+ *path = ret_path;
|
||||
}
|
||||
|
||||
/* Claim some available memory in the first /memory node. */
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
From 5025c64afc876d91d3947ce07bb59ffe9af7209d Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Tue, 25 Feb 2025 19:14:24 +0530
|
||||
Subject: [PATCH 1/9] ieee1275: adding failure check condition on
|
||||
/ibm,secure-boot
|
||||
|
||||
failure check condition is missing while finding device "/" and
|
||||
get property "ibm,secure-boot". So, adding the failure check condition.
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
---
|
||||
grub-core/kern/ieee1275/init.c | 20 ++++++++++++++------
|
||||
1 file changed, 14 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
|
||||
index f86543da0d..0e1cbf24c3 100644
|
||||
--- a/grub-core/kern/ieee1275/init.c
|
||||
+++ b/grub-core/kern/ieee1275/init.c
|
||||
@@ -987,12 +987,20 @@ grub_get_ieee1275_secure_boot (void)
|
||||
int rc;
|
||||
grub_uint32_t is_sb;
|
||||
|
||||
- grub_ieee1275_finddevice ("/", &root);
|
||||
-
|
||||
- rc = grub_ieee1275_get_integer_property (root, "ibm,secure-boot", &is_sb,
|
||||
- sizeof (is_sb), 0);
|
||||
+ if (grub_ieee1275_finddevice ("/", &root))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_UNKNOWN_DEVICE, "couldn't find / node");
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
- /* ibm,secure-boot:
|
||||
+ rc = grub_ieee1275_get_integer_property (root, "ibm,secure-boot", &is_sb, sizeof (is_sb), 0);
|
||||
+ if (rc < 0)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_UNKNOWN_DEVICE, "couldn't examine /ibm,secure-boot property");
|
||||
+ return;
|
||||
+ }
|
||||
+ /*
|
||||
+ * ibm,secure-boot:
|
||||
* 0 - disabled
|
||||
* 1 - audit
|
||||
* 2 - enforce
|
||||
@@ -1000,7 +1008,7 @@ grub_get_ieee1275_secure_boot (void)
|
||||
*
|
||||
* We only support enforce.
|
||||
*/
|
||||
- if (rc >= 0 && is_sb >= 2)
|
||||
+ if (is_sb >= 2)
|
||||
grub_lockdown ();
|
||||
}
|
||||
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@@ -22,17 +22,19 @@ Signed-off-by: Mukesh Kumar Chaurasiya <mchauras@linux.ibm.com>
|
||||
grub-core/disk/ieee1275/ofdisk.c | 80 +++++++++++++++++++++++++++++++-
|
||||
2 files changed, 86 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index d3f0f6577..c8ebc083d 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -3323,6 +3323,7 @@
|
||||
@@ -3315,6 +3315,7 @@ These variables have special meaning to GRUB.
|
||||
* net_default_ip::
|
||||
* net_default_mac::
|
||||
* net_default_server::
|
||||
+* ofdisk_retry_timeout::
|
||||
* pager::
|
||||
* prefix::
|
||||
* pxe_default_server::
|
||||
@@ -3783,6 +3784,13 @@
|
||||
* pxe_blksize::
|
||||
@@ -3744,6 +3745,13 @@ The default is the value of @samp{color_normal} (@pxref{color_normal}).
|
||||
@xref{Network}.
|
||||
|
||||
|
||||
@@ -46,19 +48,21 @@ Signed-off-by: Mukesh Kumar Chaurasiya <mchauras@linux.ibm.com>
|
||||
@node pager
|
||||
@subsection pager
|
||||
|
||||
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
|
||||
index 7197d5401..f96bbb58c 100644
|
||||
--- a/grub-core/disk/ieee1275/ofdisk.c
|
||||
+++ b/grub-core/disk/ieee1275/ofdisk.c
|
||||
@@ -25,6 +25,9 @@
|
||||
@@ -24,6 +24,9 @@
|
||||
#include <grub/ieee1275/ofdisk.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/safemath.h>
|
||||
+#include <grub/env.h>
|
||||
+
|
||||
+#define RETRY_DEFAULT_TIMEOUT 15
|
||||
|
||||
static char *last_devpath;
|
||||
static grub_ieee1275_ihandle_t last_ihandle;
|
||||
@@ -822,7 +825,7 @@
|
||||
@@ -783,7 +786,7 @@ compute_dev_path (const char *name)
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
@@ -67,7 +71,7 @@ Signed-off-by: Mukesh Kumar Chaurasiya <mchauras@linux.ibm.com>
|
||||
{
|
||||
grub_ieee1275_phandle_t dev;
|
||||
char *devpath;
|
||||
@@ -918,6 +921,56 @@
|
||||
@@ -879,6 +882,56 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -124,7 +128,7 @@ Signed-off-by: Mukesh Kumar Chaurasiya <mchauras@linux.ibm.com>
|
||||
static void
|
||||
grub_ofdisk_close (grub_disk_t disk)
|
||||
{
|
||||
@@ -954,7 +1007,7 @@
|
||||
@@ -915,7 +968,7 @@ grub_ofdisk_prepare (grub_disk_t disk, grub_disk_addr_t sector)
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
@@ -133,10 +137,11 @@ Signed-off-by: Mukesh Kumar Chaurasiya <mchauras@linux.ibm.com>
|
||||
grub_size_t size, char *buf)
|
||||
{
|
||||
grub_err_t err;
|
||||
@@ -974,6 +1027,29 @@
|
||||
@@ -934,6 +987,29 @@ grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
+static grub_err_t
|
||||
+grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||
+ grub_size_t size, char *buf)
|
||||
+{
|
||||
@@ -159,7 +164,9 @@ Signed-off-by: Mukesh Kumar Chaurasiya <mchauras@linux.ibm.com>
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
static grub_err_t
|
||||
grub_ofdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
|
||||
grub_size_t size, const char *buf)
|
||||
{
|
||||
--
|
||||
2.41.0
|
||||
|
||||
|
||||
45
0001-kern-file-Call-grub_dl_unref-after-fs-fs_close.patch
Normal file
45
0001-kern-file-Call-grub_dl_unref-after-fs-fs_close.patch
Normal file
@@ -0,0 +1,45 @@
|
||||
From 12d518fd50ed4787d3cc4bafcc11e14139dc5d76 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Frauendorfer | Miray Software <tf@miray.de>
|
||||
Date: Wed, 7 May 2025 16:15:22 +0200
|
||||
Subject: [PATCH 1/7] kern/file: Call grub_dl_unref() after fs->fs_close()
|
||||
|
||||
With commit 16f196874 (kern/file: Implement filesystem reference
|
||||
counting) files hold a reference to their file systems.
|
||||
|
||||
When closing a file in grub_file_close() we should not expect
|
||||
file->fs to stay valid after calling grub_dl_unref() on file->fs->mod.
|
||||
So, grub_dl_unref() should be called after file->fs->fs_close().
|
||||
|
||||
Fixes: CVE-2025-54771
|
||||
Fixes: 16f196874 (kern/file: Implement filesystem reference counting)
|
||||
|
||||
Reported-by: Thomas Frauendorfer | Miray Software <tf@miray.de>
|
||||
Signed-off-by: Thomas Frauendorfer | Miray Software <tf@miray.de>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/kern/file.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c
|
||||
index 7217a6ea7..dce29bedd 100644
|
||||
--- a/grub-core/kern/file.c
|
||||
+++ b/grub-core/kern/file.c
|
||||
@@ -201,12 +201,12 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len)
|
||||
grub_err_t
|
||||
grub_file_close (grub_file_t file)
|
||||
{
|
||||
- if (file->fs->mod)
|
||||
- grub_dl_unref (file->fs->mod);
|
||||
-
|
||||
if (file->fs->fs_close)
|
||||
(file->fs->fs_close) (file);
|
||||
|
||||
+ if (file->fs->mod)
|
||||
+ grub_dl_unref (file->fs->mod);
|
||||
+
|
||||
if (file->device)
|
||||
grub_device_close (file->device);
|
||||
grub_free (file->name);
|
||||
--
|
||||
2.51.1
|
||||
|
||||
122
0001-kern-ieee1275-init-Add-IEEE-1275-Radix-support-for-K.patch
Normal file
122
0001-kern-ieee1275-init-Add-IEEE-1275-Radix-support-for-K.patch
Normal file
@@ -0,0 +1,122 @@
|
||||
From ba65f46ffd2952a3f69d85a4534b1e55291f080c Mon Sep 17 00:00:00 2001
|
||||
From: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Date: Thu, 23 May 2024 18:43:14 +0530
|
||||
Subject: [PATCH] kern/ieee1275/init: Add IEEE 1275 Radix support for KVM on
|
||||
Power
|
||||
|
||||
This patch adds support for Radix, Xive and Radix_gtse in Options
|
||||
vector5 which is required for KVM LPARs. KVM LPARs ONLY support
|
||||
Radix and not the Hash. Not enabling Radix on any PowerVM KVM LPARs
|
||||
will result in boot failure.
|
||||
|
||||
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/kern/ieee1275/init.c | 63 +++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 62 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
|
||||
index bb800b275..8e08e5dd5 100644
|
||||
--- a/grub-core/kern/ieee1275/init.c
|
||||
+++ b/grub-core/kern/ieee1275/init.c
|
||||
@@ -115,6 +115,16 @@ grub_addr_t grub_ieee1275_original_stack;
|
||||
#define DRC_INFO 0x40
|
||||
#define BYTE22 (DY_MEM_V2 | DRC_INFO)
|
||||
|
||||
+/* For ibm,arch-vec-5-platform-support. */
|
||||
+#define XIVE_INDEX 0x17
|
||||
+#define MMU_INDEX 0x18
|
||||
+#define RADIX_GTSE_INDEX 0x1a
|
||||
+#define RADIX_ENABLED 0x40
|
||||
+#define XIVE_ENABLED 0x40
|
||||
+#define HASH_ENABLED 0x00
|
||||
+#define MAX_SUPPORTED 0xC0
|
||||
+#define RADIX_GTSE_ENABLED 0x40
|
||||
+
|
||||
void
|
||||
grub_exit (void)
|
||||
{
|
||||
@@ -740,6 +750,10 @@ struct option_vector5
|
||||
grub_uint32_t platform_facilities;
|
||||
grub_uint8_t sub_processors;
|
||||
grub_uint8_t byte22;
|
||||
+ grub_uint8_t xive;
|
||||
+ grub_uint8_t mmu;
|
||||
+ grub_uint8_t hpt_ext;
|
||||
+ grub_uint8_t radix_gtse;
|
||||
} GRUB_PACKED;
|
||||
|
||||
struct pvr_entry
|
||||
@@ -778,6 +792,13 @@ grub_ieee1275_ibm_cas (void)
|
||||
{
|
||||
int rc;
|
||||
grub_ieee1275_ihandle_t root;
|
||||
+ grub_uint8_t ibm_arch_platform_support[8];
|
||||
+ grub_ssize_t actual;
|
||||
+ grub_uint8_t xive_support = 0;
|
||||
+ grub_uint8_t mmu_support = 0;
|
||||
+ grub_uint8_t radix_gtse_support = 0;
|
||||
+ int i = 0;
|
||||
+ int prop_len = 8;
|
||||
struct cas_args
|
||||
{
|
||||
struct grub_ieee1275_common_hdr common;
|
||||
@@ -786,6 +807,46 @@ grub_ieee1275_ibm_cas (void)
|
||||
grub_ieee1275_cell_t cas_addr;
|
||||
grub_ieee1275_cell_t result;
|
||||
} args;
|
||||
+
|
||||
+ grub_ieee1275_get_integer_property (grub_ieee1275_chosen,
|
||||
+ "ibm,arch-vec-5-platform-support",
|
||||
+ (grub_uint32_t *) ibm_arch_platform_support,
|
||||
+ sizeof (ibm_arch_platform_support),
|
||||
+ &actual);
|
||||
+
|
||||
+ for (i = 0; i < prop_len; i++)
|
||||
+ {
|
||||
+ switch (ibm_arch_platform_support[i])
|
||||
+ {
|
||||
+ case XIVE_INDEX:
|
||||
+ if (ibm_arch_platform_support[i + 1] & MAX_SUPPORTED)
|
||||
+ xive_support = XIVE_ENABLED;
|
||||
+ else
|
||||
+ xive_support = 0;
|
||||
+ break;
|
||||
+
|
||||
+ case MMU_INDEX:
|
||||
+ if (ibm_arch_platform_support[i + 1] & MAX_SUPPORTED)
|
||||
+ mmu_support = RADIX_ENABLED;
|
||||
+ else
|
||||
+ mmu_support = HASH_ENABLED;
|
||||
+ break;
|
||||
+
|
||||
+ case RADIX_GTSE_INDEX:
|
||||
+ if (mmu_support == RADIX_ENABLED)
|
||||
+ radix_gtse_support = ibm_arch_platform_support[i + 1] & RADIX_GTSE_ENABLED;
|
||||
+ else
|
||||
+ radix_gtse_support = 0;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ /* Ignoring the other indexes of ibm,arch-vec-5-platform-support. */
|
||||
+ break;
|
||||
+ }
|
||||
+ /* Skipping the property value. */
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
struct cas_vector vector =
|
||||
{
|
||||
.pvr_list = { { 0x00000000, 0xffffffff } }, /* any processor */
|
||||
@@ -802,7 +863,7 @@ grub_ieee1275_ibm_cas (void)
|
||||
.vec4 = 0x0001, /* set required minimum capacity % to the lowest value */
|
||||
.vec5_size = 1 + sizeof (struct option_vector5) - 2,
|
||||
.vec5 = {
|
||||
- 0, BYTE2, 0, CMO, ASSOCIATIVITY, BIN_OPTS, 0, 0, MAX_CPU, 0, 0, PLATFORM_FACILITIES, SUB_PROCESSORS, BYTE22
|
||||
+ 0, BYTE2, 0, CMO, ASSOCIATIVITY, BIN_OPTS, 0, 0, MAX_CPU, 0, 0, PLATFORM_FACILITIES, SUB_PROCESSORS, BYTE22, xive_support, mmu_support, 0, radix_gtse_support
|
||||
}
|
||||
};
|
||||
|
||||
--
|
||||
2.47.0
|
||||
|
||||
116
0001-kern-misc-Implement-faster-grub_memcpy-for-aligned-b.patch
Normal file
116
0001-kern-misc-Implement-faster-grub_memcpy-for-aligned-b.patch
Normal file
@@ -0,0 +1,116 @@
|
||||
From 1fbd2a278cfc645adc45c0e1357e58bcd1909f8d Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Thu, 28 Aug 2025 15:03:35 +0800
|
||||
Subject: [PATCH] kern/misc: Implement faster grub_memcpy() for aligned buffers
|
||||
|
||||
When both "dest" and "src" are aligned, copying the data in chunks
|
||||
(unsigned long) is more efficient than a byte-by-byte copy.
|
||||
|
||||
Also tweak '__aeabi_memcpy()', '__aeabi_memcpy4()', and
|
||||
'__aeabi_memcpy8()', since 'grub_memcpy()' is not inline anymore.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
grub-core/kern/compiler-rt.c | 8 ++++----
|
||||
grub-core/kern/misc.c | 30 ++++++++++++++++++++++++++++++
|
||||
include/grub/misc.h | 8 +-------
|
||||
3 files changed, 35 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/compiler-rt.c b/grub-core/kern/compiler-rt.c
|
||||
index eda689a0c..8f3865e95 100644
|
||||
--- a/grub-core/kern/compiler-rt.c
|
||||
+++ b/grub-core/kern/compiler-rt.c
|
||||
@@ -24,7 +24,7 @@
|
||||
void * GRUB_BUILTIN_ATTR
|
||||
memcpy (void *dest, const void *src, grub_size_t n)
|
||||
{
|
||||
- return grub_memmove (dest, src, n);
|
||||
+ return grub_memcpy (dest, src, n);
|
||||
}
|
||||
void * GRUB_BUILTIN_ATTR
|
||||
memmove (void *dest, const void *src, grub_size_t n)
|
||||
@@ -372,11 +372,11 @@ grub_int32_t
|
||||
__aeabi_idiv (grub_int32_t a, grub_int32_t b)
|
||||
__attribute__ ((alias ("__divsi3")));
|
||||
void *__aeabi_memcpy (void *dest, const void *src, grub_size_t n)
|
||||
- __attribute__ ((alias ("grub_memcpy")));
|
||||
+ __attribute__ ((alias ("memcpy")));
|
||||
void *__aeabi_memcpy4 (void *dest, const void *src, grub_size_t n)
|
||||
- __attribute__ ((alias ("grub_memcpy")));
|
||||
+ __attribute__ ((alias ("memcpy")));
|
||||
void *__aeabi_memcpy8 (void *dest, const void *src, grub_size_t n)
|
||||
- __attribute__ ((alias ("grub_memcpy")));
|
||||
+ __attribute__ ((alias ("memcpy")));
|
||||
void *__aeabi_memset (void *s, int c, grub_size_t n)
|
||||
__attribute__ ((alias ("memset")));
|
||||
|
||||
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
|
||||
index 2b7922393..016932583 100644
|
||||
--- a/grub-core/kern/misc.c
|
||||
+++ b/grub-core/kern/misc.c
|
||||
@@ -99,6 +99,36 @@ grub_memmove (void *dest, const void *src, grub_size_t n)
|
||||
return dest;
|
||||
}
|
||||
|
||||
+static void *
|
||||
+__memcpy_aligned (void *dest, const void *src, grub_size_t n)
|
||||
+{
|
||||
+ unsigned long *dw = (unsigned long *) dest;
|
||||
+ const unsigned long *sw = (const unsigned long *) src;
|
||||
+ grub_uint8_t *d;
|
||||
+ const grub_uint8_t *s;
|
||||
+
|
||||
+ for (; n >= sizeof (unsigned long); n -= sizeof (unsigned long))
|
||||
+ *dw++ = *sw++;
|
||||
+
|
||||
+ d = (grub_uint8_t *) dw;
|
||||
+ s = (const grub_uint8_t *) sw;
|
||||
+ for (; n > 0; n--)
|
||||
+ *d++ = *s++;
|
||||
+
|
||||
+ return dest;
|
||||
+}
|
||||
+
|
||||
+void *
|
||||
+grub_memcpy (void *dest, const void *src, grub_size_t n)
|
||||
+{
|
||||
+ /* Check if 'dest' and 'src' are aligned */
|
||||
+ if (((grub_addr_t) dest & (sizeof (unsigned long) - 1)) == 0 &&
|
||||
+ ((grub_addr_t) src & (sizeof (unsigned long) - 1)) == 0)
|
||||
+ return __memcpy_aligned (dest, src, n);
|
||||
+
|
||||
+ return grub_memmove (dest, src, n);
|
||||
+}
|
||||
+
|
||||
char *
|
||||
grub_strcpy (char *dest, const char *src)
|
||||
{
|
||||
diff --git a/include/grub/misc.h b/include/grub/misc.h
|
||||
index e087e7b3e..b6b14ca55 100644
|
||||
--- a/include/grub/misc.h
|
||||
+++ b/include/grub/misc.h
|
||||
@@ -38,6 +38,7 @@
|
||||
#define grub_dprintf(condition, ...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, __VA_ARGS__)
|
||||
|
||||
void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n);
|
||||
+void *EXPORT_FUNC(grub_memcpy) (void *dest, const void *src, grub_size_t n);
|
||||
char *EXPORT_FUNC(grub_strcpy) (char *dest, const char *src);
|
||||
|
||||
static inline char *
|
||||
@@ -103,13 +104,6 @@ grub_strlcpy (char *dest, const char *src, grub_size_t size)
|
||||
return res;
|
||||
}
|
||||
|
||||
-/* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */
|
||||
-static inline void *
|
||||
-grub_memcpy (void *dest, const void *src, grub_size_t n)
|
||||
-{
|
||||
- return grub_memmove (dest, src, n);
|
||||
-}
|
||||
-
|
||||
#if defined(__x86_64__) && !defined (GRUB_UTIL)
|
||||
#if defined (__MINGW32__) || defined (__CYGWIN__) || defined (__MINGW64__)
|
||||
#define GRUB_ASM_ATTR __attribute__ ((sysv_abi))
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@@ -105,5 +105,5 @@ as stage1 that can be too old to load updated modules.
|
||||
+void *EXPORT_FUNC(grub_calloc) (grub_size_t nmemb, grub_size_t size);
|
||||
+#endif
|
||||
|
||||
typedef grub_uint64_t grub_mem_attr_t;
|
||||
|
||||
void grub_mm_check_real (const char *file, int line);
|
||||
#define grub_mm_check() grub_mm_check_real (GRUB_FILE, __LINE__);
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
From 4f45e963ea913000fd8e3fe20f9afb3722073cea Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Thu, 8 May 2025 19:02:07 +0200
|
||||
Subject: [PATCH 1/8] kern/rescue_reader: Block the rescue mode until the CLI
|
||||
authentication
|
||||
|
||||
This further mitigates potential misuse of the CLI after the
|
||||
root device has been successfully unlocked via TPM.
|
||||
|
||||
Fixes: CVE-2025-4382
|
||||
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/kern/rescue_reader.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/kern/rescue_reader.c b/grub-core/kern/rescue_reader.c
|
||||
index 4259857ba9..a71ada8fb7 100644
|
||||
--- a/grub-core/kern/rescue_reader.c
|
||||
+++ b/grub-core/kern/rescue_reader.c
|
||||
@@ -79,7 +79,7 @@ void __attribute__ ((noreturn))
|
||||
grub_rescue_run (void)
|
||||
{
|
||||
/* Stall if the CLI has been disabled */
|
||||
- if (grub_is_cli_disabled ())
|
||||
+ if (grub_is_cli_disabled () || grub_is_cli_need_auth ())
|
||||
{
|
||||
grub_printf ("Rescue mode has been disabled...\n");
|
||||
|
||||
--
|
||||
2.49.0
|
||||
|
||||
2267
0001-key_protector-Add-TPM2-Key-Protector.patch
Normal file
2267
0001-key_protector-Add-TPM2-Key-Protector.patch
Normal file
File diff suppressed because it is too large
Load Diff
194
0001-key_protector-Add-key-protectors-framework.patch
Normal file
194
0001-key_protector-Add-key-protectors-framework.patch
Normal file
@@ -0,0 +1,194 @@
|
||||
From 1bc53f8fc980914132040670b85a010e094559ec Mon Sep 17 00:00:00 2001
|
||||
From: Hernan Gatta <hegatta@linux.microsoft.com>
|
||||
Date: Tue, 1 Feb 2022 05:02:53 -0800
|
||||
Subject: [PATCH] key_protector: Add key protectors framework
|
||||
|
||||
A key protector encapsulates functionality to retrieve an unlocking key
|
||||
for a fully-encrypted disk from a specific source. A key protector
|
||||
module registers itself with the key protectors framework when it is
|
||||
loaded and unregisters when unloaded. Additionally, a key protector may
|
||||
accept parameters that describe how it should operate.
|
||||
|
||||
The key protectors framework, besides offering registration and
|
||||
unregistration functions, also offers a one-stop routine for finding and
|
||||
invoking a key protector by name. If a key protector with the specified
|
||||
name exists and if an unlocking key is successfully retrieved by it, the
|
||||
function returns to the caller the retrieved key and its length.
|
||||
|
||||
Cc: Vladimir Serbinenko <phcoder@gmail.com>
|
||||
Signed-off-by: Hernan Gatta <hegatta@linux.microsoft.com>
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/Makefile.am | 1 +
|
||||
grub-core/Makefile.core.def | 5 +++
|
||||
grub-core/disk/key_protector.c | 73 ++++++++++++++++++++++++++++++++++
|
||||
include/grub/key_protector.h | 47 ++++++++++++++++++++++
|
||||
4 files changed, 126 insertions(+)
|
||||
create mode 100644 grub-core/disk/key_protector.c
|
||||
create mode 100644 include/grub/key_protector.h
|
||||
|
||||
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
|
||||
index 1eda467e0..e50db8106 100644
|
||||
--- a/grub-core/Makefile.am
|
||||
+++ b/grub-core/Makefile.am
|
||||
@@ -90,6 +90,7 @@ endif
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h
|
||||
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/key_protector.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/stack_protector.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index a38955e18..37f131ae2 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1282,6 +1282,11 @@ module = {
|
||||
common = disk/raid6_recover.c;
|
||||
};
|
||||
|
||||
+module = {
|
||||
+ name = key_protector;
|
||||
+ common = disk/key_protector.c;
|
||||
+};
|
||||
+
|
||||
module = {
|
||||
name = scsi;
|
||||
common = disk/scsi.c;
|
||||
diff --git a/grub-core/disk/key_protector.c b/grub-core/disk/key_protector.c
|
||||
new file mode 100644
|
||||
index 000000000..0d146c1c0
|
||||
--- /dev/null
|
||||
+++ b/grub-core/disk/key_protector.c
|
||||
@@ -0,0 +1,73 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2022 Microsoft Corporation
|
||||
+ * Copyright (C) 2024 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/list.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/key_protector.h>
|
||||
+
|
||||
+GRUB_MOD_LICENSE ("GPLv3+");
|
||||
+
|
||||
+struct grub_key_protector *grub_key_protectors = NULL;
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_key_protector_register (struct grub_key_protector *protector)
|
||||
+{
|
||||
+ if (protector == NULL || protector->name == NULL || protector->name[0] == '\0')
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid key protector for registration");
|
||||
+
|
||||
+ if (grub_key_protectors != NULL &&
|
||||
+ grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors), protector->name) != NULL)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Key protector '%s' already registered", protector->name);
|
||||
+
|
||||
+ grub_list_push (GRUB_AS_LIST_P (&grub_key_protectors), GRUB_AS_LIST (protector));
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_key_protector_unregister (struct grub_key_protector *protector)
|
||||
+{
|
||||
+ if (protector == NULL)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid key protector for unregistration");
|
||||
+
|
||||
+ grub_list_remove (GRUB_AS_LIST (protector));
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_key_protector_recover_key (const char *protector, grub_uint8_t **key,
|
||||
+ grub_size_t *key_size)
|
||||
+{
|
||||
+ struct grub_key_protector *kp = NULL;
|
||||
+
|
||||
+ if (grub_key_protectors == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "No key protector registered");
|
||||
+
|
||||
+ if (protector == NULL || protector[0] == '\0')
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid key protector");
|
||||
+
|
||||
+ kp = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors), protector);
|
||||
+ if (kp == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "Key protector '%s' not found", protector);
|
||||
+
|
||||
+ return kp->recover_key (key, key_size);
|
||||
+}
|
||||
diff --git a/include/grub/key_protector.h b/include/grub/key_protector.h
|
||||
new file mode 100644
|
||||
index 000000000..00b15c13d
|
||||
--- /dev/null
|
||||
+++ b/include/grub/key_protector.h
|
||||
@@ -0,0 +1,47 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2022 Microsoft Corporation
|
||||
+ * Copyright (C) 2024 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_PROTECTOR_HEADER
|
||||
+#define GRUB_PROTECTOR_HEADER 1
|
||||
+
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/types.h>
|
||||
+
|
||||
+struct grub_key_protector
|
||||
+{
|
||||
+ struct grub_key_protector *next;
|
||||
+ struct grub_key_protector **prev;
|
||||
+
|
||||
+ const char *name;
|
||||
+
|
||||
+ grub_err_t (*recover_key) (grub_uint8_t **key, grub_size_t *key_size);
|
||||
+};
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_key_protector_register (struct grub_key_protector *protector);
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_key_protector_unregister (struct grub_key_protector *protector);
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_key_protector_recover_key (const char *protector,
|
||||
+ grub_uint8_t **key,
|
||||
+ grub_size_t *key_size);
|
||||
+
|
||||
+#endif /* ! GRUB_PROTECTOR_HEADER */
|
||||
--
|
||||
2.43.0
|
||||
|
||||
234
0001-lib-crypto-Introduce-new-HMAC-functions-to-reuse-buf.patch
Normal file
234
0001-lib-crypto-Introduce-new-HMAC-functions-to-reuse-buf.patch
Normal file
@@ -0,0 +1,234 @@
|
||||
From e98e880b67be178f3a5951fb345ded8c002eb6e5 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Wed, 13 Aug 2025 11:43:40 +0800
|
||||
Subject: [PATCH 1/2] lib/crypto: Introduce new HMAC functions to reuse buffers
|
||||
|
||||
To enable more efficient buffer reuse for HMAC operations, three new
|
||||
functions have been introduced. This change prevents the need to
|
||||
reallocate memory for each HMAC operation.
|
||||
|
||||
* grub_crypto_hmac_reset(): Reinitializes the hash contexts in the HMAC
|
||||
handle.
|
||||
|
||||
* grub_crypto_hmac_final(): Provides the final HMAC result without
|
||||
freeing the handle, allowing it to be reused immediately.
|
||||
|
||||
* grub_crypto_hmac_free(): Deallocates the HMAC handle and its
|
||||
associated memory.
|
||||
|
||||
To further facilitate buffer reuse, 'ctx2' is now included within the HMAC
|
||||
handle struct, and the initialization of 'ctx2' is moved to
|
||||
grub_crypto_hmac_init().
|
||||
|
||||
The intermediate hash states ('ctx' and 'ctx2') for the inner and outer
|
||||
padded keys are now cached. grub_crypto_hmac_reset() restores these cached
|
||||
states for new operations, which avoids redundant hashing of the keys.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
grub-core/disk/geli.c | 4 +-
|
||||
grub-core/lib/crypto.c | 91 ++++++++++++++++++++++++++++++------------
|
||||
include/grub/crypto.h | 8 +++-
|
||||
3 files changed, 74 insertions(+), 29 deletions(-)
|
||||
|
||||
Index: grub-2.12/grub-core/disk/geli.c
|
||||
===================================================================
|
||||
--- grub-2.12.orig/grub-core/disk/geli.c
|
||||
+++ grub-2.12/grub-core/disk/geli.c
|
||||
@@ -464,9 +464,7 @@ geli_recover_key (grub_disk_t source, gr
|
||||
grub_crypto_hmac_write (hnd, header.salt, sizeof (header.salt));
|
||||
grub_crypto_hmac_write (hnd, cargs->key_data, cargs->key_len);
|
||||
|
||||
- gcry_err = grub_crypto_hmac_fini (hnd, geomkey);
|
||||
- if (gcry_err)
|
||||
- return grub_crypto_gcry_error (gcry_err);
|
||||
+ grub_crypto_hmac_fini (hnd, geomkey);
|
||||
}
|
||||
|
||||
gcry_err = grub_crypto_hmac_buffer (dev->hash, geomkey,
|
||||
Index: grub-2.12/grub-core/lib/crypto.c
|
||||
===================================================================
|
||||
--- grub-2.12.orig/grub-core/lib/crypto.c
|
||||
+++ grub-2.12/grub-core/lib/crypto.c
|
||||
@@ -31,7 +31,9 @@ struct grub_crypto_hmac_handle
|
||||
{
|
||||
const struct gcry_md_spec *md;
|
||||
void *ctx;
|
||||
- void *opad;
|
||||
+ void *ctx2;
|
||||
+ void *ctx_cache;
|
||||
+ void *ctx2_cache;
|
||||
};
|
||||
|
||||
static gcry_cipher_spec_t *grub_ciphers = NULL;
|
||||
@@ -307,7 +309,8 @@ grub_crypto_hmac_init (const struct gcry
|
||||
{
|
||||
grub_uint8_t *helpkey = NULL;
|
||||
grub_uint8_t *ipad = NULL, *opad = NULL;
|
||||
- void *ctx = NULL;
|
||||
+ void *ctx = NULL, *ctx2 = NULL;
|
||||
+ void *ctx_cache = NULL, *ctx2_cache = NULL;
|
||||
struct grub_crypto_hmac_handle *ret = NULL;
|
||||
unsigned i;
|
||||
|
||||
@@ -318,6 +321,18 @@ grub_crypto_hmac_init (const struct gcry
|
||||
if (!ctx)
|
||||
goto err;
|
||||
|
||||
+ ctx2 = grub_malloc (md->contextsize);
|
||||
+ if (!ctx2)
|
||||
+ goto err;
|
||||
+
|
||||
+ ctx_cache = grub_malloc (md->contextsize);
|
||||
+ if (!ctx_cache)
|
||||
+ goto err;
|
||||
+
|
||||
+ ctx2_cache = grub_malloc (md->contextsize);
|
||||
+ if (!ctx2_cache)
|
||||
+ goto err;
|
||||
+
|
||||
if ( keylen > md->blocksize )
|
||||
{
|
||||
helpkey = grub_malloc (md->mdlen);
|
||||
@@ -347,26 +362,40 @@ grub_crypto_hmac_init (const struct gcry
|
||||
grub_free (helpkey);
|
||||
helpkey = NULL;
|
||||
|
||||
+ /* inner pad */
|
||||
md->init (ctx);
|
||||
-
|
||||
- md->write (ctx, ipad, md->blocksize); /* inner pad */
|
||||
+ md->write (ctx, ipad, md->blocksize);
|
||||
+ grub_memcpy (ctx_cache, ctx, md->contextsize);
|
||||
grub_memset (ipad, 0, md->blocksize);
|
||||
grub_free (ipad);
|
||||
ipad = NULL;
|
||||
|
||||
+ /* outer pad */
|
||||
+ md->init (ctx2);
|
||||
+ md->write (ctx2, opad, md->blocksize);
|
||||
+ grub_memcpy (ctx2_cache, ctx2, md->contextsize);
|
||||
+ grub_memset (opad, 0, md->blocksize);
|
||||
+ grub_free (opad);
|
||||
+ opad = NULL;
|
||||
+
|
||||
ret = grub_malloc (sizeof (*ret));
|
||||
if (!ret)
|
||||
goto err;
|
||||
|
||||
ret->md = md;
|
||||
ret->ctx = ctx;
|
||||
- ret->opad = opad;
|
||||
+ ret->ctx2 = ctx2;
|
||||
+ ret->ctx_cache = ctx_cache;
|
||||
+ ret->ctx2_cache = ctx2_cache;
|
||||
|
||||
return ret;
|
||||
|
||||
err:
|
||||
grub_free (helpkey);
|
||||
grub_free (ctx);
|
||||
+ grub_free (ctx2);
|
||||
+ grub_free (ctx_cache);
|
||||
+ grub_free (ctx2_cache);
|
||||
grub_free (ipad);
|
||||
grub_free (opad);
|
||||
return NULL;
|
||||
@@ -380,37 +409,48 @@ grub_crypto_hmac_write (struct grub_cryp
|
||||
hnd->md->write (hnd->ctx, data, datalen);
|
||||
}
|
||||
|
||||
-gcry_err_code_t
|
||||
+void
|
||||
grub_crypto_hmac_fini (struct grub_crypto_hmac_handle *hnd, void *out)
|
||||
{
|
||||
- grub_uint8_t *p;
|
||||
- grub_uint8_t *ctx2;
|
||||
+ grub_crypto_hmac_final (hnd, out);
|
||||
+ grub_crypto_hmac_free (hnd);
|
||||
+}
|
||||
|
||||
- ctx2 = grub_malloc (hnd->md->contextsize);
|
||||
- if (!ctx2)
|
||||
- return GPG_ERR_OUT_OF_MEMORY;
|
||||
+void
|
||||
+grub_crypto_hmac_reset (struct grub_crypto_hmac_handle *hnd)
|
||||
+{
|
||||
+ grub_memcpy (hnd->ctx, hnd->ctx_cache, hnd->md->contextsize);
|
||||
+ grub_memcpy (hnd->ctx2, hnd->ctx2_cache, hnd->md->contextsize);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_crypto_hmac_final (struct grub_crypto_hmac_handle *hnd, void *out)
|
||||
+{
|
||||
+ grub_uint8_t *p;
|
||||
|
||||
hnd->md->final (hnd->ctx);
|
||||
hnd->md->read (hnd->ctx);
|
||||
p = hnd->md->read (hnd->ctx);
|
||||
|
||||
- hnd->md->init (ctx2);
|
||||
- hnd->md->write (ctx2, hnd->opad, hnd->md->blocksize);
|
||||
- hnd->md->write (ctx2, p, hnd->md->mdlen);
|
||||
- hnd->md->final (ctx2);
|
||||
- grub_memset (hnd->opad, 0, hnd->md->blocksize);
|
||||
- grub_free (hnd->opad);
|
||||
- grub_memset (hnd->ctx, 0, hnd->md->contextsize);
|
||||
- grub_free (hnd->ctx);
|
||||
+ hnd->md->write (hnd->ctx2, p, hnd->md->mdlen);
|
||||
+ hnd->md->final (hnd->ctx2);
|
||||
|
||||
- grub_memcpy (out, hnd->md->read (ctx2), hnd->md->mdlen);
|
||||
- grub_memset (ctx2, 0, hnd->md->contextsize);
|
||||
- grub_free (ctx2);
|
||||
+ grub_memcpy (out, hnd->md->read (hnd->ctx2), hnd->md->mdlen);
|
||||
+}
|
||||
|
||||
+void
|
||||
+grub_crypto_hmac_free (struct grub_crypto_hmac_handle *hnd)
|
||||
+{
|
||||
+ grub_memset (hnd->ctx, 0, hnd->md->contextsize);
|
||||
+ grub_free (hnd->ctx);
|
||||
+ grub_memset (hnd->ctx2, 0, hnd->md->contextsize);
|
||||
+ grub_free (hnd->ctx2);
|
||||
+ grub_memset (hnd->ctx_cache, 0, hnd->md->contextsize);
|
||||
+ grub_free (hnd->ctx_cache);
|
||||
+ grub_memset (hnd->ctx2_cache, 0, hnd->md->contextsize);
|
||||
+ grub_free (hnd->ctx2_cache);
|
||||
grub_memset (hnd, 0, sizeof (*hnd));
|
||||
grub_free (hnd);
|
||||
-
|
||||
- return GPG_ERR_NO_ERROR;
|
||||
}
|
||||
|
||||
gcry_err_code_t
|
||||
@@ -425,7 +465,8 @@ grub_crypto_hmac_buffer (const struct gc
|
||||
return GPG_ERR_OUT_OF_MEMORY;
|
||||
|
||||
grub_crypto_hmac_write (hnd, data, datalen);
|
||||
- return grub_crypto_hmac_fini (hnd, out);
|
||||
+ grub_crypto_hmac_fini (hnd, out);
|
||||
+ return GPG_ERR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
Index: grub-2.12/include/grub/crypto.h
|
||||
===================================================================
|
||||
--- grub-2.12.orig/include/grub/crypto.h
|
||||
+++ grub-2.12/include/grub/crypto.h
|
||||
@@ -358,8 +358,14 @@ void
|
||||
grub_crypto_hmac_write (struct grub_crypto_hmac_handle *hnd,
|
||||
const void *data,
|
||||
grub_size_t datalen);
|
||||
-gcry_err_code_t
|
||||
+void
|
||||
grub_crypto_hmac_fini (struct grub_crypto_hmac_handle *hnd, void *out);
|
||||
+void
|
||||
+grub_crypto_hmac_reset (struct grub_crypto_hmac_handle *hnd);
|
||||
+void
|
||||
+grub_crypto_hmac_final (struct grub_crypto_hmac_handle *hnd, void *out);
|
||||
+void
|
||||
+grub_crypto_hmac_free (struct grub_crypto_hmac_handle *hnd);
|
||||
|
||||
gcry_err_code_t
|
||||
grub_crypto_hmac_buffer (const struct gcry_md_spec *md,
|
||||
@@ -1,119 +0,0 @@
|
||||
From f770cc82c3d65c65d812e96e006c17861d357d99 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Sat, 26 Apr 2025 15:07:36 +0800
|
||||
Subject: [PATCH 1/4] linux: fallback to EFI handover on x86_64
|
||||
|
||||
On the x86_64 platform, when the shim loader protocol is unavailable and
|
||||
UEFI Secure Boot is enabled, fall back to the Linux EFI handover boot
|
||||
protocol. This legacy method supports the in-kernel EFI stub and is used
|
||||
instead of the 32-bit boot entry.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 2 ++
|
||||
grub-core/loader/efi/linux.c | 13 +++++++------
|
||||
grub-core/loader/i386/efi/linux.c | 30 ++++--------------------------
|
||||
3 files changed, 13 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index 80ea6656a..1811661c3 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1902,6 +1902,8 @@ module = {
|
||||
loongarch64 = loader/efi/linux.c;
|
||||
riscv32 = loader/efi/linux.c;
|
||||
riscv64 = loader/efi/linux.c;
|
||||
+ i386_efi = loader/efi/linux.c;
|
||||
+ x86_64_efi = loader/efi/linux.c;
|
||||
emu = loader/emu/linux.c;
|
||||
common = loader/linux.c;
|
||||
i386_efi = loader/efi/linux_boot.c;
|
||||
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
|
||||
index 394df6039..b20dec404 100644
|
||||
--- a/grub-core/loader/efi/linux.c
|
||||
+++ b/grub-core/loader/efi/linux.c
|
||||
@@ -71,10 +71,10 @@ static initrd_media_device_path_t initrd_lf2_device_path = {
|
||||
};
|
||||
|
||||
extern grub_err_t
|
||||
-grub_cmd_linux_x86_legacy (grub_command_t cmd, int argc, char *argv[]);
|
||||
+grub_cmd_linux_efi_fallback (grub_command_t cmd, int argc, char *argv[]);
|
||||
|
||||
extern grub_err_t
|
||||
-grub_cmd_initrd_x86_legacy (grub_command_t cmd, int argc, char *argv[]);
|
||||
+grub_cmd_initrd_efi_fallback (grub_command_t cmd, int argc, char *argv[]);
|
||||
|
||||
static grub_efi_status_t __grub_efi_api
|
||||
grub_efi_initrd_load_file2 (grub_efi_load_file2_t *this,
|
||||
@@ -389,8 +389,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
- if (!initrd_use_loadfile2)
|
||||
- return grub_cmd_initrd_x86_legacy (cmd, argc, argv);
|
||||
+ if (grub_is_using_legacy_shim_lock_protocol () == true ||
|
||||
+ !initrd_use_loadfile2)
|
||||
+ return grub_cmd_initrd_efi_fallback (cmd, argc, argv);
|
||||
#endif
|
||||
|
||||
if (!loaded)
|
||||
@@ -474,7 +475,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
grub_dprintf ("linux", "using legacy shim_lock protocol, falling back to legacy Linux kernel loader\n");
|
||||
|
||||
- err = grub_cmd_linux_x86_legacy (cmd, argc, argv);
|
||||
+ err = grub_cmd_linux_efi_fallback (cmd, argc, argv);
|
||||
|
||||
if (err == GRUB_ERR_NONE)
|
||||
return GRUB_ERR_NONE;
|
||||
@@ -513,7 +514,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
*/
|
||||
fallback:
|
||||
grub_file_close (file);
|
||||
- return grub_cmd_linux_x86_legacy (cmd, argc, argv);
|
||||
+ return grub_cmd_linux_efi_fallback (cmd, argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
||||
index ca3435a88..49e4a3f19 100644
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -421,30 +421,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
-static grub_command_t cmd_linux, cmd_initrd;
|
||||
-static grub_command_t cmd_linuxefi, cmd_initrdefi;
|
||||
+extern grub_err_t __attribute__((alias("grub_cmd_linux")))
|
||||
+grub_cmd_linux_efi_fallback (grub_command_t cmd, int argc, char *argv[]);
|
||||
|
||||
-GRUB_MOD_INIT(linux)
|
||||
-{
|
||||
- cmd_linuxefi =
|
||||
- grub_register_command ("linuxefi", grub_cmd_linux,
|
||||
- 0, N_("Load Linux."));
|
||||
- cmd_initrdefi =
|
||||
- grub_register_command ("initrdefi", grub_cmd_initrd,
|
||||
- 0, N_("Load initrd."));
|
||||
- cmd_linux =
|
||||
- grub_register_command ("linux", grub_cmd_linux,
|
||||
- 0, N_("Load Linux."));
|
||||
- cmd_initrd =
|
||||
- grub_register_command ("initrd", grub_cmd_initrd,
|
||||
- 0, N_("Load initrd."));
|
||||
- my_mod = mod;
|
||||
-}
|
||||
-
|
||||
-GRUB_MOD_FINI(linux)
|
||||
-{
|
||||
- grub_unregister_command (cmd_linuxefi);
|
||||
- grub_unregister_command (cmd_initrdefi);
|
||||
- grub_unregister_command (cmd_linux);
|
||||
- grub_unregister_command (cmd_initrd);
|
||||
-}
|
||||
+extern grub_err_t __attribute__((alias("grub_cmd_initrd")))
|
||||
+grub_cmd_initrd_efi_fallback (grub_command_t cmd, int argc, char *argv[]);
|
||||
--
|
||||
2.50.1
|
||||
|
||||
@@ -12,9 +12,11 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
grub-core/disk/luks2.c | 81 ++++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 79 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c
|
||||
index d5106402f..fe5ba777a 100644
|
||||
--- a/grub-core/disk/luks2.c
|
||||
+++ b/grub-core/disk/luks2.c
|
||||
@@ -126,6 +126,14 @@
|
||||
@@ -124,6 +124,14 @@ struct grub_luks2_digest
|
||||
};
|
||||
typedef struct grub_luks2_digest grub_luks2_digest_t;
|
||||
|
||||
@@ -29,7 +31,7 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src,
|
||||
grub_uint8_t * dst, grub_size_t blocksize,
|
||||
grub_size_t blocknumbers);
|
||||
@@ -267,6 +275,39 @@
|
||||
@@ -257,6 +265,39 @@ luks2_parse_digest (grub_luks2_digest_t *out, const grub_json_t *digest)
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
@@ -69,7 +71,7 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
static grub_err_t
|
||||
luks2_get_keyslot (grub_luks2_keyslot_t *k, grub_luks2_digest_t *d, grub_luks2_segment_t *s,
|
||||
const grub_json_t *root, grub_size_t keyslot_json_idx)
|
||||
@@ -594,13 +635,14 @@
|
||||
@@ -561,13 +602,14 @@ luks2_recover_key (grub_disk_t source,
|
||||
{
|
||||
grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN];
|
||||
char cipher[32], *json_header = NULL, *ptr;
|
||||
@@ -84,9 +86,9 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
- grub_json_t *json = NULL, keyslots;
|
||||
+ grub_json_t *json = NULL, keyslots, tokens;
|
||||
grub_err_t ret;
|
||||
grub_size_t sz;
|
||||
|
||||
@@ -644,6 +686,37 @@
|
||||
if (cargs->key_data == NULL || cargs->key_len == 0)
|
||||
@@ -605,6 +647,37 @@ luks2_recover_key (grub_disk_t source,
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -124,7 +126,7 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
if (grub_disk_native_sectors (source) == GRUB_DISK_SIZE_UNKNOWN)
|
||||
{
|
||||
/* FIXME: Allow use of source disk, and maybe cause errors in read. */
|
||||
@@ -680,6 +753,10 @@
|
||||
@@ -641,6 +714,10 @@ luks2_recover_key (grub_disk_t source,
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -135,3 +137,6 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
grub_dprintf ("luks2", "Trying keyslot \"%" PRIuGRUB_UINT64_T "\"\n", keyslot.idx);
|
||||
|
||||
/* Sector size should be one of 512, 1024, 2048, or 4096. */
|
||||
--
|
||||
2.42.0
|
||||
|
||||
|
||||
68
0001-misc-Implement-grub_strlcpy.patch
Normal file
68
0001-misc-Implement-grub_strlcpy.patch
Normal file
@@ -0,0 +1,68 @@
|
||||
From f0a61161f74f9855af84778261338224d926a61f Mon Sep 17 00:00:00 2001
|
||||
From: B Horn <b@horn.uk>
|
||||
Date: Sat, 15 Jun 2024 02:33:08 +0100
|
||||
Subject: [PATCH 01/20] misc: Implement grub_strlcpy()
|
||||
|
||||
grub_strlcpy() acts the same way as strlcpy() does on most *NIX,
|
||||
returning the length of src and ensuring dest is always NUL
|
||||
terminated except when size is 0.
|
||||
|
||||
Signed-off-by: B Horn <b@horn.uk>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
include/grub/misc.h | 39 +++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 39 insertions(+)
|
||||
|
||||
diff --git a/include/grub/misc.h b/include/grub/misc.h
|
||||
index 6e94d18f5a..e087e7b3e8 100644
|
||||
--- a/include/grub/misc.h
|
||||
+++ b/include/grub/misc.h
|
||||
@@ -64,6 +64,45 @@ grub_stpcpy (char *dest, const char *src)
|
||||
return d - 1;
|
||||
}
|
||||
|
||||
+static inline grub_size_t
|
||||
+grub_strlcpy (char *dest, const char *src, grub_size_t size)
|
||||
+{
|
||||
+ char *d = dest;
|
||||
+ grub_size_t res = 0;
|
||||
+ /*
|
||||
+ * We do not subtract one from size here to avoid dealing with underflowing
|
||||
+ * the value, which is why to_copy is always checked to be greater than one
|
||||
+ * throughout this function.
|
||||
+ */
|
||||
+ grub_size_t to_copy = size;
|
||||
+
|
||||
+ /* Copy size - 1 bytes to dest. */
|
||||
+ if (to_copy > 1)
|
||||
+ while ((*d++ = *src++) != '\0' && ++res && --to_copy > 1)
|
||||
+ ;
|
||||
+
|
||||
+ /*
|
||||
+ * NUL terminate if size != 0. The previous step may have copied a NUL byte
|
||||
+ * if it reached the end of the string, but we know dest[size - 1] must always
|
||||
+ * be a NUL byte.
|
||||
+ */
|
||||
+ if (size != 0)
|
||||
+ dest[size - 1] = '\0';
|
||||
+
|
||||
+ /* If there is still space in dest, but are here, we reached the end of src. */
|
||||
+ if (to_copy > 1)
|
||||
+ return res;
|
||||
+
|
||||
+ /*
|
||||
+ * If we haven't reached the end of the string, iterate through to determine
|
||||
+ * the strings total length.
|
||||
+ */
|
||||
+ while (*src++ != '\0' && ++res)
|
||||
+ ;
|
||||
+
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
/* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */
|
||||
static inline void *
|
||||
grub_memcpy (void *dest, const void *src, grub_size_t n)
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
From d35ff22516b161f6d472f7f5371a89597b072d04 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 6 May 2024 10:34:22 +0800
|
||||
Subject: [PATCH] net/drivers/ieee1275/ofnet: Remove 200 ms timeout in
|
||||
get_card_packet() to reduce input latency
|
||||
|
||||
When GRUB image is netbooted on ppc64le, the keyboard input exhibits
|
||||
significant latency, reports even say that characters are processed
|
||||
about once per second. This issue makes interactively trying to debug
|
||||
a ppc64le config very difficult.
|
||||
|
||||
It seems that the latency is largely caused by a 200 ms timeout in the
|
||||
idle event loop, during which the network card interface is consistently
|
||||
polled for incoming packets. Often, no packets arrive during this
|
||||
period, so the timeout nearly always expires, which blocks the response
|
||||
to key inputs.
|
||||
|
||||
Furthermore, this 200 ms timeout might not need to be enforced at this
|
||||
basic layer, considering that GRUB performs synchronous reads and its
|
||||
timeout management is actually handled by higher layers, not directly in
|
||||
the card instance. Additionally, the idle polling, which reacts to
|
||||
unsolicited packets like ICMP and SLAAC, would be fine at a less frequent
|
||||
polling interval, rather than needing a timeout for receiving a response.
|
||||
|
||||
For these reasons, we believe the timeout in get_card_packet() should be
|
||||
effectively removed. According to test results, the delay has disappeared,
|
||||
and it is now much easier to use interactively.
|
||||
|
||||
Signed-Off-by: Michael Chang <mchang@suse.com>
|
||||
Tested-by: Tony Jones <tonyj@suse.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/net/drivers/ieee1275/ofnet.c | 8 ++------
|
||||
1 file changed, 2 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c
|
||||
index 78f03df8e..3bf48b3f0 100644
|
||||
--- a/grub-core/net/drivers/ieee1275/ofnet.c
|
||||
+++ b/grub-core/net/drivers/ieee1275/ofnet.c
|
||||
@@ -82,15 +82,11 @@ get_card_packet (struct grub_net_card *dev)
|
||||
grub_ssize_t actual;
|
||||
int rc;
|
||||
struct grub_ofnetcard_data *data = dev->data;
|
||||
- grub_uint64_t start_time;
|
||||
struct grub_net_buff *nb;
|
||||
|
||||
- start_time = grub_get_time_ms ();
|
||||
- do
|
||||
- rc = grub_ieee1275_read (data->handle, dev->rcvbuf, dev->rcvbufsize, &actual);
|
||||
- while ((actual <= 0 || rc < 0) && (grub_get_time_ms () - start_time < 200));
|
||||
+ rc = grub_ieee1275_read (data->handle, dev->rcvbuf, dev->rcvbufsize, &actual);
|
||||
|
||||
- if (actual <= 0)
|
||||
+ if (actual <= 0 || rc < 0)
|
||||
return NULL;
|
||||
|
||||
nb = grub_netbuff_alloc (actual + 2);
|
||||
--
|
||||
2.45.2
|
||||
|
||||
@@ -23,9 +23,11 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
grub-core/disk/ieee1275/ofdisk.c | 75 +++++++++++++++++++++++---------
|
||||
1 file changed, 55 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
|
||||
index c5c20a5ec..36ee5314d 100644
|
||||
--- a/grub-core/disk/ieee1275/ofdisk.c
|
||||
+++ b/grub-core/disk/ieee1275/ofdisk.c
|
||||
@@ -36,8 +36,13 @@
|
||||
@@ -35,8 +35,13 @@ static grub_ieee1275_ihandle_t last_ihandle;
|
||||
#define IEEE1275_DISK_ALIAS "/disk@"
|
||||
#define IEEE1275_NVMEOF_DISK_ALIAS "/nvme-of/controller@"
|
||||
|
||||
@@ -39,7 +41,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
static int is_boot_nvmeof;
|
||||
|
||||
struct ofdisk_hash_ent
|
||||
@@ -554,20 +559,30 @@
|
||||
@@ -540,20 +545,30 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
|
||||
{
|
||||
if (grub_strcmp (alias->type, "fcp") == 0)
|
||||
{
|
||||
@@ -79,7 +81,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
}
|
||||
}
|
||||
else if (grub_strcmp (alias->type, "vscsi") == 0)
|
||||
@@ -590,9 +605,8 @@
|
||||
@@ -575,9 +590,8 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
|
||||
if (boot_type &&
|
||||
grub_strcmp (boot_type, alias->type) != 0)
|
||||
{
|
||||
@@ -90,7 +92,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
}
|
||||
|
||||
if (grub_ieee1275_open (alias->path, &ihandle))
|
||||
@@ -672,9 +686,8 @@
|
||||
@@ -646,9 +660,8 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
|
||||
if (boot_type &&
|
||||
grub_strcmp (boot_type, alias->type) != 0)
|
||||
{
|
||||
@@ -100,8 +102,8 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
- goto iter_children;
|
||||
}
|
||||
|
||||
if (grub_add (grub_strlen (alias->path), sizeof ("/disk@7766554433221100"), &sz))
|
||||
@@ -1155,13 +1168,37 @@
|
||||
buf = grub_malloc (grub_strlen (alias->path) +
|
||||
@@ -1116,13 +1129,37 @@ get_parent_devname (const char *devname, int *is_nvmeof)
|
||||
return parent;
|
||||
}
|
||||
|
||||
@@ -142,7 +144,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
|
||||
if (!canon)
|
||||
{
|
||||
@@ -1170,8 +1207,6 @@
|
||||
@@ -1131,8 +1168,6 @@ get_boot_device_parent (const char *bootpath, int *is_nvmeof)
|
||||
grub_print_error ();
|
||||
return NULL;
|
||||
}
|
||||
@@ -151,7 +153,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
|
||||
parent = get_parent_devname (canon, is_nvmeof);
|
||||
early_log ("%s is parent of %s\n", parent, canon);
|
||||
@@ -1225,9 +1260,9 @@
|
||||
@@ -1179,9 +1214,9 @@ insert_bootpath (void)
|
||||
boot_parent = get_boot_device_parent (bootpath, &is_boot_nvmeof);
|
||||
boot_type = grub_ieee1275_get_device_type (boot_parent);
|
||||
if (boot_type)
|
||||
@@ -163,3 +165,6 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
}
|
||||
grub_free (type);
|
||||
grub_free (bootpath);
|
||||
--
|
||||
2.44.0
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
|
||||
--- a/grub-core/disk/ieee1275/ofdisk.c
|
||||
+++ b/grub-core/disk/ieee1275/ofdisk.c
|
||||
@@ -32,6 +32,13 @@
|
||||
@@ -31,6 +31,13 @@
|
||||
static char *last_devpath;
|
||||
static grub_ieee1275_ihandle_t last_ihandle;
|
||||
|
||||
@@ -51,7 +51,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
struct ofdisk_hash_ent
|
||||
{
|
||||
char *devpath;
|
||||
@@ -543,12 +550,21 @@
|
||||
@@ -529,12 +536,21 @@
|
||||
{
|
||||
if (grub_strcmp (alias->type, "fcp") == 0)
|
||||
{
|
||||
@@ -78,9 +78,9 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
}
|
||||
else if (grub_strcmp (alias->type, "vscsi") == 0)
|
||||
{
|
||||
@@ -567,6 +583,14 @@
|
||||
@@ -552,6 +568,14 @@
|
||||
char *buf, *bufptr;
|
||||
unsigned i;
|
||||
grub_size_t sz;
|
||||
|
||||
+ if (boot_type &&
|
||||
+ grub_strcmp (boot_type, alias->type) != 0)
|
||||
@@ -93,9 +93,9 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
if (grub_ieee1275_open (alias->path, &ihandle))
|
||||
return;
|
||||
|
||||
@@ -641,6 +665,14 @@
|
||||
@@ -615,6 +639,14 @@
|
||||
grub_uint16_t table_size;
|
||||
grub_ieee1275_ihandle_t ihandle;
|
||||
grub_size_t sz;
|
||||
|
||||
+ if (boot_type &&
|
||||
+ grub_strcmp (boot_type, alias->type) != 0)
|
||||
@@ -105,10 +105,10 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
+ goto iter_children;
|
||||
+ }
|
||||
+
|
||||
if (grub_add (grub_strlen (alias->path), sizeof ("/disk@7766554433221100"), &sz))
|
||||
{
|
||||
grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while creating buffer for sas_ioa");
|
||||
@@ -705,6 +737,7 @@
|
||||
buf = grub_malloc (grub_strlen (alias->path) +
|
||||
sizeof ("/disk@7766554433221100"));
|
||||
if (!buf)
|
||||
@@ -674,6 +706,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
{
|
||||
struct grub_ieee1275_devalias child;
|
||||
|
||||
@@ -1081,6 +1114,68 @@
|
||||
@@ -1046,6 +1079,68 @@
|
||||
.next = 0
|
||||
};
|
||||
|
||||
@@ -185,7 +185,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
static void
|
||||
insert_bootpath (void)
|
||||
{
|
||||
@@ -1123,6 +1218,12 @@
|
||||
@@ -1081,6 +1176,12 @@
|
||||
char *device = grub_ieee1275_get_devname (bootpath);
|
||||
op = ofdisk_hash_add (device, NULL);
|
||||
op->is_boot = 1;
|
||||
@@ -198,7 +198,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
}
|
||||
grub_free (type);
|
||||
grub_free (bootpath);
|
||||
@@ -1139,12 +1240,37 @@
|
||||
@@ -1097,12 +1198,37 @@
|
||||
grub_disk_dev_unregister (&grub_ofdisk_dev);
|
||||
}
|
||||
|
||||
|
||||
102
0001-powerpc-increase-MIN-RMA-size-for-CAS-negotiation.patch
Normal file
102
0001-powerpc-increase-MIN-RMA-size-for-CAS-negotiation.patch
Normal file
@@ -0,0 +1,102 @@
|
||||
From 68a2663cc316d55c2670a639c8a4a2a43ffdb141 Mon Sep 17 00:00:00 2001
|
||||
From: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Date: Wed, 15 Jan 2025 17:46:05 +0530
|
||||
Subject: [PATCH] powerpc: increase MIN RMA size for CAS negotiation
|
||||
|
||||
Change RMA size from 512 MB to 768 MB which will result
|
||||
in more memory at boot time for PowerPC. When PowerPC LPAR use/uses vTPM,
|
||||
Secure Boot or FADump, the 512 MB RMA memory is not sufficient for
|
||||
booting. With this 512 MB RMA, GRUB2 run out of memory and unable to
|
||||
load the necessary. Sometimes even usage of CDROM which requires more
|
||||
memory for installation along with the options mentioned above troubles
|
||||
the boot memory and result in boot failures. Increasing the RMA size
|
||||
will resolves multiple out of memory issues observed in PowerPC.
|
||||
|
||||
Failure details (GRUB2 debugs):
|
||||
|
||||
kern/ieee1275/init.c:550: mm requested region of size 8513000, flags 1
|
||||
kern/ieee1275/init.c:563: Cannot satisfy allocation and retain minimum runtime
|
||||
space
|
||||
kern/ieee1275/init.c:550: mm requested region of size 8513000, flags 0
|
||||
kern/ieee1275/init.c:563: Cannot satisfy allocation and retain minimum runtime
|
||||
space
|
||||
kern/file.c:215: Closing `/ppc/ppc64/initrd.img' ...
|
||||
kern/disk.c:297: Closing
|
||||
`ieee1275//vdevice/v-scsi
|
||||
@30000067/disk@8300000000000000'...
|
||||
kern/disk.c:311: Closing
|
||||
`ieee1275//vdevice/v-scsi
|
||||
@30000067/disk@8300000000000000' succeeded.
|
||||
kern/file.c:225: Closing `/ppc/ppc64/initrd.img' failed with 3.
|
||||
kern/file.c:148: Opening `/ppc/ppc64/initrd.img' succeeded.
|
||||
error: ../../grub-core/kern/mm.c:552:out of memory.
|
||||
|
||||
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Link: https://lore.kernel.org/r/20250115121605.56049-1-avnish@linux.ibm.com
|
||||
---
|
||||
grub-core/kern/ieee1275/init.c | 33 +++++++++++++++++++++++++++++----
|
||||
1 file changed, 29 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
|
||||
index 8e08e5dd5c..e0634603ef 100644
|
||||
--- a/grub-core/kern/ieee1275/init.c
|
||||
+++ b/grub-core/kern/ieee1275/init.c
|
||||
@@ -855,7 +855,7 @@ grub_ieee1275_ibm_cas (void)
|
||||
.vec1 = 0x80, /* ignore */
|
||||
.vec2_size = 1 + sizeof (struct option_vector2) - 2,
|
||||
.vec2 = {
|
||||
- 0, 0, -1, -1, -1, -1, -1, 512, -1, 0, 48
|
||||
+ 0, 0, -1, -1, -1, -1, -1, 768, -1, 0, 48
|
||||
},
|
||||
.vec3_size = 2 - 1,
|
||||
.vec3 = 0x00e0, /* ask for FP + VMX + DFP but don't halt if unsatisfied */
|
||||
@@ -892,6 +892,10 @@ grub_claim_heap (void)
|
||||
{
|
||||
grub_err_t err;
|
||||
grub_uint32_t total = HEAP_MAX_SIZE;
|
||||
+#if defined(__powerpc__)
|
||||
+ grub_uint32_t ibm_ca_support_reboot;
|
||||
+ grub_ssize_t actual;
|
||||
+#endif
|
||||
|
||||
err = grub_ieee1275_total_mem (&rmo_top);
|
||||
|
||||
@@ -904,11 +908,32 @@ grub_claim_heap (void)
|
||||
grub_mm_add_region_fn = grub_ieee1275_mm_add_region;
|
||||
|
||||
#if defined(__powerpc__)
|
||||
+ /* Check if it's a CAS reboot with below property. If so, we will skip CAS call */
|
||||
+ ibm_ca_support_reboot = 0;
|
||||
+ if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen,
|
||||
+ "ibm,client-architecture-support-reboot",
|
||||
+ &ibm_ca_support_reboot,
|
||||
+ sizeof (ibm_ca_support_reboot),
|
||||
+ &actual) >= 0)
|
||||
+ grub_dprintf ("ieee1275", "ibm,client-architecture-support-reboot: %u\n",
|
||||
+ ibm_ca_support_reboot);
|
||||
+
|
||||
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CAN_TRY_CAS_FOR_MORE_MEMORY))
|
||||
{
|
||||
- /* if we have an error, don't call CAS, just hope for the best */
|
||||
- if (err == GRUB_ERR_NONE && rmo_top < (512 * 1024 * 1024))
|
||||
- grub_ieee1275_ibm_cas ();
|
||||
+ /*
|
||||
+ * If we have an error or the reboot is detected as CAS reboot,
|
||||
+ * don't call CAS, just hope for the best.
|
||||
+ * Along with the above, if the rmo_top is 512 MB or above. We
|
||||
+ * will skip the CAS call. Though if we call CAS, the rmo_top will
|
||||
+ * be set to 768 MB via CAS Vector2. This condition is required to avoid the
|
||||
+ * issue where the older Linux kernels are still using rmo_top as 512 MB.
|
||||
+ * Calling CAS when rmo_top is less then 768 MB will result in a issue
|
||||
+ * where we won't be able to boot to a newer kernel and continue to
|
||||
+ * boot with older kernel having rmo_top as 512 MB.
|
||||
+ */
|
||||
+ if (!ibm_ca_support_reboot && err == GRUB_ERR_NONE
|
||||
+ && rmo_top < (512 * 1024 * 1024))
|
||||
+ grub_ieee1275_ibm_cas ();
|
||||
}
|
||||
#endif
|
||||
|
||||
--
|
||||
2.48.1
|
||||
|
||||
116
0001-tcp-Fix-TCP-port-number-reused-on-reboot.patch
Normal file
116
0001-tcp-Fix-TCP-port-number-reused-on-reboot.patch
Normal file
@@ -0,0 +1,116 @@
|
||||
From 468a37601083ef3352ff6e5d4f40ec8b1cebc4ef Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 8 Jul 2025 11:57:42 +0800
|
||||
Subject: [PATCH] tcp: Fix TCP port number reused on reboot
|
||||
|
||||
GRUB's TCP stack assigns source ports for outgoing connections starting
|
||||
at 21550 and increments sequentially by 1 (e.g., 21550, 21551, ...).
|
||||
While this generally works, it can lead to failures if the system
|
||||
reboots rapidly and reuses the same source port too soon.
|
||||
|
||||
This issue was observed on powerpc-ieee1275 platforms using CAS (Client
|
||||
Architecture Support) reboot. In such cases, loading the initrd over
|
||||
HTTP may fail with connection timeouts. Packet captures show the failed
|
||||
connections are flagged as "TCP Port Number Reused" by Wireshark.
|
||||
|
||||
The root cause is that GRUB reuses the same port shortly after reboot,
|
||||
while the server may still be tracking the previous connection in
|
||||
TIME_WAIT. This can result in the server rejecting the connection
|
||||
attempt or responding with a stale ACK or RST, leading to handshake
|
||||
failure.
|
||||
|
||||
This patch fixes the issue by introducing a time based source port
|
||||
selection strategy. Instead of always starting from port 21550, GRUB now
|
||||
computes an initial base port based on the current RTC time, divided
|
||||
into 5 minute windows. The purpose of this time based strategy is to
|
||||
ensure that GRUB avoids reusing the same source port within a 5 minute
|
||||
window, thereby preventing collisions with stale server side connection
|
||||
tracking that could interfere with a new TCP handshake.
|
||||
|
||||
A step size of 8 ensures that the same port will not be reused across
|
||||
reboots unless GRUB opens more than 8 TCP connections per second on
|
||||
average, something that is highly unlikely. In typical usage, a GRUB
|
||||
boot cycle lasts about 15 seconds and may open fewer than 100
|
||||
connections total, well below the reuse threshold. This makes the
|
||||
approach robust against short reboot intervals while keeping the logic
|
||||
simple and deterministic.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
---
|
||||
grub-core/net/tcp.c | 39 ++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 38 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/net/tcp.c b/grub-core/net/tcp.c
|
||||
index 93dee0caa..d0cc602dc 100644
|
||||
--- a/grub-core/net/tcp.c
|
||||
+++ b/grub-core/net/tcp.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <grub/net/netbuff.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/priority_queue.h>
|
||||
+#include <grub/datetime.h>
|
||||
|
||||
#define TCP_SYN_RETRANSMISSION_TIMEOUT GRUB_NET_INTERVAL
|
||||
#define TCP_SYN_RETRANSMISSION_COUNT GRUB_NET_TRIES
|
||||
@@ -552,6 +553,36 @@ grub_net_tcp_accept (grub_net_tcp_socket_t sock,
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Derive a time-based source port to avoid reusing the same port across
|
||||
+ * reboots. This helps prevent failures caused by server side TCP state (e.g.
|
||||
+ * TIME_WAIT) from interfering with new connections using the same socket.
|
||||
+ *
|
||||
+ * The base port starts at 21550 and increments every second by 8 across a 5
|
||||
+ * minute window (300 seconds), giving 2400 possible distinct base ports per
|
||||
+ * window. In typical GRUB usage, the number of connections per boot is small,
|
||||
+ * so reuse is effectively avoided.
|
||||
+ */
|
||||
+static grub_uint16_t
|
||||
+get_initial_base_port (void)
|
||||
+{
|
||||
+ grub_err_t err;
|
||||
+ struct grub_datetime date;
|
||||
+ grub_int64_t t = 0;
|
||||
+ grub_uint64_t r = 0;
|
||||
+
|
||||
+ err = grub_get_datetime (&date);
|
||||
+ if (err != GRUB_ERR_NONE || !grub_datetime2unixtime (&date, &t))
|
||||
+ {
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ return 21550;
|
||||
+ }
|
||||
+
|
||||
+ grub_divmod64 (t, 300, &r);
|
||||
+
|
||||
+ return 21550 + (r << 3);
|
||||
+}
|
||||
+
|
||||
grub_net_tcp_socket_t
|
||||
grub_net_tcp_open (char *server,
|
||||
grub_uint16_t out_port,
|
||||
@@ -569,13 +600,19 @@ grub_net_tcp_open (char *server,
|
||||
struct grub_net_network_level_interface *inf;
|
||||
grub_net_network_level_address_t gateway;
|
||||
grub_net_tcp_socket_t socket;
|
||||
- static grub_uint16_t in_port = 21550;
|
||||
+ static grub_uint16_t in_port;
|
||||
struct grub_net_buff *nb;
|
||||
struct tcphdr *tcph;
|
||||
int i;
|
||||
grub_uint8_t *nbd;
|
||||
grub_net_link_level_address_t ll_target_addr;
|
||||
|
||||
+ if (!in_port)
|
||||
+ {
|
||||
+ in_port = get_initial_base_port ();
|
||||
+ grub_dprintf ("net", "base port: %d\n", in_port);
|
||||
+ }
|
||||
+
|
||||
err = grub_net_resolve_address (server, &addr);
|
||||
if (err)
|
||||
return NULL;
|
||||
--
|
||||
2.50.1
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
From f0a08324d0f923527ba611887a3780c1f2cb1578 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Date: Tue, 21 Jan 2025 11:01:26 -0600
|
||||
Subject: [PATCH] term/ns8250-spcr: Return if redirection is disabled
|
||||
|
||||
The Microsoft spec for SPCR says "The base address of the Serial Port
|
||||
register set described using the ACPI Generic Address Structure, or
|
||||
0 if console redirection is disabled". So, return early if redirection
|
||||
is disabled (base address = 0). If this check is not done we may get
|
||||
invalid ports on machines with redirection disabled and boot may hang
|
||||
when reading the grub.cfg file.
|
||||
|
||||
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Reviewed-by: Leo Sandoval <lsandova@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/term/ns8250-spcr.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/grub-core/term/ns8250-spcr.c b/grub-core/term/ns8250-spcr.c
|
||||
index 4efaaf768..428b2d59a 100644
|
||||
--- a/grub-core/term/ns8250-spcr.c
|
||||
+++ b/grub-core/term/ns8250-spcr.c
|
||||
@@ -76,6 +76,11 @@ grub_ns8250_spcr_init (void)
|
||||
config.speed = 115200;
|
||||
break;
|
||||
};
|
||||
+
|
||||
+ /* If base address is 0 it means redirection is disabled. */
|
||||
+ if (spcr->base_addr.addr == 0)
|
||||
+ return NULL;
|
||||
+
|
||||
switch (spcr->base_addr.space_id)
|
||||
{
|
||||
case GRUB_ACPI_GENADDR_MEM_SPACE:
|
||||
--
|
||||
2.51.0
|
||||
|
||||
44
0001-tpm-Skip-loopback-image-measurement.patch
Normal file
44
0001-tpm-Skip-loopback-image-measurement.patch
Normal file
@@ -0,0 +1,44 @@
|
||||
From cda4b7a415eb45743ea54a7760b302c0cfe718cf Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 23 Sep 2024 10:32:18 +0800
|
||||
Subject: [PATCH] tpm: Skip loopback image measurement
|
||||
|
||||
The loopback image is configured to function as a disk by being mapped
|
||||
as a block device. Instead of measuring the entire block device, we
|
||||
should focus on tracking the individual files accessed from it. For
|
||||
example, we do not directly measure block devices like disk hd0, but the
|
||||
files opened from it.
|
||||
|
||||
This method is important to avoid running out of memory, since loopback
|
||||
images can be very large. Trying to read and measure the whole image at
|
||||
once could cause out of memory errors and disrupt the boot process.
|
||||
|
||||
Signed-Off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/tpm.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/tpm.c b/grub-core/commands/tpm.c
|
||||
index bb9aee210..ebbb4fef0 100644
|
||||
--- a/grub-core/commands/tpm.c
|
||||
+++ b/grub-core/commands/tpm.c
|
||||
@@ -41,6 +41,16 @@ grub_tpm_verify_init (grub_file_t io,
|
||||
{
|
||||
*context = io->name;
|
||||
*flags |= GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
|
||||
+
|
||||
+ /*
|
||||
+ * The loopback image is mapped as a disk, allowing it to function like a
|
||||
+ * block device. However, we measure the files read from the block device,
|
||||
+ * not the device itself. For example, we don't measure block devices like
|
||||
+ * disk hd0 directly. This process is crucial to prevent out-of-memory
|
||||
+ * errors, as loopback images are inherently large.
|
||||
+ */
|
||||
+ if ((type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_LOOPBACK)
|
||||
+ *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
--
|
||||
2.46.1
|
||||
|
||||
241
0001-tpm2_key_protector-Add-grub-emu-support.patch
Normal file
241
0001-tpm2_key_protector-Add-grub-emu-support.patch
Normal file
@@ -0,0 +1,241 @@
|
||||
From 76a2bcb99754ee5b4159c35f66042e392139b815 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Fri, 15 Nov 2024 15:34:59 +0800
|
||||
Subject: [PATCH] tpm2_key_protector: Add grub-emu support
|
||||
|
||||
As a preparation to test tpm2_key_protector with grub-emu, the new
|
||||
option, --tpm-device, is introduced to specify the TPM device for
|
||||
grub-emu so that grub-emu can access an emulated TPM device from
|
||||
the host.
|
||||
|
||||
Since grub-emu can directly access the device on host, it's easy to
|
||||
implement the essential TCG2 command submission function with the
|
||||
read/write functions and enable tpm2_key_protector module for grub-emu,
|
||||
so that we can further test TPM2 key unsealing with grub-emu.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Tested-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 3 +++
|
||||
grub-core/kern/emu/main.c | 11 +++++++-
|
||||
grub-core/kern/emu/misc.c | 51 +++++++++++++++++++++++++++++++++++
|
||||
grub-core/lib/tss2/tcg2_emu.c | 49 +++++++++++++++++++++++++++++++++
|
||||
include/grub/emu/misc.h | 5 ++++
|
||||
5 files changed, 118 insertions(+), 1 deletion(-)
|
||||
create mode 100644 grub-core/lib/tss2/tcg2_emu.c
|
||||
|
||||
Index: grub-2.12/grub-core/Makefile.core.def
|
||||
===================================================================
|
||||
--- grub-2.12.orig/grub-core/Makefile.core.def
|
||||
+++ grub-2.12/grub-core/Makefile.core.def
|
||||
@@ -2628,7 +2628,9 @@ module = {
|
||||
common = lib/tss2/tpm2_cmd.c;
|
||||
common = lib/tss2/tss2.c;
|
||||
efi = lib/efi/tcg2.c;
|
||||
+ emu = lib/tss2/tcg2_emu.c;
|
||||
enable = efi;
|
||||
+ enable = emu;
|
||||
cppflags = '-I$(srcdir)/lib/tss2';
|
||||
};
|
||||
|
||||
@@ -2640,6 +2642,7 @@ module = {
|
||||
common = commands/tpm2_key_protector/tpm2key_asn1_tab.c;
|
||||
/* The plaform support of tpm2_key_protector depends on the tcg2 implementation in tss2. */
|
||||
enable = efi;
|
||||
+ enable = emu;
|
||||
cppflags = '-I$(srcdir)/lib/tss2';
|
||||
};
|
||||
|
||||
Index: grub-2.12/grub-core/kern/emu/main.c
|
||||
===================================================================
|
||||
--- grub-2.12.orig/grub-core/kern/emu/main.c
|
||||
+++ grub-2.12/grub-core/kern/emu/main.c
|
||||
@@ -55,7 +55,7 @@
|
||||
static jmp_buf main_env;
|
||||
|
||||
/* Store the prefix specified by an argument. */
|
||||
-static char *root_dev = NULL, *dir = NULL;
|
||||
+static char *root_dev = NULL, *dir = NULL, *tpm_dev = NULL;
|
||||
|
||||
grub_addr_t grub_modbase = 0;
|
||||
|
||||
@@ -108,6 +108,7 @@ static struct argp_option options[] = {
|
||||
{"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
|
||||
{"hold", 'H', N_("SECS"), OPTION_ARG_OPTIONAL, N_("wait until a debugger will attach"), 0},
|
||||
{"kexec", 'X', 0, 0, N_("use kexec to boot Linux kernels via systemctl (pass twice to enable dangerous fallback to non-systemctl)."), 0},
|
||||
+ {"tpm-device", 't', N_("DEV"), 0, N_("set TPM device."), 0},
|
||||
{ 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -168,6 +169,10 @@ argp_parser (int key, char *arg, struct
|
||||
case 'X':
|
||||
grub_util_set_kexecute ();
|
||||
break;
|
||||
+ case 't':
|
||||
+ free (tpm_dev);
|
||||
+ tpm_dev = xstrdup (arg);
|
||||
+ break;
|
||||
|
||||
case ARGP_KEY_ARG:
|
||||
{
|
||||
@@ -282,6 +287,9 @@ main (int argc, char *argv[])
|
||||
|
||||
dir = xstrdup (dir);
|
||||
|
||||
+ if (tpm_dev)
|
||||
+ grub_util_tpm_open (tpm_dev);
|
||||
+
|
||||
/* Start GRUB! */
|
||||
if (setjmp (main_env) == 0)
|
||||
grub_main ();
|
||||
@@ -289,6 +297,7 @@ main (int argc, char *argv[])
|
||||
grub_fini_all ();
|
||||
grub_hostfs_fini ();
|
||||
grub_host_fini ();
|
||||
+ grub_util_tpm_close ();
|
||||
|
||||
grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
|
||||
|
||||
Index: grub-2.12/grub-core/kern/emu/misc.c
|
||||
===================================================================
|
||||
--- grub-2.12.orig/grub-core/kern/emu/misc.c
|
||||
+++ grub-2.12/grub-core/kern/emu/misc.c
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <fcntl.h>
|
||||
|
||||
#include <grub/mm.h>
|
||||
#include <grub/err.h>
|
||||
@@ -41,6 +43,8 @@
|
||||
int verbosity;
|
||||
int kexecute;
|
||||
|
||||
+static int grub_util_tpm_fd = -1;
|
||||
+
|
||||
void
|
||||
grub_util_warn (const char *fmt, ...)
|
||||
{
|
||||
@@ -230,3 +234,50 @@ grub_util_get_kexecute (void)
|
||||
{
|
||||
return kexecute;
|
||||
}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_util_tpm_open (const char *tpm_dev)
|
||||
+{
|
||||
+ if (grub_util_tpm_fd != -1)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ grub_util_tpm_fd = open (tpm_dev, O_RDWR);
|
||||
+ if (grub_util_tpm_fd == -1)
|
||||
+ grub_util_error (_("cannot open TPM device '%s': %s"), tpm_dev, strerror (errno));
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_util_tpm_close (void)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ if (grub_util_tpm_fd == -1)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ err = close (grub_util_tpm_fd);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ grub_util_error (_("cannot close TPM device: %s"), strerror (errno));
|
||||
+
|
||||
+ grub_util_tpm_fd = -1;
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+grub_size_t
|
||||
+grub_util_tpm_read (void *output, grub_size_t size)
|
||||
+{
|
||||
+ if (grub_util_tpm_fd == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ return read (grub_util_tpm_fd, output, size);
|
||||
+}
|
||||
+
|
||||
+grub_size_t
|
||||
+grub_util_tpm_write (const void *input, grub_size_t size)
|
||||
+{
|
||||
+ if (grub_util_tpm_fd == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ return write (grub_util_tpm_fd, input, size);
|
||||
+}
|
||||
Index: grub-2.12/grub-core/lib/tss2/tcg2_emu.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ grub-2.12/grub-core/lib/tss2/tcg2_emu.c
|
||||
@@ -0,0 +1,49 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2024 SUSE LLC
|
||||
+ * Copyright (C) 2024 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/mm.h>
|
||||
+#include <grub/emu/misc.h>
|
||||
+
|
||||
+#include <tss2_buffer.h>
|
||||
+#include <tss2_structs.h>
|
||||
+#include <tcg2.h>
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_tcg2_get_max_output_size (grub_size_t *size)
|
||||
+{
|
||||
+ if (size == NULL)
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+
|
||||
+ *size = GRUB_TPM2_BUFFER_CAPACITY;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_tcg2_submit_command (grub_size_t input_size, grub_uint8_t *input,
|
||||
+ grub_size_t output_size, grub_uint8_t *output)
|
||||
+{
|
||||
+ if (grub_util_tpm_write (input, input_size) != input_size)
|
||||
+ return GRUB_ERR_BAD_DEVICE;
|
||||
+
|
||||
+ if (grub_util_tpm_read (output, output_size) < sizeof (TPM_RESPONSE_HEADER_t))
|
||||
+ return GRUB_ERR_BAD_DEVICE;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
Index: grub-2.12/include/grub/emu/misc.h
|
||||
===================================================================
|
||||
--- grub-2.12.orig/include/grub/emu/misc.h
|
||||
+++ grub-2.12/include/grub/emu/misc.h
|
||||
@@ -75,4 +75,9 @@ grub_util_fopen (const char *path, const
|
||||
|
||||
int grub_util_file_sync (FILE *f);
|
||||
|
||||
+grub_err_t grub_util_tpm_open (const char *tpm_dev);
|
||||
+grub_err_t grub_util_tpm_close (void);
|
||||
+grub_size_t EXPORT_FUNC(grub_util_tpm_read) (void *output, grub_size_t size);
|
||||
+grub_size_t EXPORT_FUNC(grub_util_tpm_write) (const void *input, grub_size_t size);
|
||||
+
|
||||
#endif /* GRUB_EMU_MISC_H */
|
||||
253
0001-tpm2_key_protector-Dump-PCRs-on-policy-fail.patch
Normal file
253
0001-tpm2_key_protector-Dump-PCRs-on-policy-fail.patch
Normal file
@@ -0,0 +1,253 @@
|
||||
From 617dab9e476e8ea5aa314dcc5412bbd8a6f1f465 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Mon, 7 Apr 2025 16:29:15 +0800
|
||||
Subject: [PATCH 1/7] tpm2_key_protector: Dump PCRs on policy fail
|
||||
|
||||
PCR mismatch is one common cause of TPM key unsealing fail. Since the
|
||||
system may be compromised, it is not safe to boot into OS to get the PCR
|
||||
values and TPM eventlog for the further investigation.
|
||||
|
||||
To provide some hints, GRUB now dumps PCRs on policy fail, so the user
|
||||
can check the current PCR values. PCR 0~15 are chosen to cover the
|
||||
firmware, bootloader, and OS.
|
||||
|
||||
The sample output:
|
||||
|
||||
PCR Mismatch! Check firmware and bootloader before typing passphrase!
|
||||
TPM PCR [sha256]:
|
||||
00: 17401f37710984c1d8a03a81fff3ab567ae9291bac61e21715b890ee28879738
|
||||
01: 7a114329ba388445a96e8db2a072785937c1b7a8803ed7cc682b87f3ff3dd7a8
|
||||
02: 11c2776849e8e24b7d80c926cbc4257871bffa744dadfefd3ed049ce25143e05
|
||||
03: 6c33b362073e28e30b47302bbdd3e6f9cee4debca3a304e646f8c68245724350
|
||||
04: 62d38838483ecfd2484ee3a2e5450d8ca3b35fc72cda6a8c620f9f43521c37d1
|
||||
05: d8a85cb37221ab7d1f2cc5f554dbe0463acb6784b5b8dc3164ccaa66d8fff0e1
|
||||
06: 9262e37cbe71ed4daf815b4a4881fb7251c9d371092dde827557d5368121e10e
|
||||
07: 219d542233be492d62b079ffe46cf13396a8c27e520e88b08eaf2e6d3b7e70f5
|
||||
08: de1f61c973b673e505adebe0d7e8fb65fde6c24dd4ab4fbaff9e28b18df6ecd3
|
||||
09: c1de7274fa3e879a16d7e6e7629e3463d95f68adcfd17c477183846dccc41c89
|
||||
10: 0000000000000000000000000000000000000000000000000000000000000000
|
||||
11: 0000000000000000000000000000000000000000000000000000000000000000
|
||||
12: 0000000000000000000000000000000000000000000000000000000000000000
|
||||
13: 0000000000000000000000000000000000000000000000000000000000000000
|
||||
14: 9ab9ebe4879a7f4dd00c04f37e79cfd69d0dd7a8bcc6b01135525b67676a3e40
|
||||
15: 0000000000000000000000000000000000000000000000000000000000000000
|
||||
16: 0000000000000000000000000000000000000000000000000000000000000000
|
||||
17: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
18: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
19: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
20: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
21: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
22: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
23: 0000000000000000000000000000000000000000000000000000000000000000
|
||||
error: failed to unseal sealed key (TPM2_Unseal: 0x99d).
|
||||
error: no key protector provided a usable key for luks (af16e48f-746b-4a12-aae1-c14dcee429e0).
|
||||
|
||||
If the user happens to have the PCR values for key sealing, the PCR dump
|
||||
can be used to identify the changed PCRs and narrow down the scope for
|
||||
closer inspection.
|
||||
|
||||
Please note that the PCR dump is trustworthy only if the GRUB binary is
|
||||
authentic, so the user has to check the GRUB binary thoroughly before
|
||||
using the PCR dump.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
.../commands/tpm2_key_protector/module.c | 118 +++++++++++++++++-
|
||||
1 file changed, 114 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/tpm2_key_protector/module.c b/grub-core/commands/tpm2_key_protector/module.c
|
||||
index 74e79a545..d5e530f77 100644
|
||||
--- a/grub-core/commands/tpm2_key_protector/module.c
|
||||
+++ b/grub-core/commands/tpm2_key_protector/module.c
|
||||
@@ -790,7 +790,7 @@ tpm2_protector_simple_policy_seq (const tpm2_protector_context_t *ctx,
|
||||
|
||||
static grub_err_t
|
||||
tpm2_protector_unseal (tpm2key_policy_t policy_seq, TPM_HANDLE_t sealed_handle,
|
||||
- grub_uint8_t **key, grub_size_t *key_size)
|
||||
+ grub_uint8_t **key, grub_size_t *key_size, bool *dump_pcr)
|
||||
{
|
||||
TPMS_AUTH_COMMAND_t authCmd = {0};
|
||||
TPM2B_SENSITIVE_DATA_t data;
|
||||
@@ -801,6 +801,8 @@ tpm2_protector_unseal (tpm2key_policy_t policy_seq, TPM_HANDLE_t sealed_handle,
|
||||
TPM_RC_t rc;
|
||||
grub_err_t err;
|
||||
|
||||
+ *dump_pcr = false;
|
||||
+
|
||||
/* Start Auth Session */
|
||||
nonceCaller.size = TPM_SHA256_DIGEST_SIZE;
|
||||
symmetric.algorithm = TPM_ALG_NULL;
|
||||
@@ -820,6 +822,13 @@ tpm2_protector_unseal (tpm2key_policy_t policy_seq, TPM_HANDLE_t sealed_handle,
|
||||
rc = grub_tpm2_unseal (sealed_handle, &authCmd, &data, NULL);
|
||||
if (rc != TPM_RC_SUCCESS)
|
||||
{
|
||||
+ /*
|
||||
+ * Trigger PCR dump on policy fail
|
||||
+ * TPM_RC_S (0x800) | TPM_RC_1 (0x100) | RC_FMT (0x80) | TPM_RC_POLICY_FAIL (0x1D)
|
||||
+ */
|
||||
+ if (rc == 0x99D)
|
||||
+ *dump_pcr = true;
|
||||
+
|
||||
err = grub_error (GRUB_ERR_BAD_DEVICE, "failed to unseal sealed key (TPM2_Unseal: 0x%x)", rc);
|
||||
goto error;
|
||||
}
|
||||
@@ -845,6 +854,91 @@ tpm2_protector_unseal (tpm2key_policy_t policy_seq, TPM_HANDLE_t sealed_handle,
|
||||
return err;
|
||||
}
|
||||
|
||||
+#define TPM_PCR_STR_SIZE (sizeof (TPMU_HA_t) * 2 + 1)
|
||||
+
|
||||
+static grub_err_t
|
||||
+tpm2_protector_get_pcr_str (const TPM_ALG_ID_t algo, grub_uint32_t index, char *pcr_str, grub_uint16_t buf_size)
|
||||
+{
|
||||
+ TPML_PCR_SELECTION_t pcr_sel = {
|
||||
+ .count = 1,
|
||||
+ .pcrSelections = {
|
||||
+ {
|
||||
+ .hash = algo,
|
||||
+ .sizeOfSelect = 3,
|
||||
+ .pcrSelect = {0}
|
||||
+ },
|
||||
+ }
|
||||
+ };
|
||||
+ TPML_DIGEST_t digest = {0};
|
||||
+ grub_uint16_t i;
|
||||
+ TPM_RC_t rc;
|
||||
+
|
||||
+ if (buf_size < TPM_PCR_STR_SIZE)
|
||||
+ {
|
||||
+ grub_snprintf (pcr_str, buf_size, "insufficient buffer");
|
||||
+ return GRUB_ERR_OUT_OF_MEMORY;
|
||||
+ }
|
||||
+
|
||||
+ TPMS_PCR_SELECTION_SelectPCR (&pcr_sel.pcrSelections[0], index);
|
||||
+
|
||||
+ rc = grub_tpm2_pcr_read (NULL, &pcr_sel, NULL, NULL, &digest, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ grub_snprintf (pcr_str, buf_size, "TPM2_PCR_Read: 0x%x", rc);
|
||||
+ return GRUB_ERR_BAD_DEVICE;
|
||||
+ }
|
||||
+
|
||||
+ /* Check the returned digest number and size */
|
||||
+ if (digest.count != 1 || digest.digests[0].size > sizeof (TPMU_HA_t))
|
||||
+ {
|
||||
+ grub_snprintf (pcr_str, buf_size, "invalid digest");
|
||||
+ return GRUB_ERR_BAD_DEVICE;
|
||||
+ }
|
||||
+
|
||||
+ /* Print the digest to the buffer */
|
||||
+ for (i = 0; i < digest.digests[0].size; i++)
|
||||
+ grub_snprintf (pcr_str + 2 * i, buf_size - 2 * i, "%02x", digest.digests[0].buffer[i]);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+tpm2_protector_dump_pcr (const TPM_ALG_ID_t bank)
|
||||
+{
|
||||
+ const char *algo_name;
|
||||
+ char pcr_str[TPM_PCR_STR_SIZE];
|
||||
+ grub_uint8_t i;
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ if (bank == TPM_ALG_SHA1)
|
||||
+ algo_name = "sha1";
|
||||
+ else if (bank == TPM_ALG_SHA256)
|
||||
+ algo_name = "sha256";
|
||||
+ else if (bank == TPM_ALG_SHA384)
|
||||
+ algo_name = "sha384";
|
||||
+ else if (bank == TPM_ALG_SHA512)
|
||||
+ algo_name = "sha512";
|
||||
+ else
|
||||
+ algo_name = "other";
|
||||
+
|
||||
+ /* Try to fetch PCR 0 */
|
||||
+ err = tpm2_protector_get_pcr_str (bank, 0, pcr_str, sizeof (pcr_str));
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_printf ("Unsupported PCR bank [%s]: %s\n", algo_name, pcr_str);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ grub_printf ("TPM PCR [%s]:\n", algo_name);
|
||||
+
|
||||
+ grub_printf (" %02d: %s\n", 0, pcr_str);
|
||||
+ for (i = 1; i < TPM_MAX_PCRS; i++)
|
||||
+ {
|
||||
+ tpm2_protector_get_pcr_str (bank, i, pcr_str, sizeof (pcr_str));
|
||||
+ grub_printf (" %02d: %s\n", i, pcr_str);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
tpm2_protector_srk_recover (const tpm2_protector_context_t *ctx,
|
||||
grub_uint8_t **key, grub_size_t *key_size)
|
||||
@@ -859,6 +953,7 @@ tpm2_protector_srk_recover (const tpm2_protector_context_t *ctx,
|
||||
tpm2key_policy_t policy_seq = NULL;
|
||||
tpm2key_authpolicy_t authpol = NULL;
|
||||
tpm2key_authpolicy_t authpol_seq = NULL;
|
||||
+ bool dump_pcr = false;
|
||||
grub_err_t err;
|
||||
|
||||
/*
|
||||
@@ -924,7 +1019,7 @@ tpm2_protector_srk_recover (const tpm2_protector_context_t *ctx,
|
||||
/* Iterate the authpolicy sequence to find one that unseals the key */
|
||||
FOR_LIST_ELEMENTS (authpol, authpol_seq)
|
||||
{
|
||||
- err = tpm2_protector_unseal (authpol->policy_seq, sealed_handle, key, key_size);
|
||||
+ err = tpm2_protector_unseal (authpol->policy_seq, sealed_handle, key, key_size, &dump_pcr);
|
||||
if (err == GRUB_ERR_NONE)
|
||||
break;
|
||||
|
||||
@@ -952,13 +1047,20 @@ tpm2_protector_srk_recover (const tpm2_protector_context_t *ctx,
|
||||
goto exit2;
|
||||
}
|
||||
|
||||
- err = tpm2_protector_unseal (policy_seq, sealed_handle, key, key_size);
|
||||
+ err = tpm2_protector_unseal (policy_seq, sealed_handle, key, key_size, &dump_pcr);
|
||||
}
|
||||
|
||||
/* Pop error messages on success */
|
||||
if (err == GRUB_ERR_NONE)
|
||||
while (grub_error_pop ());
|
||||
|
||||
+ /* Dump PCRs if necessary */
|
||||
+ if (dump_pcr == true)
|
||||
+ {
|
||||
+ grub_printf ("PCR Mismatch! Check firmware and bootloader before typing passphrase!\n");
|
||||
+ tpm2_protector_dump_pcr (ctx->bank);
|
||||
+ }
|
||||
+
|
||||
exit2:
|
||||
grub_tpm2_flushcontext (sealed_handle);
|
||||
|
||||
@@ -978,6 +1080,7 @@ tpm2_protector_nv_recover (const tpm2_protector_context_t *ctx,
|
||||
{
|
||||
TPM_HANDLE_t sealed_handle = ctx->nv;
|
||||
tpm2key_policy_t policy_seq = NULL;
|
||||
+ bool dump_pcr = false;
|
||||
grub_err_t err;
|
||||
|
||||
/* Create a basic policy sequence based on the given PCR selection */
|
||||
@@ -985,7 +1088,14 @@ tpm2_protector_nv_recover (const tpm2_protector_context_t *ctx,
|
||||
if (err != GRUB_ERR_NONE)
|
||||
goto exit;
|
||||
|
||||
- err = tpm2_protector_unseal (policy_seq, sealed_handle, key, key_size);
|
||||
+ err = tpm2_protector_unseal (policy_seq, sealed_handle, key, key_size, &dump_pcr);
|
||||
+
|
||||
+ /* Dump PCRs if necessary */
|
||||
+ if (dump_pcr == true)
|
||||
+ {
|
||||
+ grub_printf ("PCR Mismatch! Check firmware and bootloader before typing passphrase!\n");
|
||||
+ tpm2_protector_dump_pcr (ctx->bank);
|
||||
+ }
|
||||
|
||||
exit:
|
||||
grub_tpm2_flushcontext (sealed_handle);
|
||||
--
|
||||
2.43.0
|
||||
|
||||
81
0001-tpm2_key_protector-Implement-NV-index.patch
Normal file
81
0001-tpm2_key_protector-Implement-NV-index.patch
Normal file
@@ -0,0 +1,81 @@
|
||||
From 53e24662523d033ae3506b73787b972ef332db36 Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Colp <patrick.colp@oracle.com>
|
||||
Date: Mon, 31 Jul 2023 07:01:45 -0700
|
||||
Subject: [PATCH] tpm2_key_protector: Implement NV index
|
||||
|
||||
Currently with the TPM2 protector, only SRK mode is supported and
|
||||
NV index support is just a stub. Implement the NV index option.
|
||||
|
||||
Note: This only extends support on the unseal path. grub-protect
|
||||
has not been updated. tpm2-tools can be used to insert a key into
|
||||
the NV index.
|
||||
|
||||
An example of inserting a key using tpm2-tools:
|
||||
|
||||
# Get random key.
|
||||
tpm2_getrandom 32 > key.dat
|
||||
|
||||
# Create primary object.
|
||||
tpm2_createprimary -C o -g sha256 -G ecc -c primary.ctx
|
||||
|
||||
# Create policy object. `pcrs.dat` contains the PCR values to seal against.
|
||||
tpm2_startauthsession -S session.dat
|
||||
tpm2_policypcr -S session.dat -l sha256:7,11 -f pcrs.dat -L policy.dat
|
||||
tpm2_flushcontext session.dat
|
||||
|
||||
# Seal key into TPM.
|
||||
cat key.dat | tpm2_create -C primary.ctx -u key.pub -r key.priv -L policy.dat -i-
|
||||
tpm2_load -C primary.ctx -u key.pub -r key.priv -n sealing.name -c sealing.ctx
|
||||
tpm2_evictcontrol -C o -c sealing.ctx 0x81000000
|
||||
|
||||
Then to unseal the key in grub, add this to grub.cfg:
|
||||
|
||||
tpm2_key_protector_init --mode=nv --nvindex=0x81000000 --pcrs=7,11
|
||||
cryptomount -u <UUID> --protector tpm2
|
||||
|
||||
Signed-off-by: Patrick Colp <patrick.colp@oracle.com>
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
.../commands/tpm2_key_protector/module.c | 23 +++++++++++++++----
|
||||
1 file changed, 19 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/tpm2_key_protector/module.c b/grub-core/commands/tpm2_key_protector/module.c
|
||||
index 6b4b5d460..74e79a545 100644
|
||||
--- a/grub-core/commands/tpm2_key_protector/module.c
|
||||
+++ b/grub-core/commands/tpm2_key_protector/module.c
|
||||
@@ -973,11 +973,26 @@ tpm2_protector_srk_recover (const tpm2_protector_context_t *ctx,
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-tpm2_protector_nv_recover (const tpm2_protector_context_t *ctx __attribute__ ((unused)),
|
||||
- grub_uint8_t **key __attribute__ ((unused)),
|
||||
- grub_size_t *key_size __attribute__ ((unused)))
|
||||
+tpm2_protector_nv_recover (const tpm2_protector_context_t *ctx,
|
||||
+ grub_uint8_t **key, grub_size_t *key_size)
|
||||
{
|
||||
- return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "NV Index mode is not implemented yet");
|
||||
+ TPM_HANDLE_t sealed_handle = ctx->nv;
|
||||
+ tpm2key_policy_t policy_seq = NULL;
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ /* Create a basic policy sequence based on the given PCR selection */
|
||||
+ err = tpm2_protector_simple_policy_seq (ctx, &policy_seq);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ goto exit;
|
||||
+
|
||||
+ err = tpm2_protector_unseal (policy_seq, sealed_handle, key, key_size);
|
||||
+
|
||||
+ exit:
|
||||
+ grub_tpm2_flushcontext (sealed_handle);
|
||||
+
|
||||
+ grub_tpm2key_free_policy_seq (policy_seq);
|
||||
+
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
--
|
||||
2.43.0
|
||||
|
||||
158
0001-tpm2_key_protector-Support-authorized-policy.patch
Normal file
158
0001-tpm2_key_protector-Support-authorized-policy.patch
Normal file
@@ -0,0 +1,158 @@
|
||||
From 7ef1b9b357c803cb8e30bbbebd44494b2b5c9d09 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Thu, 6 Apr 2023 16:00:25 +0800
|
||||
Subject: [PATCH] tpm2_key_protector: Support authorized policy
|
||||
|
||||
This commit handles the TPM2_PolicyAuthorize command from the key file
|
||||
in TPM 2.0 Key File format.
|
||||
|
||||
TPM2_PolicyAuthorize is the essential command to support authorized
|
||||
policy which allows the users to sign TPM policies with their own keys.
|
||||
Per TPM 2.0 Key File(*1), CommandPolicy for TPM2_PolicyAuthorize
|
||||
comprises 'TPM2B_PUBLIC pubkey', 'TPM2B_DIGEST policy_ref', and
|
||||
'TPMT_SIGNATURE signature'. To verify the signature, the current policy
|
||||
digest is hashed with the hash algorithm written in 'signature', and then
|
||||
'signature' is verified with the hashed policy digest and 'pubkey'. Once
|
||||
TPM accepts 'signature', TPM2_PolicyAuthorize is invoked to authorize the
|
||||
signed policy.
|
||||
|
||||
To create the key file with authorized policy, here are the pcr-oracle(*2)
|
||||
commands:
|
||||
|
||||
# Generate the RSA key and create the authorized policy file
|
||||
$ pcr-oracle \
|
||||
--rsa-generate-key \
|
||||
--private-key policy-key.pem \
|
||||
--auth authorized.policy \
|
||||
create-authorized-policy 0,2,4,7,9
|
||||
|
||||
# Seal the secret with the authorized policy
|
||||
$ pcr-oracle \
|
||||
--key-format tpm2.0 \
|
||||
--auth authorized.policy \
|
||||
--input disk-secret.txt \
|
||||
--output sealed.key \
|
||||
seal-secret
|
||||
|
||||
# Sign the predicted PCR policy
|
||||
$ pcr-oracle \
|
||||
--key-format tpm2.0 \
|
||||
--private-key policy-key.pem \
|
||||
--from eventlog \
|
||||
--stop-event "grub-file=grub.cfg" \
|
||||
--after \
|
||||
--input sealed.key \
|
||||
--output /boot/efi/efi/grub/sealed.tpm \
|
||||
sign 0,2,4,7,9
|
||||
|
||||
Then specify the key file and the key protector to grub.cfg in the EFI
|
||||
system partition:
|
||||
|
||||
tpm2_key_protector_init -a RSA --tpm2key=(hd0,gpt1)/efi/grub/sealed.tpm
|
||||
cryptomount -u <PART_UUID> -P tpm2
|
||||
|
||||
For any change in the boot components, just run the 'sign' command again
|
||||
to update the signature in sealed.tpm, and TPM can unseal the key file
|
||||
with the updated PCR policy.
|
||||
|
||||
(*1) https://www.hansenpartnership.com/draft-bottomley-tpm2-keys.html
|
||||
(*2) https://github.com/okirch/pcr-oracle
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
.../commands/tpm2_key_protector/module.c | 70 +++++++++++++++++++
|
||||
1 file changed, 70 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/tpm2_key_protector/module.c b/grub-core/commands/tpm2_key_protector/module.c
|
||||
index 70d4d0df7..6b4b5d460 100644
|
||||
--- a/grub-core/commands/tpm2_key_protector/module.c
|
||||
+++ b/grub-core/commands/tpm2_key_protector/module.c
|
||||
@@ -618,6 +618,73 @@ tpm2_protector_policypcr (TPMI_SH_AUTH_SESSION_t session, struct grub_tpm2_buffe
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+tpm2_protector_policyauthorize (TPMI_SH_AUTH_SESSION_t session, struct grub_tpm2_buffer *cmd_buf)
|
||||
+{
|
||||
+ TPM2B_PUBLIC_t pubkey;
|
||||
+ TPM2B_DIGEST_t policy_ref;
|
||||
+ TPMT_SIGNATURE_t signature;
|
||||
+ TPM2B_DIGEST_t pcr_policy;
|
||||
+ TPM2B_DIGEST_t pcr_policy_hash;
|
||||
+ TPMI_ALG_HASH_t sig_hash;
|
||||
+ TPMT_TK_VERIFIED_t verification_ticket;
|
||||
+ TPM_HANDLE_t pubkey_handle = 0;
|
||||
+ TPM2B_NAME_t pubname;
|
||||
+ TPM_RC_t rc;
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (cmd_buf, &pubkey);
|
||||
+ grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (cmd_buf, &policy_ref);
|
||||
+ grub_Tss2_MU_TPMT_SIGNATURE_Unmarshal (cmd_buf, &signature);
|
||||
+ if (cmd_buf->error != 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to unmarshal the buffer for TPM2_PolicyAuthorize");
|
||||
+
|
||||
+ /* Retrieve Policy Digest */
|
||||
+ rc = grub_tpm2_policygetdigest (session, NULL, &pcr_policy, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE, "failed to get policy digest (TPM2_PolicyGetDigest: 0x%x).", rc);
|
||||
+
|
||||
+ /* Calculate the digest of the polcy for VerifySignature */
|
||||
+ sig_hash = TPMT_SIGNATURE_get_hash_alg (&signature);
|
||||
+ if (sig_hash == TPM_ALG_NULL)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to get the hash algorithm of the signature");
|
||||
+
|
||||
+ rc = grub_tpm2_hash (NULL, (TPM2B_MAX_BUFFER_t *) &pcr_policy, sig_hash,
|
||||
+ TPM_RH_NULL, &pcr_policy_hash, NULL, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE, "failed to create PCR policy hash (TPM2_Hash: 0x%x)", rc);
|
||||
+
|
||||
+ /* Load the public key */
|
||||
+ rc = grub_tpm2_loadexternal (NULL, NULL, &pubkey, TPM_RH_OWNER, &pubkey_handle, &pubname, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE, "failed to load public key (TPM2_LoadExternal: 0x%x)", rc);
|
||||
+
|
||||
+ /* Verify the signature against the public key and the policy digest */
|
||||
+ rc = grub_tpm2_verifysignature (pubkey_handle, NULL, &pcr_policy_hash, &signature,
|
||||
+ &verification_ticket, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ err = grub_error (GRUB_ERR_BAD_DEVICE, "failed to verify signature (TPM2_VerifySignature: 0x%x)", rc);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ /* Authorize the signed policy with the public key and the verification ticket */
|
||||
+ rc = grub_tpm2_policyauthorize (session, NULL, &pcr_policy, &policy_ref, &pubname,
|
||||
+ &verification_ticket, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ err = grub_error (GRUB_ERR_BAD_DEVICE, "failed to authorize PCR policy (TPM2_PolicyAuthorize: 0x%x)", rc);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ err = GRUB_ERR_NONE;
|
||||
+
|
||||
+ error:
|
||||
+ grub_tpm2_flushcontext (pubkey_handle);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSION_t session)
|
||||
{
|
||||
@@ -636,6 +703,9 @@ tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSION_t s
|
||||
case TPM_CC_PolicyPCR:
|
||||
err = tpm2_protector_policypcr (session, &buf);
|
||||
break;
|
||||
+ case TPM_CC_PolicyAuthorize:
|
||||
+ err = tpm2_protector_policyauthorize (session, &buf);
|
||||
+ break;
|
||||
default:
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown TPM Command: 0x%x", policy->cmd_code);
|
||||
}
|
||||
--
|
||||
2.43.0
|
||||
|
||||
101
0001-tss2-Adjust-bit-fields-for-big-endian-targets.patch
Normal file
101
0001-tss2-Adjust-bit-fields-for-big-endian-targets.patch
Normal file
@@ -0,0 +1,101 @@
|
||||
From 99ee68a0149b1132f160c80924ab2987ebafcbdd Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Date: Tue, 26 Nov 2024 15:39:40 -0500
|
||||
Subject: [PATCH 1/7] tss2: Adjust bit fields for big endian targets
|
||||
|
||||
The TPM bit fields need to be in reverse order for big endian targets,
|
||||
such as ieee1275 PowerPC platforms that run GRUB in big endian mode.
|
||||
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/lib/tss2/tss2_structs.h | 38 +++++++++++++++++++++++++++++++
|
||||
1 file changed, 38 insertions(+)
|
||||
|
||||
diff --git a/grub-core/lib/tss2/tss2_structs.h b/grub-core/lib/tss2/tss2_structs.h
|
||||
index ca33db3ec..e5390ab56 100644
|
||||
--- a/grub-core/lib/tss2/tss2_structs.h
|
||||
+++ b/grub-core/lib/tss2/tss2_structs.h
|
||||
@@ -147,6 +147,15 @@ typedef TPM2B_DIGEST_t TPM2B_NONCE_t;
|
||||
/* TPMA_SESSION Structure */
|
||||
struct TPMA_SESSION
|
||||
{
|
||||
+#ifdef GRUB_TARGET_WORDS_BIGENDIAN
|
||||
+ grub_uint8_t audit:1;
|
||||
+ grub_uint8_t encrypt:1;
|
||||
+ grub_uint8_t decrypt:1;
|
||||
+ grub_uint8_t reserved:2;
|
||||
+ grub_uint8_t auditReset:1;
|
||||
+ grub_uint8_t auditExclusive:1;
|
||||
+ grub_uint8_t continueSession:1;
|
||||
+#else
|
||||
grub_uint8_t continueSession:1;
|
||||
grub_uint8_t auditExclusive:1;
|
||||
grub_uint8_t auditReset:1;
|
||||
@@ -154,6 +163,7 @@ struct TPMA_SESSION
|
||||
grub_uint8_t decrypt:1;
|
||||
grub_uint8_t encrypt:1;
|
||||
grub_uint8_t audit:1;
|
||||
+#endif
|
||||
};
|
||||
typedef struct TPMA_SESSION TPMA_SESSION_t;
|
||||
|
||||
@@ -206,6 +216,24 @@ typedef struct TPM2B_SENSITIVE_CREATE TPM2B_SENSITIVE_CREATE_t;
|
||||
/* TPMA_OBJECT Structure */
|
||||
struct TPMA_OBJECT
|
||||
{
|
||||
+#ifdef GRUB_TARGET_WORDS_BIGENDIAN
|
||||
+ grub_uint32_t reserved5:13;
|
||||
+ grub_uint32_t sign:1;
|
||||
+ grub_uint32_t decrypt:1;
|
||||
+ grub_uint32_t restricted:1;
|
||||
+ grub_uint32_t reserved4:4;
|
||||
+ grub_uint32_t encryptedDuplication:1;
|
||||
+ grub_uint32_t noDA:1;
|
||||
+ grub_uint32_t reserved3:2;
|
||||
+ grub_uint32_t adminWithPolicy:1;
|
||||
+ grub_uint32_t userWithAuth:1;
|
||||
+ grub_uint32_t sensitiveDataOrigin:1;
|
||||
+ grub_uint32_t fixedParent:1;
|
||||
+ grub_uint32_t reserved2:1;
|
||||
+ grub_uint32_t stClear:1;
|
||||
+ grub_uint32_t fixedTPM:1;
|
||||
+ grub_uint32_t reserved1:1;
|
||||
+#else
|
||||
grub_uint32_t reserved1:1;
|
||||
grub_uint32_t fixedTPM:1;
|
||||
grub_uint32_t stClear:1;
|
||||
@@ -222,6 +250,7 @@ struct TPMA_OBJECT
|
||||
grub_uint32_t decrypt:1;
|
||||
grub_uint32_t sign:1;
|
||||
grub_uint32_t reserved5:13;
|
||||
+#endif
|
||||
};
|
||||
typedef struct TPMA_OBJECT TPMA_OBJECT_t;
|
||||
|
||||
@@ -516,12 +545,21 @@ typedef struct TPM2B_DATA TPM2B_DATA_t;
|
||||
/* TPMA_LOCALITY Structure */
|
||||
struct TPMA_LOCALITY
|
||||
{
|
||||
+#ifdef GRUB_TARGET_WORDS_BIGENDIAN
|
||||
+ grub_uint8_t Extended:3;
|
||||
+ grub_uint8_t TPM_LOC_FOUR:1;
|
||||
+ grub_uint8_t TPM_LOC_THREE:1;
|
||||
+ grub_uint8_t TPM_LOC_TWO:1;
|
||||
+ grub_uint8_t TPM_LOC_ONE:1;
|
||||
+ grub_uint8_t TPM_LOC_ZERO:1;
|
||||
+#else
|
||||
grub_uint8_t TPM_LOC_ZERO:1;
|
||||
grub_uint8_t TPM_LOC_ONE:1;
|
||||
grub_uint8_t TPM_LOC_TWO:1;
|
||||
grub_uint8_t TPM_LOC_THREE:1;
|
||||
grub_uint8_t TPM_LOC_FOUR:1;
|
||||
grub_uint8_t Extended:3;
|
||||
+#endif
|
||||
};
|
||||
typedef struct TPMA_LOCALITY TPMA_LOCALITY_t;
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
188
0001-util-bash-completion-Fix-for-bash-completion-2.12.patch
Normal file
188
0001-util-bash-completion-Fix-for-bash-completion-2.12.patch
Normal file
@@ -0,0 +1,188 @@
|
||||
From 200dc727d1fdf3bac7aa725569b60a54b3841867 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Fri, 22 Mar 2024 16:23:38 +0800
|
||||
Subject: [PATCH] util/bash-completion: Fix for bash-completion 2.12
|
||||
|
||||
_split_longopt() was the bash-completion private API and removed since
|
||||
bash-completion 2.12. This commit initializes the bash-completion
|
||||
general variables with _init_completion() to avoid the potential
|
||||
'command not found' error.
|
||||
|
||||
Although bash-completion 2.12 introduces _comp_initialize() to deprecate
|
||||
_init_completion(), _init_completion() is still chosen for the better
|
||||
backward compatibility.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
.../bash-completion.d/grub-completion.bash.in | 61 +++++++------------
|
||||
1 file changed, 22 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/util/bash-completion.d/grub-completion.bash.in b/util/bash-completion.d/grub-completion.bash.in
|
||||
index 4c88ee901..749a5d3cf 100644
|
||||
--- a/util/bash-completion.d/grub-completion.bash.in
|
||||
+++ b/util/bash-completion.d/grub-completion.bash.in
|
||||
@@ -151,13 +151,10 @@ __grub_list_modules () {
|
||||
# grub-set-default & grub-reboot
|
||||
#
|
||||
__grub_set_entry () {
|
||||
- local cur prev split=false
|
||||
+ local cur prev words cword split
|
||||
+ _init_completion -s || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
- prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
-
|
||||
- _split_longopt && split=true
|
||||
|
||||
case "$prev" in
|
||||
--boot-directory)
|
||||
@@ -180,11 +177,10 @@ __grub_set_entry () {
|
||||
# grub-editenv
|
||||
#
|
||||
__grub_editenv () {
|
||||
- local cur prev
|
||||
+ local cur prev words cword
|
||||
+ _init_completion || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
- prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
|
||||
case "$prev" in
|
||||
create|list|set|unset)
|
||||
@@ -201,10 +197,10 @@ __grub_editenv () {
|
||||
# grub-mkconfig
|
||||
#
|
||||
__grub_mkconfig () {
|
||||
- local cur prev
|
||||
+ local cur prev words cword
|
||||
+ _init_completion || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
|
||||
if [[ "$cur" == -* ]]; then
|
||||
__grubcomp "$(__grub_get_options_from_help)"
|
||||
@@ -217,13 +213,10 @@ __grub_mkconfig () {
|
||||
# grub-setup
|
||||
#
|
||||
__grub_setup () {
|
||||
- local cur prev split=false
|
||||
+ local cur prev words cword split
|
||||
+ _init_completion -s || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
- prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
-
|
||||
- _split_longopt && split=true
|
||||
|
||||
case "$prev" in
|
||||
-d|--directory)
|
||||
@@ -246,15 +239,12 @@ __grub_setup () {
|
||||
# grub-install
|
||||
#
|
||||
__grub_install () {
|
||||
- local cur prev last split=false
|
||||
+ local cur prev words cword split last
|
||||
+ _init_completion -s || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
- prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
last=$(__grub_get_last_option)
|
||||
|
||||
- _split_longopt && split=true
|
||||
-
|
||||
case "$prev" in
|
||||
--boot-directory)
|
||||
_filedir -d
|
||||
@@ -287,10 +277,10 @@ __grub_install () {
|
||||
# grub-mkfont
|
||||
#
|
||||
__grub_mkfont () {
|
||||
- local cur
|
||||
+ local cur prev words cword
|
||||
+ _init_completion || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
|
||||
if [[ "$cur" == -* ]]; then
|
||||
__grubcomp "$(__grub_get_options_from_help)"
|
||||
@@ -304,11 +294,10 @@ __grub_mkfont () {
|
||||
# grub-mkrescue
|
||||
#
|
||||
__grub_mkrescue () {
|
||||
- local cur prev last
|
||||
+ local cur prev words cword last
|
||||
+ _init_completion || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
- prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
last=$(__grub_get_last_option)
|
||||
|
||||
if [[ "$cur" == -* ]]; then
|
||||
@@ -330,13 +319,10 @@ __grub_mkrescue () {
|
||||
# grub-mkimage
|
||||
#
|
||||
__grub_mkimage () {
|
||||
- local cur prev split=false
|
||||
+ local cur prev words cword split
|
||||
+ _init_completion -s || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
- prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
-
|
||||
- _split_longopt && split=true
|
||||
|
||||
case "$prev" in
|
||||
-d|--directory|-p|--prefix)
|
||||
@@ -367,10 +353,10 @@ __grub_mkimage () {
|
||||
# grub-mkpasswd-pbkdf2
|
||||
#
|
||||
__grub_mkpasswd_pbkdf2 () {
|
||||
- local cur
|
||||
+ local cur prev words cword
|
||||
+ _init_completion || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
|
||||
if [[ "$cur" == -* ]]; then
|
||||
__grubcomp "$(__grub_get_options_from_help)"
|
||||
@@ -384,13 +370,10 @@ __grub_mkpasswd_pbkdf2 () {
|
||||
# grub-probe
|
||||
#
|
||||
__grub_probe () {
|
||||
- local cur prev split=false
|
||||
+ local cur prev words cword split
|
||||
+ _init_completion -s || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
- prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
-
|
||||
- _split_longopt && split=true
|
||||
|
||||
case "$prev" in
|
||||
-t|--target)
|
||||
@@ -417,10 +400,10 @@ __grub_probe () {
|
||||
# grub-script-check
|
||||
#
|
||||
__grub_script_check () {
|
||||
- local cur
|
||||
+ local cur prev words cword
|
||||
+ _init_completion || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
|
||||
if [[ "$cur" == -* ]]; then
|
||||
__grubcomp "$(__grub_get_options_from_help)"
|
||||
--
|
||||
2.35.3
|
||||
|
||||
1590
0001-util-grub-protect-Add-new-tool.patch
Normal file
1590
0001-util-grub-protect-Add-new-tool.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,83 @@
|
||||
From 6c06378c1bf6ae21788427e62ab0011b7f1bc2f0 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 25 Nov 2022 16:11:24 +0800
|
||||
Subject: [PATCH] xen_boot: add missing grub_arch_efi_linux_load_image_header
|
||||
|
||||
The new xen_boot module has used grub_arch_efi_linux_load_image_header
|
||||
exported by grub-core/loader/arm64/linux.c. It is not a problem for
|
||||
upstream but many downstream projects may not use it and take
|
||||
grub-core/loader/arm64/efi/linux.c as a replacement as PE entry is the
|
||||
preferred way in combination with shim loader.
|
||||
|
||||
This patch did a trivial workaround just adding back the dropped
|
||||
defintion to the xen_boot itself.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/loader/arm64/xen_boot.c | 50 +++++++++++++++++++++++++++++++
|
||||
1 file changed, 50 insertions(+)
|
||||
|
||||
diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c
|
||||
index 26e1472c9..b82a2db89 100644
|
||||
--- a/grub-core/loader/arm64/xen_boot.c
|
||||
+++ b/grub-core/loader/arm64/xen_boot.c
|
||||
@@ -84,6 +84,56 @@ static int loaded;
|
||||
static struct xen_boot_binary *xen_hypervisor;
|
||||
static struct xen_boot_binary *module_head;
|
||||
|
||||
+/* The function is exported by grub-core/loader/arm64/linux.c that is not built
|
||||
+ * because we use PE entry provided by grub-core/loader/arm64/efi/linux.c
|
||||
+ */
|
||||
+static bool initrd_use_loadfile2 = false;
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_arch_efi_linux_load_image_header (grub_file_t file,
|
||||
+ struct linux_arch_kernel_header * lh)
|
||||
+{
|
||||
+ grub_file_seek (file, 0);
|
||||
+ if (grub_file_read (file, lh, sizeof (*lh)) < (grub_ssize_t) sizeof (*lh))
|
||||
+ return grub_error(GRUB_ERR_FILE_READ_ERROR, "failed to read Linux image header");
|
||||
+
|
||||
+ if ((lh->code0 & 0xffff) != GRUB_PE32_MAGIC)
|
||||
+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
+ N_("plain image kernel not supported - rebuild with CONFIG_(U)EFI_STUB enabled"));
|
||||
+
|
||||
+ grub_dprintf ("linux", "UEFI stub kernel:\n");
|
||||
+ grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset);
|
||||
+
|
||||
+ /*
|
||||
+ * The PE/COFF spec permits the COFF header to appear anywhere in the file, so
|
||||
+ * we need to double check whether it was where we expected it, and if not, we
|
||||
+ * must load it from the correct offset into the pe_image_header field of
|
||||
+ * struct linux_arch_kernel_header.
|
||||
+ */
|
||||
+ if ((grub_uint8_t *) lh + lh->hdr_offset != (grub_uint8_t *) &lh->pe_image_header)
|
||||
+ {
|
||||
+ if (grub_file_seek (file, lh->hdr_offset) == (grub_off_t) -1
|
||||
+ || grub_file_read (file, &lh->pe_image_header,
|
||||
+ sizeof (struct grub_pe_image_header))
|
||||
+ != sizeof (struct grub_pe_image_header))
|
||||
+ return grub_error (GRUB_ERR_FILE_READ_ERROR, "failed to read COFF image header");
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Linux kernels built for any architecture are guaranteed to support the
|
||||
+ * LoadFile2 based initrd loading protocol if the image version is >= 1.
|
||||
+ */
|
||||
+ if (lh->pe_image_header.optional_header.major_image_version >= 1)
|
||||
+ initrd_use_loadfile2 = true;
|
||||
+ else
|
||||
+ initrd_use_loadfile2 = false;
|
||||
+
|
||||
+ grub_dprintf ("linux", "LoadFile2 initrd loading %sabled\n",
|
||||
+ initrd_use_loadfile2 ? "en" : "dis");
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
static __inline grub_addr_t
|
||||
xen_boot_address_align (grub_addr_t start, grub_size_t align)
|
||||
{
|
||||
--
|
||||
2.41.0
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
From f01314a822dbe9ad39b2f7d0f3717ef6e4c24f4a Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 15 Apr 2022 21:45:04 +0800
|
||||
Subject: [PATCH 2/2] Mark environmet blocks as used for image embedding.
|
||||
|
||||
Now that grub will attempt to use full btrfs bootloader area, the
|
||||
embedded image could have overlapped with environment blocks if it's
|
||||
size grows too much. Let's define a dedicated area for environment
|
||||
blocks to the used block mappings for the embedding process so it can be
|
||||
skipped.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/fs/btrfs.c | 3 ++-
|
||||
include/grub/fs.h | 2 ++
|
||||
util/grub-editenv.c | 2 +-
|
||||
3 files changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/grub-core/fs/btrfs.c
|
||||
+++ b/grub-core/fs/btrfs.c
|
||||
@@ -2637,7 +2637,7 @@
|
||||
|
||||
static const struct {
|
||||
struct embed_region available;
|
||||
- struct embed_region used[6];
|
||||
+ struct embed_region used[7];
|
||||
} btrfs_head = {
|
||||
.available = {0, GRUB_DISK_KiB_TO_SECTORS (1024)}, /* The first 1 MiB. */
|
||||
.used = {
|
||||
@@ -2645,6 +2645,7 @@
|
||||
{GRUB_DISK_KiB_TO_SECTORS (64) - 1, 1}, /* Overflow guard. */
|
||||
{GRUB_DISK_KiB_TO_SECTORS (64), GRUB_DISK_KiB_TO_SECTORS (4)}, /* 4 KiB superblock. */
|
||||
{GRUB_DISK_KiB_TO_SECTORS (68), 1}, /* Overflow guard. */
|
||||
+ {GRUB_DISK_KiB_TO_SECTORS (ENV_BTRFS_OFFSET) - 1, 3}, /* Environment Block. */
|
||||
{GRUB_DISK_KiB_TO_SECTORS (1024) - 1, 1}, /* Overflow guard. */
|
||||
{0, 0} /* Array terminator. */
|
||||
}
|
||||
--- a/include/grub/fs.h
|
||||
+++ b/include/grub/fs.h
|
||||
@@ -128,4 +128,6 @@
|
||||
|
||||
grub_fs_t EXPORT_FUNC(grub_fs_probe) (grub_device_t device);
|
||||
|
||||
+#define ENV_BTRFS_OFFSET (256)
|
||||
+
|
||||
#endif /* ! GRUB_FS_HEADER */
|
||||
--- a/util/grub-editenv.c
|
||||
+++ b/util/grub-editenv.c
|
||||
@@ -128,7 +128,7 @@
|
||||
int offset;
|
||||
int size;
|
||||
} fs_envblk_spec[] = {
|
||||
- { "btrfs", 256 * 1024, GRUB_DISK_SECTOR_SIZE },
|
||||
+ { "btrfs", ENV_BTRFS_OFFSET * 1024, GRUB_DISK_SECTOR_SIZE },
|
||||
{ NULL, 0, 0 }
|
||||
};
|
||||
|
||||
278
0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch
Normal file
278
0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch
Normal file
@@ -0,0 +1,278 @@
|
||||
From 0ed98269c5631c4d094b2cee81ce385687803730 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 29 Aug 2024 13:27:30 +0800
|
||||
Subject: [PATCH 2/2] Requiring authentication after tpm unlock for CLI access
|
||||
|
||||
The GRUB may use TPM to verify the integrity of boot components and the
|
||||
result can determine whether a previously sealed key can be released. If
|
||||
everything checks out, showing nothing has been tampered with, the key
|
||||
is released and GRUB unlocks the encrypted root partition for the next
|
||||
stage of booting.
|
||||
|
||||
However, the liberal Command Line Interface (CLI) can be misused by
|
||||
anyone in this case to access files in the encrypted partition one way
|
||||
or another. Despite efforts to keep the CLI secure by preventing utility
|
||||
command output from leaking file content, many techniques in the wild
|
||||
could still be used to exploit the CLI, enabling attacks or learning
|
||||
methods to attack. It's nearly impossible to account for all scenarios
|
||||
where a hack could be applied.
|
||||
|
||||
Therefore, to mitigate potential misuse of the CLI after the root device
|
||||
has been successfully unlocked via TPM, the user should be required to
|
||||
authenticate using the LUKS password. This added layer of security
|
||||
ensures that only authorized users can access the CLI reducing the risk
|
||||
of exploitation or unauthorized access to the encrypted partition.
|
||||
|
||||
Fixes: CVE-2024-49504
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/disk/cryptodisk.c | 84 +++++++++++++++++++++++++++++++++++
|
||||
grub-core/kern/main.c | 12 +++++
|
||||
grub-core/normal/auth.c | 30 +++++++++++++
|
||||
grub-core/normal/main.c | 4 ++
|
||||
grub-core/normal/menu_entry.c | 4 ++
|
||||
include/grub/auth.h | 1 +
|
||||
include/grub/cryptodisk.h | 3 ++
|
||||
include/grub/misc.h | 2 +
|
||||
8 files changed, 140 insertions(+)
|
||||
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1183,6 +1183,9 @@
|
||||
ret = grub_cryptodisk_insert (dev, name, source);
|
||||
if (ret != GRUB_ERR_NONE)
|
||||
goto error;
|
||||
+#ifndef GRUB_UTIL
|
||||
+ grub_cli_set_auth_needed ();
|
||||
+#endif
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
@@ -1700,6 +1703,89 @@
|
||||
return ret;
|
||||
}
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+grub_err_t
|
||||
+grub_cryptodisk_challenge_password (void)
|
||||
+{
|
||||
+ grub_cryptodisk_t cr_dev;
|
||||
+
|
||||
+ for (cr_dev = cryptodisk_list; cr_dev != NULL; cr_dev = cr_dev->next)
|
||||
+ {
|
||||
+ grub_cryptodisk_dev_t cr;
|
||||
+ grub_disk_t source = NULL;
|
||||
+ grub_err_t ret = GRUB_ERR_NONE;
|
||||
+ grub_cryptodisk_t dev = NULL;
|
||||
+ char *part = NULL;
|
||||
+ struct grub_cryptomount_args cargs = {0};
|
||||
+
|
||||
+ cargs.check_boot = 0;
|
||||
+ cargs.search_uuid = cr_dev->uuid;
|
||||
+
|
||||
+ source = grub_disk_open (cr_dev->source);
|
||||
+
|
||||
+ if (source == NULL)
|
||||
+ {
|
||||
+ ret = grub_errno;
|
||||
+ goto error_out;
|
||||
+ }
|
||||
+
|
||||
+ FOR_CRYPTODISK_DEVS (cr)
|
||||
+ {
|
||||
+ dev = cr->scan (source, &cargs);
|
||||
+ if (grub_errno)
|
||||
+ {
|
||||
+ ret = grub_errno;
|
||||
+ goto error_out;
|
||||
+ }
|
||||
+ if (dev == NULL)
|
||||
+ continue;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (dev == NULL)
|
||||
+ {
|
||||
+ ret = grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk module can handle this device");
|
||||
+ goto error_out;
|
||||
+ }
|
||||
+
|
||||
+ part = grub_partition_get_name (source->partition);
|
||||
+ grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
|
||||
+ source->partition != NULL ? "," : "",
|
||||
+ part != NULL ? part : N_("UNKNOWN"), cr_dev->uuid);
|
||||
+ grub_free (part);
|
||||
+
|
||||
+ cargs.key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE);
|
||||
+ if (cargs.key_data == NULL)
|
||||
+ {
|
||||
+ ret = grub_errno;
|
||||
+ goto error_out;
|
||||
+ }
|
||||
+
|
||||
+ if (!grub_password_get ((char *) cargs.key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE))
|
||||
+ {
|
||||
+ ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied");
|
||||
+ goto error_out;
|
||||
+ }
|
||||
+ cargs.key_len = grub_strlen ((char *) cargs.key_data);
|
||||
+ ret = cr->recover_key (source, dev, &cargs);
|
||||
+
|
||||
+ error_out:
|
||||
+ grub_disk_close (source);
|
||||
+ if (dev != NULL)
|
||||
+ cryptodisk_close (dev);
|
||||
+ if (cargs.key_data)
|
||||
+ {
|
||||
+ grub_memset (cargs.key_data, 0, cargs.key_len);
|
||||
+ grub_free (cargs.key_data);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+#endif /* GRUB_MACHINE_EFI */
|
||||
+
|
||||
struct grub_procfs_entry luks_script =
|
||||
{
|
||||
.name = "luks_script",
|
||||
--- a/grub-core/kern/main.c
|
||||
+++ b/grub-core/kern/main.c
|
||||
@@ -37,6 +37,7 @@
|
||||
#endif
|
||||
|
||||
static bool cli_disabled = false;
|
||||
+static bool cli_need_auth = false;
|
||||
|
||||
grub_addr_t
|
||||
grub_modules_get_end (void)
|
||||
@@ -246,6 +247,17 @@
|
||||
return cli_disabled;
|
||||
}
|
||||
|
||||
+bool
|
||||
+grub_is_cli_need_auth (void)
|
||||
+{
|
||||
+ return cli_need_auth;
|
||||
+}
|
||||
+
|
||||
+void grub_cli_set_auth_needed (void)
|
||||
+{
|
||||
+ cli_need_auth = true;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
check_is_cli_disabled (void)
|
||||
{
|
||||
--- a/grub-core/normal/auth.c
|
||||
+++ b/grub-core/normal/auth.c
|
||||
@@ -25,6 +25,10 @@
|
||||
#include <grub/time.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+#include <grub/cryptodisk.h>
|
||||
+#endif
|
||||
+
|
||||
struct grub_auth_user
|
||||
{
|
||||
struct grub_auth_user *next;
|
||||
@@ -201,6 +205,32 @@
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
+grub_auth_check_cli_access (void)
|
||||
+{
|
||||
+ if (grub_is_cli_need_auth () == true)
|
||||
+ {
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+ static bool authenticated = false;
|
||||
+
|
||||
+ if (authenticated == false)
|
||||
+ {
|
||||
+ grub_err_t ret;
|
||||
+
|
||||
+ ret = grub_cryptodisk_challenge_password ();
|
||||
+ if (ret == GRUB_ERR_NONE)
|
||||
+ authenticated = true;
|
||||
+ return ret;
|
||||
+ }
|
||||
+ return GRUB_ERR_NONE;
|
||||
+#else
|
||||
+ return GRUB_ACCESS_DENIED;
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
grub_auth_check_authentication (const char *userlist)
|
||||
{
|
||||
char login[1024];
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -560,9 +560,13 @@
|
||||
}
|
||||
while (err && force_auth);
|
||||
|
||||
+ if (err == GRUB_ERR_NONE)
|
||||
+ err = grub_auth_check_cli_access ();
|
||||
+
|
||||
if (err)
|
||||
{
|
||||
grub_print_error ();
|
||||
+ grub_wait_after_message ();
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return;
|
||||
}
|
||||
--- a/grub-core/normal/menu_entry.c
|
||||
+++ b/grub-core/normal/menu_entry.c
|
||||
@@ -1256,9 +1256,13 @@
|
||||
|
||||
err = grub_auth_check_authentication (NULL);
|
||||
|
||||
+ if (err == GRUB_ERR_NONE)
|
||||
+ err = grub_auth_check_cli_access ();
|
||||
+
|
||||
if (err)
|
||||
{
|
||||
grub_print_error ();
|
||||
+ grub_wait_after_message ();
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return;
|
||||
}
|
||||
--- a/include/grub/auth.h
|
||||
+++ b/include/grub/auth.h
|
||||
@@ -33,5 +33,6 @@
|
||||
grub_err_t grub_auth_authenticate (const char *user);
|
||||
grub_err_t grub_auth_deauthenticate (const char *user);
|
||||
grub_err_t grub_auth_check_authentication (const char *userlist);
|
||||
+grub_err_t grub_auth_check_cli_access (void);
|
||||
|
||||
#endif /* ! GRUB_AUTH_HEADER */
|
||||
--- a/include/grub/cryptodisk.h
|
||||
+++ b/include/grub/cryptodisk.h
|
||||
@@ -203,4 +203,7 @@
|
||||
grub_cryptodisk_t grub_cryptodisk_get_by_uuid (const char *uuid);
|
||||
grub_cryptodisk_t grub_cryptodisk_get_by_source_disk (grub_disk_t disk);
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+grub_err_t grub_cryptodisk_challenge_password (void);
|
||||
+#endif
|
||||
#endif
|
||||
--- a/include/grub/misc.h
|
||||
+++ b/include/grub/misc.h
|
||||
@@ -392,6 +392,8 @@
|
||||
grub_uint64_t *r);
|
||||
|
||||
extern bool EXPORT_FUNC(grub_is_cli_disabled) (void);
|
||||
+extern bool EXPORT_FUNC(grub_is_cli_need_auth) (void);
|
||||
+extern void EXPORT_FUNC(grub_cli_set_auth_needed) (void);
|
||||
|
||||
/* Must match softdiv group in gentpl.py. */
|
||||
#if !defined(GRUB_MACHINE_EMU) && (defined(__arm__) || defined(__ia64__) || \
|
||||
@@ -1,69 +0,0 @@
|
||||
From a2d103ac650e5ea10ac6d40f3a5c1a136ee96613 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 19 Jan 2026 14:29:05 +0800
|
||||
Subject: [PATCH 2/2] Revert "configure: Check linker for --image-base support"
|
||||
|
||||
This reverts commit 1a5417f39a0ccefcdd5440f2a67f84d2d2e26960.
|
||||
---
|
||||
acinclude.m4 | 5 -----
|
||||
configure.ac | 14 ++------------
|
||||
2 files changed, 2 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/acinclude.m4 b/acinclude.m4
|
||||
index 70c1912f8..fa7840f09 100644
|
||||
--- a/acinclude.m4
|
||||
+++ b/acinclude.m4
|
||||
@@ -79,11 +79,6 @@ AC_DEFUN([grub_PROG_OBJCOPY_ABSOLUTE],
|
||||
[AC_MSG_CHECKING([whether ${TARGET_OBJCOPY} works for absolute addresses])
|
||||
AC_CACHE_VAL(grub_cv_prog_objcopy_absolute,
|
||||
[cat > conftest.c <<\EOF
|
||||
-asm (
|
||||
- ".globl start, _start, __start\n"
|
||||
- ".ifdef cmain; .set start = _start = __start = cmain\n.endif\n"
|
||||
- ".ifdef _cmain; .set start = _start = __start = _cmain\n.endif\n"
|
||||
-);
|
||||
void cmain (void);
|
||||
void
|
||||
cmain (void)
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index b4d4db944..450524d47 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -1461,6 +1461,7 @@ elif test x$grub_cv_target_cc_link_format = x-mi386pe || test x$grub_cv_target_c
|
||||
TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/i386-cygwin-img-ld.sc"
|
||||
TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}"
|
||||
TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/i386-cygwin-img-ld.sc"
|
||||
+ TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"
|
||||
TARGET_IMG_CFLAGS=
|
||||
else
|
||||
TARGET_APPLE_LINKER=0
|
||||
@@ -1468,6 +1469,7 @@ else
|
||||
TARGET_IMG_LDSCRIPT=
|
||||
TARGET_IMG_LDFLAGS='-Wl,-N'
|
||||
TARGET_IMG_LDFLAGS_AC='-Wl,-N'
|
||||
+ TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"
|
||||
TARGET_IMG_CFLAGS=
|
||||
fi
|
||||
|
||||
@@ -1793,18 +1795,6 @@ LIBS=""
|
||||
grub_ASM_USCORE
|
||||
grub_PROG_TARGET_CC
|
||||
if test "x$TARGET_APPLE_LINKER" != x1 ; then
|
||||
-AX_CHECK_LINK_FLAG([-Wl,--image-base,0x400000],
|
||||
- [TARGET_IMG_BASE_LDOPT="-Wl,--image-base"],
|
||||
- [TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"],
|
||||
- [],
|
||||
- [AC_LANG_SOURCE([
|
||||
-asm (".globl start; start:");
|
||||
-asm (".globl _start; _start:");
|
||||
-asm (".globl __start; __start:");
|
||||
-void __main (void);
|
||||
-void __main (void) {}
|
||||
-int main (void);
|
||||
- ])])
|
||||
grub_PROG_OBJCOPY_ABSOLUTE
|
||||
fi
|
||||
grub_PROG_LD_BUILD_ID_NONE
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@@ -16,7 +16,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1920,7 +1920,6 @@
|
||||
@@ -1860,7 +1860,6 @@
|
||||
x86_64_efi = loader/efi/linux.c;
|
||||
emu = loader/emu/linux.c;
|
||||
common = loader/linux.c;
|
||||
@@ -24,9 +24,9 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
};
|
||||
|
||||
module = {
|
||||
@@ -2787,3 +2786,8 @@
|
||||
cflags = '-Wno-uninitialized';
|
||||
cppflags = '-I$(srcdir)/lib/libtasn1-grub -I$(srcdir)/tests/asn1/';
|
||||
@@ -2611,3 +2610,8 @@
|
||||
efi = commands/bli.c;
|
||||
enable = efi;
|
||||
};
|
||||
+
|
||||
+module = {
|
||||
|
||||
134
0002-commands-search-Introduce-the-cryptodisk-only-argume.patch
Normal file
134
0002-commands-search-Introduce-the-cryptodisk-only-argume.patch
Normal file
@@ -0,0 +1,134 @@
|
||||
From 9ad07efefe389568c2cedc77a4a6b48cb830dc0a Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Thu, 8 May 2025 19:02:08 +0200
|
||||
Subject: [PATCH 2/8] commands/search: Introduce the --cryptodisk-only argument
|
||||
|
||||
This allows users to restrict the "search" command's scope to
|
||||
encrypted disks only.
|
||||
|
||||
Typically, this command is used to "rebase" $root and $prefix
|
||||
before loading additional configuration files via "source" or
|
||||
"configfile". Unfortunately, this leads to security problems,
|
||||
like CVE-2023-4001, when an unexpected, attacker-controlled
|
||||
device is chosen by the "search" command.
|
||||
|
||||
The --cryptodisk-only argument allows users to ensure that the
|
||||
file system picked is encrypted.
|
||||
|
||||
This feature supports the CLI authentication, blocking bypass
|
||||
attempts.
|
||||
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/commands/search.c | 20 ++++++++++++++++++++
|
||||
grub-core/commands/search_wrap.c | 7 ++++++-
|
||||
grub-core/normal/main.c | 3 ++-
|
||||
include/grub/search.h | 7 ++++---
|
||||
4 files changed, 32 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
|
||||
index 263f1501cd..f6bfef9585 100644
|
||||
--- a/grub-core/commands/search.c
|
||||
+++ b/grub-core/commands/search.c
|
||||
@@ -86,6 +86,26 @@ iterate_device (const char *name, void *data)
|
||||
grub_device_close (dev);
|
||||
}
|
||||
|
||||
+ /* Limit to encrypted disks when requested. */
|
||||
+ if (ctx->flags & SEARCH_FLAGS_CRYPTODISK_ONLY)
|
||||
+ {
|
||||
+ grub_device_t dev;
|
||||
+
|
||||
+ dev = grub_device_open (name);
|
||||
+ if (dev == NULL)
|
||||
+ {
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (dev->disk == NULL || dev->disk->dev->id != GRUB_DISK_DEVICE_CRYPTODISK_ID)
|
||||
+ {
|
||||
+ grub_device_close (dev);
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ grub_device_close (dev);
|
||||
+ }
|
||||
+
|
||||
#ifdef DO_SEARCH_FS_UUID
|
||||
#define compare_fn grub_strcasecmp
|
||||
#else
|
||||
diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c
|
||||
index 318581f3b1..5f536006cf 100644
|
||||
--- a/grub-core/commands/search_wrap.c
|
||||
+++ b/grub-core/commands/search_wrap.c
|
||||
@@ -41,6 +41,7 @@ static const struct grub_arg_option options[] =
|
||||
ARG_TYPE_STRING},
|
||||
{"no-floppy", 'n', 0, N_("Do not probe any floppy drive."), 0, 0},
|
||||
{"efidisk-only", 0, 0, N_("Only probe EFI disks."), 0, 0},
|
||||
+ {"cryptodisk-only", 0, 0, N_("Only probe encrypted disks."), 0, 0},
|
||||
{"hint", 'h', GRUB_ARG_OPTION_REPEATABLE,
|
||||
N_("First try the device HINT. If HINT ends in comma, "
|
||||
"also try subpartitions"), N_("HINT"), ARG_TYPE_STRING},
|
||||
@@ -75,6 +76,7 @@ enum options
|
||||
SEARCH_SET,
|
||||
SEARCH_NO_FLOPPY,
|
||||
SEARCH_EFIDISK_ONLY,
|
||||
+ SEARCH_CRYPTODISK_ONLY,
|
||||
SEARCH_HINT,
|
||||
SEARCH_HINT_IEEE1275,
|
||||
SEARCH_HINT_BIOS,
|
||||
@@ -189,6 +191,9 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
if (state[SEARCH_EFIDISK_ONLY].set)
|
||||
flags |= SEARCH_FLAGS_EFIDISK_ONLY;
|
||||
|
||||
+ if (state[SEARCH_CRYPTODISK_ONLY].set)
|
||||
+ flags |= SEARCH_FLAGS_CRYPTODISK_ONLY;
|
||||
+
|
||||
if (state[SEARCH_LABEL].set)
|
||||
grub_search_label (id, var, flags, hints, nhints);
|
||||
else if (state[SEARCH_FS_UUID].set)
|
||||
@@ -210,7 +215,7 @@ GRUB_MOD_INIT(search)
|
||||
cmd =
|
||||
grub_register_extcmd ("search", grub_cmd_search,
|
||||
GRUB_COMMAND_FLAG_EXTRACTOR | GRUB_COMMAND_ACCEPT_DASH,
|
||||
- N_("[-f|-l|-u|-s|-n] [--hint HINT [--hint HINT] ...]"
|
||||
+ N_("[-f|-l|-u|-s|-n] [--cryptodisk-only] [--hint HINT [--hint HINT] ...]"
|
||||
" NAME"),
|
||||
N_("Search devices by file, filesystem label"
|
||||
" or filesystem UUID."
|
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
|
||||
index d1cbaa1806..320adbe337 100644
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -647,7 +647,8 @@ static const char *features[] = {
|
||||
"feature_chainloader_bpb", "feature_ntldr", "feature_platform_search_hint",
|
||||
"feature_default_font_path", "feature_all_video_module",
|
||||
"feature_menuentry_id", "feature_menuentry_options", "feature_200_final",
|
||||
- "feature_nativedisk_cmd", "feature_timeout_style"
|
||||
+ "feature_nativedisk_cmd", "feature_timeout_style",
|
||||
+ "feature_search_cryptodisk_only"
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT(normal)
|
||||
diff --git a/include/grub/search.h b/include/grub/search.h
|
||||
index ffd2411ca1..3eabaf0ccd 100644
|
||||
--- a/include/grub/search.h
|
||||
+++ b/include/grub/search.h
|
||||
@@ -21,9 +21,10 @@
|
||||
|
||||
enum search_flags
|
||||
{
|
||||
- SEARCH_FLAGS_NONE = 0,
|
||||
- SEARCH_FLAGS_NO_FLOPPY = 1,
|
||||
- SEARCH_FLAGS_EFIDISK_ONLY = 2
|
||||
+ SEARCH_FLAGS_NONE = 0,
|
||||
+ SEARCH_FLAGS_NO_FLOPPY = 1,
|
||||
+ SEARCH_FLAGS_EFIDISK_ONLY = 2,
|
||||
+ SEARCH_FLAGS_CRYPTODISK_ONLY = 4
|
||||
};
|
||||
|
||||
void grub_search_fs_file (const char *key, const char *var,
|
||||
--
|
||||
2.49.0
|
||||
|
||||
43
0002-cryptodisk-Fallback-to-passphrase.patch
Normal file
43
0002-cryptodisk-Fallback-to-passphrase.patch
Normal file
@@ -0,0 +1,43 @@
|
||||
From e62b26f9765e309691e014f322d4b02b220956a1 Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Colp <patrick.colp@oracle.com>
|
||||
Date: Sun, 30 Jul 2023 12:58:18 -0700
|
||||
Subject: [PATCH 2/4] cryptodisk: Fallback to passphrase
|
||||
|
||||
If a protector is specified, but it fails to unlock the disk, fall back
|
||||
to asking for the passphrase. However, an error was set indicating that
|
||||
the protector(s) failed. Later code (e.g., LUKS code) fails as
|
||||
`grub_errno` is now set. Print the existing errors out first, before
|
||||
proceeding with the passphrase.
|
||||
|
||||
Signed-off-by: Patrick Colp <patrick.colp@oracle.com>
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
---
|
||||
grub-core/disk/cryptodisk.c | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index af4104178..f9842f776 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1193,11 +1193,16 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
source->name, source->partition != NULL ? "," : "",
|
||||
part != NULL ? part : N_("UNKNOWN"), dev->uuid);
|
||||
grub_free (part);
|
||||
- goto error;
|
||||
}
|
||||
|
||||
if (!cargs->key_len)
|
||||
{
|
||||
+ if (grub_errno)
|
||||
+ {
|
||||
+ grub_print_error ();
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ }
|
||||
+
|
||||
/* Get the passphrase from the user, if no key data. */
|
||||
askpass = 1;
|
||||
part = grub_partition_get_name (source->partition);
|
||||
--
|
||||
2.35.3
|
||||
|
||||
34
0002-fs-ufs-Fix-a-heap-OOB-write.patch
Normal file
34
0002-fs-ufs-Fix-a-heap-OOB-write.patch
Normal file
@@ -0,0 +1,34 @@
|
||||
From daec67a7ea73b859e1e0b6a4e9122157c7525676 Mon Sep 17 00:00:00 2001
|
||||
From: B Horn <b@horn.uk>
|
||||
Date: Sun, 12 May 2024 02:03:33 +0100
|
||||
Subject: [PATCH 02/20] fs/ufs: Fix a heap OOB write
|
||||
|
||||
grub_strcpy() was used to copy a symlink name from the filesystem
|
||||
image to a heap allocated buffer. This led to a OOB write to adjacent
|
||||
heap allocations. Fix by using grub_strlcpy().
|
||||
|
||||
Fixes: CVE-2024-45781
|
||||
|
||||
Reported-by: B Horn <b@horn.uk>
|
||||
Signed-off-by: B Horn <b@horn.uk>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/fs/ufs.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c
|
||||
index a354c92d93..01235101b4 100644
|
||||
--- a/grub-core/fs/ufs.c
|
||||
+++ b/grub-core/fs/ufs.c
|
||||
@@ -463,7 +463,7 @@ grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino)
|
||||
/* Check against zero is paylindromic, no need to swap. */
|
||||
if (data->inode.nblocks == 0
|
||||
&& INODE_SIZE (data) <= sizeof (data->inode.symlink))
|
||||
- grub_strcpy (symlink, (char *) data->inode.symlink);
|
||||
+ grub_strlcpy (symlink, (char *) data->inode.symlink, sz);
|
||||
else
|
||||
{
|
||||
if (grub_ufs_read_file (data, 0, 0, 0, sz, symlink) < 0)
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
From 3a69e9126d532214d940c1386f2933a124611a6c Mon Sep 17 00:00:00 2001
|
||||
From: Egor Ignatov <egori@altlinux.org>
|
||||
Date: Thu, 23 Jan 2025 20:44:14 +0300
|
||||
Subject: [PATCH 2/3] fs/xfs: Fix grub_xfs_iterate_dir() return value in case
|
||||
of failure
|
||||
|
||||
Commit ef7850c757 (fs/xfs: Fix issues found while fuzzing the XFS
|
||||
filesystem) introduced multiple boundary checks in grub_xfs_iterate_dir()
|
||||
but handled the error incorrectly returning error code instead of 0.
|
||||
Fix it. Also change the error message so that it doesn't match the
|
||||
message in grub_xfs_read_inode().
|
||||
|
||||
Fixes: ef7850c757 (fs/xfs: Fix issues found while fuzzing the XFS filesystem)
|
||||
|
||||
Signed-off-by: Egor Ignatov <egori@altlinux.org>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/fs/xfs.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
|
||||
index e3a69fe498..30e3e7f6d9 100644
|
||||
--- a/grub-core/fs/xfs.c
|
||||
+++ b/grub-core/fs/xfs.c
|
||||
@@ -859,7 +859,11 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
grub_uint8_t c;
|
||||
|
||||
if ((inopos + (smallino ? 4 : 8)) > (grub_uint8_t *) dir + grub_xfs_fshelp_size (dir->data))
|
||||
- return grub_error (GRUB_ERR_BAD_FS, "not a correct XFS inode");
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_FS, "invalid XFS inode");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
|
||||
/* inopos might be unaligned. */
|
||||
if (smallino)
|
||||
@@ -968,7 +972,10 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
|
||||
filename = (char *)(direntry + 1);
|
||||
if (filename + direntry->len + 1 > (char *) end)
|
||||
- return grub_error (GRUB_ERR_BAD_FS, "invalid XFS directory entry");
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_FS, "invalid XFS directory entry");
|
||||
+ return 0;
|
||||
+ }
|
||||
|
||||
/* The byte after the filename is for the filetype, padding, or
|
||||
tag, which is not used by GRUB. So it can be overwritten. */
|
||||
--
|
||||
2.48.1
|
||||
|
||||
216
0002-ieee1275-Platform-Keystore-PKS-Support.patch
Normal file
216
0002-ieee1275-Platform-Keystore-PKS-Support.patch
Normal file
@@ -0,0 +1,216 @@
|
||||
From ec0951f742d03f585454f0a50f588fc7ea42a257 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Mon, 24 Feb 2025 18:40:11 +0530
|
||||
Subject: [PATCH 2/9] ieee1275: Platform Keystore (PKS) Support
|
||||
|
||||
enhancing the infrastructure to enable the Platform Keystore (PKS) feature,
|
||||
which provides access to the SB VERSION, DB, and DBX secure boot variables
|
||||
from PKS.
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
---
|
||||
grub-core/Makefile.am | 1 +
|
||||
grub-core/Makefile.core.def | 1 +
|
||||
grub-core/kern/powerpc/ieee1275/ieee1275.c | 140 +++++++++++++++++++++
|
||||
include/grub/powerpc/ieee1275/ieee1275.h | 14 +++
|
||||
4 files changed, 156 insertions(+)
|
||||
create mode 100644 grub-core/kern/powerpc/ieee1275/ieee1275.c
|
||||
|
||||
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
|
||||
index 9d3d5f5193..40ed353aba 100644
|
||||
--- a/grub-core/Makefile.am
|
||||
+++ b/grub-core/Makefile.am
|
||||
@@ -241,6 +241,7 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||
endif
|
||||
|
||||
if COND_powerpc_ieee1275
|
||||
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/powerpc/ieee1275/ieee1275.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/alloc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index e1698a6923..1dfcf5f991 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -328,6 +328,7 @@ kernel = {
|
||||
extra_dist = video/sis315_init.c;
|
||||
mips_loongson = commands/keylayouts.c;
|
||||
|
||||
+ powerpc_ieee1275 = kern/powerpc/ieee1275/ieee1275.c;
|
||||
powerpc_ieee1275 = kern/powerpc/cache.S;
|
||||
powerpc_ieee1275 = kern/powerpc/dl.c;
|
||||
powerpc_ieee1275 = kern/powerpc/compiler-rt.S;
|
||||
diff --git a/grub-core/kern/powerpc/ieee1275/ieee1275.c b/grub-core/kern/powerpc/ieee1275/ieee1275.c
|
||||
new file mode 100644
|
||||
index 0000000000..f685afcfff
|
||||
--- /dev/null
|
||||
+++ b/grub-core/kern/powerpc/ieee1275/ieee1275.c
|
||||
@@ -0,0 +1,140 @@
|
||||
+/* of.c - Access the Open Firmware client interface. */
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
|
||||
+ *
|
||||
+ * GRUB is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation, either version 3 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * GRUB is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+#include <grub/ieee1275/ieee1275.h>
|
||||
+#include <grub/powerpc/ieee1275/ieee1275.h>
|
||||
+#include <grub/misc.h>
|
||||
+
|
||||
+#define IEEE1275_CELL_INVALID ((grub_ieee1275_cell_t) - 1)
|
||||
+
|
||||
+int
|
||||
+grub_ieee1275_test (const char *name, grub_ieee1275_cell_t *missing)
|
||||
+{
|
||||
+ struct test_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t name;
|
||||
+ grub_ieee1275_cell_t missing;
|
||||
+ } args;
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&args.common, "test", 1, 1);
|
||||
+ args.name = (grub_ieee1275_cell_t) name;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (args.missing == IEEE1275_CELL_INVALID)
|
||||
+ return -1;
|
||||
+
|
||||
+ *missing = args.missing;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+grub_ieee1275_pks_max_object_size (grub_size_t *result)
|
||||
+{
|
||||
+ struct mos_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t size;
|
||||
+ } args;
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&args.common, "pks-max-object-size", 0, 1);
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (args.size == IEEE1275_CELL_INVALID)
|
||||
+ return -1;
|
||||
+
|
||||
+ *result = args.size;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+grub_ieee1275_pks_read_object (grub_uint8_t consumer, grub_uint8_t *label,
|
||||
+ grub_size_t label_len, grub_uint8_t *buffer,
|
||||
+ grub_size_t buffer_len, grub_size_t *data_len,
|
||||
+ grub_uint32_t *policies)
|
||||
+{
|
||||
+ struct pks_read_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t consumer;
|
||||
+ grub_ieee1275_cell_t label;
|
||||
+ grub_ieee1275_cell_t label_len;
|
||||
+ grub_ieee1275_cell_t buffer;
|
||||
+ grub_ieee1275_cell_t buffer_len;
|
||||
+ grub_ieee1275_cell_t data_len;
|
||||
+ grub_ieee1275_cell_t policies;
|
||||
+ grub_ieee1275_cell_t rc;
|
||||
+ } args;
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&args.common, "pks-read-object", 5, 3);
|
||||
+ args.consumer = (grub_ieee1275_cell_t) consumer;
|
||||
+ args.label = (grub_ieee1275_cell_t) label;
|
||||
+ args.label_len = (grub_ieee1275_cell_t) label_len;
|
||||
+ args.buffer = (grub_ieee1275_cell_t) buffer;
|
||||
+ args.buffer_len = (grub_ieee1275_cell_t) buffer_len;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (args.data_len == IEEE1275_CELL_INVALID)
|
||||
+ return -1;
|
||||
+
|
||||
+ *data_len = args.data_len;
|
||||
+ *policies = args.policies;
|
||||
+
|
||||
+ return (int) args.rc;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+grub_ieee1275_pks_read_sbvar (grub_uint8_t sbvarflags, grub_uint8_t sbvartype,
|
||||
+ grub_uint8_t *buffer, grub_size_t buffer_len,
|
||||
+ grub_size_t *data_len)
|
||||
+{
|
||||
+ struct pks_read_sbvar_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t sbvarflags;
|
||||
+ grub_ieee1275_cell_t sbvartype;
|
||||
+ grub_ieee1275_cell_t buffer;
|
||||
+ grub_ieee1275_cell_t buffer_len;
|
||||
+ grub_ieee1275_cell_t data_len;
|
||||
+ grub_ieee1275_cell_t rc;
|
||||
+ } args;
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&args.common, "pks-read-sbvar", 4, 2);
|
||||
+ args.sbvarflags = (grub_ieee1275_cell_t) sbvarflags;
|
||||
+ args.sbvartype = (grub_ieee1275_cell_t) sbvartype;
|
||||
+ args.buffer = (grub_ieee1275_cell_t) buffer;
|
||||
+ args.buffer_len = (grub_ieee1275_cell_t) buffer_len;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (args.data_len == IEEE1275_CELL_INVALID)
|
||||
+ return -1;
|
||||
+
|
||||
+ *data_len = args.data_len;
|
||||
+
|
||||
+ return (int) args.rc;
|
||||
+}
|
||||
diff --git a/include/grub/powerpc/ieee1275/ieee1275.h b/include/grub/powerpc/ieee1275/ieee1275.h
|
||||
index 4eb2070188..0d48331c26 100644
|
||||
--- a/include/grub/powerpc/ieee1275/ieee1275.h
|
||||
+++ b/include/grub/powerpc/ieee1275/ieee1275.h
|
||||
@@ -28,4 +28,18 @@ typedef grub_uint32_t grub_ieee1275_cell_t;
|
||||
#define PRIxGRUB_IEEE1275_CELL_T PRIxGRUB_UINT32_T
|
||||
#define PRIuGRUB_IEEE1275_CELL_T PRIuGRUB_UINT32_T
|
||||
|
||||
+int EXPORT_FUNC (grub_ieee1275_test) (const char *name,
|
||||
+ grub_ieee1275_cell_t *missing);
|
||||
+
|
||||
+int grub_ieee1275_pks_max_object_size (grub_size_t *result);
|
||||
+
|
||||
+int grub_ieee1275_pks_read_object (grub_uint8_t consumer, grub_uint8_t *label,
|
||||
+ grub_size_t label_len, grub_uint8_t *buffer,
|
||||
+ grub_size_t buffer_len, grub_size_t *data_len,
|
||||
+ grub_uint32_t *policies);
|
||||
+
|
||||
+int grub_ieee1275_pks_read_sbvar (grub_uint8_t sbvarflags, grub_uint8_t sbvartype,
|
||||
+ grub_uint8_t *buffer, grub_size_t buffer_len,
|
||||
+ grub_size_t *data_len);
|
||||
+
|
||||
#endif /* ! GRUB_IEEE1275_MACHINE_HEADER */
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@@ -29,7 +29,7 @@ Fix gcc-12 error: pointer 'device_path' may be used after 'free'
|
||||
|
||||
#ifdef __sparc__
|
||||
typedef enum
|
||||
@@ -757,13 +758,74 @@
|
||||
@@ -754,13 +755,74 @@
|
||||
return new;
|
||||
}
|
||||
|
||||
@@ -90,8 +90,8 @@ Fix gcc-12 error: pointer 'device_path' may be used after 'free'
|
||||
char *
|
||||
grub_util_devname_to_ofpath (const char *sys_devname)
|
||||
{
|
||||
- char *name_buf, *device, *devnode, *devicenode, *ofpath = NULL;
|
||||
+ char *name_buf, *device, *devnode, *devicenode, *ofpath = NULL, *realname;
|
||||
- char *name_buf, *device, *devnode, *devicenode, *ofpath;
|
||||
+ char *name_buf, *device, *devnode, *devicenode, *ofpath, *realname;
|
||||
|
||||
name_buf = xrealpath (sys_devname);
|
||||
|
||||
@@ -104,4 +104,4 @@ Fix gcc-12 error: pointer 'device_path' may be used after 'free'
|
||||
+
|
||||
device = get_basename (name_buf);
|
||||
devnode = strip_trailing_digits (name_buf);
|
||||
if (devnode == NULL)
|
||||
devicenode = strip_trailing_digits (device);
|
||||
|
||||
91
0002-lib-pbkdf2-Optimize-PBKDF2-by-reusing-HMAC-handle.patch
Normal file
91
0002-lib-pbkdf2-Optimize-PBKDF2-by-reusing-HMAC-handle.patch
Normal file
@@ -0,0 +1,91 @@
|
||||
From 7126da87f17ff41334b9fa6969ad032ff9940979 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Wed, 13 Aug 2025 09:57:04 +0800
|
||||
Subject: [PATCH 2/2] lib/pbkdf2: Optimize PBKDF2 by reusing HMAC handle
|
||||
|
||||
The previous PBKDF2 implementation used grub_crypto_hmac_buffer(), which
|
||||
allocates and frees an HMAC handle on every call. This approach caused
|
||||
significant performance overhead, slowing down the boot process
|
||||
considerably.
|
||||
|
||||
This commit refactors the PBKDF2 code to use the new HMAC functions,
|
||||
allowing the HMAC handle and its buffers to be allocated once and reused
|
||||
across multiple operations. This change significantly reduces disk
|
||||
unlocking time.
|
||||
|
||||
In a QEMU/OVMF test environment, this patch reduced the time to unlock a
|
||||
LUKS2(*) partition from approximately 15 seconds to 4 seconds.
|
||||
|
||||
(*) PBKDF2 SHA256 with 3454944 iterations
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
grub-core/lib/pbkdf2.c | 21 +++++++++++++--------
|
||||
1 file changed, 13 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/grub-core/lib/pbkdf2.c b/grub-core/lib/pbkdf2.c
|
||||
index 28aa96c46..410eff580 100644
|
||||
--- a/grub-core/lib/pbkdf2.c
|
||||
+++ b/grub-core/lib/pbkdf2.c
|
||||
@@ -39,6 +39,7 @@ grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
|
||||
unsigned int c,
|
||||
grub_uint8_t *DK, grub_size_t dkLen)
|
||||
{
|
||||
+ struct grub_crypto_hmac_handle *hnd = NULL;
|
||||
unsigned int hLen = md->mdlen;
|
||||
grub_uint8_t U[GRUB_CRYPTO_MAX_MDLEN];
|
||||
grub_uint8_t T[GRUB_CRYPTO_MAX_MDLEN];
|
||||
@@ -47,7 +48,6 @@ grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
|
||||
unsigned int r;
|
||||
unsigned int i;
|
||||
unsigned int k;
|
||||
- gcry_err_code_t rc;
|
||||
grub_uint8_t *tmp;
|
||||
grub_size_t tmplen = Slen + 4;
|
||||
|
||||
@@ -72,6 +72,13 @@ grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
|
||||
|
||||
grub_memcpy (tmp, S, Slen);
|
||||
|
||||
+ hnd = grub_crypto_hmac_init (md, P, Plen);
|
||||
+ if (hnd == NULL)
|
||||
+ {
|
||||
+ grub_free (tmp);
|
||||
+ return GPG_ERR_OUT_OF_MEMORY;
|
||||
+ }
|
||||
+
|
||||
for (i = 1; i - 1 < l; i++)
|
||||
{
|
||||
grub_memset (T, 0, hLen);
|
||||
@@ -85,16 +92,13 @@ grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
|
||||
tmp[Slen + 2] = (i & 0x0000ff00) >> 8;
|
||||
tmp[Slen + 3] = (i & 0x000000ff) >> 0;
|
||||
|
||||
- rc = grub_crypto_hmac_buffer (md, P, Plen, tmp, tmplen, U);
|
||||
+ grub_crypto_hmac_write (hnd, tmp, tmplen);
|
||||
}
|
||||
else
|
||||
- rc = grub_crypto_hmac_buffer (md, P, Plen, U, hLen, U);
|
||||
+ grub_crypto_hmac_write (hnd, U, hLen);
|
||||
|
||||
- if (rc != GPG_ERR_NO_ERROR)
|
||||
- {
|
||||
- grub_free (tmp);
|
||||
- return rc;
|
||||
- }
|
||||
+ grub_crypto_hmac_final (hnd, U);
|
||||
+ grub_crypto_hmac_reset (hnd);
|
||||
|
||||
for (k = 0; k < hLen; k++)
|
||||
T[k] ^= U[k];
|
||||
@@ -103,6 +107,7 @@ grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
|
||||
grub_memcpy (DK + (i - 1) * hLen, T, i == l ? r : hLen);
|
||||
}
|
||||
|
||||
+ grub_crypto_hmac_free (hnd);
|
||||
grub_free (tmp);
|
||||
|
||||
return GPG_ERR_NO_ERROR;
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
From 1e5d19972bb64b0fcb39083042a69cf05e0cb783 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Sat, 26 Apr 2025 15:33:28 +0800
|
||||
Subject: [PATCH 2/4] linux: fallback to direct PE entry boot on arm64
|
||||
|
||||
On the arm64 platform, when the shim loader protocol is unavailable and
|
||||
UEFI Secure Boot is enabled, fall back to booting via the direct PE/COFF
|
||||
image entry point instead of requesting UEFI to load and start the
|
||||
image. This fallback allows booting binaries validated by shim's vendor
|
||||
DB, even if they are not listed in the UEFI DB.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 1 +
|
||||
grub-core/loader/arm64/efi/linux.c | 26 +++++++-------------------
|
||||
grub-core/loader/efi/linux.c | 6 +++---
|
||||
3 files changed, 11 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index 1811661c3..2100d7ff2 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1898,6 +1898,7 @@ module = {
|
||||
arm_coreboot = loader/arm/linux.c;
|
||||
arm_efi = loader/efi/linux.c;
|
||||
arm_uboot = loader/arm/linux.c;
|
||||
+ arm64 = loader/efi/linux.c;
|
||||
arm64 = loader/arm64/efi/linux.c;
|
||||
loongarch64 = loader/efi/linux.c;
|
||||
riscv32 = loader/efi/linux.c;
|
||||
diff --git a/grub-core/loader/arm64/efi/linux.c b/grub-core/loader/arm64/efi/linux.c
|
||||
index a9f5e05e4..8eab1dc86 100644
|
||||
--- a/grub-core/loader/arm64/efi/linux.c
|
||||
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||
@@ -190,8 +190,8 @@ free_params (void)
|
||||
}
|
||||
}
|
||||
|
||||
-grub_err_t
|
||||
-grub_arch_efi_linux_boot_image (grub_addr_t addr,
|
||||
+static grub_err_t
|
||||
+grub_arm64_efi_linux_boot_image (grub_addr_t addr,
|
||||
grub_size_t size __attribute__ ((unused)),
|
||||
char *args)
|
||||
{
|
||||
@@ -213,7 +213,7 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr,
|
||||
static grub_err_t
|
||||
grub_linux_boot (void)
|
||||
{
|
||||
- return (grub_arch_efi_linux_boot_image ((grub_addr_t)kernel_addr, kernel_size, linux_args));
|
||||
+ return (grub_arm64_efi_linux_boot_image ((grub_addr_t)kernel_addr, kernel_size, linux_args));
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
@@ -464,20 +464,8 @@ fail:
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
+extern grub_err_t __attribute__((alias("grub_cmd_linux")))
|
||||
+grub_cmd_linux_efi_fallback (grub_command_t cmd, int argc, char *argv[]);
|
||||
|
||||
-static grub_command_t cmd_linux, cmd_initrd;
|
||||
-
|
||||
-GRUB_MOD_INIT (linux)
|
||||
-{
|
||||
- cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0,
|
||||
- N_("Load Linux."));
|
||||
- cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, 0,
|
||||
- N_("Load initrd."));
|
||||
- my_mod = mod;
|
||||
-}
|
||||
-
|
||||
-GRUB_MOD_FINI (linux)
|
||||
-{
|
||||
- grub_unregister_command (cmd_linux);
|
||||
- grub_unregister_command (cmd_initrd);
|
||||
-}
|
||||
+extern grub_err_t __attribute__((alias("grub_cmd_initrd")))
|
||||
+grub_cmd_initrd_efi_fallback (grub_command_t cmd, int argc, char *argv[]);
|
||||
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
|
||||
index b20dec404..d29e32cba 100644
|
||||
--- a/grub-core/loader/efi/linux.c
|
||||
+++ b/grub-core/loader/efi/linux.c
|
||||
@@ -388,7 +388,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
goto fail;
|
||||
}
|
||||
|
||||
-#if defined(__i386__) || defined(__x86_64__)
|
||||
+#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
|
||||
if (grub_is_using_legacy_shim_lock_protocol () == true ||
|
||||
!initrd_use_loadfile2)
|
||||
return grub_cmd_initrd_efi_fallback (cmd, argc, argv);
|
||||
@@ -472,7 +472,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
|
||||
if (grub_is_using_legacy_shim_lock_protocol () == true)
|
||||
{
|
||||
-#if defined(__i386__) || defined(__x86_64__)
|
||||
+#if defined(__i386__) || defined(__x86_64__) || defined (__aarch64__)
|
||||
grub_dprintf ("linux", "using legacy shim_lock protocol, falling back to legacy Linux kernel loader\n");
|
||||
|
||||
err = grub_cmd_linux_efi_fallback (cmd, argc, argv);
|
||||
@@ -499,7 +499,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
kernel_size = grub_file_size (file);
|
||||
|
||||
if (grub_arch_efi_linux_load_image_header (file, &lh) != GRUB_ERR_NONE)
|
||||
-#if !defined(__i386__) && !defined(__x86_64__)
|
||||
+#if !defined(__i386__) && !defined(__x86_64__) && !defined (__aarch64__)
|
||||
goto fail;
|
||||
#else
|
||||
goto fallback;
|
||||
--
|
||||
2.50.1
|
||||
|
||||
35
0002-net-net-Unregister-net_set_vlan-command-on-unload.patch
Normal file
35
0002-net-net-Unregister-net_set_vlan-command-on-unload.patch
Normal file
@@ -0,0 +1,35 @@
|
||||
From c9af7dfdd068beb1f47b1837bcc143118a87fbb1 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Frauendorfer | Miray Software <tf@miray.de>
|
||||
Date: Fri, 9 May 2025 14:20:47 +0200
|
||||
Subject: [PATCH 2/7] net/net: Unregister net_set_vlan command on unload
|
||||
|
||||
The commit 954c48b9c (net/net: Add net_set_vlan command) added command
|
||||
net_set_vlan to the net module. Unfortunately the commit only added the
|
||||
grub_register_command() call on module load but missed the
|
||||
grub_unregister_command() on unload. Let's fix this.
|
||||
|
||||
Fixes: CVE-2025-54770
|
||||
Fixes: 954c48b9c (net/net: Add net_set_vlan command)
|
||||
|
||||
Reported-by: Thomas Frauendorfer | Miray Software <tf@miray.de>
|
||||
Signed-off-by: Thomas Frauendorfer | Miray Software <tf@miray.de>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/net/net.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/grub-core/net/net.c b/grub-core/net/net.c
|
||||
index df13c3aaa..7bd8f1bf7 100644
|
||||
--- a/grub-core/net/net.c
|
||||
+++ b/grub-core/net/net.c
|
||||
@@ -2151,6 +2151,7 @@ GRUB_MOD_FINI(net)
|
||||
grub_unregister_command (cmd_deladdr);
|
||||
grub_unregister_command (cmd_addroute);
|
||||
grub_unregister_command (cmd_delroute);
|
||||
+ grub_unregister_command (cmd_setvlan);
|
||||
grub_unregister_command (cmd_lsroutes);
|
||||
grub_unregister_command (cmd_lscards);
|
||||
grub_unregister_command (cmd_lsaddr);
|
||||
--
|
||||
2.51.1
|
||||
|
||||
@@ -31,15 +31,15 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
|
||||
--- a/grub-core/disk/ieee1275/ofdisk.c
|
||||
+++ b/grub-core/disk/ieee1275/ofdisk.c
|
||||
@@ -26,6 +26,7 @@
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/safemath.h>
|
||||
#include <grub/env.h>
|
||||
+#include <grub/command.h>
|
||||
|
||||
#define RETRY_DEFAULT_TIMEOUT 15
|
||||
|
||||
@@ -61,6 +62,9 @@
|
||||
@@ -60,6 +61,9 @@
|
||||
#define OFDISK_HASH_SZ 8
|
||||
static struct ofdisk_hash_ent *ofdisk_hash[OFDISK_HASH_SZ];
|
||||
|
||||
@@ -49,7 +49,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
static int
|
||||
ofdisk_hash_fn (const char *devpath)
|
||||
{
|
||||
@@ -1167,10 +1171,10 @@
|
||||
@@ -1132,10 +1136,10 @@
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
@@ -62,7 +62,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
|
||||
grub_free (canon);
|
||||
return parent;
|
||||
@@ -1221,9 +1225,9 @@
|
||||
@@ -1179,9 +1183,9 @@
|
||||
boot_parent = get_boot_device_parent (bootpath, &is_boot_nvmeof);
|
||||
boot_type = grub_ieee1275_get_device_type (boot_parent);
|
||||
if (boot_type)
|
||||
@@ -74,7 +74,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
}
|
||||
grub_free (type);
|
||||
grub_free (bootpath);
|
||||
@@ -1247,7 +1251,7 @@
|
||||
@@ -1205,7 +1209,7 @@
|
||||
static char *ret;
|
||||
|
||||
if (!ret)
|
||||
@@ -83,7 +83,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
boot_parent,
|
||||
boot_type ? : "unknown",
|
||||
is_boot_nvmeof);
|
||||
@@ -1263,6 +1267,17 @@
|
||||
@@ -1221,6 +1225,17 @@
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
void
|
||||
grub_ofdisk_init (void)
|
||||
{
|
||||
@@ -1272,6 +1287,9 @@
|
||||
@@ -1230,6 +1245,9 @@
|
||||
grub_register_variable_hook ("ofdisk_boot_type", grub_env_get_boot_type,
|
||||
grub_env_set_boot_type );
|
||||
|
||||
@@ -111,7 +111,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
grub_disk_dev_register (&grub_ofdisk_dev);
|
||||
}
|
||||
|
||||
@@ -1320,3 +1338,50 @@
|
||||
@@ -1278,3 +1296,50 @@
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
31
0002-term-ieee1275-serial-Cast-0-to-proper-type.patch
Normal file
31
0002-term-ieee1275-serial-Cast-0-to-proper-type.patch
Normal file
@@ -0,0 +1,31 @@
|
||||
From 29d1bd2a96948bc120cb5906188117f670797fcf Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Date: Tue, 26 Nov 2024 15:39:41 -0500
|
||||
Subject: [PATCH 2/7] term/ieee1275/serial: Cast 0 to proper type
|
||||
|
||||
Cast 0 to proper type grub_ieee1275_ihandle_t. This type is
|
||||
used for struct grub_serial_port's handle that assigns or
|
||||
compares with IEEE1275_IHANDLE_INVALID.
|
||||
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/term/ieee1275/serial.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/term/ieee1275/serial.c b/grub-core/term/ieee1275/serial.c
|
||||
index 0e4cac4c4..9bc44b306 100644
|
||||
--- a/grub-core/term/ieee1275/serial.c
|
||||
+++ b/grub-core/term/ieee1275/serial.c
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/ieee1275/console.h>
|
||||
|
||||
-#define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_cell_t) 0)
|
||||
+#define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_ihandle_t) 0)
|
||||
|
||||
struct ofserial_hash_ent
|
||||
{
|
||||
--
|
||||
2.43.0
|
||||
|
||||
84
0002-tpm2_key_protector-Add-tpm2_dump_pcr-command.patch
Normal file
84
0002-tpm2_key_protector-Add-tpm2_dump_pcr-command.patch
Normal file
@@ -0,0 +1,84 @@
|
||||
From 46c9f3a8dac5274c8d117ea131ca5c5842f9276f Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Mon, 7 Apr 2025 16:29:16 +0800
|
||||
Subject: [PATCH 2/7] tpm2_key_protector: Add tpm2_dump_pcr command
|
||||
|
||||
The user may need to inspect the TPM 2.0 PCR values with the GRUB shell,
|
||||
so the new tpm2_dump_pcr command is added to print all PCRs of the
|
||||
specified bank.
|
||||
|
||||
Also update the document for the new command.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Tested-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
docs/grub.texi | 13 +++++++
|
||||
.../commands/tpm2_key_protector/module.c | 35 +++++++++++++++++++
|
||||
2 files changed, 48 insertions(+)
|
||||
|
||||
Index: grub-2.12/grub-core/commands/tpm2_key_protector/module.c
|
||||
===================================================================
|
||||
--- grub-2.12.orig/grub-core/commands/tpm2_key_protector/module.c
|
||||
+++ grub-2.12/grub-core/commands/tpm2_key_protector/module.c
|
||||
@@ -160,6 +160,8 @@ static grub_extcmd_t tpm2_protector_init
|
||||
static grub_extcmd_t tpm2_protector_clear_cmd;
|
||||
static tpm2_protector_context_t tpm2_protector_ctx = {0};
|
||||
|
||||
+static grub_command_t tpm2_dump_pcr_cmd;
|
||||
+
|
||||
static grub_err_t
|
||||
tpm2_protector_srk_read_file (const char *filepath, void **buffer, grub_size_t *buffer_size)
|
||||
{
|
||||
@@ -1327,6 +1329,33 @@ static struct grub_key_protector tpm2_ke
|
||||
.recover_key = tpm2_protector_recover_key
|
||||
};
|
||||
|
||||
+static grub_err_t
|
||||
+tpm2_dump_pcr (grub_command_t cmd __attribute__((__unused__)),
|
||||
+ int argc, char *argv[])
|
||||
+{
|
||||
+ TPM_ALG_ID_t pcr_bank;
|
||||
+
|
||||
+ if (argc == 0)
|
||||
+ pcr_bank = TPM_ALG_SHA256;
|
||||
+ else if (grub_strcmp (argv[0], "sha1") == 0)
|
||||
+ pcr_bank = TPM_ALG_SHA1;
|
||||
+ else if (grub_strcmp (argv[0], "sha256") == 0)
|
||||
+ pcr_bank = TPM_ALG_SHA256;
|
||||
+ else if (grub_strcmp (argv[0], "sha384") == 0)
|
||||
+ pcr_bank = TPM_ALG_SHA384;
|
||||
+ else if (grub_strcmp (argv[0], "sha512") == 0)
|
||||
+ pcr_bank = TPM_ALG_SHA512;
|
||||
+ else
|
||||
+ {
|
||||
+ grub_printf ("Unknown PCR bank\n");
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ tpm2_protector_dump_pcr (pcr_bank);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
GRUB_MOD_INIT (tpm2_key_protector)
|
||||
{
|
||||
tpm2_protector_init_cmd =
|
||||
@@ -1348,6 +1377,10 @@ GRUB_MOD_INIT (tpm2_key_protector)
|
||||
N_("Clear the TPM2 key protector if previously initialized."),
|
||||
NULL);
|
||||
grub_key_protector_register (&tpm2_key_protector);
|
||||
+
|
||||
+ tpm2_dump_pcr_cmd =
|
||||
+ grub_register_command ("tpm2_dump_pcr", tpm2_dump_pcr, N_("Dump TPM2 PCRs"),
|
||||
+ N_("Print all PCRs of the specified TPM 2.0 bank"));
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI (tpm2_key_protector)
|
||||
@@ -1357,4 +1390,6 @@ GRUB_MOD_FINI (tpm2_key_protector)
|
||||
grub_key_protector_unregister (&tpm2_key_protector);
|
||||
grub_unregister_extcmd (tpm2_protector_clear_cmd);
|
||||
grub_unregister_extcmd (tpm2_protector_init_cmd);
|
||||
+
|
||||
+ grub_unregister_command (tpm2_dump_pcr_cmd);
|
||||
}
|
||||
@@ -210,8 +210,8 @@ Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
|
||||
- params->type_of_loader = 0x21;
|
||||
+ grub_dprintf ("linux", "setting lh->ext_loader_{type,ver}\n");
|
||||
+ params->hdr.ext_loader_type = 0;
|
||||
+ params->hdr.ext_loader_ver = 2;
|
||||
+ params->ext_loader_type = 0;
|
||||
+ params->ext_loader_ver = 2;
|
||||
+ grub_dprintf("linux", "kernel_mem: %p handover_offset: %08x\n",
|
||||
+ kernel_mem, handover_offset);
|
||||
|
||||
@@ -232,7 +232,7 @@ Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, BYTES_TO_PAGES(kernel_size));
|
||||
--- a/include/grub/i386/linux.h
|
||||
+++ b/include/grub/i386/linux.h
|
||||
@@ -402,6 +402,11 @@
|
||||
@@ -148,6 +148,11 @@
|
||||
grub_uint32_t kernel_alignment;
|
||||
grub_uint8_t relocatable;
|
||||
grub_uint8_t min_alignment;
|
||||
|
||||
57
0003-Make-grub_error-more-verbose.patch
Normal file
57
0003-Make-grub_error-more-verbose.patch
Normal file
@@ -0,0 +1,57 @@
|
||||
From 3526c4e467ee01a3cfd2f4d627433d078a1ab780 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Mon, 27 Aug 2018 13:14:06 -0400
|
||||
Subject: [PATCH 3/9] Make grub_error() more verbose
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
---
|
||||
grub-core/kern/efi/mm.c | 17 ++++++++++++++---
|
||||
grub-core/kern/err.c | 13 +++++++++++--
|
||||
include/grub/err.h | 5 ++++-
|
||||
3 files changed, 29 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/grub-core/kern/err.c
|
||||
+++ b/grub-core/kern/err.c
|
||||
@@ -33,15 +33,24 @@
|
||||
static int grub_error_stack_pos;
|
||||
static int grub_error_stack_assert;
|
||||
|
||||
+#ifdef grub_error
|
||||
+#undef grub_error
|
||||
+#endif
|
||||
+
|
||||
grub_err_t
|
||||
-grub_error (grub_err_t n, const char *fmt, ...)
|
||||
+grub_error (grub_err_t n, const char *file, const int line, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
+ int m;
|
||||
|
||||
grub_errno = n;
|
||||
|
||||
+ m = grub_snprintf (grub_errmsg, sizeof (grub_errmsg), "%s:%d:", file, line);
|
||||
+ if (m < 0)
|
||||
+ m = 0;
|
||||
+
|
||||
va_start (ap, fmt);
|
||||
- grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), _(fmt), ap);
|
||||
+ grub_vsnprintf (grub_errmsg + m, sizeof (grub_errmsg) - m, _(fmt), ap);
|
||||
va_end (ap);
|
||||
|
||||
return n;
|
||||
--- a/include/grub/err.h
|
||||
+++ b/include/grub/err.h
|
||||
@@ -86,8 +86,11 @@
|
||||
extern grub_err_t EXPORT_VAR(grub_errno);
|
||||
extern char EXPORT_VAR(grub_errmsg)[GRUB_MAX_ERRMSG];
|
||||
|
||||
-grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *fmt, ...)
|
||||
- __attribute__ ((format (GNU_PRINTF, 2, 3)));
|
||||
+grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *file, const int line, const char *fmt, ...)
|
||||
+ __attribute__ ((format (GNU_PRINTF, 4, 5)));
|
||||
+
|
||||
+#define grub_error(n, fmt, ...) grub_error (n, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
+
|
||||
void EXPORT_FUNC(grub_fatal) (const char *fmt, ...) __attribute__ ((noreturn));
|
||||
void EXPORT_FUNC(grub_error_push) (void);
|
||||
int EXPORT_FUNC(grub_error_pop) (void);
|
||||
@@ -21,10 +21,10 @@ V1:
|
||||
|
||||
--- a/grub-core/net/bootp.c
|
||||
+++ b/grub-core/net/bootp.c
|
||||
@@ -25,6 +25,98 @@
|
||||
@@ -24,6 +24,98 @@
|
||||
#include <grub/net/netbuff.h>
|
||||
#include <grub/net/udp.h>
|
||||
#include <grub/datetime.h>
|
||||
#include <grub/safemath.h>
|
||||
+#include <grub/time.h>
|
||||
+#include <grub/list.h>
|
||||
+
|
||||
@@ -120,7 +120,7 @@ V1:
|
||||
|
||||
struct grub_dhcp_discover_options
|
||||
{
|
||||
@@ -611,6 +703,578 @@
|
||||
@@ -610,6 +702,578 @@
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -699,7 +699,7 @@ V1:
|
||||
/*
|
||||
* This is called directly from net/ip.c:handle_dgram(), because those
|
||||
* BOOTP/DHCP packets are a bit special due to their improper
|
||||
@@ -679,6 +1343,77 @@
|
||||
@@ -678,6 +1342,77 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -777,7 +777,7 @@ V1:
|
||||
static grub_err_t
|
||||
grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
@@ -918,7 +1653,174 @@
|
||||
@@ -903,7 +1638,174 @@
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -953,7 +953,7 @@ V1:
|
||||
|
||||
void
|
||||
grub_bootp_init (void)
|
||||
@@ -932,6 +1834,9 @@
|
||||
@@ -917,6 +1819,9 @@
|
||||
cmd_getdhcp = grub_register_command ("net_get_dhcp_option", grub_cmd_dhcpopt,
|
||||
N_("VAR INTERFACE NUMBER DESCRIPTION"),
|
||||
N_("retrieve DHCP option and save it into VAR. If VAR is - then print the value."));
|
||||
@@ -963,7 +963,7 @@ V1:
|
||||
}
|
||||
|
||||
void
|
||||
@@ -940,4 +1845,5 @@
|
||||
@@ -925,4 +1830,5 @@
|
||||
grub_unregister_command (cmd_getdhcp);
|
||||
grub_unregister_command (cmd_bootp);
|
||||
grub_unregister_command (cmd_dhcp);
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
From 370e435b6ada53314888f04dcd8f096fc11cfadb Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Thu, 3 Aug 2023 15:52:52 +0800
|
||||
Subject: [PATCH 3/4] cryptodisk: wipe out the cached keys from protectors
|
||||
|
||||
An attacker may insert a malicious disk with the same crypto UUID and
|
||||
trick grub2 to mount the fake root. Even though the key from the key
|
||||
protector fails to unlock the fake root, it's not wiped out cleanly so
|
||||
the attacker could dump the memory to retrieve the secret key. To defend
|
||||
such attack, wipe out the cached key when we don't need it.
|
||||
|
||||
Cc: Fabian Vogt <fvogt@suse.com>
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
---
|
||||
grub-core/disk/cryptodisk.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index f9842f776..aa0d43562 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1355,7 +1355,11 @@ grub_cryptodisk_clear_key_cache (struct grub_cryptomount_args *cargs)
|
||||
return;
|
||||
|
||||
for (i = 0; cargs->protectors[i]; i++)
|
||||
- grub_free (cargs->key_cache[i].key);
|
||||
+ {
|
||||
+ if (cargs->key_cache[i].key)
|
||||
+ grub_memset (cargs->key_cache[i].key, 0, cargs->key_cache[i].key_len);
|
||||
+ grub_free (cargs->key_cache[i].key);
|
||||
+ }
|
||||
|
||||
grub_free (cargs->key_cache);
|
||||
}
|
||||
--
|
||||
2.35.3
|
||||
|
||||
136
0003-disk-diskfilter-Introduce-the-cryptocheck-command.patch
Normal file
136
0003-disk-diskfilter-Introduce-the-cryptocheck-command.patch
Normal file
@@ -0,0 +1,136 @@
|
||||
From 781d736bd5d0004c705d73b0348b154d8ab838cf Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Thu, 8 May 2025 19:02:09 +0200
|
||||
Subject: [PATCH 3/8] disk/diskfilter: Introduce the "cryptocheck" command
|
||||
|
||||
This command examines a given diskfilter device, e.g., an LVM disk,
|
||||
and checks if underlying disks, physical volumes, are cryptodisks,
|
||||
e.g., LUKS disks, this layout is called "LVM-on-LUKS".
|
||||
|
||||
The return value is 0 when all underlying disks (of a given device)
|
||||
are cryptodisks (1 if at least one disk is unencrypted or in an
|
||||
unknown state).
|
||||
|
||||
Users are encouraged to include the relevant check before loading
|
||||
anything from an LVM disk that is supposed to be encrypted.
|
||||
|
||||
This further supports the CLI authentication, blocking bypass
|
||||
attempts when booting from an encrypted LVM disk.
|
||||
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/disk/diskfilter.c | 75 +++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 75 insertions(+)
|
||||
|
||||
diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c
|
||||
index c45bef1caf..3f7c05e14e 100644
|
||||
--- a/grub-core/disk/diskfilter.c
|
||||
+++ b/grub-core/disk/diskfilter.c
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <grub/dl.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/mm.h>
|
||||
+#include <grub/command.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/diskfilter.h>
|
||||
@@ -1487,6 +1488,73 @@ grub_diskfilter_get_pv_from_disk (grub_disk_t disk,
|
||||
}
|
||||
#endif
|
||||
|
||||
+static int
|
||||
+grub_diskfilter_check_pvs_encrypted (grub_disk_t disk, int *pvs_cnt)
|
||||
+{
|
||||
+ struct grub_diskfilter_lv *lv = disk->data;
|
||||
+ struct grub_diskfilter_pv *pv;
|
||||
+
|
||||
+ *pvs_cnt = 0;
|
||||
+
|
||||
+ if (lv->vg->pvs)
|
||||
+ for (pv = lv->vg->pvs; pv; pv = pv->next)
|
||||
+ {
|
||||
+ (*pvs_cnt)++;
|
||||
+
|
||||
+ if (pv->disk == NULL)
|
||||
+ {
|
||||
+ /* Can be a partially activated VG, bail out. */
|
||||
+ return GRUB_ERR_TEST_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ if (pv->disk->dev->id != GRUB_DISK_DEVICE_CRYPTODISK_ID)
|
||||
+ {
|
||||
+ /* All backing devices must be cryptodisks, stop. */
|
||||
+ return GRUB_ERR_TEST_FAILURE;
|
||||
+ }
|
||||
+ }
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_cryptocheck (grub_command_t cmd __attribute__ ((unused)),
|
||||
+ int argc, char **args)
|
||||
+{
|
||||
+ grub_disk_t disk;
|
||||
+ int check_pvs_res;
|
||||
+ int namelen;
|
||||
+ int pvs_cnt;
|
||||
+
|
||||
+ if (argc != 1)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("disk name expected"));
|
||||
+
|
||||
+ namelen = grub_strlen (args[0]);
|
||||
+ if (namelen > 2 && (args[0][0] == '(') && (args[0][namelen - 1] == ')'))
|
||||
+ args[0][namelen - 1] = 0;
|
||||
+ else
|
||||
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("invalid disk: %s"),
|
||||
+ args[0]);
|
||||
+
|
||||
+ if (!is_valid_diskfilter_name (&args[0][1]))
|
||||
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("unrecognized disk: %s"),
|
||||
+ &args[0][1]);
|
||||
+
|
||||
+ disk = grub_disk_open (&args[0][1]);
|
||||
+ if (disk == NULL)
|
||||
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("no such disk: %s"),
|
||||
+ &args[0][1]);
|
||||
+
|
||||
+ check_pvs_res = grub_diskfilter_check_pvs_encrypted (disk, &pvs_cnt);
|
||||
+ grub_disk_close (disk);
|
||||
+
|
||||
+ grub_printf("%s is %sencrypted (%d pv%s examined)\n", &args[0][1],
|
||||
+ (check_pvs_res == GRUB_ERR_NONE) ? "" : "un",
|
||||
+ pvs_cnt,
|
||||
+ (pvs_cnt > 1) ? "s" : "");
|
||||
+
|
||||
+ return check_pvs_res;
|
||||
+}
|
||||
+
|
||||
static struct grub_disk_dev grub_diskfilter_dev =
|
||||
{
|
||||
.name = "diskfilter",
|
||||
@@ -1503,14 +1571,21 @@ static struct grub_disk_dev grub_diskfilter_dev =
|
||||
.next = 0
|
||||
};
|
||||
|
||||
+static grub_command_t cmd;
|
||||
+
|
||||
|
||||
GRUB_MOD_INIT(diskfilter)
|
||||
{
|
||||
grub_disk_dev_register (&grub_diskfilter_dev);
|
||||
+ cmd = grub_register_command ("cryptocheck", grub_cmd_cryptocheck,
|
||||
+ N_("DEVICE"),
|
||||
+ N_("Check if a logical volume resides on encrypted disks."));
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(diskfilter)
|
||||
{
|
||||
grub_disk_dev_unregister (&grub_diskfilter_dev);
|
||||
+ if (cmd != NULL)
|
||||
+ grub_unregister_command (cmd);
|
||||
free_array ();
|
||||
}
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
From 43b0319936f51dc6b4cba3518449195924e83dc8 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Sat, 26 Apr 2025 15:39:43 +0800
|
||||
Subject: [PATCH 3/4] efi/chainloader: fallback to direct image execution
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
When the shim loader protocol is unavailable and UEFI Secure Boot is
|
||||
enabled, fall back to chainloading the PE/COFF image by manually
|
||||
relocating it to the loaded memory address and jumping to its entry
|
||||
point, rather than invoking UEFI to load and start the image. This
|
||||
fallback supports booting binaries validated by shim’s vendor DB, even
|
||||
if they are not present in the UEFI DB.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/loader/efi/chainloader.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
|
||||
index 1830de223..7e2847217 100644
|
||||
--- a/grub-core/loader/efi/chainloader.c
|
||||
+++ b/grub-core/loader/efi/chainloader.c
|
||||
@@ -805,10 +805,14 @@ 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_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED && grub_secure_validate ((void *)address, size)))
|
||||
+ if (debug_secureboot ||
|
||||
+ (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED &&
|
||||
+ grub_is_using_legacy_shim_lock_protocol () == true &&
|
||||
+ grub_secure_validate ((void *)address, size)))
|
||||
{
|
||||
struct grub_secureboot_chainloader_context *sb_context;
|
||||
|
||||
+ grub_dprintf ("chain", "Falling back to PE loader\n");
|
||||
sb_context = grub_malloc (sizeof (*sb_context));
|
||||
if (!sb_context)
|
||||
goto fail;
|
||||
--
|
||||
2.50.1
|
||||
|
||||
34
0003-fs-hfs-Fix-stack-OOB-write-with-grub_strcpy.patch
Normal file
34
0003-fs-hfs-Fix-stack-OOB-write-with-grub_strcpy.patch
Normal file
@@ -0,0 +1,34 @@
|
||||
From 96f51e8fb8daf43da636f6475827d697829fdb8b Mon Sep 17 00:00:00 2001
|
||||
From: B Horn <b@horn.uk>
|
||||
Date: Sun, 12 May 2024 02:48:33 +0100
|
||||
Subject: [PATCH 03/20] fs/hfs: Fix stack OOB write with grub_strcpy()
|
||||
|
||||
Replaced with grub_strlcpy().
|
||||
|
||||
Fixes: CVE-2024-45782
|
||||
Fixes: CVE-2024-56737
|
||||
Fixes: https://savannah.gnu.org/bugs/?66599
|
||||
|
||||
Reported-by: B Horn <b@horn.uk>
|
||||
Signed-off-by: B Horn <b@horn.uk>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/fs/hfs.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c
|
||||
index 91dc0e69c3..920112b03e 100644
|
||||
--- a/grub-core/fs/hfs.c
|
||||
+++ b/grub-core/fs/hfs.c
|
||||
@@ -379,7 +379,7 @@ grub_hfs_mount (grub_disk_t disk)
|
||||
volume name. */
|
||||
key.parent_dir = grub_cpu_to_be32_compile_time (1);
|
||||
key.strlen = data->sblock.volname[0];
|
||||
- grub_strcpy ((char *) key.str, (char *) (data->sblock.volname + 1));
|
||||
+ grub_strlcpy ((char *) key.str, (char *) (data->sblock.volname + 1), sizeof (key.str));
|
||||
|
||||
if (grub_hfs_find_node (data, (char *) &key, data->cat_root,
|
||||
0, (char *) &dir, sizeof (dir)) == 0)
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
From 846b1d8bebd316a18fae9fb90efb3e8451ec70cc Mon Sep 17 00:00:00 2001
|
||||
From: Eric Sandeen <sandeen@redhat.com>
|
||||
Date: Wed, 4 Dec 2024 07:50:28 -0600
|
||||
Subject: [PATCH 3/3] fs/xfs: fix large extent counters incompat feature
|
||||
support
|
||||
|
||||
When large extent counter / NREXT64 support was added to grub, it missed
|
||||
a couple of direct reads of nextents which need to be changed to the new
|
||||
NREXT64-aware helper as well. Without this, we'll have mis-reads of some
|
||||
directories with this feature enabled.
|
||||
|
||||
(The large extent counter fix likely raced on merge with
|
||||
07318ee7e ("fs/xfs: Fix XFS directory extent parsing") which added the new
|
||||
direct nextents reads just prior, causing this issue.)
|
||||
|
||||
Fixes: aa7c1322671e ("fs/xfs: Add large extent counters incompat feature support")
|
||||
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
|
||||
Reviewed-by: Anthony Iliopoulos <ailiop@suse.com>
|
||||
Reviewed-by: Jon DeVree <nuxi@vault24.org>
|
||||
Link: https://lore.kernel.org/r/985816b8-35e6-4083-994f-ec9138bd35d2@redhat.com
|
||||
---
|
||||
grub-core/fs/xfs.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
|
||||
index 30e3e7f6d9..3ba232436e 100644
|
||||
--- a/grub-core/fs/xfs.c
|
||||
+++ b/grub-core/fs/xfs.c
|
||||
@@ -937,7 +937,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
* Leaf and tail information are only in the data block if the number
|
||||
* of extents is 1.
|
||||
*/
|
||||
- if (dir->inode.nextents == grub_cpu_to_be32_compile_time (1))
|
||||
+ if (grub_xfs_get_inode_nextents(&dir->inode) == 1)
|
||||
{
|
||||
end = (char *) tail;
|
||||
|
||||
@@ -992,7 +992,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
* The expected number of directory entries is only tracked for the
|
||||
* single extent case.
|
||||
*/
|
||||
- if (dir->inode.nextents == grub_cpu_to_be32_compile_time (1))
|
||||
+ if (grub_xfs_get_inode_nextents(&dir->inode) == 1)
|
||||
{
|
||||
/* Check if last direntry in this block is reached. */
|
||||
entries--;
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
From 04f3a7beebd029c10e80e9cbea5c1d8452b066ce Mon Sep 17 00:00:00 2001
|
||||
From: Alec Brown <alec.r.brown@oracle.com>
|
||||
Date: Thu, 21 Aug 2025 21:14:06 +0000
|
||||
Subject: [PATCH 3/7] gettext/gettext: Unregister gettext command on module
|
||||
unload
|
||||
|
||||
When the gettext module is loaded, the gettext command is registered but
|
||||
isn't unregistered when the module is unloaded. We need to add a call to
|
||||
grub_unregister_command() when unloading the module.
|
||||
|
||||
Fixes: CVE-2025-61662
|
||||
|
||||
Reported-by: Alec Brown <alec.r.brown@oracle.com>
|
||||
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/gettext/gettext.c | 19 ++++++++++++-------
|
||||
1 file changed, 12 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c
|
||||
index 9ffc73428..edebed998 100644
|
||||
--- a/grub-core/gettext/gettext.c
|
||||
+++ b/grub-core/gettext/gettext.c
|
||||
@@ -502,6 +502,8 @@ grub_cmd_translate (grub_command_t cmd __attribute__ ((unused)),
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static grub_command_t cmd;
|
||||
+
|
||||
GRUB_MOD_INIT (gettext)
|
||||
{
|
||||
const char *lang;
|
||||
@@ -521,13 +523,14 @@ GRUB_MOD_INIT (gettext)
|
||||
grub_register_variable_hook ("locale_dir", NULL, read_main);
|
||||
grub_register_variable_hook ("secondary_locale_dir", NULL, read_secondary);
|
||||
|
||||
- grub_register_command_p1 ("gettext", grub_cmd_translate,
|
||||
- N_("STRING"),
|
||||
- /* TRANSLATORS: It refers to passing the string through gettext.
|
||||
- So it's "translate" in the same meaning as in what you're
|
||||
- doing now.
|
||||
- */
|
||||
- N_("Translates the string with the current settings."));
|
||||
+ cmd = grub_register_command_p1 ("gettext", grub_cmd_translate,
|
||||
+ N_("STRING"),
|
||||
+ /*
|
||||
+ * TRANSLATORS: It refers to passing the string through gettext.
|
||||
+ * So it's "translate" in the same meaning as in what you're
|
||||
+ * doing now.
|
||||
+ */
|
||||
+ N_("Translates the string with the current settings."));
|
||||
|
||||
/* Reload .mo file information if lang changes. */
|
||||
grub_register_variable_hook ("lang", NULL, grub_gettext_env_write_lang);
|
||||
@@ -544,6 +547,8 @@ GRUB_MOD_FINI (gettext)
|
||||
grub_register_variable_hook ("secondary_locale_dir", NULL, NULL);
|
||||
grub_register_variable_hook ("lang", NULL, NULL);
|
||||
|
||||
+ grub_unregister_command (cmd);
|
||||
+
|
||||
grub_gettext_delete_list (&main_context);
|
||||
grub_gettext_delete_list (&secondary_context);
|
||||
|
||||
--
|
||||
2.51.1
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
From 7344b3c7cee8dea94dbc97211c5e6d1925848865 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Date: Tue, 26 Nov 2024 15:39:42 -0500
|
||||
Subject: [PATCH 3/7] ieee1275: Consolidate repeated definitions of
|
||||
IEEE1275_IHANDLE_INVALID
|
||||
|
||||
Consolidate repeated definitions of IEEE1275_IHANDLE_INVALID that are cast
|
||||
to the type grub_ieee1275_ihandle_t. On the occasion add "GRUB_" prefix to
|
||||
the constant name.
|
||||
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/commands/ieee1275/ibmvtpm.c | 4 +---
|
||||
grub-core/term/ieee1275/serial.c | 8 +++-----
|
||||
include/grub/ieee1275/ieee1275.h | 1 +
|
||||
3 files changed, 5 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/ieee1275/ibmvtpm.c b/grub-core/commands/ieee1275/ibmvtpm.c
|
||||
index a6fee5c51..dd30c7432 100644
|
||||
--- a/grub-core/commands/ieee1275/ibmvtpm.c
|
||||
+++ b/grub-core/commands/ieee1275/ibmvtpm.c
|
||||
@@ -29,8 +29,6 @@
|
||||
static grub_ieee1275_ihandle_t tpm_ihandle;
|
||||
static grub_uint8_t tpm_version;
|
||||
|
||||
-#define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_ihandle_t) 0)
|
||||
-
|
||||
static void
|
||||
tpm_get_tpm_version (void)
|
||||
{
|
||||
@@ -53,7 +51,7 @@ tpm_init (void)
|
||||
{
|
||||
if (grub_ieee1275_open ("/vdevice/vtpm", &tpm_ihandle) < 0)
|
||||
{
|
||||
- tpm_ihandle = IEEE1275_IHANDLE_INVALID;
|
||||
+ tpm_ihandle = GRUB_IEEE1275_IHANDLE_INVALID;
|
||||
return GRUB_ERR_UNKNOWN_DEVICE;
|
||||
}
|
||||
|
||||
diff --git a/grub-core/term/ieee1275/serial.c b/grub-core/term/ieee1275/serial.c
|
||||
index 9bc44b306..ac2a8f827 100644
|
||||
--- a/grub-core/term/ieee1275/serial.c
|
||||
+++ b/grub-core/term/ieee1275/serial.c
|
||||
@@ -25,8 +25,6 @@
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/ieee1275/console.h>
|
||||
|
||||
-#define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_ihandle_t) 0)
|
||||
-
|
||||
struct ofserial_hash_ent
|
||||
{
|
||||
char *devpath;
|
||||
@@ -44,7 +42,7 @@ do_real_config (struct grub_serial_port *port)
|
||||
|
||||
if (grub_ieee1275_open (port->elem->devpath, &port->handle)
|
||||
|| port->handle == (grub_ieee1275_ihandle_t) -1)
|
||||
- port->handle = IEEE1275_IHANDLE_INVALID;
|
||||
+ port->handle = GRUB_IEEE1275_IHANDLE_INVALID;
|
||||
|
||||
port->configured = 1;
|
||||
}
|
||||
@@ -58,7 +56,7 @@ serial_hw_fetch (struct grub_serial_port *port)
|
||||
|
||||
do_real_config (port);
|
||||
|
||||
- if (port->handle == IEEE1275_IHANDLE_INVALID)
|
||||
+ if (port->handle == GRUB_IEEE1275_IHANDLE_INVALID)
|
||||
return -1;
|
||||
grub_ieee1275_read (port->handle, &c, 1, &actual);
|
||||
|
||||
@@ -76,7 +74,7 @@ serial_hw_put (struct grub_serial_port *port, const int c)
|
||||
|
||||
do_real_config (port);
|
||||
|
||||
- if (port->handle == IEEE1275_IHANDLE_INVALID)
|
||||
+ if (port->handle == GRUB_IEEE1275_IHANDLE_INVALID)
|
||||
return;
|
||||
|
||||
grub_ieee1275_write (port->handle, &c0, 1, &actual);
|
||||
diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h
|
||||
index dddb38514..c445d0499 100644
|
||||
--- a/include/grub/ieee1275/ieee1275.h
|
||||
+++ b/include/grub/ieee1275/ieee1275.h
|
||||
@@ -60,6 +60,7 @@ struct grub_ieee1275_common_hdr
|
||||
typedef grub_uint32_t grub_ieee1275_ihandle_t;
|
||||
typedef grub_uint32_t grub_ieee1275_phandle_t;
|
||||
|
||||
+#define GRUB_IEEE1275_IHANDLE_INVALID ((grub_ieee1275_ihandle_t) 0)
|
||||
#define GRUB_IEEE1275_PHANDLE_INVALID ((grub_ieee1275_phandle_t) -1)
|
||||
|
||||
struct grub_ieee1275_devalias
|
||||
--
|
||||
2.43.0
|
||||
|
||||
693
0003-ieee1275-Read-the-DB-and-DBX-secure-boot-variables.patch
Normal file
693
0003-ieee1275-Read-the-DB-and-DBX-secure-boot-variables.patch
Normal file
@@ -0,0 +1,693 @@
|
||||
From 07b675536e5ae8a0f34d65c40027458d0474d802 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Mon, 24 Feb 2025 20:01:51 +0530
|
||||
Subject: [PATCH 3/9] ieee1275: Read the DB and DBX secure boot variables
|
||||
|
||||
If secure boot is enabled with PKS, it will read secure boot variables
|
||||
such as db and dbx from PKS and extract ESL's from it.
|
||||
The ESL's would be saved in the platform keystore buffer, and
|
||||
the appendedsig (module) would read it later to extract
|
||||
the certificate's details from ESL.
|
||||
|
||||
In the following scenarios, static key mode will be activated:
|
||||
1. When Secure Boot is enabled with static keys
|
||||
2. When SB Version is unavailable but Secure Boot is enabled
|
||||
3. When PKS support is unavailable but Secure Boot is enabled
|
||||
|
||||
Note:-
|
||||
|
||||
SB Version - Secure Boot mode
|
||||
1 - PKS
|
||||
0 - static key (embeded key)
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
---
|
||||
grub-core/Makefile.am | 1 +
|
||||
grub-core/Makefile.core.def | 1 +
|
||||
grub-core/kern/ieee1275/init.c | 15 +-
|
||||
.../kern/powerpc/ieee1275/platform_keystore.c | 335 ++++++++++++++++++
|
||||
.../grub/powerpc/ieee1275/platform_keystore.h | 225 ++++++++++++
|
||||
include/grub/types.h | 9 +
|
||||
6 files changed, 584 insertions(+), 2 deletions(-)
|
||||
create mode 100644 grub-core/kern/powerpc/ieee1275/platform_keystore.c
|
||||
create mode 100644 include/grub/powerpc/ieee1275/platform_keystore.h
|
||||
|
||||
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
|
||||
index 40ed353aba..999e62788f 100644
|
||||
--- a/grub-core/Makefile.am
|
||||
+++ b/grub-core/Makefile.am
|
||||
@@ -247,6 +247,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/alloc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
|
||||
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/powerpc/ieee1275/platform_keystore.h
|
||||
endif
|
||||
|
||||
if COND_sparc64_ieee1275
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index 1dfcf5f991..85e717c122 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -333,6 +333,7 @@ kernel = {
|
||||
powerpc_ieee1275 = kern/powerpc/dl.c;
|
||||
powerpc_ieee1275 = kern/powerpc/compiler-rt.S;
|
||||
powerpc_ieee1275 = kern/lockdown.c;
|
||||
+ powerpc_ieee1275 = kern/powerpc/ieee1275/platform_keystore.c;
|
||||
|
||||
sparc64_ieee1275 = kern/sparc64/cache.S;
|
||||
sparc64_ieee1275 = kern/sparc64/dl.c;
|
||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
|
||||
index 0e1cbf24c3..45f787eff4 100644
|
||||
--- a/grub-core/kern/ieee1275/init.c
|
||||
+++ b/grub-core/kern/ieee1275/init.c
|
||||
@@ -50,6 +50,8 @@
|
||||
#include <grub/ieee1275/alloc.h>
|
||||
#endif
|
||||
#include <grub/lockdown.h>
|
||||
+#include <grub/powerpc/ieee1275/ieee1275.h>
|
||||
+#include <grub/powerpc/ieee1275/platform_keystore.h>
|
||||
|
||||
/* The maximum heap size we're going to claim at boot. Not used by sparc. */
|
||||
#ifdef __i386__
|
||||
@@ -985,7 +987,7 @@ grub_get_ieee1275_secure_boot (void)
|
||||
{
|
||||
grub_ieee1275_phandle_t root;
|
||||
int rc;
|
||||
- grub_uint32_t is_sb;
|
||||
+ grub_uint32_t is_sb = 0;
|
||||
|
||||
if (grub_ieee1275_finddevice ("/", &root))
|
||||
{
|
||||
@@ -1009,7 +1011,16 @@ grub_get_ieee1275_secure_boot (void)
|
||||
* We only support enforce.
|
||||
*/
|
||||
if (is_sb >= 2)
|
||||
- grub_lockdown ();
|
||||
+ {
|
||||
+ grub_printf ("Secure Boot Enabled\n");
|
||||
+ rc = grub_pks_keystore_init ();
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ grub_printf ("Initialization of the Platform Keystore failed!\n");
|
||||
+
|
||||
+ grub_lockdown ();
|
||||
+ }
|
||||
+ else
|
||||
+ grub_printf ("Secure Boot Disabled\n");
|
||||
}
|
||||
|
||||
grub_addr_t grub_modbase;
|
||||
diff --git a/grub-core/kern/powerpc/ieee1275/platform_keystore.c b/grub-core/kern/powerpc/ieee1275/platform_keystore.c
|
||||
new file mode 100644
|
||||
index 0000000000..ea9f27eb22
|
||||
--- /dev/null
|
||||
+++ b/grub-core/kern/powerpc/ieee1275/platform_keystore.c
|
||||
@@ -0,0 +1,335 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2024 Free Software Foundation, Inc.
|
||||
+ * Copyright (C) 2024 IBM Corporation
|
||||
+ *
|
||||
+ * 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/mm.h>
|
||||
+#include <grub/powerpc/ieee1275/ieee1275.h>
|
||||
+#include <grub/types.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/lockdown.h>
|
||||
+#include <grub/powerpc/ieee1275/platform_keystore.h>
|
||||
+
|
||||
+#define PKS_CONSUMER_FW 1
|
||||
+#define SB_VERSION_KEY_NAME ((grub_uint8_t *) "SB_VERSION")
|
||||
+#define SB_VERSION_KEY_LEN 10
|
||||
+#define DB 1
|
||||
+#define DBX 2
|
||||
+#define PKS_OBJECT_NOT_FOUND ((grub_err_t) - 7)
|
||||
+
|
||||
+/* Platform Keystore */
|
||||
+static grub_size_t pks_max_object_size;
|
||||
+grub_uint8_t grub_pks_use_keystore = 0;
|
||||
+grub_pks_t grub_pks_keystore = { .db = NULL, .dbx = NULL, .db_entries = 0, .dbx_entries = 0 };
|
||||
+
|
||||
+/* Convert the esl data into the ESL */
|
||||
+static grub_esl_t *
|
||||
+convert_to_esl (const grub_uint8_t *esl_data, const grub_size_t esl_data_size)
|
||||
+{
|
||||
+ grub_esl_t *esl = NULL;
|
||||
+
|
||||
+ if (esl_data_size < sizeof (grub_esl_t) || esl_data == NULL)
|
||||
+ return esl;
|
||||
+
|
||||
+ esl = (grub_esl_t *) esl_data;
|
||||
+
|
||||
+ return esl;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Import the GUID, esd, and its size into the pks sd buffer and
|
||||
+ * pks sd entries from the EFI signature list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+esd_from_esl (const grub_uint8_t *esl_data, grub_size_t esl_size,
|
||||
+ const grub_size_t signature_size, const grub_uuid_t *guid,
|
||||
+ grub_pks_sd_t **pks_sd, grub_size_t *pks_sd_entries)
|
||||
+{
|
||||
+ grub_esd_t *esd = NULL;
|
||||
+ grub_pks_sd_t *signature = *pks_sd;
|
||||
+ grub_size_t entries = *pks_sd_entries;
|
||||
+ grub_size_t data_size = 0, offset = 0;
|
||||
+
|
||||
+ /* reads the esd from esl */
|
||||
+ while (esl_size > 0)
|
||||
+ {
|
||||
+ esd = (grub_esd_t *) (esl_data + offset);
|
||||
+ data_size = signature_size - sizeof (grub_esd_t);
|
||||
+
|
||||
+ signature = grub_realloc (signature, (entries + 1) * sizeof (grub_pks_sd_t));
|
||||
+ if (signature == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+
|
||||
+ signature[entries].data = grub_malloc (data_size * sizeof (grub_uint8_t));
|
||||
+ if (signature[entries].data == NULL)
|
||||
+ {
|
||||
+ /*
|
||||
+ * allocated memory will be freed by
|
||||
+ * grub_free_platform_keystore
|
||||
+ */
|
||||
+ *pks_sd = signature;
|
||||
+ *pks_sd_entries = entries + 1;
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+ }
|
||||
+
|
||||
+ grub_memcpy (signature[entries].data, esd->signaturedata, data_size);
|
||||
+ signature[entries].data_size = data_size;
|
||||
+ signature[entries].guid = *guid;
|
||||
+ entries++;
|
||||
+ esl_size -= signature_size;
|
||||
+ offset += signature_size;
|
||||
+ }
|
||||
+
|
||||
+ *pks_sd = signature;
|
||||
+ *pks_sd_entries = entries;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Extract the esd after removing the esl header from esl.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+esl_to_esd (const grub_uint8_t *esl_data, grub_size_t *next_esl,
|
||||
+ grub_pks_sd_t **pks_sd, grub_size_t *pks_sd_entries)
|
||||
+{
|
||||
+ grub_uuid_t guid = { 0 };
|
||||
+ grub_esl_t *esl = NULL;
|
||||
+ grub_size_t offset = 0, esl_size = 0,
|
||||
+ signature_size = 0, signature_header_size = 0;
|
||||
+
|
||||
+ esl = convert_to_esl (esl_data, *next_esl);
|
||||
+ if (esl == NULL)
|
||||
+ return grub_error (GRUB_ERR_BUG, "invalid ESL");
|
||||
+
|
||||
+ esl_size = grub_le_to_cpu32 (esl->signaturelistsize);
|
||||
+ signature_header_size = grub_le_to_cpu32 (esl->signatureheadersize);
|
||||
+ signature_size = grub_le_to_cpu32 (esl->signaturesize);
|
||||
+ guid = esl->signaturetype;
|
||||
+
|
||||
+ if (esl_size < sizeof (grub_esl_t) || esl_size > *next_esl)
|
||||
+ return grub_error (GRUB_ERR_BUG, "invalid ESL size (%u)\n", esl_size);
|
||||
+
|
||||
+ *next_esl = esl_size;
|
||||
+ offset = sizeof (grub_esl_t) + signature_header_size;
|
||||
+ esl_size = esl_size - offset;
|
||||
+
|
||||
+ return esd_from_esl (esl_data + offset, esl_size, signature_size, &guid,
|
||||
+ pks_sd, pks_sd_entries);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Import the EFI signature data and the number of esd from the esl
|
||||
+ * into the pks sd buffer and pks sd entries.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+pks_sd_from_esl (const grub_uint8_t *esl_data, grub_size_t esl_size,
|
||||
+ grub_pks_sd_t **pks_sd, grub_size_t *pks_sd_entries)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t next_esl = esl_size;
|
||||
+
|
||||
+ do
|
||||
+ {
|
||||
+ rc = esl_to_esd (esl_data, &next_esl, pks_sd, pks_sd_entries);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ break;
|
||||
+
|
||||
+ esl_data += next_esl;
|
||||
+ esl_size -= next_esl;
|
||||
+ next_esl = esl_size;
|
||||
+ }
|
||||
+ while (esl_size > 0);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Read the secure boot version from PKS as an object.
|
||||
+ * caller must free result
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+read_sbversion_from_pks (grub_uint8_t **out, grub_size_t *outlen, grub_size_t *policy)
|
||||
+{
|
||||
+ *out = grub_malloc (pks_max_object_size);
|
||||
+ if (*out == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+
|
||||
+ return grub_ieee1275_pks_read_object (PKS_CONSUMER_FW, SB_VERSION_KEY_NAME,
|
||||
+ SB_VERSION_KEY_LEN, *out, pks_max_object_size,
|
||||
+ outlen, policy);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * reads the secure boot variable from PKS.
|
||||
+ * caller must free result
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+read_sbvar_from_pks (const grub_uint8_t sbvarflags, const grub_uint8_t sbvartype,
|
||||
+ grub_uint8_t **out, grub_size_t *outlen)
|
||||
+{
|
||||
+ *out = grub_malloc (pks_max_object_size);
|
||||
+ if (*out == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+
|
||||
+ return grub_ieee1275_pks_read_sbvar (sbvarflags, sbvartype, *out,
|
||||
+ pks_max_object_size, outlen);
|
||||
+}
|
||||
+
|
||||
+/* Test the availability of PKS support. */
|
||||
+static int
|
||||
+is_support_pks (void)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_ieee1275_cell_t missing = 0;
|
||||
+
|
||||
+ rc = grub_ieee1275_test ("pks-max-object-size", &missing);
|
||||
+ if (rc != GRUB_ERR_NONE || (int) missing == -1)
|
||||
+ grub_printf ("Firmware doesn't have PKS support!\n");
|
||||
+ else
|
||||
+ {
|
||||
+ rc = grub_ieee1275_pks_max_object_size (&pks_max_object_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ grub_printf ("PKS support is there but it has zero objects!\n");
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Retrieve the secure boot variable from PKS, unpacks it, read the esd
|
||||
+ * from ESL, and store the information in the pks sd buffer.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+read_secure_boot_variables (const grub_uint8_t sbvarflags, const grub_uint8_t sbvartype,
|
||||
+ grub_pks_sd_t **pks_sd, grub_size_t *pks_sd_entries)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_uint8_t *esl_data = NULL;
|
||||
+ grub_size_t esl_data_size = 0;
|
||||
+
|
||||
+ rc = read_sbvar_from_pks (sbvarflags, sbvartype, &esl_data, &esl_data_size);
|
||||
+ /*
|
||||
+ * at this point we have SB_VERSION, so any error is worth
|
||||
+ * at least some user-visible info
|
||||
+ */
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ rc = grub_error (rc, "secure boot variable %s reading (%d)",
|
||||
+ (sbvartype == DB ? "db" : "dbx"), rc);
|
||||
+ else if (esl_data_size != 0)
|
||||
+ rc = pks_sd_from_esl ((const grub_uint8_t *) esl_data, esl_data_size,
|
||||
+ pks_sd, pks_sd_entries);
|
||||
+ grub_free (esl_data);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/* reads secure boot version (SB_VERSION) and it supports following
|
||||
+ * SB_VERSION
|
||||
+ * 1 - PKS
|
||||
+ * 0 - static key (embeded key)
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+get_secure_boot_version (void)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_uint8_t *data = NULL;
|
||||
+ grub_size_t len = 0, policy = 0;
|
||||
+
|
||||
+ rc = read_sbversion_from_pks (&data, &len, &policy);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ grub_printf ("SB version read failed! (%d)\n", rc);
|
||||
+ else if (len != 1 || (*data != 1 && *data != 0))
|
||||
+ {
|
||||
+ grub_printf ("found unexpected SB version! (%d)\n", *data);
|
||||
+ rc = GRUB_ERR_INVALID_COMMAND;
|
||||
+ }
|
||||
+
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_printf ("Switch to Static Key!\n");
|
||||
+ if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED)
|
||||
+ grub_fatal ("Secure Boot locked down");
|
||||
+ }
|
||||
+ else
|
||||
+ grub_pks_use_keystore = *data;
|
||||
+
|
||||
+ grub_free (data);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/* Free allocated memory */
|
||||
+void
|
||||
+grub_pks_free_keystore (void)
|
||||
+{
|
||||
+ grub_size_t i = 0;
|
||||
+
|
||||
+ for (i = 0; i < grub_pks_keystore.db_entries; i++)
|
||||
+ grub_free (grub_pks_keystore.db[i].data);
|
||||
+
|
||||
+ for (i = 0; i < grub_pks_keystore.dbx_entries; i++)
|
||||
+ grub_free (grub_pks_keystore.dbx[i].data);
|
||||
+
|
||||
+ grub_free (grub_pks_keystore.db);
|
||||
+ grub_free (grub_pks_keystore.dbx);
|
||||
+ grub_memset (&grub_pks_keystore, 0, sizeof (grub_pks_t));
|
||||
+}
|
||||
+
|
||||
+/* Initialization of the Platform Keystore */
|
||||
+grub_err_t
|
||||
+grub_pks_keystore_init (void)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+
|
||||
+ grub_printf ("trying to load Platform Keystore\n");
|
||||
+
|
||||
+ rc = is_support_pks ();
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_printf ("Switch to Static Key!\n");
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ /* SB_VERSION */
|
||||
+ rc = get_secure_boot_version ();
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ return rc;
|
||||
+
|
||||
+ if (grub_pks_use_keystore)
|
||||
+ {
|
||||
+ grub_memset (&grub_pks_keystore, 0, sizeof (grub_pks_t));
|
||||
+ /* DB */
|
||||
+ rc = read_secure_boot_variables (0, DB, &grub_pks_keystore.db, &grub_pks_keystore.db_entries);
|
||||
+ if (rc == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ /* DBX */
|
||||
+ rc = read_secure_boot_variables (0, DBX, &grub_pks_keystore.dbx, &grub_pks_keystore.dbx_entries);
|
||||
+ if (rc == PKS_OBJECT_NOT_FOUND)
|
||||
+ {
|
||||
+ grub_printf ("dbx is not found!\n");
|
||||
+ rc = GRUB_ERR_NONE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ grub_pks_free_keystore ();
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
diff --git a/include/grub/powerpc/ieee1275/platform_keystore.h b/include/grub/powerpc/ieee1275/platform_keystore.h
|
||||
new file mode 100644
|
||||
index 0000000000..0641adb0f1
|
||||
--- /dev/null
|
||||
+++ b/include/grub/powerpc/ieee1275/platform_keystore.h
|
||||
@@ -0,0 +1,225 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved. This
|
||||
+ * program and the accompanying materials are licensed and made available
|
||||
+ * under the terms and conditions of the 2-Clause BSD License which
|
||||
+ * accompanies this distribution.
|
||||
+ *
|
||||
+ * Redistribution and use in source and binary forms, with or without
|
||||
+ * modification, are permitted provided that the following conditions are met:
|
||||
+ *
|
||||
+ * 1. Redistributions of source code must retain the above copyright notice,
|
||||
+ * this list of conditions and the following disclaimer.
|
||||
+ *
|
||||
+ * 2. Redistributions in binary form must reproduce the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer in the
|
||||
+ * documentation and/or other materials provided with the distribution.
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
+ * POSSIBILITY OF SUCH DAMAGE.
|
||||
+ *
|
||||
+ *
|
||||
+ * https://github.com/tianocore/edk2-staging (edk2-staging repo of tianocore),
|
||||
+ * the ImageAuthentication.h file under it, and here's the copyright and license.
|
||||
+ *
|
||||
+ * MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ *
|
||||
+ * Copyright 2024 IBM Corp.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __PLATFORM_KEYSTORE_H__
|
||||
+#define __PLATFORM_KEYSTORE_H__
|
||||
+
|
||||
+#include <grub/symbol.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/types.h>
|
||||
+
|
||||
+#if __GNUC__ >= 9
|
||||
+#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
|
||||
+#endif
|
||||
+
|
||||
+#define GRUB_MAX_HASH_SIZE 64
|
||||
+
|
||||
+typedef struct grub_esd grub_esd_t;
|
||||
+typedef struct grub_esl grub_esl_t;
|
||||
+
|
||||
+/*
|
||||
+ * It is derived from EFI_SIGNATURE_DATA
|
||||
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ *
|
||||
+ * The structure of an EFI signature database (ESD).*/
|
||||
+struct grub_esd
|
||||
+{
|
||||
+ /*
|
||||
+ * An identifier which identifies the agent which added
|
||||
+ * the signature to the list.
|
||||
+ */
|
||||
+ grub_uuid_t signatureowner;
|
||||
+ /* The format of the signature is defined by the SignatureType.*/
|
||||
+ grub_uint8_t signaturedata[];
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+/*
|
||||
+ * It is derived from EFI_SIGNATURE_LIST
|
||||
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ *
|
||||
+ * The structure of an EFI signature list (ESL).*/
|
||||
+struct grub_esl
|
||||
+{
|
||||
+ /* Type of the signature. GUID signature types are defined in below.*/
|
||||
+ grub_uuid_t signaturetype;
|
||||
+ /* Total size of the signature list, including this header.*/
|
||||
+ grub_uint32_t signaturelistsize;
|
||||
+ /*
|
||||
+ * Size of the signature header which precedes
|
||||
+ * the array of signatures.
|
||||
+ */
|
||||
+ grub_uint32_t signatureheadersize;
|
||||
+ /* Size of each signature.*/
|
||||
+ grub_uint32_t signaturesize;
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+/*
|
||||
+ * It is derived from EFI_CERT_X509_GUID
|
||||
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ */
|
||||
+#define GRUB_PKS_CERT_X509_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0xa1, 0x59, 0xc0, 0xa5, 0xe4, 0x94, \
|
||||
+ 0xa7, 0x4a, 0x87, 0xb5, 0xab, 0x15, \
|
||||
+ 0x5c, 0x2b, 0xf0, 0x72 \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+/*
|
||||
+ * It is derived from EFI_CERT_SHA256_GUID
|
||||
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ */
|
||||
+#define GRUB_PKS_CERT_SHA256_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x26, 0x16, 0xc4, 0xc1, 0x4c, 0x50, \
|
||||
+ 0x92, 0x40, 0xac, 0xa9, 0x41, 0xf9, \
|
||||
+ 0x36, 0x93, 0x43, 0x28 \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+/*
|
||||
+ * It is derived from EFI_CERT_SHA384_GUID
|
||||
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ */
|
||||
+#define GRUB_PKS_CERT_SHA384_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x07, 0x53, 0x3e, 0xff, 0xd0, 0x9f, \
|
||||
+ 0xc9, 0x48, 0x85, 0xf1, 0x8a, 0xd5, \
|
||||
+ 0x6c, 0x70, 0x1e, 0x1 \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+/*
|
||||
+ * It is derived from EFI_CERT_SHA512_GUID
|
||||
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ */
|
||||
+#define GRUB_PKS_CERT_SHA512_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0xae, 0x0f, 0x3e, 0x09, 0xc4, 0xa6, \
|
||||
+ 0x50, 0x4f, 0x9f, 0x1b, 0xd4, 0x1e, \
|
||||
+ 0x2b, 0x89, 0xc1, 0x9a \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+/*
|
||||
+ * It is derived from EFI_CERT_X509_SHA256_GUID
|
||||
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ */
|
||||
+#define GRUB_PKS_CERT_X509_SHA256_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x92, 0xa4, 0xd2, 0x3b, 0xc0, 0x96, \
|
||||
+ 0x79, 0x40, 0xb4, 0x20, 0xfc, 0xf9, \
|
||||
+ 0x8e, 0xf1, 0x03, 0xed \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+/*
|
||||
+ * It is derived from EFI_CERT_X509_SHA384_GUID
|
||||
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ */
|
||||
+#define GRUB_PKS_CERT_X509_SHA384_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x6e, 0x87, 0x76, 0x70, 0xc2, 0x80, \
|
||||
+ 0xe6, 0x4e, 0xaa, 0xd2, 0x28, 0xb3, \
|
||||
+ 0x49, 0xa6, 0x86, 0x5b \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+/*
|
||||
+ * It is derived from EFI_CERT_X509_SHA512_GUID
|
||||
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ */
|
||||
+#define GRUB_PKS_CERT_X509_SHA512_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x63, 0xbf, 0x6d, 0x44, 0x02, 0x25, \
|
||||
+ 0xda, 0x4c, 0xbc, 0xfa, 0x24, 0x65, \
|
||||
+ 0xd2, 0xb0, 0xfe, 0x9d \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+typedef struct grub_pks_sd grub_pks_sd_t;
|
||||
+typedef struct grub_pks grub_pks_t;
|
||||
+
|
||||
+/* The structure of a PKS signature data.*/
|
||||
+struct grub_pks_sd
|
||||
+{
|
||||
+ grub_uuid_t guid; /* signature type */
|
||||
+ grub_uint8_t *data; /* signature data */
|
||||
+ grub_size_t data_size; /* size of signature data */
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+/* The structure of a PKS.*/
|
||||
+struct grub_pks
|
||||
+{
|
||||
+ grub_pks_sd_t *db; /* signature database */
|
||||
+ grub_pks_sd_t *dbx; /* forbidden signature database */
|
||||
+ grub_size_t db_entries; /* size of signature database */
|
||||
+ grub_size_t dbx_entries; /* size of forbidden signature database */
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+#ifdef __powerpc__
|
||||
+
|
||||
+/* Initialization of the Platform Keystore */
|
||||
+grub_err_t grub_pks_keystore_init (void);
|
||||
+/* Free allocated memory */
|
||||
+void EXPORT_FUNC(grub_pks_free_keystore) (void);
|
||||
+extern grub_uint8_t EXPORT_VAR(grub_pks_use_keystore);
|
||||
+extern grub_pks_t EXPORT_VAR(grub_pks_keystore);
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+#define grub_pks_use_keystore 0
|
||||
+grub_pks_t grub_pks_keystore = {NULL, NULL, 0, 0};
|
||||
+void grub_pks_free_keystore (void);
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+#endif
|
||||
diff --git a/include/grub/types.h b/include/grub/types.h
|
||||
index 064066e2e1..5542b9aa09 100644
|
||||
--- a/include/grub/types.h
|
||||
+++ b/include/grub/types.h
|
||||
@@ -388,4 +388,13 @@ struct grub_packed_guid
|
||||
} GRUB_PACKED;
|
||||
typedef struct grub_packed_guid grub_packed_guid_t;
|
||||
|
||||
+
|
||||
+#define GRUB_UUID_SIZE 16
|
||||
+typedef struct grub_uuid grub_uuid_t;
|
||||
+/* The structure of a UUID.*/
|
||||
+struct grub_uuid
|
||||
+{
|
||||
+ grub_uint8_t b[GRUB_UUID_SIZE];
|
||||
+};
|
||||
+
|
||||
#endif /* ! GRUB_TYPES_HEADER */
|
||||
--
|
||||
2.48.1
|
||||
|
||||
66
0003-tss2-Fix-the-missing-authCommand.patch
Normal file
66
0003-tss2-Fix-the-missing-authCommand.patch
Normal file
@@ -0,0 +1,66 @@
|
||||
From 041164d00e79ffd2433675a5dd5b824833b9fc6a Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Mon, 7 Apr 2025 16:29:17 +0800
|
||||
Subject: [PATCH 3/7] tss2: Fix the missing authCommand
|
||||
|
||||
grub_tpm2_readpublic() and grub_tpm2_testparms() didn't check
|
||||
authCommand when marshaling the input data buffer. Currently, there is
|
||||
no caller using non-NULL authCommand. However, to avoid the potential
|
||||
issue, the conditional check is added to insert authCommand into the
|
||||
input buffer if necessary.
|
||||
|
||||
Also fix a few pointer checks.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/lib/tss2/tpm2_cmd.c | 10 +++++++---
|
||||
1 file changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/lib/tss2/tpm2_cmd.c b/grub-core/lib/tss2/tpm2_cmd.c
|
||||
index cd0c6fd31..211d807d5 100644
|
||||
--- a/grub-core/lib/tss2/tpm2_cmd.c
|
||||
+++ b/grub-core/lib/tss2/tpm2_cmd.c
|
||||
@@ -341,6 +341,8 @@ grub_tpm2_readpublic (const TPMI_DH_OBJECT_t objectHandle,
|
||||
/* Marshal */
|
||||
grub_tpm2_buffer_init (&in);
|
||||
grub_tpm2_buffer_pack_u32 (&in, objectHandle);
|
||||
+ if (authCommand != NULL)
|
||||
+ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
|
||||
if (in.error != 0)
|
||||
return TPM_RC_FAILURE;
|
||||
|
||||
@@ -398,7 +400,7 @@ grub_tpm2_load (const TPMI_DH_OBJECT_t parent_handle,
|
||||
/* Marshal */
|
||||
grub_tpm2_buffer_init (&in);
|
||||
grub_tpm2_buffer_pack_u32 (&in, parent_handle);
|
||||
- if (authCommand)
|
||||
+ if (authCommand != NULL)
|
||||
grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
|
||||
grub_Tss2_MU_TPM2B_Marshal (&in, inPrivate->size, inPrivate->buffer);
|
||||
grub_Tss2_MU_TPM2B_PUBLIC_Marshal (&in, inPublic);
|
||||
@@ -461,9 +463,9 @@ grub_tpm2_loadexternal (const TPMS_AUTH_COMMAND_t *authCommand,
|
||||
|
||||
/* Marshal */
|
||||
grub_tpm2_buffer_init (&in);
|
||||
- if (authCommand)
|
||||
+ if (authCommand != NULL)
|
||||
grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
|
||||
- if (inPrivate)
|
||||
+ if (inPrivate != NULL)
|
||||
grub_Tss2_MU_TPM2B_SENSITIVE_Marshal (&in, inPrivate);
|
||||
else
|
||||
grub_tpm2_buffer_pack_u16 (&in, 0);
|
||||
@@ -1023,6 +1025,8 @@ grub_tpm2_testparms (const TPMT_PUBLIC_PARMS_t *parms,
|
||||
/* Marshal */
|
||||
grub_tpm2_buffer_init (&in);
|
||||
grub_Tss2_MU_TPMT_PUBLIC_PARMS_Marshal (&in, parms);
|
||||
+ if (authCommand != NULL)
|
||||
+ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
|
||||
if (in.error != 0)
|
||||
return TPM_RC_FAILURE;
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
298
0004-Add-suport-for-signing-grub-with-an-appended-signatu.patch
Normal file
298
0004-Add-suport-for-signing-grub-with-an-appended-signatu.patch
Normal file
@@ -0,0 +1,298 @@
|
||||
From cf6b16f113b1b5e6efce79b569be1de3e504de8f Mon Sep 17 00:00:00 2001
|
||||
From: Rashmica Gupta <rashmica.g@gmail.com>
|
||||
Date: Thu, 11 Jun 2020 11:26:23 +1000
|
||||
Subject: [PATCH 04/23] Add suport for signing grub with an appended signature
|
||||
|
||||
Add infrastructure to allow firmware to verify the integrity of grub
|
||||
by use of a Linux-kernel-module-style appended signature. We initially
|
||||
target powerpc-ieee1275, but the code should be extensible to other
|
||||
platforms.
|
||||
|
||||
Usually these signatures are appended to a file without modifying the
|
||||
ELF file itself. (This is what the 'sign-file' tool does, for example.)
|
||||
The verifier loads the signed file from the file system and looks at the
|
||||
end of the file for the appended signature. However, on powerpc-ieee1275
|
||||
platforms, the bootloader is often stored directly in the PReP partition
|
||||
as raw bytes without a file-system. This makes determining the location
|
||||
of an appended signature more difficult.
|
||||
|
||||
To address this, we add a new ELF note.
|
||||
|
||||
The name field of shall be the string "Appended-Signature", zero-padded
|
||||
to 4 byte alignment. The type field shall be 0x41536967 (the ASCII values
|
||||
for the string "ASig"). It must be the final section in the ELF binary.
|
||||
|
||||
The description shall contain the appended signature structure as defined
|
||||
by the Linux kernel. The description will also be padded to be a multiple
|
||||
of 4 bytes. The padding shall be added before the appended signature
|
||||
structure (not at the end) so that the final bytes of a signed ELF file
|
||||
are the appended signature magic.
|
||||
|
||||
A subsequent patch documents how to create a grub core.img validly signed
|
||||
under this scheme.
|
||||
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>
|
||||
|
||||
---
|
||||
|
||||
You can experiment with this code with a patched version of SLOF
|
||||
that verifies these signatures. You can find one at:
|
||||
https://github.com/daxtens/SLOF
|
||||
|
||||
I will be proposing this for inclusion in a future Power Architecture
|
||||
Platform Reference (PAPR).
|
||||
---
|
||||
include/grub/util/install.h | 8 ++++++--
|
||||
include/grub/util/mkimage.h | 4 ++--
|
||||
util/grub-install-common.c | 15 +++++++++++---
|
||||
util/grub-mkimage.c | 11 +++++++++++
|
||||
util/grub-mkimagexx.c | 39 ++++++++++++++++++++++++++++++++++++-
|
||||
util/mkimage.c | 13 +++++++------
|
||||
6 files changed, 76 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -67,6 +67,9 @@
|
||||
N_("SBAT metadata"), 0 }, \
|
||||
{ "disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, \
|
||||
N_("disable shim_lock verifier"), 0 }, \
|
||||
+ { "appended-signature-size", GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,\
|
||||
+ "SIZE", 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), \
|
||||
+ 1}, \
|
||||
{ "verbose", 'v', 0, 0, \
|
||||
N_("print verbose messages."), 1 }
|
||||
|
||||
@@ -130,7 +133,8 @@
|
||||
GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS,
|
||||
GRUB_INSTALL_OPTIONS_DTB,
|
||||
GRUB_INSTALL_OPTIONS_SBAT,
|
||||
- GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK
|
||||
+ GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK,
|
||||
+ GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE
|
||||
};
|
||||
|
||||
extern char *grub_install_source_directory;
|
||||
@@ -190,7 +194,7 @@
|
||||
size_t npubkeys,
|
||||
char *config_path,
|
||||
const struct grub_install_image_target_desc *image_target,
|
||||
- int note,
|
||||
+ int note, size_t appsig_size,
|
||||
grub_compression_t comp, const char *dtb_file,
|
||||
const char *sbat_path, const int disable_shim_lock);
|
||||
|
||||
--- a/include/grub/util/mkimage.h
|
||||
+++ b/include/grub/util/mkimage.h
|
||||
@@ -51,12 +51,12 @@
|
||||
const struct grub_install_image_target_desc *image_target);
|
||||
void
|
||||
grub_mkimage_generate_elf32 (const struct grub_install_image_target_desc *image_target,
|
||||
- int note, char **core_img, size_t *core_size,
|
||||
+ int note, size_t appsig_size, char **core_img, size_t *core_size,
|
||||
Elf32_Addr target_addr,
|
||||
struct grub_mkimage_layout *layout);
|
||||
void
|
||||
grub_mkimage_generate_elf64 (const struct grub_install_image_target_desc *image_target,
|
||||
- int note, char **core_img, size_t *core_size,
|
||||
+ int note, size_t appsig_size, char **core_img, size_t *core_size,
|
||||
Elf64_Addr target_addr,
|
||||
struct grub_mkimage_layout *layout);
|
||||
|
||||
--- a/util/grub-install-common.c
|
||||
+++ b/util/grub-install-common.c
|
||||
@@ -466,10 +466,12 @@
|
||||
static char *sbat;
|
||||
static int disable_shim_lock;
|
||||
static grub_compression_t compression;
|
||||
+static size_t appsig_size;
|
||||
|
||||
int
|
||||
grub_install_parse (int key, char *arg)
|
||||
{
|
||||
+ const char *end;
|
||||
switch (key)
|
||||
{
|
||||
case GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS:
|
||||
@@ -567,6 +569,12 @@
|
||||
grub_util_error (_("Unrecognized compression `%s'"), arg);
|
||||
case GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE:
|
||||
return 1;
|
||||
+ case GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE:
|
||||
+ grub_errno = 0;
|
||||
+ appsig_size = grub_strtol(arg, &end, 10);
|
||||
+ if (grub_errno)
|
||||
+ return 0;
|
||||
+ return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -679,9 +687,11 @@
|
||||
*p = '\0';
|
||||
|
||||
grub_util_info ("grub-mkimage --directory '%s' --prefix '%s' --output '%s'"
|
||||
- " --format '%s' --compression '%s'%s%s%s\n",
|
||||
+ " --format '%s' --compression '%s'"
|
||||
+ " --appended-signature-size %zu%s%s%s\n",
|
||||
dir, prefix, outname,
|
||||
mkimage_target, compnames[compression],
|
||||
+ appsig_size,
|
||||
note ? " --note" : "",
|
||||
disable_shim_lock ? " --disable-shim-lock" : "", s);
|
||||
free (s);
|
||||
@@ -693,7 +703,7 @@
|
||||
grub_install_generate_image (dir, prefix, fp, outname,
|
||||
modules.entries, memdisk_path,
|
||||
pubkeys, npubkeys, config_path, tgt,
|
||||
- note, compression, dtb, sbat,
|
||||
+ note, appsig_size, compression, dtb, sbat,
|
||||
disable_shim_lock);
|
||||
while (dc--)
|
||||
grub_install_pop_module ();
|
||||
--- a/util/grub-mkimage.c
|
||||
+++ b/util/grub-mkimage.c
|
||||
@@ -84,6 +84,7 @@
|
||||
{"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},
|
||||
+ {"appended-signature-size", 'S', N_("SIZE"), 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), 0},
|
||||
{ 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -128,6 +129,7 @@
|
||||
char *sbat;
|
||||
int note;
|
||||
int disable_shim_lock;
|
||||
+ size_t appsig_size;
|
||||
const struct grub_install_image_target_desc *image_target;
|
||||
grub_compression_t comp;
|
||||
};
|
||||
@@ -138,6 +140,7 @@
|
||||
/* Get the input argument from argp_parse, which we
|
||||
know is a pointer to our arguments structure. */
|
||||
struct arguments *arguments = state->input;
|
||||
+ const char* end;
|
||||
|
||||
switch (key)
|
||||
{
|
||||
@@ -170,6 +173,13 @@
|
||||
arguments->note = 1;
|
||||
break;
|
||||
|
||||
+ case 'S':
|
||||
+ grub_errno = 0;
|
||||
+ arguments->appsig_size = grub_strtol(arg, &end, 10);
|
||||
+ if (grub_errno)
|
||||
+ return 0;
|
||||
+ break;
|
||||
+
|
||||
case 'm':
|
||||
if (arguments->memdisk)
|
||||
free (arguments->memdisk);
|
||||
@@ -324,6 +334,7 @@
|
||||
arguments.memdisk, arguments.pubkeys,
|
||||
arguments.npubkeys, arguments.config,
|
||||
arguments.image_target, arguments.note,
|
||||
+ arguments.appsig_size,
|
||||
arguments.comp, arguments.dtb,
|
||||
arguments.sbat, arguments.disable_shim_lock);
|
||||
|
||||
--- a/util/grub-mkimagexx.c
|
||||
+++ b/util/grub-mkimagexx.c
|
||||
@@ -85,6 +85,15 @@
|
||||
struct grub_ieee1275_note_desc descriptor;
|
||||
};
|
||||
|
||||
+#define GRUB_APPENDED_SIGNATURE_NOTE_NAME "Appended-Signature"
|
||||
+#define GRUB_APPENDED_SIGNATURE_NOTE_TYPE 0x41536967 /* "ASig" */
|
||||
+
|
||||
+struct grub_appended_signature_note
|
||||
+{
|
||||
+ Elf32_Nhdr header;
|
||||
+ char name[ALIGN_UP(sizeof (GRUB_APPENDED_SIGNATURE_NOTE_NAME), 4)];
|
||||
+};
|
||||
+
|
||||
#define GRUB_XEN_NOTE_NAME "Xen"
|
||||
|
||||
struct fixup_block_list
|
||||
@@ -208,7 +217,7 @@
|
||||
|
||||
void
|
||||
SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc *image_target,
|
||||
- int note, char **core_img, size_t *core_size,
|
||||
+ int note, size_t appsig_size, char **core_img, size_t *core_size,
|
||||
Elf_Addr target_addr,
|
||||
struct grub_mkimage_layout *layout)
|
||||
{
|
||||
@@ -222,6 +231,12 @@
|
||||
int shnum = 4;
|
||||
int string_size = sizeof (".text") + sizeof ("mods") + 1;
|
||||
|
||||
+ if (appsig_size)
|
||||
+ {
|
||||
+ phnum++;
|
||||
+ footer_size += ALIGN_UP(sizeof (struct grub_appended_signature_note) + appsig_size, 4);
|
||||
+ }
|
||||
+
|
||||
if (image_target->id != IMAGE_LOONGSON_ELF)
|
||||
phnum += 2;
|
||||
|
||||
@@ -485,6 +500,28 @@
|
||||
phdr->p_offset = grub_host_to_target32 (header_size + program_size);
|
||||
}
|
||||
|
||||
+ if (appsig_size) {
|
||||
+ int note_size = ALIGN_UP(sizeof (struct grub_appended_signature_note) + appsig_size, 4);
|
||||
+ struct grub_appended_signature_note *note_ptr = (struct grub_appended_signature_note *)
|
||||
+ (elf_img + program_size + header_size + (note ? sizeof (struct grub_ieee1275_note) : 0));
|
||||
+
|
||||
+ note_ptr->header.n_namesz = grub_host_to_target32 (sizeof (GRUB_APPENDED_SIGNATURE_NOTE_NAME));
|
||||
+ /* needs to sit at the end, so we round this up and sign some zero padding */
|
||||
+ note_ptr->header.n_descsz = grub_host_to_target32 (ALIGN_UP(appsig_size, 4));
|
||||
+ note_ptr->header.n_type = grub_host_to_target32 (GRUB_APPENDED_SIGNATURE_NOTE_TYPE);
|
||||
+ strcpy (note_ptr->name, GRUB_APPENDED_SIGNATURE_NOTE_NAME);
|
||||
+
|
||||
+ phdr++;
|
||||
+ phdr->p_type = grub_host_to_target32 (PT_NOTE);
|
||||
+ phdr->p_flags = grub_host_to_target32 (PF_R);
|
||||
+ phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof);
|
||||
+ phdr->p_vaddr = 0;
|
||||
+ phdr->p_paddr = 0;
|
||||
+ phdr->p_filesz = grub_host_to_target32 (note_size);
|
||||
+ phdr->p_memsz = 0;
|
||||
+ phdr->p_offset = grub_host_to_target32 (header_size + program_size + (note ? sizeof (struct grub_ieee1275_note) : 0));
|
||||
+ }
|
||||
+
|
||||
{
|
||||
char *str_start = (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr)
|
||||
+ shnum * sizeof (*shdr));
|
||||
--- a/util/mkimage.c
|
||||
+++ b/util/mkimage.c
|
||||
@@ -885,8 +885,9 @@
|
||||
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,
|
||||
- const char *sbat_path, int disable_shim_lock)
|
||||
+ int note, size_t appsig_size, grub_compression_t comp,
|
||||
+ const char *dtb_path, const char *sbat_path,
|
||||
+ int disable_shim_lock)
|
||||
{
|
||||
char *kernel_img, *core_img;
|
||||
size_t total_module_size, core_size;
|
||||
@@ -1810,11 +1811,11 @@
|
||||
else
|
||||
target_addr = image_target->link_addr;
|
||||
if (image_target->voidp_sizeof == 4)
|
||||
- grub_mkimage_generate_elf32 (image_target, note, &core_img, &core_size,
|
||||
- target_addr, &layout);
|
||||
+ grub_mkimage_generate_elf32 (image_target, note, appsig_size, &core_img,
|
||||
+ &core_size, target_addr, &layout);
|
||||
else
|
||||
- grub_mkimage_generate_elf64 (image_target, note, &core_img, &core_size,
|
||||
- target_addr, &layout);
|
||||
+ grub_mkimage_generate_elf64 (image_target, note, appsig_size, &core_img,
|
||||
+ &core_size, target_addr, &layout);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -27,9 +27,9 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -2794,3 +2794,9 @@
|
||||
name = cmdline;
|
||||
common = lib/cmdline.c;
|
||||
@@ -2679,3 +2679,9 @@
|
||||
common = lib/libtasn1_wrap/tests/Test_strings.c;
|
||||
common = lib/libtasn1_wrap/wrap_tests.c;
|
||||
};
|
||||
+
|
||||
+module = {
|
||||
|
||||
798
0004-appendedsig-The-creation-of-trusted-and-distrusted-l.patch
Normal file
798
0004-appendedsig-The-creation-of-trusted-and-distrusted-l.patch
Normal file
@@ -0,0 +1,798 @@
|
||||
From eb82056864ac03155a9dd18adbf1ca1c60dc69b5 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Tue, 25 Feb 2025 00:06:18 +0530
|
||||
Subject: [PATCH 4/9] appendedsig: The creation of trusted and distrusted lists
|
||||
|
||||
The trusted certificates and binary hashes, distrusted certificates and
|
||||
binary/certificate hashes will be extracted from the platform keystore buffer
|
||||
if Secure Boot is enabled with PKS.
|
||||
|
||||
In order to verify the integrity of the kernel, the extracted data
|
||||
needs to be stored stored in the buffer db and dbx.
|
||||
|
||||
The trusted certificates will be extracted from the grub ELFNOTE if Secure Boot is
|
||||
enabled with static key. In order to verify the integerity of the kernel,
|
||||
the extracted data needs to be stored in the buffer db.
|
||||
|
||||
Note:-
|
||||
|
||||
If neither the trusted certificate nor binary hash exists in the distrusted list (dbx),
|
||||
rejects it while extracting certificate/binary hash from the platform keystore buffer.
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
---
|
||||
grub-core/commands/appendedsig/appendedsig.c | 617 +++++++++++++++++--
|
||||
grub-core/kern/file.c | 34 +
|
||||
include/grub/file.h | 1 +
|
||||
3 files changed, 590 insertions(+), 62 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/appendedsig/appendedsig.c b/grub-core/commands/appendedsig/appendedsig.c
|
||||
index e63ad1ac64..3df950c00b 100644
|
||||
--- a/grub-core/commands/appendedsig/appendedsig.c
|
||||
+++ b/grub-core/commands/appendedsig/appendedsig.c
|
||||
@@ -33,7 +33,7 @@
|
||||
#include <grub/libtasn1.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/lockdown.h>
|
||||
-
|
||||
+#include <grub/powerpc/ieee1275/platform_keystore.h>
|
||||
#include "appendedsig.h"
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
@@ -66,8 +66,23 @@ struct grub_appended_signature
|
||||
struct pkcs7_signedData pkcs7; /* Parsed PKCS#7 data */
|
||||
};
|
||||
|
||||
-/* Trusted certificates for verifying appended signatures */
|
||||
-struct x509_certificate *grub_trusted_key;
|
||||
+/* This represents a trusted/distrusted list*/
|
||||
+struct grub_database
|
||||
+{
|
||||
+ struct x509_certificate *keys; /* Certificates */
|
||||
+ grub_size_t key_entries; /* Number of certificates */
|
||||
+ grub_uint8_t **signatures; /* Certificate/binary hashes */
|
||||
+ grub_size_t *signature_size; /* Size of certificate/binary hashes */
|
||||
+ grub_size_t signature_entries; /* Number of certificate/binary hashes */
|
||||
+};
|
||||
+
|
||||
+/* Trusted list */
|
||||
+struct grub_database db = {.keys = NULL, .key_entries = 0, .signatures = NULL,
|
||||
+ .signature_size = NULL, .signature_entries = 0};
|
||||
+
|
||||
+/* Distrusted list */
|
||||
+struct grub_database dbx = {.signatures = NULL, .signature_size = NULL,
|
||||
+ .signature_entries = 0};
|
||||
|
||||
/*
|
||||
* Force gcry_rsa to be a module dependency.
|
||||
@@ -89,6 +104,13 @@ struct x509_certificate *grub_trusted_key;
|
||||
* also resolves our concerns about loading from the filesystem.
|
||||
*/
|
||||
extern gcry_pk_spec_t _gcry_pubkey_spec_rsa;
|
||||
+extern gcry_md_spec_t _gcry_digest_spec_sha224;
|
||||
+extern gcry_md_spec_t _gcry_digest_spec_sha384;
|
||||
+
|
||||
+/* Free trusted list memory */
|
||||
+static void free_trusted_list (void);
|
||||
+/* Free distrusted list memory */
|
||||
+static void free_distrusted_list (void);
|
||||
|
||||
static enum
|
||||
{ check_sigs_no = 0,
|
||||
@@ -96,6 +118,204 @@ static enum
|
||||
check_sigs_forced = 2
|
||||
} check_sigs = check_sigs_no;
|
||||
|
||||
+/*
|
||||
+ * GUID can be used to determine the hashing function and
|
||||
+ * generate the hash using determined hashing function.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+get_hash (const grub_uuid_t *guid, const grub_uint8_t *data, const grub_size_t data_size,
|
||||
+ grub_uint8_t *hash, grub_size_t *hash_size)
|
||||
+{
|
||||
+ gcry_md_spec_t *hash_func = NULL;
|
||||
+
|
||||
+ if (guid == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "GUID is null");
|
||||
+
|
||||
+ if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA256_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA256_GUID, GRUB_UUID_SIZE) == 0)
|
||||
+ hash_func = &_gcry_digest_spec_sha256;
|
||||
+ else if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA384_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA384_GUID, GRUB_UUID_SIZE) == 0)
|
||||
+ hash_func = &_gcry_digest_spec_sha384;
|
||||
+ else if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA512_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA512_GUID, GRUB_UUID_SIZE) == 0)
|
||||
+ hash_func = &_gcry_digest_spec_sha512;
|
||||
+ else
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "Unsupported GUID for hash");
|
||||
+
|
||||
+ grub_memset (hash, 0, GRUB_MAX_HASH_SIZE);
|
||||
+ grub_crypto_hash (hash_func, hash, data, data_size);
|
||||
+ *hash_size = hash_func->mdlen;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/* Add the certificate/binary hash into the trusted/distrusted list */
|
||||
+static grub_err_t
|
||||
+add_hash (const grub_uint8_t **data, const grub_size_t data_size,
|
||||
+ grub_uint8_t ***signature_list, grub_size_t **signature_size_list,
|
||||
+ grub_size_t *signature_list_entries)
|
||||
+{
|
||||
+ grub_uint8_t **signatures = *signature_list;
|
||||
+ grub_size_t *signature_size = *signature_size_list;
|
||||
+ grub_size_t signature_entries = *signature_list_entries;
|
||||
+
|
||||
+ if (*data == NULL || data_size == 0)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "certificate/binary hash data/size is null");
|
||||
+
|
||||
+ signatures = grub_realloc (signatures, sizeof (grub_uint8_t *) * (signature_entries + 1));
|
||||
+ signature_size = grub_realloc (signature_size,
|
||||
+ sizeof (grub_size_t) * (signature_entries + 1));
|
||||
+
|
||||
+ if (signatures == NULL || signature_size == NULL)
|
||||
+ {
|
||||
+ /*
|
||||
+ * allocated memory will be freed by
|
||||
+ * free_trusted_list/free_distrusted_list
|
||||
+ */
|
||||
+ if (signatures != NULL)
|
||||
+ {
|
||||
+ *signature_list = signatures;
|
||||
+ *signature_list_entries = signature_entries + 1;
|
||||
+ }
|
||||
+
|
||||
+ if (signature_size != NULL)
|
||||
+ *signature_size_list = signature_size;
|
||||
+
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+ }
|
||||
+
|
||||
+ signatures[signature_entries] = (grub_uint8_t *) *data;
|
||||
+ signature_size[signature_entries] = data_size;
|
||||
+ signature_entries++;
|
||||
+ *data = NULL;
|
||||
+
|
||||
+ *signature_list = signatures;
|
||||
+ *signature_size_list = signature_size;
|
||||
+ *signature_list_entries = signature_entries;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+is_x509 (const grub_uuid_t *guid)
|
||||
+{
|
||||
+ if (grub_memcmp (guid, &GRUB_PKS_CERT_X509_GUID, GRUB_UUID_SIZE) == 0)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ return GRUB_ERR_UNKNOWN_COMMAND;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+is_cert_match (const struct x509_certificate *distrusted_cert,
|
||||
+ const struct x509_certificate *db_cert)
|
||||
+{
|
||||
+
|
||||
+ if (grub_memcmp (distrusted_cert->subject, db_cert->subject, db_cert->subject_len) == 0
|
||||
+ && grub_memcmp (distrusted_cert->serial, db_cert->serial, db_cert->serial_len) == 0
|
||||
+ && grub_memcmp (distrusted_cert->mpis[0], db_cert->mpis[0], sizeof (db_cert->mpis[0])) == 0
|
||||
+ && grub_memcmp (distrusted_cert->mpis[1], db_cert->mpis[1], sizeof (db_cert->mpis[1])) == 0)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ return GRUB_ERR_UNKNOWN_COMMAND;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Verify the certificate against the certificate from platform keystore buffer's
|
||||
+ * distrusted list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+is_distrusted_cert (const struct x509_certificate *db_cert)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t i = 0;
|
||||
+ struct x509_certificate *distrusted_cert = NULL;
|
||||
+
|
||||
+ for (i = 0; i < grub_pks_keystore.dbx_entries; i++)
|
||||
+ {
|
||||
+ if (grub_pks_keystore.dbx[i].data == NULL)
|
||||
+ continue;
|
||||
+
|
||||
+ if (is_x509 (&grub_pks_keystore.dbx[i].guid) == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ distrusted_cert = grub_zalloc (sizeof (struct x509_certificate));
|
||||
+ if (distrusted_cert == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+
|
||||
+ rc = parse_x509_certificate (grub_pks_keystore.dbx[i].data,
|
||||
+ grub_pks_keystore.dbx[i].data_size, distrusted_cert);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_free (distrusted_cert);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (is_cert_match (distrusted_cert, db_cert) == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_printf ("Warning: a trusted certificate CN='%s' is ignored "
|
||||
+ "because it is on the distrusted list (dbx).\n", db_cert->subject);
|
||||
+ grub_free (grub_pks_keystore.dbx[i].data);
|
||||
+ grub_memset (&grub_pks_keystore.dbx[i], 0, sizeof (grub_pks_sd_t));
|
||||
+ certificate_release (distrusted_cert);
|
||||
+ grub_free (distrusted_cert);
|
||||
+ return GRUB_ERR_ACCESS_DENIED;
|
||||
+ }
|
||||
+
|
||||
+ certificate_release (distrusted_cert);
|
||||
+ grub_free (distrusted_cert);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/* Add the certificate into the trusted/distrusted list */
|
||||
+static grub_err_t
|
||||
+add_certificate (const grub_uint8_t *data, const grub_size_t data_size,
|
||||
+ struct grub_database *database, const grub_size_t is_db)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t key_entries = database->key_entries;
|
||||
+ struct x509_certificate *cert = NULL;
|
||||
+
|
||||
+ if (data == NULL || data_size == 0)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "certificate data/size is null");
|
||||
+
|
||||
+ cert = grub_zalloc (sizeof (struct x509_certificate));
|
||||
+ if (cert == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+
|
||||
+ rc = parse_x509_certificate (data, data_size, cert);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_dprintf ("appendedsig", "skipping %s certificate (%d)\n",
|
||||
+ (is_db ? "trusted":"distrusted"), rc);
|
||||
+ grub_free (cert);
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ if (is_db)
|
||||
+ {
|
||||
+ rc = is_distrusted_cert (cert);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ certificate_release (cert);
|
||||
+ grub_free (cert);
|
||||
+ return rc;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ grub_dprintf ("appendedsig", "add a %s certificate CN='%s'\n",
|
||||
+ (is_db ? "trusted":"distrusted"), cert->subject);
|
||||
+
|
||||
+ key_entries++;
|
||||
+ cert->next = database->keys;
|
||||
+ database->keys = cert;
|
||||
+ database->key_entries = key_entries;
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
static const char *
|
||||
grub_env_read_sec (struct grub_env_var *var __attribute__((unused)),
|
||||
const char *val __attribute__((unused)))
|
||||
@@ -267,9 +487,8 @@ grub_verify_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize)
|
||||
struct pkcs7_signerInfo *si;
|
||||
int i;
|
||||
|
||||
- if (!grub_trusted_key)
|
||||
- return grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
- N_("No trusted keys to verify against"));
|
||||
+ if (!db.key_entries)
|
||||
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("No trusted keys to verify against"));
|
||||
|
||||
err = extract_appended_signature (buf, bufsize, &sig);
|
||||
if (err != GRUB_ERR_NONE)
|
||||
@@ -299,17 +518,16 @@ grub_verify_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize)
|
||||
datasize, i, hash[0], hash[1], hash[2], hash[3]);
|
||||
|
||||
err = GRUB_ERR_BAD_SIGNATURE;
|
||||
- for (pk = grub_trusted_key; pk; pk = pk->next)
|
||||
- {
|
||||
- rc = grub_crypto_rsa_pad (&hashmpi, hash, si->hash, pk->mpis[0]);
|
||||
- if (rc)
|
||||
- {
|
||||
- err = grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
- N_("Error padding hash for RSA verification: %d"),
|
||||
- rc);
|
||||
- grub_free (context);
|
||||
- goto cleanup;
|
||||
- }
|
||||
+ for (pk = db.keys; pk; pk = pk->next)
|
||||
+ {
|
||||
+ rc = grub_crypto_rsa_pad (&hashmpi, hash, si->hash, pk->mpis[0]);
|
||||
+ if (rc)
|
||||
+ {
|
||||
+ err = grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
+ N_("Error padding hash for RSA verification: %d"), rc);
|
||||
+ grub_free (context);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
|
||||
rc = _gcry_pubkey_spec_rsa.verify (0, hashmpi, &si->sig_mpi,
|
||||
pk->mpis, NULL, NULL);
|
||||
@@ -402,16 +620,16 @@ grub_cmd_distrust (grub_command_t cmd __attribute__((unused)),
|
||||
|
||||
if (cert_num == 1)
|
||||
{
|
||||
- cert = grub_trusted_key;
|
||||
- grub_trusted_key = cert->next;
|
||||
+ cert = db.keys;
|
||||
+ db.keys = cert->next;
|
||||
|
||||
certificate_release (cert);
|
||||
grub_free (cert);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
i = 2;
|
||||
- prev = grub_trusted_key;
|
||||
- cert = grub_trusted_key->next;
|
||||
+ prev = db.keys;
|
||||
+ cert = db.keys->next;
|
||||
while (cert)
|
||||
{
|
||||
if (i == cert_num)
|
||||
@@ -464,8 +682,8 @@ grub_cmd_trust (grub_command_t cmd __attribute__((unused)),
|
||||
grub_dprintf ("appendedsig", "Loaded certificate with CN: %s\n",
|
||||
cert->subject);
|
||||
|
||||
- cert->next = grub_trusted_key;
|
||||
- grub_trusted_key = cert;
|
||||
+ cert->next = db.keys;
|
||||
+ db.keys = cert;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
@@ -479,7 +697,7 @@ grub_cmd_list (grub_command_t cmd __attribute__((unused)),
|
||||
int cert_num = 1;
|
||||
grub_size_t i;
|
||||
|
||||
- for (cert = grub_trusted_key; cert; cert = cert->next)
|
||||
+ for (cert = db.keys; cert; cert = cert->next)
|
||||
{
|
||||
grub_printf (N_("Certificate %d:\n"), cert_num);
|
||||
|
||||
@@ -579,6 +797,274 @@ static struct grub_fs pseudo_fs = {
|
||||
|
||||
static grub_command_t cmd_verify, cmd_list, cmd_distrust, cmd_trust;
|
||||
|
||||
+/*
|
||||
+ * Verify the trusted certificate against the certificate hashes from platform keystore buffer's
|
||||
+ * distrusted list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+is_distrusted_cert_hash (const grub_uint8_t *data, const grub_size_t data_size)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t i = 0, cert_hash_size = 0;
|
||||
+ grub_uint8_t cert_hash[GRUB_MAX_HASH_SIZE] = { 0 };
|
||||
+
|
||||
+ if (data == NULL || data_size == 0)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "trusted certificate data/size is null");
|
||||
+
|
||||
+ for (i = 0; i < grub_pks_keystore.dbx_entries; i++)
|
||||
+ {
|
||||
+ if (grub_pks_keystore.dbx[i].data == NULL ||
|
||||
+ grub_pks_keystore.dbx[i].data_size == 0)
|
||||
+ continue;
|
||||
+
|
||||
+ rc = get_hash (&grub_pks_keystore.dbx[i].guid, data, data_size,
|
||||
+ cert_hash, &cert_hash_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ continue;
|
||||
+
|
||||
+ if (cert_hash_size == grub_pks_keystore.dbx[i].data_size &&
|
||||
+ grub_memcmp (grub_pks_keystore.dbx[i].data, cert_hash, cert_hash_size) == 0)
|
||||
+ {
|
||||
+ grub_printf ("Warning: a trusted certificate (%02x%02x%02x%02x) is ignored "
|
||||
+ "because this certificate hash is on the distrusted list (dbx).\n",
|
||||
+ cert_hash[0], cert_hash[1], cert_hash[2], cert_hash[3]);
|
||||
+ grub_free (grub_pks_keystore.dbx[i].data);
|
||||
+ grub_memset (&grub_pks_keystore.dbx[i], 0, sizeof (grub_pks_keystore.dbx[i]));
|
||||
+ return GRUB_ERR_BAD_SIGNATURE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Verify the trusted binary hash against the platform keystore buffer's
|
||||
+ * distrusted list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+is_distrusted_binary_hash (const grub_uint8_t *binary_hash,
|
||||
+ const grub_size_t binary_hash_size)
|
||||
+{
|
||||
+ grub_size_t i = 0;
|
||||
+
|
||||
+ for (i = 0; i < grub_pks_keystore.dbx_entries; i++)
|
||||
+ {
|
||||
+ if (grub_pks_keystore.dbx[i].data == NULL ||
|
||||
+ grub_pks_keystore.dbx[i].data_size == 0)
|
||||
+ continue;
|
||||
+
|
||||
+ if (binary_hash_size == grub_pks_keystore.dbx[i].data_size &&
|
||||
+ grub_memcmp (grub_pks_keystore.dbx[i].data, binary_hash, binary_hash_size) == 0)
|
||||
+ {
|
||||
+ grub_printf ("Warning: a trusted binary hash (%02x%02x%02x%02x) is ignored"
|
||||
+ " because it is on the distrusted list (dbx).\n",
|
||||
+ binary_hash[0], binary_hash[1], binary_hash[2], binary_hash[3]);
|
||||
+ grub_free (grub_pks_keystore.dbx[i].data);
|
||||
+ grub_memset (&grub_pks_keystore.dbx[i], 0, sizeof(grub_pks_keystore.dbx[i]));
|
||||
+ return GRUB_ERR_BAD_SIGNATURE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Extract the binary hashes from the platform keystore buffer,
|
||||
+ * and add it to the trusted list if it does not exist in the distrusted list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+add_trusted_binary_hash (const grub_uint8_t **data, const grub_size_t data_size)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+
|
||||
+ if (*data == NULL || data_size == 0)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "trusted binary hash data/size is null");
|
||||
+
|
||||
+ rc = is_distrusted_binary_hash (*data, data_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ return rc;
|
||||
+
|
||||
+ rc = add_hash (data, data_size, &db.signatures, &db.signature_size,
|
||||
+ &db.signature_entries);
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+is_hash (const grub_uuid_t *guid)
|
||||
+{
|
||||
+ /* GUID type of the binary hash */
|
||||
+ if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA256_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_SHA384_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_SHA512_GUID, GRUB_UUID_SIZE) == 0)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ /* GUID type of the certificate hash */
|
||||
+ if (grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA256_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA384_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA512_GUID, GRUB_UUID_SIZE) == 0)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ return GRUB_ERR_UNKNOWN_COMMAND;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Extract the x509 certificates/binary hashes from the platform keystore buffer,
|
||||
+ * parse it, and add it to the trusted list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+create_trusted_list (void)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t i = 0;
|
||||
+
|
||||
+ for (i = 0; i < grub_pks_keystore.db_entries; i++)
|
||||
+ {
|
||||
+ if (is_hash (&grub_pks_keystore.db[i].guid) == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ rc = add_trusted_binary_hash ((const grub_uint8_t **)
|
||||
+ &grub_pks_keystore.db[i].data,
|
||||
+ grub_pks_keystore.db[i].data_size);
|
||||
+ if (rc == GRUB_ERR_OUT_OF_MEMORY)
|
||||
+ return rc;
|
||||
+ }
|
||||
+ else if (is_x509 (&grub_pks_keystore.db[i].guid) == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ rc = is_distrusted_cert_hash (grub_pks_keystore.db[i].data,
|
||||
+ grub_pks_keystore.db[i].data_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ continue;
|
||||
+
|
||||
+ rc = add_certificate (grub_pks_keystore.db[i].data,
|
||||
+ grub_pks_keystore.db[i].data_size, &db, 1);
|
||||
+ if (rc == GRUB_ERR_OUT_OF_MEMORY)
|
||||
+ return rc;
|
||||
+ else if (rc != GRUB_ERR_NONE)
|
||||
+ continue;
|
||||
+ }
|
||||
+ else
|
||||
+ grub_dprintf ("appendedsig", "unsupported signature data type and "
|
||||
+ "skipping trusted data (%" PRIuGRUB_SIZE ")\n", i + 1);
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Extract the certificates, certificate/binary hashes out of the platform keystore buffer,
|
||||
+ * and add it to the distrusted list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+create_distrusted_list (void)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t i = 0;
|
||||
+
|
||||
+ for (i = 0; i < grub_pks_keystore.dbx_entries; i++)
|
||||
+ {
|
||||
+ if (grub_pks_keystore.dbx[i].data != NULL ||
|
||||
+ grub_pks_keystore.dbx[i].data_size > 0)
|
||||
+ {
|
||||
+ if (is_x509 (&grub_pks_keystore.dbx[i].guid) == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ rc = add_certificate (grub_pks_keystore.dbx[i].data,
|
||||
+ grub_pks_keystore.dbx[i].data_size, &dbx, 0);
|
||||
+ if (rc == GRUB_ERR_OUT_OF_MEMORY)
|
||||
+ return rc;
|
||||
+ }
|
||||
+ else if (is_hash (&grub_pks_keystore.dbx[i].guid) == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ rc = add_hash ((const grub_uint8_t **) &grub_pks_keystore.dbx[i].data,
|
||||
+ grub_pks_keystore.dbx[i].data_size,
|
||||
+ &dbx.signatures, &dbx.signature_size,
|
||||
+ &dbx.signature_entries);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ return rc;
|
||||
+ }
|
||||
+ else
|
||||
+ grub_dprintf ("appendedsig", "unsupported signature data type and "
|
||||
+ "skipping distrusted data (%" PRIuGRUB_SIZE ")\n", i + 1);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Extract the x509 certificates from the ELF note header,
|
||||
+ * parse it, and add it to the trusted list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+build_static_trusted_list (const struct grub_module_header *header)
|
||||
+{
|
||||
+ grub_err_t err = GRUB_ERR_NONE;
|
||||
+ struct grub_file pseudo_file;
|
||||
+ grub_uint8_t *cert_data = NULL;
|
||||
+ grub_ssize_t cert_data_size = 0;
|
||||
+
|
||||
+ grub_memset (&pseudo_file, 0, sizeof (pseudo_file));
|
||||
+ pseudo_file.fs = &pseudo_fs;
|
||||
+ pseudo_file.size = header->size - sizeof (struct grub_module_header);
|
||||
+ pseudo_file.data = (char *) header + sizeof (struct grub_module_header);
|
||||
+
|
||||
+ grub_dprintf ("appendedsig", "found an x509 key, size=%" PRIuGRUB_UINT64_T "\n",
|
||||
+ pseudo_file.size);
|
||||
+
|
||||
+ err = grub_read_file (&pseudo_file, &cert_data, &cert_data_size);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ return err;
|
||||
+
|
||||
+ err = add_certificate (cert_data, cert_data_size, &db, 1);
|
||||
+ grub_free (cert_data);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+/* releasing memory */
|
||||
+static void
|
||||
+free_trusted_list (void)
|
||||
+{
|
||||
+ struct x509_certificate *cert;
|
||||
+ grub_size_t i = 0;
|
||||
+
|
||||
+ while (db.keys != NULL)
|
||||
+ {
|
||||
+ cert = db.keys;
|
||||
+ db.keys = db.keys->next;
|
||||
+ certificate_release (cert);
|
||||
+ grub_free (cert);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < db.signature_entries; i++)
|
||||
+ grub_free (db.signatures[i]);
|
||||
+
|
||||
+ grub_free (db.signatures);
|
||||
+ grub_free (db.signature_size);
|
||||
+ grub_memset (&db, 0, sizeof (db));
|
||||
+}
|
||||
+
|
||||
+/* releasing memory */
|
||||
+static void
|
||||
+free_distrusted_list (void)
|
||||
+{
|
||||
+ struct x509_certificate *cert;
|
||||
+ grub_size_t i = 0;
|
||||
+
|
||||
+ while (dbx.keys != NULL)
|
||||
+ {
|
||||
+ cert = dbx.keys;
|
||||
+ dbx.keys = dbx.keys->next;
|
||||
+ certificate_release (cert);
|
||||
+ grub_free (cert);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < dbx.signature_entries; i++)
|
||||
+ grub_free (dbx.signatures[i]);
|
||||
+
|
||||
+ grub_free (dbx.signatures);
|
||||
+ grub_free (dbx.signature_size);
|
||||
+ grub_memset (&dbx, 0, sizeof (dbx));
|
||||
+}
|
||||
+
|
||||
GRUB_MOD_INIT (appendedsig)
|
||||
{
|
||||
int rc;
|
||||
@@ -588,10 +1074,7 @@ GRUB_MOD_INIT (appendedsig)
|
||||
if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED)
|
||||
check_sigs = check_sigs_forced;
|
||||
|
||||
- grub_trusted_key = NULL;
|
||||
-
|
||||
- grub_register_variable_hook ("check_appended_signatures",
|
||||
- grub_env_read_sec, grub_env_write_sec);
|
||||
+ grub_register_variable_hook ("check_appended_signatures", grub_env_read_sec, grub_env_write_sec);
|
||||
grub_env_export ("check_appended_signatures");
|
||||
|
||||
rc = asn1_init ();
|
||||
@@ -599,40 +1082,50 @@ GRUB_MOD_INIT (appendedsig)
|
||||
grub_fatal ("Error initing ASN.1 data structures: %d: %s\n", rc,
|
||||
asn1_strerror (rc));
|
||||
|
||||
- FOR_MODULES (header)
|
||||
- {
|
||||
- struct grub_file pseudo_file;
|
||||
- struct x509_certificate *pk = NULL;
|
||||
- grub_err_t err;
|
||||
-
|
||||
- /* Not an ELF module, skip. */
|
||||
- if (header->type != OBJ_TYPE_X509_PUBKEY)
|
||||
- continue;
|
||||
-
|
||||
- grub_memset (&pseudo_file, 0, sizeof (pseudo_file));
|
||||
- pseudo_file.fs = &pseudo_fs;
|
||||
- pseudo_file.size = header->size - sizeof (struct grub_module_header);
|
||||
- pseudo_file.data = (char *) header + sizeof (struct grub_module_header);
|
||||
-
|
||||
- grub_dprintf ("appendedsig",
|
||||
- "Found an x509 key, size=%" PRIuGRUB_UINT64_T "\n",
|
||||
- pseudo_file.size);
|
||||
-
|
||||
- pk = grub_zalloc (sizeof (struct x509_certificate));
|
||||
- if (!pk)
|
||||
- {
|
||||
- grub_fatal ("Out of memory loading initial certificates");
|
||||
- }
|
||||
-
|
||||
- err = read_cert_from_file (&pseudo_file, pk);
|
||||
- if (err != GRUB_ERR_NONE)
|
||||
- grub_fatal ("Error loading initial key: %s", grub_errmsg);
|
||||
-
|
||||
- grub_dprintf ("appendedsig", "loaded certificate CN='%s'\n", pk->subject);
|
||||
-
|
||||
- pk->next = grub_trusted_key;
|
||||
- grub_trusted_key = pk;
|
||||
- }
|
||||
+ if (!grub_pks_use_keystore && check_sigs == check_sigs_forced)
|
||||
+ {
|
||||
+ FOR_MODULES (header)
|
||||
+ {
|
||||
+ /* Not an ELF module, skip. */
|
||||
+ if (header->type != OBJ_TYPE_X509_PUBKEY)
|
||||
+ continue;
|
||||
+
|
||||
+ rc = build_static_trusted_list (header);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ free_trusted_list ();
|
||||
+ grub_error (rc, "static trusted list creation failed");
|
||||
+ }
|
||||
+ else
|
||||
+ grub_printf ("appendedsig: the trusted list now has %" PRIuGRUB_SIZE " static keys\n",
|
||||
+ db.key_entries);
|
||||
+ }
|
||||
+ }
|
||||
+ else if (grub_pks_use_keystore && check_sigs == check_sigs_forced)
|
||||
+ {
|
||||
+ rc = create_trusted_list ();
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ free_trusted_list ();
|
||||
+ grub_error (rc, "trusted list creation failed");
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ rc = create_distrusted_list ();
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ free_trusted_list ();
|
||||
+ free_distrusted_list ();
|
||||
+ grub_error (rc, "distrusted list creation failed");
|
||||
+ }
|
||||
+ else
|
||||
+ grub_printf ("appendedsig: the trusted list now has %" PRIuGRUB_SIZE " keys.\n"
|
||||
+ "appendedsig: the distrusted list now has %" PRIuGRUB_SIZE " keys.\n",
|
||||
+ db.signature_entries + db.key_entries, dbx.signature_entries);
|
||||
+ }
|
||||
+
|
||||
+ grub_pks_free_keystore ();
|
||||
+ }
|
||||
|
||||
cmd_trust =
|
||||
grub_register_command ("trust_certificate", grub_cmd_trust,
|
||||
diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c
|
||||
index 6e7efe89ab..7217a6ea7f 100644
|
||||
--- a/grub-core/kern/file.c
|
||||
+++ b/grub-core/kern/file.c
|
||||
@@ -231,3 +231,37 @@ grub_file_seek (grub_file_t file, grub_off_t offset)
|
||||
|
||||
return old;
|
||||
}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_read_file (const grub_file_t file, grub_uint8_t **data, grub_ssize_t *data_size)
|
||||
+{
|
||||
+ grub_uint8_t *buffer = NULL;
|
||||
+ grub_ssize_t read_size = 0;
|
||||
+ grub_off_t total_read_size = 0;
|
||||
+ grub_off_t file_size = grub_file_size (file);
|
||||
+
|
||||
+ if (file_size == GRUB_FILE_SIZE_UNKNOWN)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("could not determine the size of the file."));
|
||||
+
|
||||
+ buffer = grub_zalloc (file_size);
|
||||
+ if (buffer == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||
+
|
||||
+ while (total_read_size < file_size)
|
||||
+ {
|
||||
+ read_size = grub_file_read (file, &buffer[total_read_size], file_size - total_read_size);
|
||||
+ if (read_size < 0)
|
||||
+ {
|
||||
+ grub_free (buffer);
|
||||
+ return grub_error (GRUB_ERR_READ_ERROR, N_("unable to read the file"));
|
||||
+ }
|
||||
+
|
||||
+ total_read_size += read_size;
|
||||
+ }
|
||||
+
|
||||
+ *data = buffer;
|
||||
+ *data_size = total_read_size;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
diff --git a/include/grub/file.h b/include/grub/file.h
|
||||
index f9484f8d69..804d512231 100644
|
||||
--- a/include/grub/file.h
|
||||
+++ b/include/grub/file.h
|
||||
@@ -219,6 +219,7 @@ grub_ssize_t EXPORT_FUNC(grub_file_read) (grub_file_t file, void *buf,
|
||||
grub_size_t len);
|
||||
grub_off_t EXPORT_FUNC(grub_file_seek) (grub_file_t file, grub_off_t offset);
|
||||
grub_err_t EXPORT_FUNC(grub_file_close) (grub_file_t file);
|
||||
+grub_err_t EXPORT_FUNC(grub_read_file) (const grub_file_t file, grub_uint8_t **data, grub_ssize_t *data_size);
|
||||
|
||||
/* Return value of grub_file_size() in case file size is unknown. */
|
||||
#define GRUB_FILE_SIZE_UNKNOWN 0xffffffffffffffffULL
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@@ -79,7 +79,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
|
||||
--- a/grub-core/kern/efi/mm.c
|
||||
+++ b/grub-core/kern/efi/mm.c
|
||||
@@ -155,6 +155,7 @@
|
||||
@@ -153,6 +153,7 @@
|
||||
{
|
||||
grub_efi_status_t status;
|
||||
grub_efi_boot_services_t *b;
|
||||
@@ -87,7 +87,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
|
||||
/* Limit the memory access to less than 4GB for 32-bit platforms. */
|
||||
if (address > GRUB_EFI_MAX_USABLE_ADDRESS)
|
||||
@@ -171,19 +172,22 @@
|
||||
@@ -169,19 +170,22 @@
|
||||
}
|
||||
|
||||
b = grub_efi_system_table->boot_services;
|
||||
@@ -111,10 +111,10 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
- status = b->allocate_pages (alloctype, memtype, pages, &address);
|
||||
+ ret = address;
|
||||
+ status = b->allocate_pages (alloctype, memtype, pages, &ret);
|
||||
b->free_pages (0, pages);
|
||||
grub_efi_free_pages (0, pages);
|
||||
if (status != GRUB_EFI_SUCCESS)
|
||||
{
|
||||
@@ -192,9 +196,9 @@
|
||||
@@ -190,9 +194,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
}
|
||||
|
||||
void *
|
||||
@@ -719,8 +723,21 @@
|
||||
@@ -711,8 +715,21 @@
|
||||
for (desc = memory_map, *base_addr = GRUB_EFI_MAX_USABLE_ADDRESS;
|
||||
(grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size);
|
||||
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
|
||||
|
||||
30
0004-blscfg-Don-t-root-device-in-emu-builds.patch
Normal file
30
0004-blscfg-Don-t-root-device-in-emu-builds.patch
Normal file
@@ -0,0 +1,30 @@
|
||||
From 2fccb958910afaaf03cbec1a6b98ad197d088ad4 Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Thu, 25 Aug 2022 17:57:55 -0400
|
||||
Subject: [PATCH 4/9] blscfg: Don't root device in emu builds
|
||||
|
||||
Otherwise, we end up looking for kernel/initrd in /boot/boot which
|
||||
doesn't work at all. Non-emu builds need to be looking in
|
||||
($root)/boot/, which is what this is for.
|
||||
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
grub-core/commands/blscfg.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
|
||||
index 7132555df..150ca96f4 100644
|
||||
--- a/grub-core/commands/blscfg.c
|
||||
+++ b/grub-core/commands/blscfg.c
|
||||
@@ -41,7 +41,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
#define GRUB_BLS_CONFIG_PATH "/loader/entries/"
|
||||
#ifdef GRUB_MACHINE_EMU
|
||||
-#define GRUB_BOOT_DEVICE "/boot"
|
||||
+#define GRUB_BOOT_DEVICE ""
|
||||
#else
|
||||
#define GRUB_BOOT_DEVICE "($root)"
|
||||
#endif
|
||||
--
|
||||
2.44.0
|
||||
|
||||
70
0004-commands-search-Add-the-diskfilter-support.patch
Normal file
70
0004-commands-search-Add-the-diskfilter-support.patch
Normal file
@@ -0,0 +1,70 @@
|
||||
From 13ae8a054a4a0b871ce3fd8ddaaff7a4f2ba2478 Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Thu, 8 May 2025 19:02:10 +0200
|
||||
Subject: [PATCH 4/8] commands/search: Add the diskfilter support
|
||||
|
||||
When the --cryptodisk-only argument is given, also check the target
|
||||
device using the "cryptocheck" command, if available.
|
||||
|
||||
This extends the checks to common layouts like LVM-on-LUKS, so the
|
||||
--cryptodisk-only argument transparently handles such setups.
|
||||
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/commands/search.c | 32 +++++++++++++++++++++++++++++++-
|
||||
1 file changed, 31 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
|
||||
index f6bfef9585..185c1e70f7 100644
|
||||
--- a/grub-core/commands/search.c
|
||||
+++ b/grub-core/commands/search.c
|
||||
@@ -54,6 +54,36 @@ struct search_ctx
|
||||
int is_cache;
|
||||
};
|
||||
|
||||
+static bool
|
||||
+is_unencrypted_disk (grub_disk_t disk)
|
||||
+{
|
||||
+ grub_command_t cmd;
|
||||
+ char *disk_str;
|
||||
+ int disk_str_len;
|
||||
+ int res;
|
||||
+
|
||||
+ if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
|
||||
+ return false; /* This is (crypto) disk. */
|
||||
+
|
||||
+ if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID)
|
||||
+ {
|
||||
+ cmd = grub_command_find ("cryptocheck");
|
||||
+ if (cmd == NULL) /* No diskfilter module loaded for some reason. */
|
||||
+ return true;
|
||||
+
|
||||
+ disk_str_len = grub_strlen (disk->name) + 2 + 1;
|
||||
+ disk_str = grub_malloc (disk_str_len);
|
||||
+ if (disk_str == NULL) /* Something is wrong, better report as unencrypted. */
|
||||
+ return true;
|
||||
+
|
||||
+ grub_snprintf (disk_str, disk_str_len, "(%s)", disk->name);
|
||||
+ res = cmd->func (cmd, 1, &disk_str);
|
||||
+ grub_free (disk_str);
|
||||
+ return (res != GRUB_ERR_NONE) ? true : false; /* GRUB_ERR_NONE for encrypted. */
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
/* Helper for FUNC_NAME. */
|
||||
static int
|
||||
iterate_device (const char *name, void *data)
|
||||
@@ -97,7 +127,7 @@ iterate_device (const char *name, void *data)
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return 0;
|
||||
}
|
||||
- if (dev->disk == NULL || dev->disk->dev->id != GRUB_DISK_DEVICE_CRYPTODISK_ID)
|
||||
+ if (dev->disk == NULL || is_unencrypted_disk (dev->disk) == true)
|
||||
{
|
||||
grub_device_close (dev);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
--
|
||||
2.49.0
|
||||
|
||||
356
0004-cryptodisk-Support-key-protectors.patch
Normal file
356
0004-cryptodisk-Support-key-protectors.patch
Normal file
@@ -0,0 +1,356 @@
|
||||
From 7ce7b7889ce73174a0d8091978254ecf2d2e205f Mon Sep 17 00:00:00 2001
|
||||
From: Hernan Gatta <hegatta@linux.microsoft.com>
|
||||
Date: Tue, 1 Feb 2022 05:02:56 -0800
|
||||
Subject: [PATCH 4/5] cryptodisk: Support key protectors
|
||||
|
||||
Add a new parameter to cryptomount to support the key protectors framework: -P.
|
||||
The parameter is used to automatically retrieve a key from specified key
|
||||
protectors. The parameter may be repeated to specify any number of key
|
||||
protectors. These are tried in order until one provides a usable key for any
|
||||
given disk.
|
||||
|
||||
Signed-off-by: Hernan Gatta <hegatta@linux.microsoft.com>
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Glenn Washburn <development@efficientek.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
---
|
||||
Makefile.util.def | 1 +
|
||||
grub-core/disk/cryptodisk.c | 172 +++++++++++++++++++++++++++++-------
|
||||
include/grub/cryptodisk.h | 16 ++++
|
||||
3 files changed, 158 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/Makefile.util.def b/Makefile.util.def
|
||||
index 3b9435307..252d70af2 100644
|
||||
--- a/Makefile.util.def
|
||||
+++ b/Makefile.util.def
|
||||
@@ -40,6 +40,7 @@ library = {
|
||||
common = grub-core/disk/luks.c;
|
||||
common = grub-core/disk/luks2.c;
|
||||
common = grub-core/disk/geli.c;
|
||||
+ common = grub-core/disk/key_protector.c;
|
||||
common = grub-core/disk/cryptodisk.c;
|
||||
common = grub-core/disk/AFSplitter.c;
|
||||
common = grub-core/lib/pbkdf2.c;
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index 2246af51b..b7648ffb7 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <grub/file.h>
|
||||
#include <grub/procfs.h>
|
||||
#include <grub/partition.h>
|
||||
+#include <grub/key_protector.h>
|
||||
|
||||
#ifdef GRUB_UTIL
|
||||
#include <grub/emu/hostdisk.h>
|
||||
@@ -44,7 +45,8 @@ enum
|
||||
OPTION_KEYFILE,
|
||||
OPTION_KEYFILE_OFFSET,
|
||||
OPTION_KEYFILE_SIZE,
|
||||
- OPTION_HEADER
|
||||
+ OPTION_HEADER,
|
||||
+ OPTION_PROTECTOR
|
||||
};
|
||||
|
||||
static const struct grub_arg_option options[] =
|
||||
@@ -58,6 +60,8 @@ static const struct grub_arg_option options[] =
|
||||
{"keyfile-offset", 'O', 0, N_("Key file offset (bytes)"), 0, ARG_TYPE_INT},
|
||||
{"keyfile-size", 'S', 0, N_("Key file data size (bytes)"), 0, ARG_TYPE_INT},
|
||||
{"header", 'H', 0, N_("Read header from file"), 0, ARG_TYPE_STRING},
|
||||
+ {"protector", 'P', GRUB_ARG_OPTION_REPEATABLE,
|
||||
+ N_("Unlock volume(s) using key protector(s)."), 0, ARG_TYPE_STRING},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -1061,6 +1065,7 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
grub_err_t ret = GRUB_ERR_NONE;
|
||||
grub_cryptodisk_t dev;
|
||||
grub_cryptodisk_dev_t cr;
|
||||
+ int i;
|
||||
struct cryptodisk_read_hook_ctx read_hook_data = {0};
|
||||
int askpass = 0;
|
||||
char *part = NULL;
|
||||
@@ -1113,41 +1118,112 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
goto error_no_close;
|
||||
if (!dev)
|
||||
continue;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- if (!cargs->key_len)
|
||||
- {
|
||||
- /* Get the passphrase from the user, if no key data. */
|
||||
- askpass = 1;
|
||||
- part = grub_partition_get_name (source->partition);
|
||||
- grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
|
||||
- source->partition != NULL ? "," : "",
|
||||
- part != NULL ? part : N_("UNKNOWN"),
|
||||
- dev->uuid);
|
||||
- grub_free (part);
|
||||
-
|
||||
- cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE);
|
||||
- if (cargs->key_data == NULL)
|
||||
- goto error_no_close;
|
||||
-
|
||||
- if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE))
|
||||
- {
|
||||
- grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied");
|
||||
- goto error;
|
||||
- }
|
||||
- cargs->key_len = grub_strlen ((char *) cargs->key_data);
|
||||
- }
|
||||
+ if (dev == NULL)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_MODULE,
|
||||
+ "no cryptodisk module can handle this device");
|
||||
+ goto error_no_close;
|
||||
+ }
|
||||
|
||||
- ret = cr->recover_key (source, dev, cargs);
|
||||
- if (ret != GRUB_ERR_NONE)
|
||||
- goto error;
|
||||
+ if (cargs->protectors)
|
||||
+ {
|
||||
+ for (i = 0; cargs->protectors[i]; i++)
|
||||
+ {
|
||||
+ if (cargs->key_cache[i].invalid)
|
||||
+ continue;
|
||||
+
|
||||
+ if (cargs->key_cache[i].key == NULL)
|
||||
+ {
|
||||
+ ret = grub_key_protector_recover_key (cargs->protectors[i],
|
||||
+ &cargs->key_cache[i].key,
|
||||
+ &cargs->key_cache[i].key_len);
|
||||
+ if (ret != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ if (grub_errno)
|
||||
+ {
|
||||
+ grub_print_error ();
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ }
|
||||
+
|
||||
+ grub_dprintf ("cryptodisk",
|
||||
+ "failed to recover a key from key protector "
|
||||
+ "%s, will not try it again for any other "
|
||||
+ "disks, if any, during this invocation of "
|
||||
+ "cryptomount\n",
|
||||
+ cargs->protectors[i]);
|
||||
+
|
||||
+ cargs->key_cache[i].invalid = 1;
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ cargs->key_data = cargs->key_cache[i].key;
|
||||
+ cargs->key_len = cargs->key_cache[i].key_len;
|
||||
+
|
||||
+ ret = cr->recover_key (source, dev, cargs);
|
||||
+ if (ret != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ part = grub_partition_get_name (source->partition);
|
||||
+ grub_dprintf ("cryptodisk",
|
||||
+ "recovered a key from key protector %s but it "
|
||||
+ "failed to unlock %s%s%s (%s)\n",
|
||||
+ cargs->protectors[i], source->name,
|
||||
+ source->partition != NULL ? "," : "",
|
||||
+ part != NULL ? part : N_("UNKNOWN"), dev->uuid);
|
||||
+ grub_free (part);
|
||||
+ continue;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ ret = grub_cryptodisk_insert (dev, name, source);
|
||||
+ if (ret != GRUB_ERR_NONE)
|
||||
+ goto error;
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- ret = grub_cryptodisk_insert (dev, name, source);
|
||||
- if (ret != GRUB_ERR_NONE)
|
||||
+ part = grub_partition_get_name (source->partition);
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED,
|
||||
+ N_("no key protector provided a usable key for %s%s%s (%s)"),
|
||||
+ source->name, source->partition != NULL ? "," : "",
|
||||
+ part != NULL ? part : N_("UNKNOWN"), dev->uuid);
|
||||
+ grub_free (part);
|
||||
goto error;
|
||||
+ }
|
||||
+
|
||||
+ if (!cargs->key_len)
|
||||
+ {
|
||||
+ /* Get the passphrase from the user, if no key data. */
|
||||
+ askpass = 1;
|
||||
+ part = grub_partition_get_name (source->partition);
|
||||
+ grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
|
||||
+ source->partition != NULL ? "," : "",
|
||||
+ part != NULL ? part : N_("UNKNOWN"), dev->uuid);
|
||||
+ grub_free (part);
|
||||
+
|
||||
+ cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE);
|
||||
+ if (cargs->key_data == NULL)
|
||||
+ goto error;
|
||||
+
|
||||
+ if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied");
|
||||
+ goto error;
|
||||
+ }
|
||||
+ cargs->key_len = grub_strlen ((char *) cargs->key_data);
|
||||
+ }
|
||||
+
|
||||
+ ret = cr->recover_key (source, dev, cargs);
|
||||
+ if (ret != GRUB_ERR_NONE)
|
||||
+ goto error;
|
||||
+
|
||||
+ ret = grub_cryptodisk_insert (dev, name, source);
|
||||
+ if (ret != GRUB_ERR_NONE)
|
||||
+ goto error;
|
||||
|
||||
- goto cleanup;
|
||||
- }
|
||||
- grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk module can handle this device");
|
||||
goto cleanup;
|
||||
|
||||
error:
|
||||
@@ -1259,6 +1335,20 @@ grub_cryptodisk_scan_device (const char *name,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static void
|
||||
+grub_cryptodisk_clear_key_cache (struct grub_cryptomount_args *cargs)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ if (cargs->key_cache == NULL || cargs->protectors == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; cargs->protectors[i]; i++)
|
||||
+ grub_free (cargs->key_cache[i].key);
|
||||
+
|
||||
+ grub_free (cargs->key_cache);
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
@@ -1271,6 +1361,10 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
if (grub_cryptodisk_list == NULL)
|
||||
return grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk modules loaded");
|
||||
|
||||
+ if (state[OPTION_PASSWORD].set && state[OPTION_PROTECTOR].set) /* password and key protector */
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ "a password and a key protector cannot both be set");
|
||||
+
|
||||
if (state[OPTION_PASSWORD].set) /* password */
|
||||
{
|
||||
cargs.key_data = (grub_uint8_t *) state[OPTION_PASSWORD].arg;
|
||||
@@ -1363,6 +1457,15 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
+ if (state[OPTION_PROTECTOR].set) /* key protector(s) */
|
||||
+ {
|
||||
+ cargs.key_cache = grub_zalloc (state[OPTION_PROTECTOR].set * sizeof (*cargs.key_cache));
|
||||
+ if (cargs.key_cache == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||||
+ "no memory for key protector key cache");
|
||||
+ cargs.protectors = state[OPTION_PROTECTOR].args;
|
||||
+ }
|
||||
+
|
||||
if (state[OPTION_UUID].set) /* uuid */
|
||||
{
|
||||
int found_uuid;
|
||||
@@ -1371,6 +1474,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
dev = grub_cryptodisk_get_by_uuid (args[0]);
|
||||
if (dev)
|
||||
{
|
||||
+ grub_cryptodisk_clear_key_cache (&cargs);
|
||||
grub_dprintf ("cryptodisk",
|
||||
"already mounted as crypto%lu\n", dev->id);
|
||||
return GRUB_ERR_NONE;
|
||||
@@ -1379,6 +1483,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
cargs.check_boot = state[OPTION_BOOT].set;
|
||||
cargs.search_uuid = args[0];
|
||||
found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
|
||||
+ grub_cryptodisk_clear_key_cache (&cargs);
|
||||
|
||||
if (found_uuid)
|
||||
return GRUB_ERR_NONE;
|
||||
@@ -1398,6 +1503,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
cargs.check_boot = state[OPTION_BOOT].set;
|
||||
grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
|
||||
+ grub_cryptodisk_clear_key_cache (&cargs);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
else
|
||||
@@ -1421,6 +1527,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
disk = grub_disk_open (diskname);
|
||||
if (!disk)
|
||||
{
|
||||
+ grub_cryptodisk_clear_key_cache (&cargs);
|
||||
if (disklast)
|
||||
*disklast = ')';
|
||||
return grub_errno;
|
||||
@@ -1431,12 +1538,14 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
grub_dprintf ("cryptodisk", "already mounted as crypto%lu\n", dev->id);
|
||||
grub_disk_close (disk);
|
||||
+ grub_cryptodisk_clear_key_cache (&cargs);
|
||||
if (disklast)
|
||||
*disklast = ')';
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
dev = grub_cryptodisk_scan_device_real (diskname, disk, &cargs);
|
||||
+ grub_cryptodisk_clear_key_cache (&cargs);
|
||||
|
||||
grub_disk_close (disk);
|
||||
if (disklast)
|
||||
@@ -1590,6 +1699,7 @@ GRUB_MOD_INIT (cryptodisk)
|
||||
cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0,
|
||||
N_("[ [-p password] | [-k keyfile"
|
||||
" [-O keyoffset] [-S keysize] ] ] [-H file]"
|
||||
+ " [-P protector [-P protector ...]]"
|
||||
" <SOURCE|-u UUID|-a|-b>"),
|
||||
N_("Mount a crypto device."), options);
|
||||
grub_procfs_register ("luks_script", &luks_script);
|
||||
diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h
|
||||
index d94df68b6..0b41e249e 100644
|
||||
--- a/include/grub/cryptodisk.h
|
||||
+++ b/include/grub/cryptodisk.h
|
||||
@@ -70,6 +70,18 @@ typedef gcry_err_code_t
|
||||
(*grub_cryptodisk_rekey_func_t) (struct grub_cryptodisk *dev,
|
||||
grub_uint64_t zoneno);
|
||||
|
||||
+struct grub_cryptomount_cached_key
|
||||
+{
|
||||
+ grub_uint8_t *key;
|
||||
+ grub_size_t key_len;
|
||||
+
|
||||
+ /*
|
||||
+ * The key protector associated with this cache entry failed, so avoid it
|
||||
+ * even if the cached entry (an instance of this structure) is empty.
|
||||
+ */
|
||||
+ int invalid;
|
||||
+};
|
||||
+
|
||||
struct grub_cryptomount_args
|
||||
{
|
||||
/* scan: Flag to indicate that only bootable volumes should be decrypted */
|
||||
@@ -81,6 +93,10 @@ struct grub_cryptomount_args
|
||||
/* recover_key: Length of key_data */
|
||||
grub_size_t key_len;
|
||||
grub_file_t hdr_file;
|
||||
+ /* recover_key: Names of the key protectors to use (NULL-terminated) */
|
||||
+ char **protectors;
|
||||
+ /* recover_key: Key cache to avoid invoking the same key protector twice */
|
||||
+ struct grub_cryptomount_cached_key *key_cache;
|
||||
};
|
||||
typedef struct grub_cryptomount_args *grub_cryptomount_args_t;
|
||||
|
||||
--
|
||||
2.35.3
|
||||
|
||||
91
0004-diskfilter-look-up-cryptodisk-devices-first.patch
Normal file
91
0004-diskfilter-look-up-cryptodisk-devices-first.patch
Normal file
@@ -0,0 +1,91 @@
|
||||
From 91a99dffbe78b91a0c18b32ebecf755ba9d74032 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Thu, 10 Aug 2023 10:19:29 +0800
|
||||
Subject: [PATCH 4/4] diskfilter: look up cryptodisk devices first
|
||||
|
||||
When using disk auto-unlocking with TPM 2.0, the typical grub.cfg may
|
||||
look like this:
|
||||
|
||||
tpm2_key_protector_init --tpm2key=(hd0,gpt1)/boot/grub2/sealed.tpm
|
||||
cryptomount -u <PART-UUID> -P tpm2
|
||||
search --fs-uuid --set=root <FS-UUID>
|
||||
|
||||
Since the disk search order is based on the order of module loading, the
|
||||
attacker could insert a malicious disk with the same FS-UUID root to
|
||||
trick grub2 to boot into the malicious root and further dump memory to
|
||||
steal the unsealed key.
|
||||
|
||||
Do defend against such an attack, we can specify the hint provided by
|
||||
'grub-probe' to search the encrypted partition first:
|
||||
|
||||
search --fs-uuid --set=root --hint='cryptouuid/<PART-UUID>' <FS-UUID>
|
||||
|
||||
However, for LVM on an encrypted partition, the search hint provided by
|
||||
'grub-probe' is:
|
||||
|
||||
--hint='lvmid/<VG-UUID>/<LV-UUID>'
|
||||
|
||||
It doesn't guarantee to look up the logical volume from the encrypted
|
||||
partition, so the attacker may have the chance to fool grub2 to boot
|
||||
into the malicious disk.
|
||||
|
||||
To minimize the attack surface, this commit tweaks the disk device search
|
||||
in diskfilter to look up cryptodisk devices first and then others, so
|
||||
that the auto-unlocked disk will be found first, not the attacker's disk.
|
||||
|
||||
Cc: Fabian Vogt <fvogt@suse.com>
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
---
|
||||
grub-core/disk/diskfilter.c | 35 ++++++++++++++++++++++++++---------
|
||||
1 file changed, 26 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c
|
||||
index 41e177549..c45bef1ca 100644
|
||||
--- a/grub-core/disk/diskfilter.c
|
||||
+++ b/grub-core/disk/diskfilter.c
|
||||
@@ -322,15 +322,32 @@ scan_devices (const char *arname)
|
||||
int need_rescan;
|
||||
|
||||
for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++)
|
||||
- for (p = grub_disk_dev_list; p; p = p->next)
|
||||
- if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID
|
||||
- && p->disk_iterate)
|
||||
- {
|
||||
- if ((p->disk_iterate) (scan_disk_hook, NULL, pull))
|
||||
- return;
|
||||
- if (arname && is_lv_readable (find_lv (arname), 1))
|
||||
- return;
|
||||
- }
|
||||
+ {
|
||||
+ /* look up the crytodisk devices first */
|
||||
+ for (p = grub_disk_dev_list; p; p = p->next)
|
||||
+ if (p->id == GRUB_DISK_DEVICE_CRYPTODISK_ID
|
||||
+ && p->disk_iterate)
|
||||
+ {
|
||||
+ if ((p->disk_iterate) (scan_disk_hook, NULL, pull))
|
||||
+ return;
|
||||
+ if (arname && is_lv_readable (find_lv (arname), 1))
|
||||
+ return;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* check the devices other than crytodisk */
|
||||
+ for (p = grub_disk_dev_list; p; p = p->next)
|
||||
+ if (p->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
|
||||
+ continue;
|
||||
+ else if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID
|
||||
+ && p->disk_iterate)
|
||||
+ {
|
||||
+ if ((p->disk_iterate) (scan_disk_hook, NULL, pull))
|
||||
+ return;
|
||||
+ if (arname && is_lv_readable (find_lv (arname), 1))
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
scan_depth = 0;
|
||||
need_rescan = 1;
|
||||
--
|
||||
2.35.3
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
From e2a6f238920ab547d216ce96283bca6faf36378b Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Wed, 30 Apr 2025 21:16:50 +0800
|
||||
Subject: [PATCH 4/4] efi/chainloader: fix missing file_path in loaded_image
|
||||
|
||||
The file_path field in the loaded_image protocol may be unset for
|
||||
chainloaded target images. When this occurs, populate the file_path to
|
||||
ensure the target image can use the loaded_image protocol for location
|
||||
dependent operations, such as reading configuration files from its
|
||||
directory. Without this, the chainloaded image may fail to start due to
|
||||
an inability to reconfigure itself properly.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/loader/efi/chainloader.c | 52 +++++++++++++++++-------------
|
||||
1 file changed, 29 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
|
||||
index 7e2847217..9b70e1e61 100644
|
||||
--- a/grub-core/loader/efi/chainloader.c
|
||||
+++ b/grub-core/loader/efi/chainloader.c
|
||||
@@ -222,6 +222,29 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
|
||||
return file_path;
|
||||
}
|
||||
|
||||
+static grub_efi_device_path_t *
|
||||
+grub_efi_get_media_file_path (grub_efi_device_path_t *dp)
|
||||
+{
|
||||
+ while (1)
|
||||
+ {
|
||||
+ grub_efi_uint8_t type;
|
||||
+ grub_efi_uint8_t subtype;
|
||||
+
|
||||
+ if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
|
||||
+ break;
|
||||
+
|
||||
+ type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
|
||||
+ subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
|
||||
+
|
||||
+ if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
|
||||
+ return dp;
|
||||
+
|
||||
+ dp = GRUB_EFI_NEXT_DEVICE_PATH (dp);
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
#ifdef SUPPORT_SECURE_BOOT
|
||||
#define SHIM_LOCK_GUID \
|
||||
{ 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }
|
||||
@@ -461,29 +484,6 @@ relocate_coff (pe_coff_loader_image_context_t *context, void *data)
|
||||
return GRUB_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
-static grub_efi_device_path_t *
|
||||
-grub_efi_get_media_file_path (grub_efi_device_path_t *dp)
|
||||
-{
|
||||
- while (1)
|
||||
- {
|
||||
- grub_efi_uint8_t type;
|
||||
- grub_efi_uint8_t subtype;
|
||||
-
|
||||
- if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
|
||||
- break;
|
||||
-
|
||||
- type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
|
||||
- subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
|
||||
-
|
||||
- if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
|
||||
- return dp;
|
||||
-
|
||||
- dp = GRUB_EFI_NEXT_DEVICE_PATH (dp);
|
||||
- }
|
||||
-
|
||||
- return NULL;
|
||||
-}
|
||||
-
|
||||
static grub_efi_boolean_t
|
||||
handle_image (struct grub_secureboot_chainloader_context *load_context)
|
||||
{
|
||||
@@ -881,6 +881,12 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
loaded_image->device_handle = dev_handle;
|
||||
|
||||
+ if (! loaded_image->file_path)
|
||||
+ {
|
||||
+ grub_dprintf ("chain", "bailout file_path\n");
|
||||
+ loaded_image->file_path = grub_efi_get_media_file_path (file_path);
|
||||
+ }
|
||||
+
|
||||
/* Build load options with arguments from chainloader command line. */
|
||||
if (cmdline)
|
||||
{
|
||||
--
|
||||
2.50.1
|
||||
|
||||
92
0004-fs-tar-Integer-overflow-leads-to-heap-OOB-write.patch
Normal file
92
0004-fs-tar-Integer-overflow-leads-to-heap-OOB-write.patch
Normal file
@@ -0,0 +1,92 @@
|
||||
From 8f99c43384b9122eedeab1411ab5076ca5878ef9 Mon Sep 17 00:00:00 2001
|
||||
From: Lidong Chen <lidong.chen@oracle.com>
|
||||
Date: Fri, 22 Nov 2024 06:27:58 +0000
|
||||
Subject: [PATCH 04/20] fs/tar: Integer overflow leads to heap OOB write
|
||||
|
||||
Both namesize and linksize are derived from hd.size, a 12-digit octal
|
||||
number parsed by read_number(). Later direct arithmetic calculation like
|
||||
"namesize + 1" and "linksize + 1" may exceed the maximum value of
|
||||
grub_size_t leading to heap OOB write. This patch fixes the issue by
|
||||
using grub_add() and checking for an overflow.
|
||||
|
||||
Fixes: CVE-2024-45780
|
||||
|
||||
Reported-by: Nils Langius <nils@langius.de>
|
||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Reviewed-by: Alec Brown <alec.r.brown@oracle.com>
|
||||
---
|
||||
grub-core/fs/tar.c | 23 ++++++++++++++++++-----
|
||||
1 file changed, 18 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/grub-core/fs/tar.c b/grub-core/fs/tar.c
|
||||
index c551ed6b52..a9e39b0eb6 100644
|
||||
--- a/grub-core/fs/tar.c
|
||||
+++ b/grub-core/fs/tar.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <grub/mm.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/i18n.h>
|
||||
+#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -76,6 +77,7 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
|
||||
{
|
||||
struct head hd;
|
||||
int reread = 0, have_longname = 0, have_longlink = 0;
|
||||
+ grub_size_t sz;
|
||||
|
||||
data->hofs = data->next_hofs;
|
||||
|
||||
@@ -97,7 +99,11 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
|
||||
{
|
||||
grub_err_t err;
|
||||
grub_size_t namesize = read_number (hd.size, sizeof (hd.size));
|
||||
- *name = grub_malloc (namesize + 1);
|
||||
+
|
||||
+ if (grub_add (namesize, 1, &sz))
|
||||
+ return grub_error (GRUB_ERR_BAD_FS, N_("name size overflow"));
|
||||
+
|
||||
+ *name = grub_malloc (sz);
|
||||
if (*name == NULL)
|
||||
return grub_errno;
|
||||
err = grub_disk_read (data->disk, 0,
|
||||
@@ -117,15 +123,19 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
|
||||
{
|
||||
grub_err_t err;
|
||||
grub_size_t linksize = read_number (hd.size, sizeof (hd.size));
|
||||
- if (data->linkname_alloc < linksize + 1)
|
||||
+
|
||||
+ if (grub_add (linksize, 1, &sz))
|
||||
+ return grub_error (GRUB_ERR_BAD_FS, N_("link size overflow"));
|
||||
+
|
||||
+ if (data->linkname_alloc < sz)
|
||||
{
|
||||
char *n;
|
||||
- n = grub_calloc (2, linksize + 1);
|
||||
+ n = grub_calloc (2, sz);
|
||||
if (!n)
|
||||
return grub_errno;
|
||||
grub_free (data->linkname);
|
||||
data->linkname = n;
|
||||
- data->linkname_alloc = 2 * (linksize + 1);
|
||||
+ data->linkname_alloc = 2 * (sz);
|
||||
}
|
||||
|
||||
err = grub_disk_read (data->disk, 0,
|
||||
@@ -148,7 +158,10 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
|
||||
while (extra_size < sizeof (hd.prefix)
|
||||
&& hd.prefix[extra_size])
|
||||
extra_size++;
|
||||
- *name = grub_malloc (sizeof (hd.name) + extra_size + 2);
|
||||
+
|
||||
+ if (grub_add (sizeof (hd.name) + 2, extra_size, &sz))
|
||||
+ return grub_error (GRUB_ERR_BAD_FS, N_("long name size overflow"));
|
||||
+ *name = grub_malloc (sz);
|
||||
if (*name == NULL)
|
||||
return grub_errno;
|
||||
if (hd.prefix[0])
|
||||
--
|
||||
2.48.1
|
||||
|
||||
218
0004-ieee1275-ibmvpm-Move-TPM-initialization-functions-to.patch
Normal file
218
0004-ieee1275-ibmvpm-Move-TPM-initialization-functions-to.patch
Normal file
@@ -0,0 +1,218 @@
|
||||
From 8c0b5f200352603e53b799fca7b63f845a978f19 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Date: Tue, 26 Nov 2024 15:39:43 -0500
|
||||
Subject: [PATCH 4/7] ieee1275/ibmvpm: Move TPM initialization functions to own
|
||||
file
|
||||
|
||||
Move common initialization functions from the ibmvtpm driver module into
|
||||
tcg2.c that will be moved into the new TCG2 driver in a subsequent patch.
|
||||
Make the functions available to the ibmvtpm driver as public functions
|
||||
and variables.
|
||||
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 1 +
|
||||
grub-core/commands/ieee1275/ibmvtpm.c | 44 ++-----------------
|
||||
grub-core/lib/ieee1275/tcg2.c | 61 +++++++++++++++++++++++++++
|
||||
include/grub/ieee1275/tpm.h | 31 ++++++++++++++
|
||||
4 files changed, 97 insertions(+), 40 deletions(-)
|
||||
create mode 100644 grub-core/lib/ieee1275/tcg2.c
|
||||
create mode 100644 include/grub/ieee1275/tpm.h
|
||||
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index 40427165e..c5fd796d4 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1155,6 +1155,7 @@ module = {
|
||||
name = tpm;
|
||||
common = commands/tpm.c;
|
||||
ieee1275 = commands/ieee1275/ibmvtpm.c;
|
||||
+ ieee1275 = lib/ieee1275/tcg2.c;
|
||||
enable = powerpc_ieee1275;
|
||||
};
|
||||
|
||||
diff --git a/grub-core/commands/ieee1275/ibmvtpm.c b/grub-core/commands/ieee1275/ibmvtpm.c
|
||||
index dd30c7432..284673217 100644
|
||||
--- a/grub-core/commands/ieee1275/ibmvtpm.c
|
||||
+++ b/grub-core/commands/ieee1275/ibmvtpm.c
|
||||
@@ -23,46 +23,10 @@
|
||||
#include <grub/types.h>
|
||||
#include <grub/tpm.h>
|
||||
#include <grub/ieee1275/ieee1275.h>
|
||||
+#include <grub/ieee1275/tpm.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
|
||||
-static grub_ieee1275_ihandle_t tpm_ihandle;
|
||||
-static grub_uint8_t tpm_version;
|
||||
-
|
||||
-static void
|
||||
-tpm_get_tpm_version (void)
|
||||
-{
|
||||
- grub_ieee1275_phandle_t vtpm;
|
||||
- char buffer[20];
|
||||
-
|
||||
- if (!grub_ieee1275_finddevice ("/vdevice/vtpm", &vtpm) &&
|
||||
- !grub_ieee1275_get_property (vtpm, "compatible", buffer,
|
||||
- sizeof (buffer), NULL) &&
|
||||
- !grub_strcmp (buffer, "IBM,vtpm20"))
|
||||
- tpm_version = 2;
|
||||
-}
|
||||
-
|
||||
-static grub_err_t
|
||||
-tpm_init (void)
|
||||
-{
|
||||
- static int init_success = 0;
|
||||
-
|
||||
- if (!init_success)
|
||||
- {
|
||||
- if (grub_ieee1275_open ("/vdevice/vtpm", &tpm_ihandle) < 0)
|
||||
- {
|
||||
- tpm_ihandle = GRUB_IEEE1275_IHANDLE_INVALID;
|
||||
- return GRUB_ERR_UNKNOWN_DEVICE;
|
||||
- }
|
||||
-
|
||||
- init_success = 1;
|
||||
-
|
||||
- tpm_get_tpm_version ();
|
||||
- }
|
||||
-
|
||||
- return GRUB_ERR_NONE;
|
||||
-}
|
||||
-
|
||||
static int
|
||||
ibmvtpm_2hash_ext_log (grub_uint8_t pcrindex,
|
||||
grub_uint32_t eventtype,
|
||||
@@ -88,7 +52,7 @@ ibmvtpm_2hash_ext_log (grub_uint8_t pcrindex,
|
||||
|
||||
INIT_IEEE1275_COMMON (&args.common, "call-method", 8, 2);
|
||||
args.method = (grub_ieee1275_cell_t) "2hash-ext-log";
|
||||
- args.ihandle = tpm_ihandle;
|
||||
+ args.ihandle = grub_ieee1275_tpm_ihandle;
|
||||
args.pcrindex = pcrindex;
|
||||
args.eventtype = eventtype;
|
||||
args.description = (grub_ieee1275_cell_t) description;
|
||||
@@ -136,7 +100,7 @@ grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||||
grub_dprintf ("tpm", "log_event, pcr = %d, size = 0x%" PRIxGRUB_SIZE ", %s\n",
|
||||
pcr, size, description);
|
||||
|
||||
- if (tpm_version == 2)
|
||||
+ if (grub_ieee1275_tpm_version == 2)
|
||||
return tpm2_log_event (buf, size, pcr, description);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
@@ -149,5 +113,5 @@ grub_tpm_present (void)
|
||||
* Call tpm_init() "late" rather than from GRUB_MOD_INIT() so that device nodes
|
||||
* can be found.
|
||||
*/
|
||||
- return tpm_init() == GRUB_ERR_NONE;
|
||||
+ return grub_ieee1275_tpm_init() == GRUB_ERR_NONE;
|
||||
}
|
||||
diff --git a/grub-core/lib/ieee1275/tcg2.c b/grub-core/lib/ieee1275/tcg2.c
|
||||
new file mode 100644
|
||||
index 000000000..1819d1447
|
||||
--- /dev/null
|
||||
+++ b/grub-core/lib/ieee1275/tcg2.c
|
||||
@@ -0,0 +1,61 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2024 IBM Corporation
|
||||
+ * Copyright (C) 2024 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/types.h>
|
||||
+#include <grub/tpm.h>
|
||||
+#include <grub/ieee1275/tpm.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/misc.h>
|
||||
+
|
||||
+grub_ieee1275_ihandle_t grub_ieee1275_tpm_ihandle;
|
||||
+grub_uint8_t grub_ieee1275_tpm_version;
|
||||
+
|
||||
+static void
|
||||
+tpm_get_tpm_version (void)
|
||||
+{
|
||||
+ grub_ieee1275_phandle_t vtpm;
|
||||
+ char buffer[20];
|
||||
+
|
||||
+ if (!grub_ieee1275_finddevice ("/vdevice/vtpm", &vtpm) &&
|
||||
+ !grub_ieee1275_get_property (vtpm, "compatible", buffer,
|
||||
+ sizeof (buffer), NULL) &&
|
||||
+ !grub_strcmp (buffer, "IBM,vtpm20"))
|
||||
+ grub_ieee1275_tpm_version = 2;
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_ieee1275_tpm_init (void)
|
||||
+{
|
||||
+ static int init_success = 0;
|
||||
+
|
||||
+ if (!init_success)
|
||||
+ {
|
||||
+ if (grub_ieee1275_open ("/vdevice/vtpm", &grub_ieee1275_tpm_ihandle) < 0)
|
||||
+ {
|
||||
+ grub_ieee1275_tpm_ihandle = GRUB_IEEE1275_IHANDLE_INVALID;
|
||||
+ return GRUB_ERR_UNKNOWN_DEVICE;
|
||||
+ }
|
||||
+
|
||||
+ init_success = 1;
|
||||
+
|
||||
+ tpm_get_tpm_version ();
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
diff --git a/include/grub/ieee1275/tpm.h b/include/grub/ieee1275/tpm.h
|
||||
new file mode 100644
|
||||
index 000000000..9575c1c68
|
||||
--- /dev/null
|
||||
+++ b/include/grub/ieee1275/tpm.h
|
||||
@@ -0,0 +1,31 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2024 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_IEEE1275_TPM_HEADER
|
||||
+#define GRUB_IEEE1275_TPM_HEADER 1
|
||||
+
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/types.h>
|
||||
+#include <grub/ieee1275/ieee1275.h>
|
||||
+
|
||||
+extern grub_ieee1275_ihandle_t grub_ieee1275_tpm_ihandle;
|
||||
+extern grub_uint8_t grub_ieee1275_tpm_version;
|
||||
+
|
||||
+extern grub_err_t grub_ieee1275_tpm_init (void);
|
||||
+
|
||||
+#endif
|
||||
--
|
||||
2.43.0
|
||||
|
||||
58
0004-normal-main-Unregister-commands-on-module-unload.patch
Normal file
58
0004-normal-main-Unregister-commands-on-module-unload.patch
Normal file
@@ -0,0 +1,58 @@
|
||||
From 41330d7fafe122d79d7a9ec28884c0771eb4fdf3 Mon Sep 17 00:00:00 2001
|
||||
From: Alec Brown <alec.r.brown@oracle.com>
|
||||
Date: Thu, 21 Aug 2025 21:14:07 +0000
|
||||
Subject: [PATCH 4/7] normal/main: Unregister commands on module unload
|
||||
|
||||
When the normal module is loaded, the normal and normal_exit commands
|
||||
are registered but aren't unregistered when the module is unloaded. We
|
||||
need to add calls to grub_unregister_command() when unloading the module
|
||||
for these commands.
|
||||
|
||||
Fixes: CVE-2025-61663
|
||||
Fixes: CVE-2025-61664
|
||||
|
||||
Reported-by: Alec Brown <alec.r.brown@oracle.com>
|
||||
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/normal/main.c | 12 +++++++-----
|
||||
1 file changed, 7 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
|
||||
index 398169299..b77d55eb3 100644
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -639,7 +639,7 @@ grub_mini_cmd_clear (struct grub_command *cmd __attribute__ ((unused)),
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static grub_command_t cmd_clear;
|
||||
+static grub_command_t cmd_clear, cmd_normal, cmd_normal_exit;
|
||||
|
||||
static void (*grub_xputs_saved) (const char *str);
|
||||
static const char *features[] = {
|
||||
@@ -682,10 +682,10 @@ GRUB_MOD_INIT(normal)
|
||||
grub_env_export ("pager");
|
||||
|
||||
/* Register a command "normal" for the rescue mode. */
|
||||
- grub_register_command ("normal", grub_cmd_normal,
|
||||
- 0, N_("Enter normal mode."));
|
||||
- grub_register_command ("normal_exit", grub_cmd_normal_exit,
|
||||
- 0, N_("Exit from normal mode."));
|
||||
+ cmd_normal = grub_register_command ("normal", grub_cmd_normal,
|
||||
+ 0, N_("Enter normal mode."));
|
||||
+ cmd_normal_exit = grub_register_command ("normal_exit", grub_cmd_normal_exit,
|
||||
+ 0, N_("Exit from normal mode."));
|
||||
|
||||
/* Reload terminal colors when these variables are written to. */
|
||||
grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal);
|
||||
@@ -727,4 +727,6 @@ GRUB_MOD_FINI(normal)
|
||||
grub_register_variable_hook ("color_highlight", NULL, NULL);
|
||||
grub_fs_autoload_hook = 0;
|
||||
grub_unregister_command (cmd_clear);
|
||||
+ grub_unregister_command (cmd_normal);
|
||||
+ grub_unregister_command (cmd_normal_exit);
|
||||
}
|
||||
--
|
||||
2.51.1
|
||||
|
||||
413
0004-tss2-Add-TPM-2.0-NV-index-commands.patch
Normal file
413
0004-tss2-Add-TPM-2.0-NV-index-commands.patch
Normal file
@@ -0,0 +1,413 @@
|
||||
From 75c480885ab00fb9bc046fe214df60007116aef2 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Mon, 7 Apr 2025 16:29:18 +0800
|
||||
Subject: [PATCH 4/7] tss2: Add TPM 2.0 NV index commands
|
||||
|
||||
The following TPM 2.0 commands are introduced to tss2 to access the
|
||||
TPM non-volatile memory associated with the NV index handles:
|
||||
- TPM2_NV_DefineSpace,
|
||||
- TPM2_NV_UndefineSpace,
|
||||
- TPM2_NV_ReadPublic,
|
||||
- TPM2_NV_Read,
|
||||
- TPM2_NV_Write.
|
||||
|
||||
The related marshal/unmarshal functions are also introduced.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/lib/tss2/tpm2_cmd.c | 201 ++++++++++++++++++++++++++++++++
|
||||
grub-core/lib/tss2/tpm2_cmd.h | 32 +++++
|
||||
grub-core/lib/tss2/tss2_mu.c | 39 +++++++
|
||||
grub-core/lib/tss2/tss2_mu.h | 12 ++
|
||||
grub-core/lib/tss2/tss2_types.h | 6 +
|
||||
5 files changed, 290 insertions(+)
|
||||
|
||||
diff --git a/grub-core/lib/tss2/tpm2_cmd.c b/grub-core/lib/tss2/tpm2_cmd.c
|
||||
index 211d807d5..6d25db1ab 100644
|
||||
--- a/grub-core/lib/tss2/tpm2_cmd.c
|
||||
+++ b/grub-core/lib/tss2/tpm2_cmd.c
|
||||
@@ -1045,3 +1045,204 @@ grub_tpm2_testparms (const TPMT_PUBLIC_PARMS_t *parms,
|
||||
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
+
|
||||
+TPM_RC_t
|
||||
+grub_tpm2_nv_definespace (const TPMI_RH_PROVISION_t authHandle,
|
||||
+ const TPMS_AUTH_COMMAND_t *authCommand,
|
||||
+ const TPM2B_AUTH_t *auth,
|
||||
+ const TPM2B_NV_PUBLIC_t *publicInfo)
|
||||
+{
|
||||
+ TPM_RC_t rc;
|
||||
+ struct grub_tpm2_buffer in;
|
||||
+ struct grub_tpm2_buffer out;
|
||||
+ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS;
|
||||
+ TPM_RC_t responseCode;
|
||||
+
|
||||
+ if (publicInfo == NULL)
|
||||
+ return TPM_RC_VALUE;
|
||||
+
|
||||
+ /* Marshal */
|
||||
+ grub_tpm2_buffer_init (&in);
|
||||
+ grub_tpm2_buffer_pack_u32 (&in, authHandle);
|
||||
+ if (authCommand != NULL)
|
||||
+ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
|
||||
+ if (auth != NULL)
|
||||
+ grub_Tss2_MU_TPM2B_Marshal (&in, auth->size, auth->buffer);
|
||||
+ else
|
||||
+ grub_tpm2_buffer_pack_u16 (&in, 0);
|
||||
+ grub_Tss2_MU_TPM2B_NV_PUBLIC_Marshal (&in, publicInfo);
|
||||
+ if (in.error != 0)
|
||||
+ return TPM_RC_FAILURE;
|
||||
+
|
||||
+ /* Submit */
|
||||
+ grub_tpm2_buffer_init (&out);
|
||||
+ rc = tpm2_submit_command (tag, TPM_CC_NV_DefineSpace, &responseCode, &in, &out);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return rc;
|
||||
+ if (responseCode != TPM_RC_SUCCESS)
|
||||
+ return responseCode;
|
||||
+
|
||||
+ /* Unmarshal */
|
||||
+ if (out.error != 0)
|
||||
+ return TPM_RC_FAILURE;
|
||||
+
|
||||
+ return TPM_RC_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+TPM_RC_t
|
||||
+grub_tpm2_nv_undefinespace (const TPMI_RH_PROVISION_t authHandle,
|
||||
+ const TPMI_RH_NV_INDEX_t nvIndex,
|
||||
+ const TPMS_AUTH_COMMAND_t *authCommand)
|
||||
+{
|
||||
+ TPM_RC_t rc;
|
||||
+ struct grub_tpm2_buffer in;
|
||||
+ struct grub_tpm2_buffer out;
|
||||
+ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS;
|
||||
+ TPM_RC_t responseCode;
|
||||
+
|
||||
+ /* Marshal */
|
||||
+ grub_tpm2_buffer_init (&in);
|
||||
+ grub_tpm2_buffer_pack_u32 (&in, authHandle);
|
||||
+ grub_tpm2_buffer_pack_u32 (&in, nvIndex);
|
||||
+ if (authCommand != NULL)
|
||||
+ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
|
||||
+ if (in.error != 0)
|
||||
+ return TPM_RC_FAILURE;
|
||||
+
|
||||
+ /* Submit */
|
||||
+ grub_tpm2_buffer_init (&out);
|
||||
+ rc = tpm2_submit_command (tag, TPM_CC_NV_UndefineSpace, &responseCode, &in, &out);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return rc;
|
||||
+ if (responseCode != TPM_RC_SUCCESS)
|
||||
+ return responseCode;
|
||||
+
|
||||
+ /* Unmarshal */
|
||||
+ if (out.error != 0)
|
||||
+ return TPM_RC_FAILURE;
|
||||
+
|
||||
+ return TPM_RC_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+TPM_RC_t
|
||||
+grub_tpm2_nv_readpublic (const TPMI_RH_NV_INDEX_t nvIndex,
|
||||
+ const TPMS_AUTH_COMMAND_t *authCommand,
|
||||
+ TPM2B_NV_PUBLIC_t *nvPublic,
|
||||
+ TPM2B_NAME_t *nvName)
|
||||
+{
|
||||
+ TPM_RC_t rc;
|
||||
+ struct grub_tpm2_buffer in;
|
||||
+ struct grub_tpm2_buffer out;
|
||||
+ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS;
|
||||
+ TPM_RC_t responseCode;
|
||||
+ grub_uint32_t param_size;
|
||||
+
|
||||
+ /* Marshal */
|
||||
+ grub_tpm2_buffer_init (&in);
|
||||
+ grub_tpm2_buffer_pack_u32 (&in, nvIndex);
|
||||
+ if (authCommand != NULL)
|
||||
+ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
|
||||
+ if (in.error != 0)
|
||||
+ return TPM_RC_FAILURE;
|
||||
+
|
||||
+ /* Submit */
|
||||
+ grub_tpm2_buffer_init (&out);
|
||||
+ rc = tpm2_submit_command (tag, TPM_CC_NV_ReadPublic, &responseCode, &in, &out);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return rc;
|
||||
+ if (responseCode != TPM_RC_SUCCESS)
|
||||
+ return responseCode;
|
||||
+
|
||||
+ /* Unmarshal */
|
||||
+ if (tag == TPM_ST_SESSIONS)
|
||||
+ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size);
|
||||
+ grub_Tss2_MU_TPM2B_NV_PUBLIC_Unmarshal (&out, nvPublic);
|
||||
+ grub_Tss2_MU_TPM2B_NAME_Unmarshal (&out, nvName);
|
||||
+ if (out.error != 0)
|
||||
+ return TPM_RC_FAILURE;
|
||||
+
|
||||
+ return TPM_RC_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+TPM_RC_t
|
||||
+grub_tpm2_nv_read (const TPMI_RH_NV_AUTH_t authHandle,
|
||||
+ const TPMI_RH_NV_INDEX_t nvIndex,
|
||||
+ const TPMS_AUTH_COMMAND_t *authCommand,
|
||||
+ const grub_uint16_t size,
|
||||
+ const grub_uint16_t offset,
|
||||
+ TPM2B_MAX_NV_BUFFER_t *data)
|
||||
+{
|
||||
+ TPM_RC_t rc;
|
||||
+ struct grub_tpm2_buffer in;
|
||||
+ struct grub_tpm2_buffer out;
|
||||
+ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS;
|
||||
+ TPM_RC_t responseCode;
|
||||
+ grub_uint32_t param_size;
|
||||
+
|
||||
+ /* Marshal */
|
||||
+ grub_tpm2_buffer_init (&in);
|
||||
+ grub_tpm2_buffer_pack_u32 (&in, authHandle);
|
||||
+ grub_tpm2_buffer_pack_u32 (&in, nvIndex);
|
||||
+ if (authCommand != NULL)
|
||||
+ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
|
||||
+ grub_tpm2_buffer_pack_u16 (&in, size);
|
||||
+ grub_tpm2_buffer_pack_u16 (&in, offset);
|
||||
+ if (in.error != 0)
|
||||
+ return TPM_RC_FAILURE;
|
||||
+
|
||||
+ /* Submit */
|
||||
+ grub_tpm2_buffer_init (&out);
|
||||
+ rc = tpm2_submit_command (tag, TPM_CC_NV_Read, &responseCode, &in, &out);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return rc;
|
||||
+ if (responseCode != TPM_RC_SUCCESS)
|
||||
+ return responseCode;
|
||||
+
|
||||
+ /* Unmarshal */
|
||||
+ if (tag == TPM_ST_SESSIONS)
|
||||
+ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size);
|
||||
+ grub_Tss2_MU_TPM2B_NAX_NV_BUFFER_Unmarshal (&out, data);
|
||||
+ if (out.error != 0)
|
||||
+ return TPM_RC_FAILURE;
|
||||
+
|
||||
+ return TPM_RC_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+TPM_RC_t
|
||||
+grub_tpm2_nv_write (const TPMI_RH_NV_AUTH_t authHandle,
|
||||
+ const TPMI_RH_NV_INDEX_t nvIndex,
|
||||
+ const TPMS_AUTH_COMMAND_t *authCommand,
|
||||
+ const TPM2B_MAX_NV_BUFFER_t *data,
|
||||
+ const grub_uint16_t offset)
|
||||
+{
|
||||
+ TPM_RC_t rc;
|
||||
+ struct grub_tpm2_buffer in;
|
||||
+ struct grub_tpm2_buffer out;
|
||||
+ TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS;
|
||||
+ TPM_RC_t responseCode;
|
||||
+
|
||||
+ /* Marshal */
|
||||
+ grub_tpm2_buffer_init (&in);
|
||||
+ grub_tpm2_buffer_pack_u32 (&in, authHandle);
|
||||
+ grub_tpm2_buffer_pack_u32 (&in, nvIndex);
|
||||
+ if (authCommand != NULL)
|
||||
+ grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
|
||||
+ grub_Tss2_MU_TPM2B_Marshal (&in, data->size, data->buffer);
|
||||
+ grub_tpm2_buffer_pack_u16 (&in, offset);
|
||||
+ if (in.error != 0)
|
||||
+ return TPM_RC_FAILURE;
|
||||
+
|
||||
+ /* Submit */
|
||||
+ grub_tpm2_buffer_init (&out);
|
||||
+ rc = tpm2_submit_command (tag, TPM_CC_NV_Write, &responseCode, &in, &out);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return rc;
|
||||
+ if (responseCode != TPM_RC_SUCCESS)
|
||||
+ return responseCode;
|
||||
+
|
||||
+ /* Unmarshal */
|
||||
+ if (out.error != 0)
|
||||
+ return TPM_RC_FAILURE;
|
||||
+
|
||||
+ return TPM_RC_SUCCESS;
|
||||
+}
|
||||
diff --git a/grub-core/lib/tss2/tpm2_cmd.h b/grub-core/lib/tss2/tpm2_cmd.h
|
||||
index d313cba00..90b42efec 100644
|
||||
--- a/grub-core/lib/tss2/tpm2_cmd.h
|
||||
+++ b/grub-core/lib/tss2/tpm2_cmd.h
|
||||
@@ -154,4 +154,36 @@ extern TPM_RC_t
|
||||
grub_tpm2_testparms (const TPMT_PUBLIC_PARMS_t *parms,
|
||||
const TPMS_AUTH_COMMAND_t *authCommand);
|
||||
|
||||
+extern TPM_RC_t
|
||||
+grub_tpm2_nv_definespace (const TPMI_RH_PROVISION_t authHandle,
|
||||
+ const TPMS_AUTH_COMMAND_t *authCommand,
|
||||
+ const TPM2B_AUTH_t *auth,
|
||||
+ const TPM2B_NV_PUBLIC_t *publicInfo);
|
||||
+
|
||||
+extern TPM_RC_t
|
||||
+grub_tpm2_nv_undefinespace (const TPMI_RH_PROVISION_t authHandle,
|
||||
+ const TPMI_RH_NV_INDEX_t nvIndex,
|
||||
+ const TPMS_AUTH_COMMAND_t *authCommand);
|
||||
+
|
||||
+extern TPM_RC_t
|
||||
+grub_tpm2_nv_readpublic (const TPMI_RH_NV_INDEX_t nvIndex,
|
||||
+ const TPMS_AUTH_COMMAND_t *authCommand,
|
||||
+ TPM2B_NV_PUBLIC_t *nvPublic,
|
||||
+ TPM2B_NAME_t *nvName);
|
||||
+
|
||||
+extern TPM_RC_t
|
||||
+grub_tpm2_nv_read (const TPMI_RH_NV_AUTH_t authHandle,
|
||||
+ const TPMI_RH_NV_INDEX_t nvIndex,
|
||||
+ const TPMS_AUTH_COMMAND_t *authCommand,
|
||||
+ const grub_uint16_t size,
|
||||
+ const grub_uint16_t offset,
|
||||
+ TPM2B_MAX_NV_BUFFER_t *data);
|
||||
+
|
||||
+extern TPM_RC_t
|
||||
+grub_tpm2_nv_write (const TPMI_RH_NV_AUTH_t authHandle,
|
||||
+ const TPMI_RH_NV_INDEX_t nvIndex,
|
||||
+ const TPMS_AUTH_COMMAND_t *authCommand,
|
||||
+ const TPM2B_MAX_NV_BUFFER_t *data,
|
||||
+ const grub_uint16_t offset);
|
||||
+
|
||||
#endif /* ! GRUB_TPM2_COMMANDS_HEADER */
|
||||
diff --git a/grub-core/lib/tss2/tss2_mu.c b/grub-core/lib/tss2/tss2_mu.c
|
||||
index 86134cc0a..816e5b37f 100644
|
||||
--- a/grub-core/lib/tss2/tss2_mu.c
|
||||
+++ b/grub-core/lib/tss2/tss2_mu.c
|
||||
@@ -17,6 +17,7 @@
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
+#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
|
||||
#include <tss2_mu.h>
|
||||
@@ -572,6 +573,37 @@ grub_Tss2_MU_TPMT_TK_VERIFIED_Marshal (grub_tpm2_buffer_t buffer,
|
||||
grub_Tss2_MU_TPM2B_Marshal (buffer, p->digest.size, p->digest.buffer);
|
||||
}
|
||||
|
||||
+void
|
||||
+grub_Tss2_MU_TPMS_NV_PUBLIC_Marshal (grub_tpm2_buffer_t buffer,
|
||||
+ const TPMS_NV_PUBLIC_t *p)
|
||||
+{
|
||||
+ grub_tpm2_buffer_pack_u32 (buffer, p->nvIndex);
|
||||
+ grub_tpm2_buffer_pack_u16 (buffer, p->nameAlg);
|
||||
+ grub_tpm2_buffer_pack_u32 (buffer, p->attributes);
|
||||
+ grub_Tss2_MU_TPM2B_Marshal (buffer, p->authPolicy.size, p->authPolicy.buffer);
|
||||
+ grub_tpm2_buffer_pack_u16 (buffer, p->dataSize);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_Tss2_MU_TPM2B_NV_PUBLIC_Marshal (grub_tpm2_buffer_t buffer,
|
||||
+ const TPM2B_NV_PUBLIC_t *p)
|
||||
+{
|
||||
+ grub_uint32_t start;
|
||||
+ grub_uint16_t size;
|
||||
+
|
||||
+ if (p != NULL)
|
||||
+ {
|
||||
+ grub_tpm2_buffer_pack_u16 (buffer, p->size);
|
||||
+
|
||||
+ start = buffer->size;
|
||||
+ grub_Tss2_MU_TPMS_NV_PUBLIC_Marshal (buffer, &p->nvPublic);
|
||||
+ size = grub_cpu_to_be16 (buffer->size - start);
|
||||
+ grub_memcpy (&buffer->data[start - sizeof (grub_uint16_t)], &size, sizeof (size));
|
||||
+ }
|
||||
+ else
|
||||
+ grub_tpm2_buffer_pack_u16 (buffer, 0);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
__Tss2_MU_TPM2B_BUFFER_Unmarshal (grub_tpm2_buffer_t buffer,
|
||||
TPM2B_t *p, grub_uint16_t bound)
|
||||
@@ -982,6 +1014,13 @@ grub_Tss2_MU_TPM2B_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer,
|
||||
grub_Tss2_MU_TPMS_NV_PUBLIC_Unmarshal (buffer, &p->nvPublic);
|
||||
}
|
||||
|
||||
+void
|
||||
+grub_Tss2_MU_TPM2B_NAX_NV_BUFFER_Unmarshal (grub_tpm2_buffer_t buffer,
|
||||
+ TPM2B_MAX_NV_BUFFER_t *p)
|
||||
+{
|
||||
+ TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_MAX_NV_BUFFER_t, p);
|
||||
+}
|
||||
+
|
||||
void
|
||||
grub_Tss2_MU_TPM2B_NAME_Unmarshal (grub_tpm2_buffer_t buffer,
|
||||
TPM2B_NAME_t *n)
|
||||
diff --git a/grub-core/lib/tss2/tss2_mu.h b/grub-core/lib/tss2/tss2_mu.h
|
||||
index 8f82126e1..6440de57c 100644
|
||||
--- a/grub-core/lib/tss2/tss2_mu.h
|
||||
+++ b/grub-core/lib/tss2/tss2_mu.h
|
||||
@@ -193,6 +193,14 @@ extern void
|
||||
grub_Tss2_MU_TPMT_TK_VERIFIED_Marshal (grub_tpm2_buffer_t buffer,
|
||||
const TPMT_TK_VERIFIED_t *p);
|
||||
|
||||
+extern void
|
||||
+grub_Tss2_MU_TPMS_NV_PUBLIC_Marshal (grub_tpm2_buffer_t buffer,
|
||||
+ const TPMS_NV_PUBLIC_t *p);
|
||||
+
|
||||
+extern void
|
||||
+grub_Tss2_MU_TPM2B_NV_PUBLIC_Marshal (grub_tpm2_buffer_t buffer,
|
||||
+ const TPM2B_NV_PUBLIC_t *p);
|
||||
+
|
||||
extern void
|
||||
grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (grub_tpm2_buffer_t buffer,
|
||||
TPMS_AUTH_RESPONSE_t *p);
|
||||
@@ -336,6 +344,10 @@ extern void
|
||||
grub_Tss2_MU_TPM2B_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer,
|
||||
TPM2B_NV_PUBLIC_t *p);
|
||||
|
||||
+extern void
|
||||
+grub_Tss2_MU_TPM2B_NAX_NV_BUFFER_Unmarshal (grub_tpm2_buffer_t buffer,
|
||||
+ TPM2B_MAX_NV_BUFFER_t *p);
|
||||
+
|
||||
extern void
|
||||
grub_Tss2_MU_TPM2B_NAME_Unmarshal (grub_tpm2_buffer_t buffer,
|
||||
TPM2B_NAME_t *n);
|
||||
diff --git a/grub-core/lib/tss2/tss2_types.h b/grub-core/lib/tss2/tss2_types.h
|
||||
index 5b1a7947d..bddde7191 100644
|
||||
--- a/grub-core/lib/tss2/tss2_types.h
|
||||
+++ b/grub-core/lib/tss2/tss2_types.h
|
||||
@@ -270,6 +270,7 @@ typedef TPM_HANDLE_t TPMI_RH_NV_INDEX_t;
|
||||
|
||||
/* TPM_HT_t Constants */
|
||||
typedef grub_uint8_t TPM_HT_t;
|
||||
+#define TPM_HT_NV_INDEX ((TPM_HT_t) 0x01)
|
||||
#define TPM_HT_PERMANENT ((TPM_HT_t) 0x40)
|
||||
#define TPM_HT_PERSISTENT ((TPM_HT_t) 0x81)
|
||||
|
||||
@@ -300,6 +301,7 @@ typedef TPM_HANDLE_t TPM_HC_t;
|
||||
#define TPM_HR_HANDLE_MASK ((TPM_HC_t) 0x00FFFFFF)
|
||||
#define TPM_HR_RANGE_MASK ((TPM_HC_t) 0xFF000000)
|
||||
#define TPM_HR_SHIFT ((TPM_HC_t) 24)
|
||||
+#define TPM_HR_NV_INDEX ((TPM_HC_t) (TPM_HT_NV_INDEX << TPM_HR_SHIFT))
|
||||
#define TPM_HR_PERSISTENT ((TPM_HC_t) (TPM_HT_PERSISTENT << TPM_HR_SHIFT))
|
||||
#define TPM_HR_PERMANENT ((TPM_HC_t) (TPM_HT_PERMANENT << TPM_HR_SHIFT))
|
||||
#define TPM_PERSISTENT_FIRST ((TPM_HC_t) (TPM_HR_PERSISTENT + 0))
|
||||
@@ -308,6 +310,7 @@ typedef TPM_HANDLE_t TPM_HC_t;
|
||||
#define TPM_PERMANENT_LAST ((TPM_HC_t) TPM_RH_LAST)
|
||||
|
||||
/* TPM Handle Type Checks */
|
||||
+#define TPM_HT_IS_NVINDEX(HANDLE) (((HANDLE) >> TPM_HR_SHIFT) == TPM_HT_NV_INDEX)
|
||||
#define TPM_HT_IS_PERMANENT(HANDLE) (((HANDLE) >> TPM_HR_SHIFT) == TPM_HT_PERMANENT)
|
||||
#define TPM_HT_IS_PERSISTENT(HANDLE) (((HANDLE) >> TPM_HR_SHIFT) == TPM_HT_PERSISTENT)
|
||||
|
||||
@@ -334,8 +337,11 @@ typedef grub_uint32_t TPM_CC_t;
|
||||
#define TPM_CC_ReadPublic ((TPM_CC_t) 0x00000173)
|
||||
#define TPM_CC_StartAuthSession ((TPM_CC_t) 0x00000176)
|
||||
#define TPM_CC_PolicyPCR ((TPM_CC_t) 0x0000017f)
|
||||
+#define TPM_CC_NV_DefineSpace ((TPM_CC_t) 0x0000012a)
|
||||
#define TPM_CC_NV_Read ((TPM_CC_t) 0x0000014e)
|
||||
#define TPM_CC_NV_ReadPublic ((TPM_CC_t) 0x00000169)
|
||||
+#define TPM_CC_NV_Write ((TPM_CC_t) 0x00000137)
|
||||
+#define TPM_CC_NV_UndefineSpace ((TPM_CC_t) 0x00000122)
|
||||
#define TPM_CC_GetCapability ((TPM_CC_t) 0x0000017a)
|
||||
#define TPM_CC_PCR_Read ((TPM_CC_t) 0x0000017e)
|
||||
#define TPM_CC_Load ((TPM_CC_t) 0x00000157)
|
||||
--
|
||||
2.43.0
|
||||
|
||||
255
0005-appendedsig-While-verifying-the-kernel-use-trusted-a.patch
Normal file
255
0005-appendedsig-While-verifying-the-kernel-use-trusted-a.patch
Normal file
@@ -0,0 +1,255 @@
|
||||
From bd776f35de3afbbe818c0531be9c9754797f2c08 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Tue, 25 Feb 2025 01:18:35 +0530
|
||||
Subject: [PATCH 5/9] appendedsig: While verifying the kernel, use trusted and
|
||||
distrusted lists
|
||||
|
||||
To verify the kernel's signature: verify the kernel binary against lists of binary hashes
|
||||
that are either distrusted or trusted. If it is not list in either trusted or distrusted hashes list
|
||||
then the trusted keys from the trusted key list are used to verify the signature.
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
---
|
||||
grub-core/commands/appendedsig/appendedsig.c | 199 +++++++++++++------
|
||||
1 file changed, 139 insertions(+), 60 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/appendedsig/appendedsig.c b/grub-core/commands/appendedsig/appendedsig.c
|
||||
index 3df950c00b..b6daccd3d7 100644
|
||||
--- a/grub-core/commands/appendedsig/appendedsig.c
|
||||
+++ b/grub-core/commands/appendedsig/appendedsig.c
|
||||
@@ -473,6 +473,83 @@ extract_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize,
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+get_binary_hash (const grub_size_t binary_hash_size, const grub_uint8_t *data,
|
||||
+ const grub_size_t data_size, grub_uint8_t *hash, grub_size_t *hash_size)
|
||||
+{
|
||||
+ grub_uuid_t guid = { 0 };
|
||||
+
|
||||
+ /* support SHA256, SHA384 and SHA512 for binary hash */
|
||||
+ if (binary_hash_size == 32)
|
||||
+ grub_memcpy (&guid, &GRUB_PKS_CERT_SHA256_GUID, GRUB_UUID_SIZE);
|
||||
+ else if (binary_hash_size == 48)
|
||||
+ grub_memcpy (&guid, &GRUB_PKS_CERT_SHA384_GUID, GRUB_UUID_SIZE);
|
||||
+ else if (binary_hash_size == 64)
|
||||
+ grub_memcpy (&guid, &GRUB_PKS_CERT_SHA512_GUID, GRUB_UUID_SIZE);
|
||||
+ else
|
||||
+ {
|
||||
+ grub_dprintf ("appendedsig", "unsupported hash type (%" PRIuGRUB_SIZE ") and skipping binary hash\n",
|
||||
+ binary_hash_size);
|
||||
+ return GRUB_ERR_UNKNOWN_COMMAND;
|
||||
+ }
|
||||
+
|
||||
+ return get_hash (&guid, data, data_size, hash, hash_size);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Verify binary hash against the list of binary hashes that are distrusted
|
||||
+ * and trusted.
|
||||
+ * The following errors can occur:
|
||||
+ * - GRUB_ERR_BAD_SIGNATURE: indicates that the hash is distrusted.
|
||||
+ * - GRUB_ERR_NONE: the hash is trusted, since it was found in the trusted hashes list
|
||||
+ * - GRUB_ERR_EOF: the hash could not be found in the hashes list
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+verify_binary_hash (const grub_uint8_t *data, const grub_size_t data_size)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t i = 0, hash_size = 0;
|
||||
+ grub_uint8_t hash[GRUB_MAX_HASH_SIZE] = { 0 };
|
||||
+
|
||||
+ for (i = 0; i < dbx.signature_entries; i++)
|
||||
+ {
|
||||
+ rc = get_binary_hash (dbx.signature_size[i], data, data_size, hash, &hash_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ continue;
|
||||
+
|
||||
+ if (hash_size == dbx.signature_size[i] &&
|
||||
+ grub_memcmp (dbx.signatures[i], hash, hash_size) == 0)
|
||||
+ {
|
||||
+ grub_dprintf ("appendedsig", "the binary hash (%02x%02x%02x%02x) was listed as distrusted\n",
|
||||
+ hash[0], hash[1], hash[2], hash[3]);
|
||||
+ return GRUB_ERR_BAD_SIGNATURE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < db.signature_entries; i++)
|
||||
+ {
|
||||
+ rc = get_binary_hash (db.signature_size[i], data, data_size, hash, &hash_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ continue;
|
||||
+
|
||||
+ if (hash_size == db.signature_size[i] &&
|
||||
+ grub_memcmp (db.signatures[i], hash, hash_size) == 0)
|
||||
+ {
|
||||
+ grub_dprintf ("appendedsig", "verified with a trusted binary hash (%02x%02x%02x%02x)\n",
|
||||
+ hash[0], hash[1], hash[2], hash[3]);
|
||||
+ return GRUB_ERR_NONE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_EOF;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * Verify the kernel's integrity, the trusted key will be used from
|
||||
+ * the trusted key list. If it fails, verify it against the list of binary hashes
|
||||
+ * that are distrusted and trusted.
|
||||
+ */
|
||||
static grub_err_t
|
||||
grub_verify_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize)
|
||||
{
|
||||
@@ -482,12 +559,12 @@ grub_verify_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize)
|
||||
unsigned char *hash;
|
||||
gcry_mpi_t hashmpi;
|
||||
gcry_err_code_t rc;
|
||||
- struct x509_certificate *pk;
|
||||
+ struct x509_certificate *cert;
|
||||
struct grub_appended_signature sig;
|
||||
struct pkcs7_signerInfo *si;
|
||||
int i;
|
||||
|
||||
- if (!db.key_entries)
|
||||
+ if (!db.key_entries && !db.signature_entries)
|
||||
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("No trusted keys to verify against"));
|
||||
|
||||
err = extract_appended_signature (buf, bufsize, &sig);
|
||||
@@ -495,71 +572,73 @@ grub_verify_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize)
|
||||
return err;
|
||||
|
||||
datasize = bufsize - sig.signature_len;
|
||||
-
|
||||
- for (i = 0; i < sig.pkcs7.signerInfo_count; i++)
|
||||
+ err = verify_binary_hash (buf, datasize);
|
||||
+ if (err != GRUB_ERR_EOF && err != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ err = grub_error (err, N_("failed to verify binary-hash/signature with any trusted binary-hash/key\n"));
|
||||
+ return err;
|
||||
+ }
|
||||
+ else if (err == GRUB_ERR_EOF)
|
||||
{
|
||||
- /* This could be optimised in a couple of ways:
|
||||
- - we could only compute hashes once per hash type
|
||||
- - we could track signer information and only verify where IDs match
|
||||
- For now we do the naive O(trusted keys * pkcs7 signers) approach.
|
||||
- */
|
||||
- si = &sig.pkcs7.signerInfos[i];
|
||||
- context = grub_zalloc (si->hash->contextsize);
|
||||
- if (!context)
|
||||
- return grub_errno;
|
||||
-
|
||||
- si->hash->init (context);
|
||||
- si->hash->write (context, buf, datasize);
|
||||
- si->hash->final (context);
|
||||
- hash = si->hash->read (context);
|
||||
-
|
||||
- grub_dprintf ("appendedsig",
|
||||
- "data size %" PRIxGRUB_SIZE ", signer %d hash %02x%02x%02x%02x...\n",
|
||||
- datasize, i, hash[0], hash[1], hash[2], hash[3]);
|
||||
-
|
||||
- err = GRUB_ERR_BAD_SIGNATURE;
|
||||
- for (pk = db.keys; pk; pk = pk->next)
|
||||
+ /* Binary hash was not found in trusted and distrusted list: check signature now */
|
||||
+ for (i = 0; i < sig.pkcs7.signerInfo_count; i++)
|
||||
{
|
||||
- rc = grub_crypto_rsa_pad (&hashmpi, hash, si->hash, pk->mpis[0]);
|
||||
- if (rc)
|
||||
+ /*
|
||||
+ * This could be optimised in a couple of ways:
|
||||
+ * - we could only compute hashes once per hash type
|
||||
+ * - we could track signer information and only verify where IDs match
|
||||
+ * For now we do the naive O(db.keys * pkcs7 signers) approach.
|
||||
+ */
|
||||
+ si = &sig.pkcs7.signerInfos[i];
|
||||
+ context = grub_zalloc (si->hash->contextsize);
|
||||
+ if (context == NULL)
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ si->hash->init (context);
|
||||
+ si->hash->write (context, buf, datasize);
|
||||
+ si->hash->final (context);
|
||||
+ hash = si->hash->read (context);
|
||||
+
|
||||
+ grub_dprintf ("appendedsig",
|
||||
+ "data size %" PRIxGRUB_SIZE ", signer %d hash %02x%02x%02x%02x...\n",
|
||||
+ datasize, i, hash[0], hash[1], hash[2], hash[3]);
|
||||
+
|
||||
+ err = GRUB_ERR_BAD_SIGNATURE;
|
||||
+ for (cert = db.keys; cert; cert = cert->next)
|
||||
{
|
||||
- err = grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
- N_("Error padding hash for RSA verification: %d"), rc);
|
||||
- grub_free (context);
|
||||
- goto cleanup;
|
||||
+ rc = grub_crypto_rsa_pad (&hashmpi, hash, si->hash, cert->mpis[0]);
|
||||
+ if (rc != 0)
|
||||
+ {
|
||||
+ err = grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
+ N_("Error padding hash for RSA verification: %d"), rc);
|
||||
+ grub_free (context);
|
||||
+ pkcs7_signedData_release (&sig.pkcs7);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ rc = _gcry_pubkey_spec_rsa.verify (0, hashmpi, &si->sig_mpi, cert->mpis, NULL, NULL);
|
||||
+ gcry_mpi_release (hashmpi);
|
||||
+ if (rc == 0)
|
||||
+ {
|
||||
+ grub_dprintf ("appendedsig", "verify signer %d with key '%s' succeeded\n",
|
||||
+ i, cert->subject);
|
||||
+ err = GRUB_ERR_NONE;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ grub_dprintf ("appendedsig", "verify signer %d with key '%s' failed with %d\n",
|
||||
+ i, cert->subject, rc);
|
||||
}
|
||||
-
|
||||
- rc = _gcry_pubkey_spec_rsa.verify (0, hashmpi, &si->sig_mpi,
|
||||
- pk->mpis, NULL, NULL);
|
||||
- gcry_mpi_release (hashmpi);
|
||||
-
|
||||
- if (rc == 0)
|
||||
- {
|
||||
- grub_dprintf ("appendedsig",
|
||||
- "verify signer %d with key '%s' succeeded\n", i,
|
||||
- pk->subject);
|
||||
- err = GRUB_ERR_NONE;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- grub_dprintf ("appendedsig",
|
||||
- "verify signer %d with key '%s' failed with %d\n", i,
|
||||
- pk->subject, rc);
|
||||
- }
|
||||
-
|
||||
- grub_free (context);
|
||||
-
|
||||
- if (err == GRUB_ERR_NONE)
|
||||
- break;
|
||||
+ grub_free (context);
|
||||
+ if (err == GRUB_ERR_NONE)
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
- /* If we didn't verify, provide a neat message */
|
||||
if (err != GRUB_ERR_NONE)
|
||||
- err = grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
- N_("Failed to verify signature against a trusted key"));
|
||||
-
|
||||
-cleanup:
|
||||
- pkcs7_signedData_release (&sig.pkcs7);
|
||||
+ err = grub_error (err, N_("failed to verify signature with any trusted key\n"));
|
||||
+ else
|
||||
+ grub_printf ("appendedsig: successfully verified the signature with a trusted key\n");
|
||||
|
||||
return err;
|
||||
}
|
||||
--
|
||||
2.48.1
|
||||
|
||||
121
0005-blscfg-check-for-mounted-boot-in-emu.patch
Normal file
121
0005-blscfg-check-for-mounted-boot-in-emu.patch
Normal file
@@ -0,0 +1,121 @@
|
||||
From 6d33393fd3c538aaead2698777c02d6d6d0221c9 Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Tue, 7 Mar 2023 18:59:40 -0500
|
||||
Subject: [PATCH 5/9] blscfg: check for mounted /boot in emu
|
||||
|
||||
Irritatingly, BLS defines paths relatives to the mountpoint of the
|
||||
filesystem which contains its snippets, not / or any other fixed
|
||||
location. So grub2-emu needs to know whether /boot is a separate
|
||||
filesysem from / and conditionally prepend a path.
|
||||
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
grub-core/commands/blscfg.c | 54 +++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 49 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
|
||||
index 150ca96f4..6495891b9 100644
|
||||
--- a/grub-core/commands/blscfg.c
|
||||
+++ b/grub-core/commands/blscfg.c
|
||||
@@ -40,8 +40,9 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
#include "loadenv.h"
|
||||
|
||||
#define GRUB_BLS_CONFIG_PATH "/loader/entries/"
|
||||
+
|
||||
#ifdef GRUB_MACHINE_EMU
|
||||
-#define GRUB_BOOT_DEVICE ""
|
||||
+#define GRUB_BOOT_DEVICE "/boot"
|
||||
#else
|
||||
#define GRUB_BOOT_DEVICE "($root)"
|
||||
#endif
|
||||
@@ -54,8 +55,50 @@ struct keyval
|
||||
|
||||
static struct bls_entry *entries = NULL;
|
||||
|
||||
+/* Cache probing in frob_boot_device(). Used for linux entry also.
|
||||
+ * Always true in non-emu, meaning to prefix things with GRUB_BOOT_DEVICE. */
|
||||
+static int separate_boot = -1;
|
||||
+
|
||||
#define FOR_BLS_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries)
|
||||
|
||||
+/* BLS appears to make paths relative to the filesystem that snippets are
|
||||
+ * on, not /. Attempt to cope. */
|
||||
+static char *frob_boot_device(char *tmp)
|
||||
+{
|
||||
+#ifdef GRUB_MACHINE_EMU
|
||||
+ grub_file_t f;
|
||||
+ char *line = NULL;
|
||||
+
|
||||
+ if (separate_boot != -1)
|
||||
+ goto probed;
|
||||
+
|
||||
+ separate_boot = 0;
|
||||
+
|
||||
+ f = grub_file_open ("/proc/mounts", GRUB_FILE_TYPE_CONFIG);
|
||||
+ if (f == NULL)
|
||||
+ goto probed;
|
||||
+
|
||||
+ while ((line = grub_file_getline (f)))
|
||||
+ {
|
||||
+ if (grub_strstr (line, " " GRUB_BOOT_DEVICE " "))
|
||||
+ {
|
||||
+ separate_boot = 1;
|
||||
+ grub_free (line);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ grub_free(line);
|
||||
+ }
|
||||
+
|
||||
+ grub_file_close (f);
|
||||
+ probed:
|
||||
+ if (!separate_boot)
|
||||
+ return grub_stpcpy (tmp, " ");
|
||||
+#endif
|
||||
+
|
||||
+ return grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
|
||||
+}
|
||||
+
|
||||
static int bls_add_keyval(struct bls_entry *entry, char *key, char *val)
|
||||
{
|
||||
char *k, *v;
|
||||
@@ -842,7 +885,7 @@ static void create_entry (struct bls_entry *entry)
|
||||
for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++)
|
||||
{
|
||||
grub_dprintf ("blscfg", "adding early initrd %s\n", early_initrds[i]);
|
||||
- tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
|
||||
+ tmp = frob_boot_device (tmp);
|
||||
tmp = grub_stpcpy (tmp, initrd_prefix);
|
||||
tmp = grub_stpcpy (tmp, early_initrds[i]);
|
||||
grub_free(early_initrds[i]);
|
||||
@@ -851,7 +894,7 @@ static void create_entry (struct bls_entry *entry)
|
||||
for (i = 0; initrds != NULL && initrds[i] != NULL; i++)
|
||||
{
|
||||
grub_dprintf ("blscfg", "adding initrd %s\n", initrds[i]);
|
||||
- tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
|
||||
+ tmp = frob_boot_device (tmp);
|
||||
tmp = grub_stpcpy (tmp, initrds[i]);
|
||||
}
|
||||
tmp = grub_stpcpy (tmp, "\n");
|
||||
@@ -888,7 +931,7 @@ static void create_entry (struct bls_entry *entry)
|
||||
}
|
||||
char *tmp = dt;
|
||||
tmp = grub_stpcpy (dt, "devicetree");
|
||||
- tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
|
||||
+ tmp = frob_boot_device (tmp);
|
||||
if (add_dt_prefix)
|
||||
tmp = grub_stpcpy (tmp, prefix);
|
||||
tmp = grub_stpcpy (tmp, devicetree);
|
||||
@@ -907,7 +950,8 @@ static void create_entry (struct bls_entry *entry)
|
||||
"linux %s%s%s%s\n"
|
||||
"%s%s",
|
||||
savedefault ? "savedefault\n" : "",
|
||||
- GRUB_BOOT_DEVICE, clinux, options ? " " : "", options ? options : "",
|
||||
+ separate_boot ? GRUB_BOOT_DEVICE : "",
|
||||
+ clinux, options ? " " : "", options ? options : "",
|
||||
initrd ? initrd : "", dt ? dt : "");
|
||||
|
||||
grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey, NULL, src, 0, 0, &index, entry);
|
||||
--
|
||||
2.44.0
|
||||
|
||||
71
0005-docs-Document-available-crypto-disks-checks.patch
Normal file
71
0005-docs-Document-available-crypto-disks-checks.patch
Normal file
@@ -0,0 +1,71 @@
|
||||
From 45fffe05e9c33582258a88b4a722a5a561dbfa6e Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Thu, 8 May 2025 19:02:11 +0200
|
||||
Subject: [PATCH 5/8] docs: Document available crypto disks checks
|
||||
|
||||
Document the --cryptodisk-only argument. Also, document the
|
||||
"cryptocheck" command invoked when that argument is processed.
|
||||
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
docs/grub.texi | 22 +++++++++++++++++++++-
|
||||
1 file changed, 21 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index 9aaea72826..1c078c5c5b 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -4368,6 +4368,7 @@ you forget a command, you can run the command @command{help}
|
||||
* configfile:: Load a configuration file
|
||||
* cpuid:: Check for CPU features
|
||||
* crc:: Compute or check CRC32 checksums
|
||||
+* cryptocheck:: Check if a device is encrypted
|
||||
* cryptomount:: Mount a crypto device
|
||||
* cutmem:: Remove memory regions
|
||||
* date:: Display or set current date and time
|
||||
@@ -4680,6 +4681,16 @@ Alias for @code{hashsum --hash crc32 arg @dots{}}. See command @command{hashsum}
|
||||
(@pxref{hashsum}) for full description.
|
||||
@end deffn
|
||||
|
||||
+@node cryptocheck
|
||||
+@subsection cryptocheck
|
||||
+
|
||||
+@deffn Command cryptocheck device
|
||||
+Check if a given diskfilter device is backed by encrypted devices
|
||||
+(@pxref{cryptomount} for additional information).
|
||||
+
|
||||
+The command examines all backing devices, physical volumes, of a specified
|
||||
+logical volume, like LVM2, and fails when at least one of them is unencrypted.
|
||||
+@end deffn
|
||||
|
||||
@node cryptomount
|
||||
@subsection cryptomount
|
||||
@@ -5531,7 +5542,8 @@ unbootable. @xref{Using GPG-style digital signatures}, for more information.
|
||||
|
||||
@deffn Command search @
|
||||
[@option{--file}|@option{--label}|@option{--fs-uuid}] @
|
||||
- [@option{--set} [var]] [@option{--no-floppy}|@option{--efidisk-only}] name
|
||||
+ [@option{--set} [var]] [@option{--no-floppy}|@option{--efidisk-only}|@option{--cryptodisk-only}] @
|
||||
+ name
|
||||
Search devices by file (@option{-f}, @option{--file}), filesystem label
|
||||
(@option{-l}, @option{--label}), or filesystem UUID (@option{-u},
|
||||
@option{--fs-uuid}).
|
||||
@@ -5546,6 +5558,14 @@ devices, which can be slow.
|
||||
The (@option{--efidisk-only}) option prevents searching any other devices then
|
||||
EFI disks. This is typically used when chainloading to local EFI partition.
|
||||
|
||||
+The (@option{--cryptodisk-only}) option prevents searching any devices other
|
||||
+than encrypted disks. This is typically used when booting from an encrypted
|
||||
+file system to ensure that no code gets executed from an unencrypted device
|
||||
+having the same filesystem UUID or label.
|
||||
+
|
||||
+This option implicitly invokes the command @command{cryptocheck}, if it is
|
||||
+available (@pxref{cryptocheck} for additional information).
|
||||
+
|
||||
The @samp{search.file}, @samp{search.fs_label}, and @samp{search.fs_uuid}
|
||||
commands are aliases for @samp{search --file}, @samp{search --label}, and
|
||||
@samp{search --fs-uuid} respectively.
|
||||
--
|
||||
2.49.0
|
||||
|
||||
59
0005-docs-grub-Document-signing-grub-under-UEFI.patch
Normal file
59
0005-docs-grub-Document-signing-grub-under-UEFI.patch
Normal file
@@ -0,0 +1,59 @@
|
||||
From f7b9580133cf346d77f345d175fa5cb8a591be16 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
Date: Sat, 15 Aug 2020 02:00:57 +1000
|
||||
Subject: [PATCH 05/23] docs/grub: Document signing grub under UEFI
|
||||
|
||||
Before adding information about how grub is signed with an appended
|
||||
signature scheme, it's worth adding some information about how it
|
||||
can currently be signed for UEFI.
|
||||
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
---
|
||||
docs/grub.texi | 22 +++++++++++++++++++++-
|
||||
1 file changed, 21 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -6345,6 +6345,7 @@
|
||||
* Secure Boot Advanced Targeting:: Embedded information for generation number based revocation
|
||||
* Measured Boot:: Measuring boot components
|
||||
* Lockdown:: Lockdown when booting on a secure setup
|
||||
+* Signing GRUB itself:: Ensuring the integrity of the GRUB core image
|
||||
@end menu
|
||||
|
||||
@node Authentication and authorisation
|
||||
@@ -6423,7 +6424,7 @@
|
||||
|
||||
GRUB's @file{core.img} can optionally provide enforcement that all files
|
||||
subsequently read from disk are covered by a valid digital signature.
|
||||
-This document does @strong{not} cover how to ensure that your
|
||||
+This section does @strong{not} cover how to ensure that your
|
||||
platform's firmware (e.g., Coreboot) validates @file{core.img}.
|
||||
|
||||
If environment variable @code{check_signatures}
|
||||
@@ -6586,6 +6587,25 @@
|
||||
The @samp{lockdown} variable is set to @samp{y} when the GRUB is locked down.
|
||||
Otherwise it does not exit.
|
||||
|
||||
+@node Signing GRUB itself
|
||||
+@section Signing GRUB itself
|
||||
+
|
||||
+To ensure a complete secure-boot chain, there must be a way for the code that
|
||||
+loads GRUB to verify the integrity of the core image.
|
||||
+
|
||||
+This is ultimately platform-specific and individual platforms can define their
|
||||
+own mechanisms. However, there are general-purpose mechanisms that can be used
|
||||
+with GRUB.
|
||||
+
|
||||
+@section Signing GRUB for UEFI secure boot
|
||||
+
|
||||
+On UEFI platforms, @file{core.img} is a PE binary. Therefore, it can be signed
|
||||
+with a tool such as @command{pesign} or @command{sbsign}. Refer to the
|
||||
+suggestions in @pxref{UEFI secure boot and shim} to ensure that the final
|
||||
+image works under UEFI secure boot and can maintain the secure-boot chain. It
|
||||
+will also be necessary to enrol the public key used into a relevant firmware
|
||||
+key database.
|
||||
+
|
||||
@node Platform limitations
|
||||
@chapter Platform limitations
|
||||
|
||||
38
0005-fs-hfsplus-Set-a-grub_errno-if-mount-fails.patch
Normal file
38
0005-fs-hfsplus-Set-a-grub_errno-if-mount-fails.patch
Normal file
@@ -0,0 +1,38 @@
|
||||
From 3f1980191c693670380aa9aa5a949c5574a3bd04 Mon Sep 17 00:00:00 2001
|
||||
From: B Horn <b@horn.uk>
|
||||
Date: Sun, 12 May 2024 06:22:51 +0100
|
||||
Subject: [PATCH 05/20] fs/hfsplus: Set a grub_errno if mount fails
|
||||
|
||||
It was possible for mount to fail but not set grub_errno. This led to
|
||||
a possible double decrement of the module reference count if the NULL
|
||||
page was mapped.
|
||||
|
||||
Fixing in general as a similar bug was fixed in commit 61b13c187
|
||||
(fs/hfsplus: Set grub_errno to prevent NULL pointer access) and there
|
||||
are likely more variants around.
|
||||
|
||||
Fixes: CVE-2024-45783
|
||||
|
||||
Reported-by: B Horn <b@horn.uk>
|
||||
Signed-off-by: B Horn <b@horn.uk>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/fs/hfsplus.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c
|
||||
index 295822f694..de71fd486b 100644
|
||||
--- a/grub-core/fs/hfsplus.c
|
||||
+++ b/grub-core/fs/hfsplus.c
|
||||
@@ -405,7 +405,7 @@ grub_hfsplus_mount (grub_disk_t disk)
|
||||
|
||||
fail:
|
||||
|
||||
- if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
|
||||
+ if (grub_errno == GRUB_ERR_OUT_OF_RANGE || grub_errno == GRUB_ERR_NONE)
|
||||
grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem");
|
||||
|
||||
grub_free (data);
|
||||
--
|
||||
2.48.1
|
||||
|
||||
109
0005-ieee1275-tcg2-Refactor-grub_ieee1275_tpm_init.patch
Normal file
109
0005-ieee1275-tcg2-Refactor-grub_ieee1275_tpm_init.patch
Normal file
@@ -0,0 +1,109 @@
|
||||
From 72092a8641958af95402fa0e3e74cc57c36feefa Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Date: Tue, 26 Nov 2024 15:39:44 -0500
|
||||
Subject: [PATCH 5/7] ieee1275/tcg2: Refactor grub_ieee1275_tpm_init()
|
||||
|
||||
Move tpm_get_tpm_version() into grub_ieee1275_tpm_init() and invalidate
|
||||
grub_ieee1275_tpm_ihandle in case no TPM 2 could be detected. Try the
|
||||
initialization only once so that grub_tpm_present() will always return
|
||||
the same result. Use the grub_ieee1275_tpm_ihandle as indicator for an
|
||||
available TPM instead of grub_ieee1275_tpm_version, which can now be
|
||||
removed.
|
||||
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/commands/ieee1275/ibmvtpm.c | 2 +-
|
||||
grub-core/lib/ieee1275/tcg2.c | 40 ++++++++++++---------------
|
||||
include/grub/ieee1275/tpm.h | 1 -
|
||||
3 files changed, 18 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/ieee1275/ibmvtpm.c b/grub-core/commands/ieee1275/ibmvtpm.c
|
||||
index 284673217..4958b04a9 100644
|
||||
--- a/grub-core/commands/ieee1275/ibmvtpm.c
|
||||
+++ b/grub-core/commands/ieee1275/ibmvtpm.c
|
||||
@@ -100,7 +100,7 @@ grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||||
grub_dprintf ("tpm", "log_event, pcr = %d, size = 0x%" PRIxGRUB_SIZE ", %s\n",
|
||||
pcr, size, description);
|
||||
|
||||
- if (grub_ieee1275_tpm_version == 2)
|
||||
+ if (grub_ieee1275_tpm_ihandle != GRUB_IEEE1275_IHANDLE_INVALID)
|
||||
return tpm2_log_event (buf, size, pcr, description);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
diff --git a/grub-core/lib/ieee1275/tcg2.c b/grub-core/lib/ieee1275/tcg2.c
|
||||
index 1819d1447..ea01a30eb 100644
|
||||
--- a/grub-core/lib/ieee1275/tcg2.c
|
||||
+++ b/grub-core/lib/ieee1275/tcg2.c
|
||||
@@ -23,39 +23,33 @@
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
|
||||
-grub_ieee1275_ihandle_t grub_ieee1275_tpm_ihandle;
|
||||
-grub_uint8_t grub_ieee1275_tpm_version;
|
||||
-
|
||||
-static void
|
||||
-tpm_get_tpm_version (void)
|
||||
-{
|
||||
- grub_ieee1275_phandle_t vtpm;
|
||||
- char buffer[20];
|
||||
-
|
||||
- if (!grub_ieee1275_finddevice ("/vdevice/vtpm", &vtpm) &&
|
||||
- !grub_ieee1275_get_property (vtpm, "compatible", buffer,
|
||||
- sizeof (buffer), NULL) &&
|
||||
- !grub_strcmp (buffer, "IBM,vtpm20"))
|
||||
- grub_ieee1275_tpm_version = 2;
|
||||
-}
|
||||
+grub_ieee1275_ihandle_t grub_ieee1275_tpm_ihandle = GRUB_IEEE1275_IHANDLE_INVALID;
|
||||
|
||||
grub_err_t
|
||||
grub_ieee1275_tpm_init (void)
|
||||
{
|
||||
- static int init_success = 0;
|
||||
+ static bool init_tried = false;
|
||||
+ grub_ieee1275_phandle_t vtpm;
|
||||
+ char buffer[20];
|
||||
|
||||
- if (!init_success)
|
||||
+ if (init_tried == false)
|
||||
{
|
||||
- if (grub_ieee1275_open ("/vdevice/vtpm", &grub_ieee1275_tpm_ihandle) < 0)
|
||||
+ init_tried = true;
|
||||
+
|
||||
+ if (grub_ieee1275_open ("/vdevice/vtpm", &grub_ieee1275_tpm_ihandle) < 0 ||
|
||||
+ grub_ieee1275_finddevice ("/vdevice/vtpm", &vtpm) ||
|
||||
+ grub_ieee1275_get_property (vtpm, "compatible", buffer, sizeof (buffer), NULL) ||
|
||||
+ grub_strcmp (buffer, "IBM,vtpm20"))
|
||||
{
|
||||
+ if (grub_ieee1275_tpm_ihandle != GRUB_IEEE1275_IHANDLE_INVALID)
|
||||
+ grub_ieee1275_close (grub_ieee1275_tpm_ihandle);
|
||||
+
|
||||
grub_ieee1275_tpm_ihandle = GRUB_IEEE1275_IHANDLE_INVALID;
|
||||
- return GRUB_ERR_UNKNOWN_DEVICE;
|
||||
}
|
||||
-
|
||||
- init_success = 1;
|
||||
-
|
||||
- tpm_get_tpm_version ();
|
||||
}
|
||||
|
||||
+ if (grub_ieee1275_tpm_ihandle == GRUB_IEEE1275_IHANDLE_INVALID)
|
||||
+ return GRUB_ERR_UNKNOWN_DEVICE;
|
||||
+
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
diff --git a/include/grub/ieee1275/tpm.h b/include/grub/ieee1275/tpm.h
|
||||
index 9575c1c68..fe5cb4713 100644
|
||||
--- a/include/grub/ieee1275/tpm.h
|
||||
+++ b/include/grub/ieee1275/tpm.h
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <grub/ieee1275/ieee1275.h>
|
||||
|
||||
extern grub_ieee1275_ihandle_t grub_ieee1275_tpm_ihandle;
|
||||
-extern grub_uint8_t grub_ieee1275_tpm_version;
|
||||
|
||||
extern grub_err_t grub_ieee1275_tpm_init (void);
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
From 0289adccc2127a1179fea9da0c787fab04a831f7 Mon Sep 17 00:00:00 2001
|
||||
From: Alec Brown <alec.r.brown@oracle.com>
|
||||
Date: Thu, 21 Aug 2025 21:14:08 +0000
|
||||
Subject: [PATCH 5/7] tests/lib/functional_test: Unregister commands on module
|
||||
unload
|
||||
|
||||
When the functional_test module is loaded, both the functional_test and
|
||||
all_functional_test commands are registered but only the all_functional_test
|
||||
command is being unregistered since it was the last to set the cmd variable
|
||||
that gets unregistered when the module is unloaded. To unregister both
|
||||
commands, we need to create an additional grub_extcmd_t variable.
|
||||
|
||||
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/tests/lib/functional_test.c | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/tests/lib/functional_test.c b/grub-core/tests/lib/functional_test.c
|
||||
index 403fa5c78..31b6b5dab 100644
|
||||
--- a/grub-core/tests/lib/functional_test.c
|
||||
+++ b/grub-core/tests/lib/functional_test.c
|
||||
@@ -90,17 +90,18 @@ grub_functional_all_tests (grub_extcmd_context_t ctxt __attribute__ ((unused)),
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
-static grub_extcmd_t cmd;
|
||||
+static grub_extcmd_t cmd, cmd_all;
|
||||
|
||||
GRUB_MOD_INIT (functional_test)
|
||||
{
|
||||
cmd = grub_register_extcmd ("functional_test", grub_functional_test, 0, 0,
|
||||
"Run all loaded functional tests.", 0);
|
||||
- cmd = grub_register_extcmd ("all_functional_test", grub_functional_all_tests, 0, 0,
|
||||
- "Run all functional tests.", 0);
|
||||
+ cmd_all = grub_register_extcmd ("all_functional_test", grub_functional_all_tests, 0, 0,
|
||||
+ "Run all functional tests.", 0);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI (functional_test)
|
||||
{
|
||||
grub_unregister_extcmd (cmd);
|
||||
+ grub_unregister_extcmd (cmd_all);
|
||||
}
|
||||
--
|
||||
2.51.1
|
||||
|
||||
200
0005-tpm2_key_protector-Unseal-key-from-a-buffer.patch
Normal file
200
0005-tpm2_key_protector-Unseal-key-from-a-buffer.patch
Normal file
@@ -0,0 +1,200 @@
|
||||
From fa69deac565e5d5015ca396b017239cd96900673 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Mon, 7 Apr 2025 16:29:19 +0800
|
||||
Subject: [PATCH 5/7] tpm2_key_protector: Unseal key from a buffer
|
||||
|
||||
Extract the logic to handle the file buffer from the SRK recover
|
||||
function to prepare to load the sealed key from the NV index handle,
|
||||
so the NV index mode can share the same code path in the later patch.
|
||||
The SRK recover function now only reads the file and sends the file
|
||||
buffer to the new function.
|
||||
|
||||
Besides this, to avoid introducing more options for the NV index mode,
|
||||
the file format is detected automatically before unmarshaling the data,
|
||||
so there is no need to use the command option to specify the file format
|
||||
anymore. In other words, "-T" and "-k" are the same now.
|
||||
|
||||
Also update grub.text to address the change.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
docs/grub.texi | 13 +-
|
||||
.../commands/tpm2_key_protector/module.c | 122 +++++++++++++-----
|
||||
2 files changed, 96 insertions(+), 39 deletions(-)
|
||||
|
||||
Index: grub-2.12/grub-core/commands/tpm2_key_protector/module.c
|
||||
===================================================================
|
||||
--- grub-2.12.orig/grub-core/commands/tpm2_key_protector/module.c
|
||||
+++ grub-2.12/grub-core/commands/tpm2_key_protector/module.c
|
||||
@@ -218,10 +218,51 @@ tpm2_protector_srk_read_file (const char
|
||||
return err;
|
||||
}
|
||||
|
||||
+/* Check if the data is in TPM 2.0 Key File format */
|
||||
+static bool
|
||||
+tpm2_protector_is_tpm2key (grub_uint8_t *buffer, grub_size_t buffer_size)
|
||||
+{
|
||||
+ /* id-sealedkey OID (2.23.133.10.1.5) in DER */
|
||||
+ const grub_uint8_t sealed_key_oid[] = {0x06, 0x06, 0x67, 0x81, 0x05, 0x0a};
|
||||
+ grub_size_t skip = 0;
|
||||
+
|
||||
+ /* Need at least the first two bytes to check the tag and the length */
|
||||
+ if (buffer_size < 2)
|
||||
+ return false;
|
||||
+
|
||||
+ /* The first byte is always 0x30 (SEQUENCE). */
|
||||
+ if (buffer[0] != 0x30)
|
||||
+ return false;
|
||||
+
|
||||
+ /*
|
||||
+ * Get the bytes of the length
|
||||
+ *
|
||||
+ * If the bit 8 of the second byte is 0, it is in the short form, so the second byte
|
||||
+ * alone represents the length. Thus, the first two bytes are skipped.
|
||||
+ *
|
||||
+ * Otherwise, it is in the long form, and bits 1~7 indicate how many more bytes are in
|
||||
+ * the length field, so we skip the first two bytes plus the bytes for the length.
|
||||
+ */
|
||||
+ if ((buffer[1] & 0x80) == 0)
|
||||
+ skip = 2;
|
||||
+ else
|
||||
+ skip = (buffer[1] & 0x7F) + 2;
|
||||
+
|
||||
+ /* Make sure the buffer is large enough to contain id-sealedkey OID */
|
||||
+ if (buffer_size < skip + sizeof (sealed_key_oid))
|
||||
+ return false;
|
||||
+
|
||||
+ /* Check id-sealedkey OID */
|
||||
+ if (grub_memcmp (buffer + skip, sealed_key_oid, sizeof (sealed_key_oid)) != 0)
|
||||
+ return false;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
-tpm2_protector_srk_unmarshal_keyfile (void *sealed_key,
|
||||
- grub_size_t sealed_key_size,
|
||||
- tpm2_sealed_key_t *sk)
|
||||
+tpm2_protector_unmarshal_raw (void *sealed_key,
|
||||
+ grub_size_t sealed_key_size,
|
||||
+ tpm2_sealed_key_t *sk)
|
||||
{
|
||||
struct grub_tpm2_buffer buf;
|
||||
|
||||
@@ -242,13 +283,13 @@ tpm2_protector_srk_unmarshal_keyfile (vo
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-tpm2_protector_srk_unmarshal_tpm2key (void *sealed_key,
|
||||
- grub_size_t sealed_key_size,
|
||||
- tpm2key_policy_t *policy_seq,
|
||||
- tpm2key_authpolicy_t *authpol_seq,
|
||||
- grub_uint8_t *rsaparent,
|
||||
- grub_uint32_t *parent,
|
||||
- tpm2_sealed_key_t *sk)
|
||||
+tpm2_protector_unmarshal_tpm2key (void *sealed_key,
|
||||
+ grub_size_t sealed_key_size,
|
||||
+ tpm2key_policy_t *policy_seq,
|
||||
+ tpm2key_authpolicy_t *authpol_seq,
|
||||
+ grub_uint8_t *rsaparent,
|
||||
+ grub_uint32_t *parent,
|
||||
+ tpm2_sealed_key_t *sk)
|
||||
{
|
||||
asn1_node tpm2key = NULL;
|
||||
grub_uint8_t rsaparent_tmp;
|
||||
@@ -954,12 +995,11 @@ tpm2_protector_dump_pcr (const TPM_ALG_I
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-tpm2_protector_srk_recover (const tpm2_protector_context_t *ctx,
|
||||
- grub_uint8_t **key, grub_size_t *key_size)
|
||||
+tpm2_protector_key_from_buffer (const tpm2_protector_context_t *ctx,
|
||||
+ void *buffer, grub_size_t buf_size,
|
||||
+ grub_uint8_t **key, grub_size_t *key_size)
|
||||
{
|
||||
tpm2_sealed_key_t sealed_key = {0};
|
||||
- void *file_bytes = NULL;
|
||||
- grub_size_t file_size = 0;
|
||||
grub_uint8_t rsaparent = 0;
|
||||
TPM_HANDLE_t parent_handle = 0;
|
||||
TPM_HANDLE_t srk_handle = 0;
|
||||
@@ -972,22 +1012,17 @@ tpm2_protector_srk_recover (const tpm2_p
|
||||
|
||||
/*
|
||||
* Retrieve sealed key, parent handle, policy sequence, and authpolicy
|
||||
- * sequence from the key file
|
||||
+ * sequence from the buffer
|
||||
*/
|
||||
- if (ctx->tpm2key != NULL)
|
||||
+ if (tpm2_protector_is_tpm2key (buffer, buf_size) == true)
|
||||
{
|
||||
- err = tpm2_protector_srk_read_file (ctx->tpm2key, &file_bytes,
|
||||
- &file_size);
|
||||
- if (err != GRUB_ERR_NONE)
|
||||
- return err;
|
||||
-
|
||||
- err = tpm2_protector_srk_unmarshal_tpm2key (file_bytes,
|
||||
- file_size,
|
||||
- &policy_seq,
|
||||
- &authpol_seq,
|
||||
- &rsaparent,
|
||||
- &parent_handle,
|
||||
- &sealed_key);
|
||||
+ err = tpm2_protector_unmarshal_tpm2key (buffer,
|
||||
+ buf_size,
|
||||
+ &policy_seq,
|
||||
+ &authpol_seq,
|
||||
+ &rsaparent,
|
||||
+ &parent_handle,
|
||||
+ &sealed_key);
|
||||
if (err != GRUB_ERR_NONE)
|
||||
goto exit1;
|
||||
|
||||
@@ -1003,12 +1038,8 @@ tpm2_protector_srk_recover (const tpm2_p
|
||||
}
|
||||
else
|
||||
{
|
||||
- err = tpm2_protector_srk_read_file (ctx->keyfile, &file_bytes, &file_size);
|
||||
- if (err != GRUB_ERR_NONE)
|
||||
- return err;
|
||||
-
|
||||
parent_handle = TPM_RH_OWNER;
|
||||
- err = tpm2_protector_srk_unmarshal_keyfile (file_bytes, file_size, &sealed_key);
|
||||
+ err = tpm2_protector_unmarshal_raw (buffer, buf_size, &sealed_key);
|
||||
if (err != GRUB_ERR_NONE)
|
||||
goto exit1;
|
||||
}
|
||||
@@ -1084,6 +1115,31 @@ tpm2_protector_srk_recover (const tpm2_p
|
||||
exit1:
|
||||
grub_tpm2key_free_policy_seq (policy_seq);
|
||||
grub_tpm2key_free_authpolicy_seq (authpol_seq);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+tpm2_protector_srk_recover (const tpm2_protector_context_t *ctx,
|
||||
+ grub_uint8_t **key, grub_size_t *key_size)
|
||||
+{
|
||||
+ const char *filepath;
|
||||
+ void *file_bytes = NULL;
|
||||
+ grub_size_t file_size = 0;
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ if (ctx->tpm2key != NULL)
|
||||
+ filepath = ctx->tpm2key;
|
||||
+ else if (ctx->keyfile != NULL)
|
||||
+ filepath = ctx->keyfile;
|
||||
+ else
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("key file not specified"));
|
||||
+
|
||||
+ err = tpm2_protector_srk_read_file (filepath, &file_bytes, &file_size);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ return err;
|
||||
+
|
||||
+ err = tpm2_protector_key_from_buffer (ctx, file_bytes, file_size, key, key_size);
|
||||
+
|
||||
grub_free (file_bytes);
|
||||
return err;
|
||||
}
|
||||
168
0006-Follow-the-device-where-blscfg-is-discovered.patch
Normal file
168
0006-Follow-the-device-where-blscfg-is-discovered.patch
Normal file
@@ -0,0 +1,168 @@
|
||||
From 6523d493b0772316a3fbb249eb070ada5d266a98 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Wed, 28 Jun 2023 14:32:40 +0800
|
||||
Subject: [PATCH 6/9] Follow the device where blscfg is discovered
|
||||
|
||||
Previously, the code assumed that GRUB_BOOT_DEVICE "($root)" was always
|
||||
the correct device for the discovered bls menu. However, this assumption
|
||||
could lead to inaccuracies when attempting to load bls for devices other
|
||||
than $root.
|
||||
|
||||
This patch introduces a more robust approach by utilizing the `struct
|
||||
find_entry_info *info->devid` parameter, representing the device used to
|
||||
discover the bls directory. This change ensures consistency in
|
||||
subsequent translations to native GRUB commands, eliminating potential
|
||||
discrepancies in device identification during the blscfg process.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/blscfg.c | 40 +++++++++++++++++++++++++------------
|
||||
include/grub/menu.h | 1 +
|
||||
2 files changed, 28 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
|
||||
index 6495891b9..c872bcef0 100644
|
||||
--- a/grub-core/commands/blscfg.c
|
||||
+++ b/grub-core/commands/blscfg.c
|
||||
@@ -55,15 +55,18 @@ struct keyval
|
||||
|
||||
static struct bls_entry *entries = NULL;
|
||||
|
||||
-/* Cache probing in frob_boot_device(). Used for linux entry also.
|
||||
- * Always true in non-emu, meaning to prefix things with GRUB_BOOT_DEVICE. */
|
||||
-static int separate_boot = -1;
|
||||
-
|
||||
#define FOR_BLS_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries)
|
||||
|
||||
/* BLS appears to make paths relative to the filesystem that snippets are
|
||||
* on, not /. Attempt to cope. */
|
||||
-static char *frob_boot_device(char *tmp)
|
||||
+#ifdef GRUB_MACHINE_EMU
|
||||
+/* Cache probing in frob_boot_device(). Used for linux entry also.
|
||||
+ * Unused in non-emu, meaning to prefix things with device of parent blsdir. */
|
||||
+static int separate_boot = -1;
|
||||
+static char *frob_boot_device(char *tmp, const char *bootdev UNUSED)
|
||||
+#else
|
||||
+static char *frob_boot_device(char *tmp, const char *bootdev)
|
||||
+#endif
|
||||
{
|
||||
#ifdef GRUB_MACHINE_EMU
|
||||
grub_file_t f;
|
||||
@@ -94,9 +97,11 @@ static char *frob_boot_device(char *tmp)
|
||||
probed:
|
||||
if (!separate_boot)
|
||||
return grub_stpcpy (tmp, " ");
|
||||
-#endif
|
||||
-
|
||||
return grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
|
||||
+#else
|
||||
+ tmp = grub_stpcpy (tmp, " ");
|
||||
+ return grub_stpcpy (tmp, bootdev);
|
||||
+#endif
|
||||
}
|
||||
|
||||
static int bls_add_keyval(struct bls_entry *entry, char *key, char *val)
|
||||
@@ -568,6 +573,9 @@ static int read_entry (
|
||||
if (rc < 0)
|
||||
break;
|
||||
}
|
||||
+
|
||||
+ if (info->devid)
|
||||
+ entry->devid = grub_strdup(info->devid);
|
||||
|
||||
if (!rc)
|
||||
bls_add_entry(entry);
|
||||
@@ -772,6 +780,7 @@ static void create_entry (struct bls_entry *entry)
|
||||
char *id = entry->filename;
|
||||
char *dotconf = id;
|
||||
char *hotkey = NULL;
|
||||
+ char *bootdev = entry->devid ? grub_xasprintf("(%s)", entry->devid) : grub_strdup (GRUB_BOOT_DEVICE);
|
||||
|
||||
char *users = NULL;
|
||||
char **classes = NULL;
|
||||
@@ -865,12 +874,12 @@ static void create_entry (struct bls_entry *entry)
|
||||
char *tmp;
|
||||
|
||||
for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++)
|
||||
- initrd_size += sizeof (" " GRUB_BOOT_DEVICE) \
|
||||
+ initrd_size += sizeof (" ") + grub_strlen (bootdev) \
|
||||
+ grub_strlen(initrd_prefix) \
|
||||
+ grub_strlen (early_initrds[i]) + 1;
|
||||
|
||||
for (i = 0; initrds != NULL && initrds[i] != NULL; i++)
|
||||
- initrd_size += sizeof (" " GRUB_BOOT_DEVICE) \
|
||||
+ initrd_size += sizeof (" ") + grub_strlen (bootdev) \
|
||||
+ grub_strlen (initrds[i]) + 1;
|
||||
initrd_size += 1;
|
||||
|
||||
@@ -885,7 +894,7 @@ static void create_entry (struct bls_entry *entry)
|
||||
for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++)
|
||||
{
|
||||
grub_dprintf ("blscfg", "adding early initrd %s\n", early_initrds[i]);
|
||||
- tmp = frob_boot_device (tmp);
|
||||
+ tmp = frob_boot_device (tmp, bootdev);
|
||||
tmp = grub_stpcpy (tmp, initrd_prefix);
|
||||
tmp = grub_stpcpy (tmp, early_initrds[i]);
|
||||
grub_free(early_initrds[i]);
|
||||
@@ -894,7 +903,7 @@ static void create_entry (struct bls_entry *entry)
|
||||
for (i = 0; initrds != NULL && initrds[i] != NULL; i++)
|
||||
{
|
||||
grub_dprintf ("blscfg", "adding initrd %s\n", initrds[i]);
|
||||
- tmp = frob_boot_device (tmp);
|
||||
+ tmp = frob_boot_device (tmp, bootdev);
|
||||
tmp = grub_stpcpy (tmp, initrds[i]);
|
||||
}
|
||||
tmp = grub_stpcpy (tmp, "\n");
|
||||
@@ -916,7 +925,7 @@ static void create_entry (struct bls_entry *entry)
|
||||
}
|
||||
}
|
||||
|
||||
- dt_size = sizeof("devicetree " GRUB_BOOT_DEVICE) + grub_strlen(devicetree) + 1;
|
||||
+ dt_size = sizeof("devicetree ") + grub_strlen(bootdev) + grub_strlen(devicetree) + 1;
|
||||
|
||||
if (add_dt_prefix)
|
||||
{
|
||||
@@ -931,7 +940,7 @@ static void create_entry (struct bls_entry *entry)
|
||||
}
|
||||
char *tmp = dt;
|
||||
tmp = grub_stpcpy (dt, "devicetree");
|
||||
- tmp = frob_boot_device (tmp);
|
||||
+ tmp = frob_boot_device (tmp, bootdev);
|
||||
if (add_dt_prefix)
|
||||
tmp = grub_stpcpy (tmp, prefix);
|
||||
tmp = grub_stpcpy (tmp, devicetree);
|
||||
@@ -950,7 +959,11 @@ static void create_entry (struct bls_entry *entry)
|
||||
"linux %s%s%s%s\n"
|
||||
"%s%s",
|
||||
savedefault ? "savedefault\n" : "",
|
||||
+#ifdef GRUB_MACHINE_EMU
|
||||
separate_boot ? GRUB_BOOT_DEVICE : "",
|
||||
+#else
|
||||
+ bootdev,
|
||||
+#endif
|
||||
clinux, options ? " " : "", options ? options : "",
|
||||
initrd ? initrd : "", dt ? dt : "");
|
||||
|
||||
@@ -969,6 +982,7 @@ finish:
|
||||
grub_free (args);
|
||||
grub_free (argv);
|
||||
grub_free (src);
|
||||
+ grub_free (bootdev);
|
||||
}
|
||||
|
||||
struct find_entry_info {
|
||||
diff --git a/include/grub/menu.h b/include/grub/menu.h
|
||||
index 43080828c..76b191c33 100644
|
||||
--- a/include/grub/menu.h
|
||||
+++ b/include/grub/menu.h
|
||||
@@ -28,6 +28,7 @@ struct bls_entry
|
||||
int nkeyvals;
|
||||
char *filename;
|
||||
int visible;
|
||||
+ const char *devid;
|
||||
};
|
||||
|
||||
struct grub_menu_entry_class
|
||||
--
|
||||
2.44.0
|
||||
|
||||
34
0006-commands-usbtest-Use-correct-string-length-field.patch
Normal file
34
0006-commands-usbtest-Use-correct-string-length-field.patch
Normal file
@@ -0,0 +1,34 @@
|
||||
From 8dd7026738fb445abd811bb6bd98ff297676329e Mon Sep 17 00:00:00 2001
|
||||
From: Jamie <volticks@gmail.com>
|
||||
Date: Mon, 14 Jul 2025 09:52:59 +0100
|
||||
Subject: [PATCH 6/7] commands/usbtest: Use correct string length field
|
||||
|
||||
An incorrect length field is used for buffer allocation. This leads to
|
||||
grub_utf16_to_utf8() receiving an incorrect/different length and possibly
|
||||
causing OOB write. This makes sure to use the correct length.
|
||||
|
||||
Fixes: CVE-2025-61661
|
||||
|
||||
Reported-by: Jamie <volticks@gmail.com>
|
||||
Signed-off-by: Jamie <volticks@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/commands/usbtest.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/commands/usbtest.c b/grub-core/commands/usbtest.c
|
||||
index 2c6d93fe6..8ef187a9a 100644
|
||||
--- a/grub-core/commands/usbtest.c
|
||||
+++ b/grub-core/commands/usbtest.c
|
||||
@@ -99,7 +99,7 @@ grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid,
|
||||
return GRUB_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
- *string = grub_malloc (descstr.length * 2 + 1);
|
||||
+ *string = grub_malloc (descstrp->length * 2 + 1);
|
||||
if (! *string)
|
||||
{
|
||||
grub_free (descstrp);
|
||||
--
|
||||
2.51.1
|
||||
|
||||
150
0006-disk-cryptodisk-Add-the-erase-secrets-function.patch
Normal file
150
0006-disk-cryptodisk-Add-the-erase-secrets-function.patch
Normal file
@@ -0,0 +1,150 @@
|
||||
From 0a11bc48ea60f7611df2c5b640cecc325c7c4fd9 Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Thu, 8 May 2025 19:02:12 +0200
|
||||
Subject: [PATCH 6/8] disk/cryptodisk: Add the "erase secrets" function
|
||||
|
||||
This commit adds the grub_cryptodisk_erasesecrets() function to wipe
|
||||
master keys from all cryptodisks. This function is EFI-only.
|
||||
|
||||
Since there is no easy way to "force unmount" a given encrypted disk,
|
||||
this function renders all mounted cryptodisks unusable. An attempt to
|
||||
read them will return garbage.
|
||||
|
||||
This is why this function must be used in "no way back" conditions.
|
||||
|
||||
Currently, it is used when unloading the cryptodisk module and when
|
||||
performing the "exit" command (it is often used to switch to the next
|
||||
EFI application). This function is not called when performing the
|
||||
"chainloader" command, because the callee may return to GRUB. For this
|
||||
reason, users are encouraged to use "exit" instead of "chainloader" to
|
||||
execute third-party boot applications.
|
||||
|
||||
This function does not guarantee that all secrets are wiped from RAM.
|
||||
Console output, chunks from disk read requests and other may remain.
|
||||
|
||||
This function does not clear the IV prefix and rekey key for geli disks.
|
||||
|
||||
Also, this commit adds the relevant documentation improvements.
|
||||
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
docs/grub.texi | 6 ++++++
|
||||
grub-core/commands/minicmd.c | 11 +++++++++++
|
||||
grub-core/disk/cryptodisk.c | 28 ++++++++++++++++++++++++++++
|
||||
include/grub/cryptodisk.h | 1 +
|
||||
4 files changed, 46 insertions(+)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index 1c078c5c5b..c4936db8c1 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -4727,6 +4727,11 @@ namespace in addition to the cryptodisk namespace.
|
||||
|
||||
Support for plain encryption mode (plain dm-crypt) is provided via separate
|
||||
@command{@pxref{plainmount}} command.
|
||||
+
|
||||
+On the EFI platform, GRUB tries to erase master keys from memory when the cryptodisk
|
||||
+module is unloaded or the command @command{exit} is executed. All secrets remain in
|
||||
+memory when the command @command{chainloader} is issued, because execution can
|
||||
+return to GRUB on the EFI platform.
|
||||
@end deffn
|
||||
|
||||
@node cutmem
|
||||
@@ -6981,6 +6986,7 @@ USB support provides benefits similar to ATA (for USB disks) or AT (for USB
|
||||
keyboards). In addition it allows USBserial.
|
||||
|
||||
Chainloading refers to the ability to load another bootloader through the same protocol
|
||||
+and on some platforms, like EFI, allow that bootloader to return to the GRUB.
|
||||
|
||||
Hints allow faster disk discovery by already knowing in advance which is the disk in
|
||||
question. On some platforms hints are correct unless you move the disk between boots.
|
||||
diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c
|
||||
index 903af33131..bd9cb681ec 100644
|
||||
--- a/grub-core/commands/minicmd.c
|
||||
+++ b/grub-core/commands/minicmd.c
|
||||
@@ -29,6 +29,10 @@
|
||||
#include <grub/command.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+#include <grub/cryptodisk.h>
|
||||
+#endif
|
||||
+
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
/* cat FILE */
|
||||
@@ -187,6 +191,13 @@ grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char *argv[] __attribute__ ((unused)))
|
||||
{
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+ /*
|
||||
+ * The "exit" command is often used to launch the next boot application.
|
||||
+ * So, erase the secrets.
|
||||
+ */
|
||||
+ grub_cryptodisk_erasesecrets ();
|
||||
+#endif
|
||||
grub_exit ();
|
||||
/* Not reached. */
|
||||
}
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index 33eb6568ca..f9ae750f85 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1784,6 +1784,31 @@ grub_cryptodisk_challenge_password (void)
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
+
|
||||
+void
|
||||
+grub_cryptodisk_erasesecrets (void)
|
||||
+{
|
||||
+ grub_cryptodisk_t i;
|
||||
+ grub_uint8_t *buf;
|
||||
+
|
||||
+ buf = grub_zalloc (GRUB_CRYPTODISK_MAX_KEYLEN);
|
||||
+ if (buf == NULL)
|
||||
+ grub_fatal ("grub_cryptodisk_erasesecrets: cannot allocate memory");
|
||||
+
|
||||
+ for (i = cryptodisk_list; i != NULL; i = i->next)
|
||||
+ if (grub_cryptodisk_setkey (i, buf, i->keysize))
|
||||
+ grub_fatal ("grub_cryptodisk_erasesecrets: cannot erase secrets for %s", i->source);
|
||||
+ else
|
||||
+ grub_printf ("Erased crypto secrets for %s\n", i->source);
|
||||
+ /*
|
||||
+ * Unfortunately, there is no way to "force unmount" a given disk, it may
|
||||
+ * have mounted "child" disks as well, e.g., an LVM volume. So, this
|
||||
+ * function MUST be called when there is no way back, e.g., when exiting.
|
||||
+ * Otherwise, subsequent read calls for a cryptodisk will return garbage.
|
||||
+ */
|
||||
+
|
||||
+ grub_free (buf);
|
||||
+}
|
||||
#endif /* GRUB_MACHINE_EFI */
|
||||
|
||||
struct grub_procfs_entry luks_script =
|
||||
@@ -1808,6 +1833,9 @@ GRUB_MOD_INIT (cryptodisk)
|
||||
|
||||
GRUB_MOD_FINI (cryptodisk)
|
||||
{
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+ grub_cryptodisk_erasesecrets ();
|
||||
+#endif
|
||||
grub_disk_dev_unregister (&grub_cryptodisk_dev);
|
||||
cryptodisk_cleanup ();
|
||||
grub_unregister_extcmd (cmd);
|
||||
diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h
|
||||
index b3291519b1..08abfb7b6c 100644
|
||||
--- a/include/grub/cryptodisk.h
|
||||
+++ b/include/grub/cryptodisk.h
|
||||
@@ -205,5 +205,6 @@ grub_cryptodisk_t grub_cryptodisk_get_by_source_disk (grub_disk_t disk);
|
||||
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
grub_err_t grub_cryptodisk_challenge_password (void);
|
||||
+void grub_cryptodisk_erasesecrets (void);
|
||||
#endif
|
||||
#endif
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
From ac539a315495792cd75fe8ab1c474f26e0a78852 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
Date: Sat, 15 Aug 2020 02:19:36 +1000
|
||||
Subject: [PATCH 06/23] docs/grub: Document signing grub with an appended
|
||||
signature
|
||||
|
||||
Signing grub for firmware that verifies an appended signature is a
|
||||
bit fiddly. I don't want people to have to figure it out from scratch
|
||||
so document it here.
|
||||
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
---
|
||||
docs/grub.texi | 42 ++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 42 insertions(+)
|
||||
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -6606,6 +6606,48 @@
|
||||
will also be necessary to enrol the public key used into a relevant firmware
|
||||
key database.
|
||||
|
||||
+@section Signing GRUB with an appended signature
|
||||
+
|
||||
+The @file{core.img} itself can be signed with a Linux kernel module-style
|
||||
+appended signature.
|
||||
+
|
||||
+To support IEEE1275 platforms where the boot image is often loaded directly
|
||||
+from a disk partition rather than from a file system, the @file{core.img}
|
||||
+can specify the size and location of the appended signature with an ELF
|
||||
+note added by @command{grub-install}.
|
||||
+
|
||||
+An image can be signed this way using the @command{sign-file} command from
|
||||
+the Linux kernel:
|
||||
+
|
||||
+@example
|
||||
+@group
|
||||
+# grub.key is your private key and certificate.der is your public key
|
||||
+
|
||||
+# Determine the size of the appended signature. It depends on the signing
|
||||
+# certificate and the hash algorithm
|
||||
+touch empty
|
||||
+sign-file SHA256 grub.key certificate.der empty empty.sig
|
||||
+SIG_SIZE=`stat -c '%s' empty.sig`
|
||||
+rm empty empty.sig
|
||||
+
|
||||
+# Build a grub image with $SIG_SIZE reserved for the signature
|
||||
+grub-install --appended-signature-size $SIG_SIZE --modules="..." ...
|
||||
+
|
||||
+# Replace the reserved size with a signature:
|
||||
+# cut off the last $SIG_SIZE bytes with truncate's minus modifier
|
||||
+truncate -s -$SIG_SIZE /boot/grub/powerpc-ieee1275/core.elf core.elf.unsigned
|
||||
+# sign the trimmed file with an appended signature, restoring the correct size
|
||||
+sign-file SHA256 grub.key certificate.der core.elf.unsigned core.elf.signed
|
||||
+
|
||||
+# Don't forget to install the signed image as required
|
||||
+# (e.g. on powerpc-ieee1275, to the PReP partition)
|
||||
+@end group
|
||||
+@end example
|
||||
+
|
||||
+As with UEFI secure boot, it is necessary to build in the required modules,
|
||||
+or sign them separately.
|
||||
+
|
||||
+
|
||||
@node Platform limitations
|
||||
@chapter Platform limitations
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user