Compare commits
1 Commits
Author | SHA256 | Date | |
---|---|---|---|
ac2036fa17 |
@@ -1,325 +0,0 @@
|
||||
From cb72de6caff51b79c0e5ef13dbd7a79754e3de35 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 17 Apr 2025 22:13:43 +0800
|
||||
Subject: [PATCH] Fix PowerPC CAS reboot to evaluate menu context
|
||||
|
||||
The Client Architecture Support (CAS) negotiation between the firmware
|
||||
and the operating system kernel can result in a reboot, allowing the
|
||||
firmware to reinitialize itself to satisfy the request. In this case,
|
||||
grub is expected to resume from the previous session by booting the
|
||||
entry recorded in the boot-last-label OpenFirmware property.
|
||||
|
||||
However, the current implementation fails when a CAS-triggered reboot
|
||||
originates from a menu entry within a submenu. For example, when booting
|
||||
into a Btrfs snapshot. The root cause is that the menu context is not
|
||||
evaluated. As a result, if the resumed boot entry relies on any
|
||||
evaluated variables, the behavior becomes undefined.
|
||||
|
||||
This patch addresses the issue by storing both the entry ID and its
|
||||
content in the boot-last-label property. The ID is used to descend into
|
||||
the correct menu context, ensuring the entry is executed in the same
|
||||
environment it was originally selected from.
|
||||
|
||||
A caret (^) is used to separate the entry ID from its content. The
|
||||
resulting format in boot-last-label looks like this:
|
||||
|
||||
gnulinux-simple-2315b72a-17f2-4537-bc62-63da478ce1dd^setparams 'SLES 15-SP6'
|
||||
|
||||
set gfxpayload=text
|
||||
insmod gzio
|
||||
insmod part_gpt
|
||||
insmod btrfs
|
||||
search --no-floppy --fs-uuid --set=root 2315b72a-17f2- ...
|
||||
echo 'Loading Linux 6.4.0-150600.23.25-default ...'
|
||||
linux /boot/vmlinux-6.4.0-150600.23.25-default root=UUID= ...
|
||||
echo 'Loading initial ramdisk ...'
|
||||
initrd /boot/initrd-6.4.0-150600.23.25-default
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/normal/main.c | 60 ++++++++++++++++++++++--------
|
||||
grub-core/normal/menu.c | 45 +++++++++++++++++++++-
|
||||
grub-core/normal/menu_entry.c | 70 +++++++++++++++++++++++++++++++++--
|
||||
grub-core/script/execute.c | 7 ----
|
||||
4 files changed, 154 insertions(+), 28 deletions(-)
|
||||
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -365,21 +365,6 @@
|
||||
{
|
||||
menu = read_config_file (config);
|
||||
|
||||
-#ifdef GRUB_MACHINE_IEEE1275
|
||||
- int boot;
|
||||
- boot = 0;
|
||||
- char *script = NULL;
|
||||
- char *dummy[1] = { NULL };
|
||||
- if (! grub_ieee1275_cas_reboot (&script) && script)
|
||||
- {
|
||||
- if (! grub_script_execute_new_scope (script, 0, dummy))
|
||||
- boot = 1;
|
||||
- }
|
||||
- grub_free (script);
|
||||
- if (boot)
|
||||
- grub_command_execute ("boot", 0, 0);
|
||||
-#endif
|
||||
-
|
||||
/* Ignore any error. */
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
@@ -393,7 +378,50 @@
|
||||
{
|
||||
if (menu && menu->size)
|
||||
{
|
||||
+#ifdef GRUB_MACHINE_IEEE1275
|
||||
+ char *entry_id = NULL;
|
||||
+ char *delim;
|
||||
+ const char *chosen;
|
||||
|
||||
+ if (grub_ieee1275_cas_reboot (&entry_id) != 0)
|
||||
+ goto enter_menu;
|
||||
+
|
||||
+ if ((delim = grub_strchr (entry_id, '^')) != NULL)
|
||||
+ *delim = '\0';
|
||||
+ else
|
||||
+ goto enter_menu;
|
||||
+
|
||||
+ chosen = grub_env_get ("chosen") ? : "";
|
||||
+ if (! grub_strlen (chosen))
|
||||
+ {
|
||||
+ grub_env_set ("default", entry_id);
|
||||
+ grub_env_set ("timeout", "0");
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ delim = entry_id;
|
||||
+ while ((delim = grub_strchr (delim, '>')) != NULL)
|
||||
+ {
|
||||
+ if (delim[1] == '>')
|
||||
+ {
|
||||
+ delim += 2;
|
||||
+ continue;
|
||||
+ }
|
||||
+ *delim = '\0';
|
||||
+ if (grub_strcmp (chosen, entry_id) == 0)
|
||||
+ {
|
||||
+ grub_env_set ("default", delim + 1);
|
||||
+ grub_env_set ("timeout", "0");
|
||||
+ break;
|
||||
+ }
|
||||
+ *delim++ = '>';
|
||||
+ }
|
||||
+ if (delim == NULL)
|
||||
+ grub_dprintf ("normal", "CAS triggered but find no match: %s\n", entry_id);
|
||||
+ }
|
||||
+ enter_menu:
|
||||
+ grub_free (entry_id);
|
||||
+#endif
|
||||
grub_boot_time ("Entering menu");
|
||||
grub_show_menu (menu, nested, 0);
|
||||
if (nested)
|
||||
--- a/grub-core/normal/menu.c
|
||||
+++ b/grub-core/normal/menu.c
|
||||
@@ -32,6 +32,9 @@
|
||||
#include <grub/script_sh.h>
|
||||
#include <grub/gfxterm.h>
|
||||
#include <grub/dl.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. */
|
||||
@@ -317,8 +320,31 @@
|
||||
grub_env_set ("default", ptr + 1);
|
||||
else
|
||||
grub_env_unset ("default");
|
||||
+#ifdef GRUB_MACHINE_IEEE1275
|
||||
+ char *cas_entry_id = NULL;
|
||||
+ char *cas_entry_source;
|
||||
+ const char *id;
|
||||
+ const char *sourcecode = entry->sourcecode;
|
||||
|
||||
+ id = grub_env_get ("chosen") ? : "";
|
||||
+
|
||||
+ if (grub_ieee1275_cas_reboot (&cas_entry_id) != 0)
|
||||
+ goto exec_new_scope;
|
||||
+
|
||||
+ if ((cas_entry_source = grub_strchr (cas_entry_id, '^')) != NULL)
|
||||
+ *cas_entry_source++ = '\0';
|
||||
+ else
|
||||
+ goto exec_new_scope;
|
||||
+
|
||||
+ if (grub_strcmp (id, cas_entry_id) == 0)
|
||||
+ sourcecode = cas_entry_source;
|
||||
+
|
||||
+ exec_new_scope:
|
||||
+ grub_script_execute_new_scope (sourcecode, entry->argc, entry->args);
|
||||
+ grub_free (cas_entry_id);
|
||||
+#else
|
||||
grub_script_execute_new_scope (entry->sourcecode, entry->argc, entry->args);
|
||||
+#endif
|
||||
|
||||
if (errs_before != grub_err_printed_errors)
|
||||
grub_wait_after_message ();
|
||||
@@ -326,8 +352,23 @@
|
||||
errs_before = grub_err_printed_errors;
|
||||
|
||||
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
|
||||
- /* Implicit execution of boot, only if something is loaded. */
|
||||
- grub_command_execute ("boot", 0, 0);
|
||||
+ {
|
||||
+#ifdef GRUB_MACHINE_IEEE1275
|
||||
+ char *entry_data;
|
||||
+
|
||||
+ entry_data = grub_xasprintf ("%s^%s", id, sourcecode);
|
||||
+ if (entry_data)
|
||||
+ grub_ieee1275_set_boot_last_label (entry_data);
|
||||
+ else
|
||||
+ grub_print_error ();
|
||||
+ grub_free (entry_data);
|
||||
+#endif
|
||||
+ /* Implicit execution of boot, only if something is loaded. */
|
||||
+ grub_command_execute ("boot", 0, 0);
|
||||
+#ifdef GRUB_MACHINE_IEEE1275
|
||||
+ grub_ieee1275_set_boot_last_label ("");
|
||||
+#endif
|
||||
+ }
|
||||
|
||||
if (errs_before != grub_err_printed_errors)
|
||||
grub_wait_after_message ();
|
||||
--- a/grub-core/normal/menu_entry.c
|
||||
+++ b/grub-core/normal/menu_entry.c
|
||||
@@ -29,6 +29,9 @@
|
||||
#include <grub/charset.h>
|
||||
#include <grub/safemath.h>
|
||||
#include <grub/crypttab.h>
|
||||
+#ifdef GRUB_MACHINE_IEEE1275
|
||||
+#include <grub/ieee1275/ieee1275.h>
|
||||
+#endif
|
||||
|
||||
enum update_mode
|
||||
{
|
||||
@@ -78,6 +81,9 @@
|
||||
int completion_shown;
|
||||
|
||||
int submenu;
|
||||
+#ifdef GRUB_MACHINE_IEEE1275
|
||||
+ char *id;
|
||||
+#endif
|
||||
|
||||
struct per_term_screen *terms;
|
||||
unsigned nterms;
|
||||
@@ -578,6 +584,9 @@
|
||||
grub_free (screen->killed_text);
|
||||
grub_free (screen->lines);
|
||||
grub_free (screen->terms);
|
||||
+#ifdef GRUB_MACHINE_IEEE1275
|
||||
+ grub_free (screen->id);
|
||||
+#endif
|
||||
grub_free (screen);
|
||||
}
|
||||
|
||||
@@ -599,6 +608,11 @@
|
||||
screen->lines = grub_malloc (sizeof (struct line));
|
||||
if (! screen->lines)
|
||||
goto fail;
|
||||
+#ifdef GRUB_MACHINE_IEEE1275
|
||||
+ screen->id = grub_strdup (entry->id);
|
||||
+ if (! screen->id)
|
||||
+ goto fail;
|
||||
+#endif
|
||||
|
||||
/* Initialize the first line which must be always present. */
|
||||
if (! init_line (screen, screen->lines))
|
||||
@@ -1215,14 +1229,64 @@
|
||||
script[size] = '\0';
|
||||
}
|
||||
grub_script_execute_new_scope (script, 0, dummy);
|
||||
- grub_free (script);
|
||||
|
||||
if (errs_before != grub_err_printed_errors)
|
||||
grub_wait_after_message ();
|
||||
|
||||
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
|
||||
- /* Implicit execution of boot, only if something is loaded. */
|
||||
- grub_command_execute ("boot", 0, 0);
|
||||
+ {
|
||||
+#ifdef GRUB_MACHINE_IEEE1275
|
||||
+ char *entry_data = NULL;
|
||||
+ const char *chosen;
|
||||
+ const char *ptr;
|
||||
+ grub_size_t sz = 0;
|
||||
+ char *buf = NULL;
|
||||
+ char *optr;
|
||||
+
|
||||
+ chosen = grub_env_get ("chosen") ? : "";
|
||||
+ for (ptr = screen->id; *ptr; ptr++)
|
||||
+ sz += (*ptr == '>') ? 2 : 1;
|
||||
+ sz++;
|
||||
+ sz += grub_strlen (chosen);
|
||||
+ sz++;
|
||||
+ buf = grub_malloc (sz);
|
||||
+ if (!buf)
|
||||
+ {
|
||||
+ grub_print_error ();
|
||||
+ goto exec_boot;
|
||||
+ }
|
||||
+ optr = buf;
|
||||
+ if (*chosen != '\0')
|
||||
+ {
|
||||
+ optr = grub_stpcpy (optr, chosen);
|
||||
+ *optr++ = '>';
|
||||
+ }
|
||||
+ for (ptr = screen->id; *ptr; ptr++)
|
||||
+ {
|
||||
+ if (*ptr == '>')
|
||||
+ *optr++ = '>';
|
||||
+ *optr++ = *ptr;
|
||||
+ }
|
||||
+ *optr = 0;
|
||||
+ entry_data = grub_xasprintf ("%s^%s", buf, script);
|
||||
+ if (entry_data)
|
||||
+ grub_ieee1275_set_boot_last_label (entry_data);
|
||||
+ else
|
||||
+ grub_print_error ();
|
||||
+ grub_free (entry_data);
|
||||
+ grub_free (buf);
|
||||
+ grub_free (script);
|
||||
+ script = NULL;
|
||||
+ exec_boot:
|
||||
+#endif
|
||||
+ /* Implicit execution of boot, only if something is loaded. */
|
||||
+ grub_command_execute ("boot", 0, 0);
|
||||
+#ifdef GRUB_MACHINE_IEEE1275
|
||||
+ grub_ieee1275_set_boot_last_label ("");
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
+ grub_free (script);
|
||||
|
||||
if (screen->submenu)
|
||||
{
|
||||
--- a/grub-core/script/execute.c
|
||||
+++ b/grub-core/script/execute.c
|
||||
@@ -28,9 +28,6 @@
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/verify.h>
|
||||
-#ifdef GRUB_MACHINE_IEEE1275
|
||||
-#include <grub/ieee1275/ieee1275.h>
|
||||
-#endif
|
||||
|
||||
/* 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. */
|
||||
@@ -886,10 +883,6 @@
|
||||
grub_err_t ret = 0;
|
||||
struct grub_script *parsed_script;
|
||||
|
||||
-#ifdef GRUB_MACHINE_IEEE1275
|
||||
- grub_ieee1275_set_boot_last_label (source);
|
||||
-#endif
|
||||
-
|
||||
while (source)
|
||||
{
|
||||
char *line;
|
@@ -1,7 +1,7 @@
|
||||
From 7b6cdb8ff71e43f95de9cefc19a7949e924c2be9 Mon Sep 17 00:00:00 2001
|
||||
From 27b3e919b9b51a4fedeb3a5aef19c87f0cd7b687 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 17 Nov 2023 12:32:59 +0800
|
||||
Subject: [PATCH 1/2] Improve TPM key protection on boot interruptions
|
||||
Subject: [PATCH] Improve TPM key protection on boot interruptions
|
||||
|
||||
The unattended boot process for full disk encryption relies on an
|
||||
authorized TPM policy to ensure the system's integrity before releasing
|
||||
@@ -25,21 +25,19 @@ By implementing these changes, this enhancement seeks to fortify the
|
||||
protection of TPM keys, thereby ensuring a more robust defense against
|
||||
potential unauthorized modifications during the boot process.
|
||||
|
||||
v2: erase cached credentials in grub_cryptodisk_erasesecrets
|
||||
|
||||
Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/crypttab.c | 38 ++++++++++++++++++++++++++---------
|
||||
grub-core/disk/cryptodisk.c | 10 ++++++++-
|
||||
grub-core/disk/cryptodisk.c | 8 +++++++-
|
||||
grub-core/loader/linux.c | 6 +++---
|
||||
grub-core/normal/main.c | 2 +-
|
||||
grub-core/normal/menu.c | 7 +++++++
|
||||
grub-core/normal/menu_entry.c | 2 +-
|
||||
include/grub/crypttab.h | 18 ++++++++++-------
|
||||
7 files changed, 61 insertions(+), 22 deletions(-)
|
||||
7 files changed, 59 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/crypttab.c b/grub-core/commands/crypttab.c
|
||||
index c2217ca980..9397bede9e 100644
|
||||
index c2217ca98..9397bede9 100644
|
||||
--- a/grub-core/commands/crypttab.c
|
||||
+++ b/grub-core/commands/crypttab.c
|
||||
@@ -9,17 +9,20 @@
|
||||
@@ -127,7 +125,7 @@ index c2217ca980..9397bede9e 100644
|
||||
|
||||
static grub_command_t cmd;
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index cb87d337ac..5fd68f4549 100644
|
||||
index aa0d43562..babc94868 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1071,6 +1071,9 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
@@ -140,15 +138,17 @@ index cb87d337ac..5fd68f4549 100644
|
||||
|
||||
dev = grub_cryptodisk_get_by_source_disk (source);
|
||||
|
||||
@@ -1185,6 +1188,7 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
@@ -1183,6 +1186,9 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
ret = grub_cryptodisk_insert (dev, name, source);
|
||||
if (ret != GRUB_ERR_NONE)
|
||||
goto error;
|
||||
#ifndef GRUB_UTIL
|
||||
grub_cli_set_auth_needed ();
|
||||
+#ifndef GRUB_UTIL
|
||||
+ is_tpmkey = 1;
|
||||
#endif
|
||||
+#endif
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -1247,7 +1251,7 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
}
|
||||
@@ -1244,7 +1250,7 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
|
||||
#ifndef GRUB_UTIL
|
||||
if (cargs->key_data && dev)
|
||||
@@ -157,19 +157,8 @@ index cb87d337ac..5fd68f4549 100644
|
||||
#endif
|
||||
if (askpass)
|
||||
{
|
||||
@@ -1792,6 +1796,10 @@ grub_cryptodisk_erasesecrets (void)
|
||||
grub_cryptodisk_t i;
|
||||
grub_uint8_t *buf;
|
||||
|
||||
+#ifndef GRUB_UTIL
|
||||
+ grub_cryptokey_discard ();
|
||||
+#endif
|
||||
+
|
||||
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
|
||||
index 9ee8f3790..e5e792958 100644
|
||||
--- a/grub-core/loader/linux.c
|
||||
+++ b/grub-core/loader/linux.c
|
||||
@@ -226,13 +226,13 @@ grub_initrd_init (int argc, char *argv[],
|
||||
@@ -198,10 +187,10 @@ index 9ee8f37907..e5e7929581 100644
|
||||
{
|
||||
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
|
||||
index a3f711d1d..1b426af69 100644
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -599,7 +599,7 @@ grub_cmdline_run (int nested, int force_auth)
|
||||
@@ -479,7 +479,7 @@ grub_cmdline_run (int nested, int force_auth)
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -211,7 +200,7 @@ index 320adbe337..343cdbae2c 100644
|
||||
|
||||
while (1)
|
||||
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
|
||||
index f243c5e0bd..897da6abac 100644
|
||||
index 14b0ab1ec..1df2638d7 100644
|
||||
--- a/grub-core/normal/menu.c
|
||||
+++ b/grub-core/normal/menu.c
|
||||
@@ -32,6 +32,7 @@
|
||||
@@ -219,10 +208,10 @@ index f243c5e0bd..897da6abac 100644
|
||||
#include <grub/gfxterm.h>
|
||||
#include <grub/dl.h>
|
||||
+#include <grub/crypttab.h>
|
||||
#ifdef GRUB_MACHINE_IEEE1275
|
||||
#include <grub/ieee1275/ieee1275.h>
|
||||
#endif
|
||||
@@ -769,6 +770,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot, int *notify_boot)
|
||||
|
||||
/* Time to delay after displaying an error message about a default/fallback
|
||||
entry failing to boot. */
|
||||
@@ -708,6 +709,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot, int *notify_boot)
|
||||
if (grub_key_is_interrupt (key))
|
||||
{
|
||||
timeout = -1;
|
||||
@@ -230,7 +219,7 @@ index f243c5e0bd..897da6abac 100644
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -851,6 +853,11 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot, int *notify_boot)
|
||||
@@ -790,6 +792,11 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot, int *notify_boot)
|
||||
clear_timeout ();
|
||||
}
|
||||
|
||||
@@ -243,10 +232,10 @@ index f243c5e0bd..897da6abac 100644
|
||||
{
|
||||
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
|
||||
index 384ab9ce3..e5ba91ea4 100644
|
||||
--- a/grub-core/normal/menu_entry.c
|
||||
+++ b/grub-core/normal/menu_entry.c
|
||||
@@ -1331,7 +1331,7 @@ grub_menu_entry_run (grub_menu_entry_t entry)
|
||||
@@ -1263,7 +1263,7 @@ grub_menu_entry_run (grub_menu_entry_t entry)
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -256,7 +245,7 @@ index 38c958e657..bbd05e5638 100644
|
||||
screen = make_screen (entry);
|
||||
if (! screen)
|
||||
diff --git a/include/grub/crypttab.h b/include/grub/crypttab.h
|
||||
index 113c53cfce..f86404686f 100644
|
||||
index 113c53cfc..f86404686 100644
|
||||
--- a/include/grub/crypttab.h
|
||||
+++ b/include/grub/crypttab.h
|
||||
@@ -4,21 +4,25 @@
|
||||
@@ -293,5 +282,5 @@ index 113c53cfce..f86404686f 100644
|
||||
+grub_cryptokey_tpmkey_discard (void);
|
||||
#endif /* ! GRUB_CRYPTTAB_HEADER */
|
||||
--
|
||||
2.49.0
|
||||
2.35.3
|
||||
|
||||
|
@@ -1,188 +0,0 @@
|
||||
From 8201e8e6fbb7ee992c430679705852ede91efcd6 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 20 Aug 2024 12:14:35 +0800
|
||||
Subject: [PATCH] Streamline BLS and improve PCR stability
|
||||
|
||||
Introduce an environment variable enable_blscfg to allow looking for and
|
||||
reading BLS (Boot Loader Specification) configurations right at startup,
|
||||
rather than relying on the traditional grub.cfg. The benefit of this
|
||||
approach is that it eliminates the layer of using an external grub.cfg
|
||||
to piggyback the blscfg command. This change reduces the complexity of
|
||||
managing command sequences, which would otherwise complicate the PCR
|
||||
(Platform Configuration Register) policy. Managing a sequence of
|
||||
commands can be difficult to maintain and ensure they remain in order
|
||||
indefinitely.
|
||||
|
||||
Along the way, we can remove the external grub.cfg and have everything
|
||||
embedded in memdisk and early embedded configurations. This approach
|
||||
significantly improves the overall stability and makes it easier to
|
||||
maintain a consistent and predictable PCR outcome.
|
||||
|
||||
The grubenv in the EFI boot directory can be used to override default
|
||||
settings in the grubbls image, allowing for continued customization.
|
||||
|
||||
By introducing grubbls.efi for managing BLS configuration integration,
|
||||
all necessary modules are built-in, and sensible default settings are
|
||||
applied. This allows us to remove the following hardcoded command
|
||||
sequences in blscfg:
|
||||
|
||||
load_video
|
||||
set gfxpalyload=keep
|
||||
insmod gzio
|
||||
|
||||
Since these are now part of the EFI image, this change effectively
|
||||
simplifies the TPM event log, making it easier to handle with tools like
|
||||
pcr-oracle or systemd-pcrlock.
|
||||
|
||||
Signed-Off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/blscfg.c | 4 ++
|
||||
grub-core/normal/main.c | 82 +++++++++++++++++++++++++++++++++++++
|
||||
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 @@ read_config_file_getline (char **line, int cont __attribute__ ((unused)),
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+
|
||||
+static void
|
||||
+read_envblk_from_cmdpath (void)
|
||||
+{
|
||||
+ const char *cmdpath;
|
||||
+ char *envfile = NULL;
|
||||
+ int found = 0;
|
||||
+
|
||||
+ cmdpath = grub_env_get ("cmdpath");
|
||||
+
|
||||
+ if (cmdpath)
|
||||
+ envfile = grub_xasprintf ("%s/grubenv", cmdpath);
|
||||
+
|
||||
+ if (envfile)
|
||||
+ {
|
||||
+ grub_file_t file;
|
||||
+
|
||||
+ file = grub_file_open (envfile, GRUB_FILE_TYPE_FS_SEARCH
|
||||
+ | GRUB_FILE_TYPE_NO_DECOMPRESS | GRUB_FILE_TYPE_SKIP_SIGNATURE);
|
||||
+ if (file)
|
||||
+ {
|
||||
+ found = 1;
|
||||
+ grub_file_close (file);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (found)
|
||||
+ {
|
||||
+ char *cfg;
|
||||
+
|
||||
+ cfg = grub_xasprintf ("load_env -f %s\n", envfile);
|
||||
+ grub_parser_execute ((char *)cfg);
|
||||
+ grub_free (cfg);
|
||||
+ }
|
||||
+
|
||||
+ grub_free (envfile);
|
||||
+}
|
||||
+
|
||||
+static grub_menu_t
|
||||
+read_blscfg (void)
|
||||
+{
|
||||
+ grub_menu_t newmenu;
|
||||
+ newmenu = grub_env_get_menu ();
|
||||
+ if (! newmenu)
|
||||
+ {
|
||||
+ newmenu = grub_zalloc (sizeof (*newmenu));
|
||||
+ if (! newmenu)
|
||||
+ return 0;
|
||||
+
|
||||
+ grub_env_set_menu (newmenu);
|
||||
+ }
|
||||
+
|
||||
+ grub_parser_execute ((char *)"blscfg\n");
|
||||
+ return newmenu;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
static grub_menu_t
|
||||
read_config_file (const char *config)
|
||||
{
|
||||
@@ -282,6 +341,26 @@ grub_normal_execute (const char *config, int nested, int batch)
|
||||
|
||||
grub_boot_time ("Executing config file");
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+ const char *val;
|
||||
+
|
||||
+ val = grub_env_get ("enable_blscfg");
|
||||
+ if (val && (val[0] == '1' || val[0] == 'y'))
|
||||
+ read_envblk_from_cmdpath ();
|
||||
+
|
||||
+ /* Above would be used to override enable_blscfg, so verify again */
|
||||
+ val = grub_env_get ("enable_blscfg");
|
||||
+ if (val && (val[0] == '1' || val[0] == 'y'))
|
||||
+ {
|
||||
+ menu = read_blscfg ();
|
||||
+ /* Ignore any error. */
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ /* unset to let configfile and source commands continue to work */
|
||||
+ grub_env_unset ("enable_blscfg");
|
||||
+ goto check_batch;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
if (config)
|
||||
{
|
||||
menu = read_config_file (config);
|
||||
@@ -307,6 +386,9 @@ grub_normal_execute (const char *config, int nested, int batch)
|
||||
|
||||
grub_boot_time ("Executed config file");
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+ check_batch:
|
||||
+#endif
|
||||
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 @@ struct grub_parser
|
||||
};
|
||||
typedef struct grub_parser *grub_parser_t;
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+grub_err_t EXPORT_FUNC (grub_parser_execute) (char *source);
|
||||
+#else
|
||||
grub_err_t grub_parser_execute (char *source);
|
||||
+#endif
|
||||
|
||||
grub_err_t
|
||||
grub_rescue_parse_line (char *line,
|
||||
--
|
||||
2.46.0
|
||||
|
@@ -1,34 +0,0 @@
|
||||
From f85cc4bac3cfb787c5a47a8864a4565519dd01e9 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 6 Mar 2025 16:29:48 +0800
|
||||
Subject: [PATCH] autofs: Ignore zfs not found
|
||||
|
||||
We put zfs modules in a separate package so they can be missing during
|
||||
the file-system probe that kicks in automatic file-system module
|
||||
loading. We ignore the error message for the missing zfs module, as that
|
||||
is not an abnormal condition like others.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/normal/autofs.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/grub-core/normal/autofs.c b/grub-core/normal/autofs.c
|
||||
index 7a7cf2b0f7..591b5fc8c3 100644
|
||||
--- a/grub-core/normal/autofs.c
|
||||
+++ b/grub-core/normal/autofs.c
|
||||
@@ -42,6 +42,11 @@ autoload_fs_module (void)
|
||||
break;
|
||||
}
|
||||
|
||||
+ /* We put zfs in a separate package, so ignoring if it's not found */
|
||||
+ if (grub_strcmp (p->name, "zfs") == 0 &&
|
||||
+ grub_errno == GRUB_ERR_FILE_NOT_FOUND)
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+
|
||||
if (grub_errno)
|
||||
grub_print_error ();
|
||||
|
||||
--
|
||||
2.48.1
|
||||
|
@@ -1,82 +0,0 @@
|
||||
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
|
||||
|
@@ -1,44 +0,0 @@
|
||||
From e873743f4ed7841542dd7dc11a183cb136670382 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Wed, 19 Feb 2025 14:52:52 +0800
|
||||
Subject: [PATCH] bls: Accept .conf suffix in setting default entry
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/normal/menu.c | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
|
||||
index b11b28e0d9..dfdf0c7268 100644
|
||||
--- a/grub-core/normal/menu.c
|
||||
+++ b/grub-core/normal/menu.c
|
||||
@@ -557,6 +557,26 @@ get_entry_number (grub_menu_t menu, const char *name)
|
||||
entry = i;
|
||||
break;
|
||||
}
|
||||
+
|
||||
+ if (e->bls)
|
||||
+ {
|
||||
+ char *v, *ext;
|
||||
+
|
||||
+ if ((v = grub_strdup (val)) &&
|
||||
+ (ext = grub_strrchr (v, '.')) &&
|
||||
+ grub_strcmp (ext, ".conf") == 0)
|
||||
+ {
|
||||
+ *ext = '\0';
|
||||
+ if (menuentry_eq (e->id, v))
|
||||
+ {
|
||||
+ entry = i;
|
||||
+ grub_free (v);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ grub_free (v);
|
||||
+ }
|
||||
+
|
||||
e = e->next;
|
||||
|
||||
/* Skip hidden entries */
|
||||
--
|
||||
2.48.1
|
||||
|
@@ -1,259 +0,0 @@
|
||||
From 434b014e20ebb7930599fe30e09441af6b449fef Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 14 Apr 2025 08:52:26 +0800
|
||||
Subject: [PATCH] blscfg: read fragments in order
|
||||
|
||||
The PCR 9 measurements of BLS entry files made by blscfg module are
|
||||
performed in "readdir" order, which depends on the filesystem and is
|
||||
therefore inherently unpredictable and unreliable. To make future PCR
|
||||
values more predictable, the entries should be processed in a
|
||||
deterministic order, such as alphabetically by filename.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/blscfg.c | 164 ++++++++++++++++++++++--------------
|
||||
1 file changed, 103 insertions(+), 61 deletions(-)
|
||||
|
||||
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 struct bls_entry *entries = NULL;
|
||||
|
||||
+struct bls_fragment
|
||||
+{
|
||||
+ struct bls_fragment *next;
|
||||
+ struct bls_fragment *prev;
|
||||
+ char *filename;
|
||||
+};
|
||||
+typedef struct bls_fragment *bls_fragment_t;
|
||||
+static bls_fragment_t fragments;
|
||||
+
|
||||
#define FOR_BLS_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries)
|
||||
|
||||
/* 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 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;
|
||||
+
|
||||
+ n = grub_strlen (filename);
|
||||
+ 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);
|
||||
+
|
||||
+ fragment = grub_zalloc (sizeof (*fragment));
|
||||
+ fragment->filename = grub_strdup (p);
|
||||
+
|
||||
+ if (!fragments)
|
||||
+ {
|
||||
+ fragments = fragment;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ FOR_LIST_ELEMENTS (f, fragments)
|
||||
+ {
|
||||
+ int rc;
|
||||
+ rc = grub_strcmp(fragment->filename, f->filename);
|
||||
+ if (!rc)
|
||||
+ {
|
||||
+ grub_free (fragment);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (rc < 0)
|
||||
+ {
|
||||
+ fragment->next = f;
|
||||
+ if (f->prev)
|
||||
+ f->prev->next = fragment;
|
||||
+ fragment->prev = f->prev;
|
||||
+ f->prev = fragment;
|
||||
+ if (f == fragments)
|
||||
+ {
|
||||
+ fragments = fragment;
|
||||
+ fragment->prev = NULL;
|
||||
+ }
|
||||
+ return 0;
|
||||
+ }
|
||||
+ last = f;
|
||||
+ }
|
||||
+
|
||||
+ if (last)
|
||||
+ {
|
||||
+ last->next = fragment;
|
||||
+ fragment->prev = last;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static grub_envblk_t saved_env = NULL;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
+ }
|
||||
+
|
||||
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,374 +0,0 @@
|
||||
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
|
||||
|
@@ -1,153 +0,0 @@
|
||||
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,55 +0,0 @@
|
||||
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
|
||||
|
@@ -1,48 +0,0 @@
|
||||
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
|
||||
|
@@ -1,65 +0,0 @@
|
||||
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,44 @@
|
||||
From a59b58f6ae327a8f6949991cb5531db01e1ba14d Mon Sep 17 00:00:00 2001
|
||||
From: Wen Xiong <wenxiong@linux.ibm.com>
|
||||
Date: Tue, 7 Feb 2023 15:10:15 -0500
|
||||
Subject: [PATCH] grub2: Can't setup a default boot device correctly on nvme
|
||||
device in Beta3
|
||||
|
||||
The patch in Bug 200486 - SUSE1205666 - SLES15SP5 Beta1: Setup multiple dev path
|
||||
for a nvmf boot device in grub2 caused the issue. That patch didn't consider
|
||||
nvme devices carefully.
|
||||
|
||||
The new patch will check "nvme-of" instead of "nvme" to call
|
||||
build_multi_boot_device().
|
||||
|
||||
Signed-off-by: Wen Xiong<wenxiong@linux.ibm.com>
|
||||
---
|
||||
grub-core/osdep/unix/platform.c | 10 +++++++---
|
||||
1 file changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c
|
||||
index db8fa4b95..fb47c0ffa 100644
|
||||
--- a/grub-core/osdep/unix/platform.c
|
||||
+++ b/grub-core/osdep/unix/platform.c
|
||||
@@ -288,11 +288,15 @@ grub_install_register_ieee1275 (int is_prep, const char *install_device,
|
||||
}
|
||||
*ptr = '\0';
|
||||
}
|
||||
- else if (grub_strstr(install_device, "nvme"))
|
||||
- boot_device = build_multi_boot_device(install_device);
|
||||
- else
|
||||
+ else {
|
||||
boot_device = get_ofpathname (install_device);
|
||||
|
||||
+ if (grub_strstr(boot_device, "nvme-of")) {
|
||||
+ free (boot_device);
|
||||
+ boot_device = build_multi_boot_device(install_device);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device",
|
||||
boot_device, NULL }))
|
||||
{
|
||||
--
|
||||
2.39.1
|
||||
|
164
0001-grub2-Set-multiple-device-path-for-a-nvmf-boot-devic.patch
Normal file
164
0001-grub2-Set-multiple-device-path-for-a-nvmf-boot-devic.patch
Normal file
@@ -0,0 +1,164 @@
|
||||
From 3e77c5494fd06f430588ae9c304fea370439d531 Mon Sep 17 00:00:00 2001
|
||||
From: Wen Xiong <Wen Xiong>
|
||||
Date: Thu, 15 Dec 2022 21:33:41 -0500
|
||||
Subject: [PATCH] grub2: Set multiple device path for a nvmf boot device
|
||||
|
||||
nvmf support native multipath(ANA) by default.
|
||||
The patch added the support for setting multiple
|
||||
device path for a nvmf boot device.
|
||||
|
||||
localhost:~ grub2-install -v /dev/nvme1n1p1
|
||||
...
|
||||
...
|
||||
...
|
||||
grub2-install: info: executing nvsetenv boot-device /pci@800000020000132/fibre-channel@0,1/nvme-of/controller@5005076810193675,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec /pci@800000020000132/fibre-channel@0/nvme-of/controller@5005076810193675,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec /pci@800000020000132/fibre-channel@0/nvme-of/controller@50050768101935e5,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec /pci@800000020000132/fibre-channel@0,1/nvme-of/controller@50050768101935e5,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec.
|
||||
Installation finished. No error reported.
|
||||
|
||||
localhost:~ # bootlist -m normal -o
|
||||
nvme7n1
|
||||
nvme5n1
|
||||
nvme1n1
|
||||
nvme4n1
|
||||
|
||||
localhost:~ # bootlist -m normal -r
|
||||
/pci@800000020000132/fibre-channel@0,1/nvme-of/controller@5005076810193675,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec
|
||||
/pci@800000020000132/fibre-channel@0/nvme-of/controller@5005076810193675,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec
|
||||
/pci@800000020000132/fibre-channel@0/nvme-of/controller@50050768101935e5,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec
|
||||
/pci@800000020000132/fibre-channel@0,1/nvme-of/controller@50050768101935e5,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec
|
||||
|
||||
Signed-off-by: Wen Xiong <wenxiong@linux.ibm.com>
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 6 ++---
|
||||
grub-core/osdep/unix/platform.c | 48 +++++++++++++++++++++++++++++++++
|
||||
include/grub/util/install.h | 3 +++
|
||||
include/grub/util/ofpath.h | 9 +++++++
|
||||
4 files changed, 63 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/grub-core/osdep/linux/ofpath.c
|
||||
+++ b/grub-core/osdep/linux/ofpath.c
|
||||
@@ -209,7 +209,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
xrealpath (const char *in)
|
||||
{
|
||||
char *out;
|
||||
@@ -224,7 +224,7 @@
|
||||
return out;
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
block_device_get_sysfs_path_and_link(const char *devicenode)
|
||||
{
|
||||
char *rpath;
|
||||
@@ -535,7 +535,7 @@
|
||||
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
nvme_get_syspath(const char *nvmedev)
|
||||
{
|
||||
char *sysfs_path, *controller_node;
|
||||
--- a/grub-core/osdep/unix/platform.c
|
||||
+++ b/grub-core/osdep/unix/platform.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <config.h>
|
||||
|
||||
#include <grub/util/install.h>
|
||||
+#include <grub/util/ofpath.h>
|
||||
#include <grub/emu/hostdisk.h>
|
||||
#include <grub/util/misc.h>
|
||||
#include <grub/misc.h>
|
||||
@@ -131,6 +132,51 @@
|
||||
return rc;
|
||||
}
|
||||
|
||||
+char *
|
||||
+build_multi_boot_device(const char *install_device)
|
||||
+{
|
||||
+ char *sysfs_path;
|
||||
+ char *nvme_ns;
|
||||
+ unsigned int nsid;
|
||||
+ char *ptr;
|
||||
+ char *boot_device_string;
|
||||
+ struct dirent *ep;
|
||||
+ DIR *dp;
|
||||
+
|
||||
+ nvme_ns = strchr(install_device, 'n');
|
||||
+ nsid = of_path_get_nvme_nsid(nvme_ns);
|
||||
+ sysfs_path = nvme_get_syspath(nvme_ns);
|
||||
+ strcat(sysfs_path, "/device");
|
||||
+ sysfs_path = xrealpath(sysfs_path);
|
||||
+
|
||||
+ dp = opendir(sysfs_path);
|
||||
+ ptr = boot_device_string = xmalloc (1000);
|
||||
+
|
||||
+ /* We cannot have a boot list with more than five entries */
|
||||
+ while((ep = readdir(dp)) != NULL){
|
||||
+ char *nvme_device;
|
||||
+
|
||||
+ if (grub_strstr(ep->d_name, "nvme")) {
|
||||
+ nvme_device = xasprintf ("%s%s%x ",
|
||||
+ get_ofpathname(ep->d_name),"/namespace@", nsid);
|
||||
+ if ((strlen(boot_device_string) + strlen(nvme_device)) >= 200*5 - 1) {
|
||||
+ grub_util_warn (_("More than five entries cannot be specified in the bootlist"));
|
||||
+ free(nvme_device);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ strncpy(ptr, nvme_device, strlen(nvme_device));
|
||||
+ ptr += strlen(nvme_device);
|
||||
+ free(nvme_device);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *--ptr = '\0';
|
||||
+ closedir(dp);
|
||||
+
|
||||
+ return boot_device_string;
|
||||
+}
|
||||
+
|
||||
int
|
||||
grub_install_register_efi (const grub_disk_t *efidir_grub_disk,
|
||||
const char *efifile_path,
|
||||
@@ -242,6 +288,8 @@
|
||||
}
|
||||
*ptr = '\0';
|
||||
}
|
||||
+ else if (grub_strstr(install_device, "nvme"))
|
||||
+ boot_device = build_multi_boot_device(install_device);
|
||||
else
|
||||
boot_device = get_ofpathname (install_device);
|
||||
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -241,6 +241,9 @@
|
||||
const char *efi_distributor,
|
||||
const char *force_disk);
|
||||
|
||||
+char *
|
||||
+build_multi_boot_device(const char *install_device);
|
||||
+
|
||||
void
|
||||
grub_install_register_ieee1275 (int is_prep, const char *install_device,
|
||||
int partno, const char *relpath);
|
||||
--- a/include/grub/util/ofpath.h
|
||||
+++ b/include/grub/util/ofpath.h
|
||||
@@ -32,4 +32,13 @@
|
||||
|
||||
char* of_find_fc_host(char* host_wwpn);
|
||||
|
||||
+char* nvme_get_syspath(const char *nvmedev);
|
||||
+
|
||||
+char* block_device_get_sysfs_path_and_link(const char *devicenode);
|
||||
+
|
||||
+char* xrealpath (const char *in);
|
||||
+
|
||||
+unsigned int of_path_get_nvme_nsid(const char* devname);
|
||||
+
|
||||
+
|
||||
#endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */
|
@@ -1,56 +0,0 @@
|
||||
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
|
||||
|
@@ -1,220 +0,0 @@
|
||||
From e56c40ade88270bec8b50680fe34bb358919057b Mon Sep 17 00:00:00 2001
|
||||
From: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Date: Mon, 19 May 2025 16:34:34 +0530
|
||||
Subject: [PATCH] ieee1275: support added for multiple nvme bootpaths
|
||||
|
||||
This patch sets mupltiple NVMe boot-devices for more robust boot.
|
||||
Scenario where NVMe multipaths are available, all the available bootpaths (Max 5)
|
||||
will be added as the boot-device.
|
||||
|
||||
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Link: https://lore.kernel.org/r/20250519110434.28686-1-avnish@linux.ibm.com
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 6 +-
|
||||
grub-core/osdep/unix/platform.c | 114 +++++++++++++++++++++++++++++++-
|
||||
include/grub/util/install.h | 3 +
|
||||
include/grub/util/ofpath.h | 4 ++
|
||||
4 files changed, 123 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
|
||||
index dd50d785dd..66a256b18b 100644
|
||||
--- a/grub-core/osdep/linux/ofpath.c
|
||||
+++ b/grub-core/osdep/linux/ofpath.c
|
||||
@@ -209,7 +209,7 @@ find_obppath (const char *sysfs_path_orig)
|
||||
}
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
xrealpath (const char *in)
|
||||
{
|
||||
char *out;
|
||||
@@ -224,7 +224,7 @@ xrealpath (const char *in)
|
||||
return out;
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
block_device_get_sysfs_path_and_link(const char *devicenode)
|
||||
{
|
||||
char *rpath;
|
||||
@@ -613,7 +613,7 @@ of_path_get_nvme_nsid (const char* devname)
|
||||
return nsid;
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
nvme_get_syspath (const char *nvmedev)
|
||||
{
|
||||
char *sysfs_path, *controller_node;
|
||||
diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c
|
||||
index 1e2961e006..e8e28f3d4b 100644
|
||||
--- a/grub-core/osdep/unix/platform.c
|
||||
+++ b/grub-core/osdep/unix/platform.c
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
+#include <grub/util/ofpath.h>
|
||||
+#define BOOTDEV_BUFFER 1000
|
||||
|
||||
static char *
|
||||
get_ofpathname (const char *dev)
|
||||
@@ -203,6 +205,105 @@ grub_install_register_efi (const grub_disk_t *efidir_grub_disk,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+
|
||||
+char *
|
||||
+add_multiple_nvme_bootdevices (const char *install_device)
|
||||
+{
|
||||
+ char *sysfs_path, *nvme_ns, *ptr, *non_splitter_path;
|
||||
+ unsigned int nsid;
|
||||
+ char *multipath_boot, *ofpath, *ext_dir;
|
||||
+ struct dirent *ep, *splitter_ep;
|
||||
+ DIR *dp, *splitter_dp;
|
||||
+ char *cntl_id, *dirR1, *dirR2, *splitter_info_path;
|
||||
+ int is_FC = 0, is_splitter = 0;
|
||||
+
|
||||
+ nvme_ns = grub_strstr (install_device, "nvme");
|
||||
+ nsid = of_path_get_nvme_nsid (nvme_ns);
|
||||
+ if (nsid == 0)
|
||||
+ return NULL;
|
||||
+
|
||||
+ sysfs_path = nvme_get_syspath (nvme_ns);
|
||||
+ ofpath = xasprintf ("%s",get_ofpathname (nvme_ns));
|
||||
+
|
||||
+ if (grub_strstr (ofpath, "fibre-channel"))
|
||||
+ {
|
||||
+ strcat (sysfs_path, "/device");
|
||||
+ is_FC = 1;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ strcat (sysfs_path, "/subsystem");
|
||||
+ is_FC = 0;
|
||||
+ }
|
||||
+ if (is_FC == 0)
|
||||
+ {
|
||||
+ cntl_id = grub_strstr (nvme_ns, "e");
|
||||
+ dirR1 = xasprintf ("nvme%c",cntl_id[1]);
|
||||
+
|
||||
+ splitter_info_path = xasprintf ("%s%s%s", "/sys/block/", nvme_ns, "/device");
|
||||
+ splitter_dp = opendir (splitter_info_path);
|
||||
+ if (!splitter_dp)
|
||||
+ return NULL;
|
||||
+
|
||||
+ while ((splitter_ep = readdir (splitter_dp)) != NULL)
|
||||
+ {
|
||||
+ if (grub_strstr (splitter_ep->d_name, "nvme"))
|
||||
+ {
|
||||
+ if (grub_strstr (splitter_ep->d_name, dirR1))
|
||||
+ continue;
|
||||
+
|
||||
+ ext_dir = grub_strstr (splitter_ep->d_name, "e");
|
||||
+ if (!(grub_strstr (ext_dir, "n")))
|
||||
+ {
|
||||
+ dirR2 = xasprintf("%s", splitter_ep->d_name);
|
||||
+ is_splitter = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ closedir (splitter_dp);
|
||||
+ }
|
||||
+ sysfs_path = xrealpath (sysfs_path);
|
||||
+ dp = opendir (sysfs_path);
|
||||
+ if (!dp)
|
||||
+ return NULL;
|
||||
+
|
||||
+ ptr = multipath_boot = xmalloc (BOOTDEV_BUFFER);
|
||||
+ if (is_splitter == 0 && is_FC == 0)
|
||||
+ {
|
||||
+ non_splitter_path = xasprintf ("%s%s%x:1 ", get_ofpathname (dirR1), "/namespace@", nsid);
|
||||
+ strncpy (ptr, non_splitter_path, strlen (non_splitter_path));
|
||||
+ ptr += strlen (non_splitter_path);
|
||||
+ free (non_splitter_path);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ while ((ep = readdir (dp)) != NULL)
|
||||
+ {
|
||||
+ char *path;
|
||||
+ if (grub_strstr (ep->d_name, "nvme"))
|
||||
+ {
|
||||
+ if (is_FC == 0 && !grub_strstr (ep->d_name, dirR1) && !grub_strstr (ep->d_name, dirR2))
|
||||
+ continue;
|
||||
+ path = xasprintf ("%s%s%x ", get_ofpathname (ep->d_name), "/namespace@", nsid);
|
||||
+ if ((strlen (multipath_boot) + strlen (path)) > BOOTDEV_BUFFER)
|
||||
+ {
|
||||
+ grub_util_warn (_("Maximum five entries are allowed in the bootlist"));
|
||||
+ free (path);
|
||||
+ break;
|
||||
+ }
|
||||
+ strncpy (ptr, path, strlen (path));
|
||||
+ ptr += strlen (path);
|
||||
+ free (path);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ *--ptr = '\0';
|
||||
+ closedir (dp);
|
||||
+
|
||||
+ return multipath_boot;
|
||||
+}
|
||||
+
|
||||
void
|
||||
grub_install_register_ieee1275 (int is_prep, const char *install_device,
|
||||
int partno, const char *relpath)
|
||||
@@ -242,8 +343,19 @@ grub_install_register_ieee1275 (int is_prep, const char *install_device,
|
||||
}
|
||||
*ptr = '\0';
|
||||
}
|
||||
+ else if (grub_strstr (install_device, "nvme"))
|
||||
+ {
|
||||
+ boot_device = add_multiple_nvme_bootdevices (install_device);
|
||||
+ }
|
||||
else
|
||||
- boot_device = get_ofpathname (install_device);
|
||||
+ {
|
||||
+ boot_device = get_ofpathname (install_device);
|
||||
+ if (grub_strstr (boot_device, "nvme-of"))
|
||||
+ {
|
||||
+ free (boot_device);
|
||||
+ boot_device = add_multiple_nvme_bootdevices (install_device);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device",
|
||||
boot_device, NULL }))
|
||||
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
|
||||
index 563cf68e94..2f220ed3aa 100644
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -223,6 +223,9 @@ grub_install_get_image_targets_string (void);
|
||||
const char *
|
||||
grub_util_get_target_dirname (const struct grub_install_image_target_desc *t);
|
||||
|
||||
+char *
|
||||
+add_multiple_nvme_bootdevices (const char *install_device);
|
||||
+
|
||||
void
|
||||
grub_install_create_envblk_file (const char *name);
|
||||
|
||||
diff --git a/include/grub/util/ofpath.h b/include/grub/util/ofpath.h
|
||||
index 7ab377c7cc..7e75866853 100644
|
||||
--- a/include/grub/util/ofpath.h
|
||||
+++ b/include/grub/util/ofpath.h
|
||||
@@ -30,5 +30,9 @@ int add_filename_to_pile (char *filename, struct ofpath_files_list_root* root);
|
||||
void find_file (char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth);
|
||||
char* of_find_fc_host (char* host_wwpn);
|
||||
void free_ofpath_files_list (struct ofpath_files_list_root* root);
|
||||
+char* nvme_get_syspath (const char *nvmedev);
|
||||
+char* block_device_get_sysfs_path_and_link (const char *devicenode);
|
||||
+char* xrealpath (const char *in);
|
||||
+unsigned int of_path_get_nvme_nsid (const char* devname);
|
||||
|
||||
#endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */
|
||||
--
|
||||
2.49.0
|
||||
|
@@ -1,122 +0,0 @@
|
||||
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
|
||||
|
@@ -1,66 +0,0 @@
|
||||
From 56b221476d31310de485af26550c8651618832bb Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 29 Oct 2024 11:54:28 +0800
|
||||
Subject: [PATCH] kern/main: Fix cmdpath in root directory
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The "cmdpath" environment variable is set at startup to the location
|
||||
from which the grub image is loaded. It includes a device part and,
|
||||
optionally, an absolute directory name if the grub image is booted as a
|
||||
file in a local file-system directory, or in a remote server directory,
|
||||
like TFTP.
|
||||
|
||||
This entire process relies on firmware to provide the correct device
|
||||
path of the booted image.
|
||||
|
||||
We encountered an issue when the image is booted from the root
|
||||
directory, where the absolute directory name "/" is discarded. This
|
||||
makes it unclear whether the root path was missing in the firmware
|
||||
provided device path or if it is simply the root directory. This
|
||||
ambiguity can cause confusion in custom scripts, potentially causing
|
||||
them to interpret firmware data incorrectly and trigger unintended
|
||||
fallback measures.
|
||||
|
||||
This patch fixes the problem by properly assigning the "fwpath" returned
|
||||
by "grub_machine_get_bootlocation()" to "cmdpath". The fix is based on
|
||||
the fact that fwpath is NULL if the firmware didn’t provide a path part
|
||||
or an NUL character, "", if it represents the root directory. With this,
|
||||
it becomes possible to clearly distinguish:
|
||||
|
||||
- cmdpath=(hd0,1) - Either the image is booted from the first (raw)
|
||||
partition, or the firmware failed to provide the path part.
|
||||
- cmdpath=(hd0,1)/ - The image is booted from the root directory in the
|
||||
first partition.
|
||||
|
||||
As a side note, the fix is similar to [1], but without the renaming
|
||||
part.
|
||||
|
||||
[1] https://mail.gnu.org/archive/html/grub-devel/2024-10/msg00155.html
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/kern/main.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
|
||||
index ef3b3756d..f9ab12c74 100644
|
||||
--- a/grub-core/kern/main.c
|
||||
+++ b/grub-core/kern/main.c
|
||||
@@ -136,7 +136,11 @@ grub_set_prefix_and_root (void)
|
||||
{
|
||||
char *cmdpath;
|
||||
|
||||
- cmdpath = grub_xasprintf ("(%s)%s", fwdevice, fwpath ? : "");
|
||||
+ if (fwpath && *fwpath == '\0')
|
||||
+ cmdpath = grub_xasprintf ("(%s)/", fwdevice);
|
||||
+ else
|
||||
+ cmdpath = grub_xasprintf ("(%s)%s", fwdevice, fwpath ? : "");
|
||||
+
|
||||
if (cmdpath)
|
||||
{
|
||||
grub_env_set ("cmdpath", cmdpath);
|
||||
--
|
||||
2.47.0
|
||||
|
@@ -1,33 +0,0 @@
|
||||
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
|
||||
|
@@ -1,7 +1,7 @@
|
||||
From 1bc53f8fc980914132040670b85a010e094559ec Mon Sep 17 00:00:00 2001
|
||||
From bf09618c47c6632b763960e265436294ab98dd43 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
|
||||
Subject: [PATCH 1/5] 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
|
||||
@@ -19,18 +19,17 @@ 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(+)
|
||||
grub-core/disk/key_protector.c | 78 ++++++++++++++++++++++++++++++++++
|
||||
include/grub/key_protector.h | 46 ++++++++++++++++++++
|
||||
4 files changed, 130 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
|
||||
index f18550c1c..9d3d5f519 100644
|
||||
--- a/grub-core/Makefile.am
|
||||
+++ b/grub-core/Makefile.am
|
||||
@@ -90,6 +90,7 @@ endif
|
||||
@@ -42,10 +41,10 @@ index 1eda467e0..e50db8106 100644
|
||||
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
|
||||
index bc893e547..4307b8e2d 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1282,6 +1282,11 @@ module = {
|
||||
@@ -1302,6 +1302,11 @@ module = {
|
||||
common = disk/raid6_recover.c;
|
||||
};
|
||||
|
||||
@@ -59,14 +58,13 @@ index a38955e18..37f131ae2 100644
|
||||
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
|
||||
index 000000000..b84afe1c7
|
||||
--- /dev/null
|
||||
+++ b/grub-core/disk/key_protector.c
|
||||
@@ -0,0 +1,73 @@
|
||||
@@ -0,0 +1,78 @@
|
||||
+/*
|
||||
+ * 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
|
||||
@@ -95,14 +93,16 @@ index 000000000..0d146c1c0
|
||||
+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 (protector == NULL || protector->name == NULL || grub_strlen (protector->name) == 0)
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+
|
||||
+ 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);
|
||||
+ if (grub_key_protectors &&
|
||||
+ grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors),
|
||||
+ protector->name))
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+
|
||||
+ grub_list_push (GRUB_AS_LIST_P (&grub_key_protectors), GRUB_AS_LIST (protector));
|
||||
+ grub_list_push (GRUB_AS_LIST_P (&grub_key_protectors),
|
||||
+ GRUB_AS_LIST (protector));
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
@@ -111,7 +111,7 @@ index 000000000..0d146c1c0
|
||||
+grub_key_protector_unregister (struct grub_key_protector *protector)
|
||||
+{
|
||||
+ if (protector == NULL)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid key protector for unregistration");
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+
|
||||
+ grub_list_remove (GRUB_AS_LIST (protector));
|
||||
+
|
||||
@@ -125,27 +125,30 @@ index 000000000..0d146c1c0
|
||||
+ struct grub_key_protector *kp = NULL;
|
||||
+
|
||||
+ if (grub_key_protectors == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "No key protector registered");
|
||||
+ return GRUB_ERR_OUT_OF_RANGE;
|
||||
+
|
||||
+ if (protector == NULL || protector[0] == '\0')
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid key protector");
|
||||
+ if (protector == NULL || grub_strlen (protector) == 0)
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+
|
||||
+ kp = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors), 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 grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
+ N_("A key protector with name '%s' could not be found. "
|
||||
+ "Is the name spelled correctly and is the "
|
||||
+ "corresponding module loaded?"), 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
|
||||
index 000000000..6e6a6fb24
|
||||
--- /dev/null
|
||||
+++ b/include/grub/key_protector.h
|
||||
@@ -0,0 +1,47 @@
|
||||
@@ -0,0 +1,46 @@
|
||||
+/*
|
||||
+ * 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
|
||||
@@ -190,5 +193,5 @@ index 000000000..00b15c13d
|
||||
+
|
||||
+#endif /* ! GRUB_PROTECTOR_HEADER */
|
||||
--
|
||||
2.43.0
|
||||
2.35.3
|
||||
|
||||
|
@@ -1,68 +0,0 @@
|
||||
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
|
||||
|
@@ -1,53 +0,0 @@
|
||||
From a5208417eecf9313239aa0659d4b015f2a3ba33e Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 29 May 2025 11:47:08 +0800
|
||||
Subject: [PATCH] mkconfig: Determine GRUB_DISTRIBUTOR from /etc/SUSE-brand
|
||||
|
||||
Starting with SLE 16, the $NAME field in /etc/os-release contains only
|
||||
the unified value "SLE". To provide a more specific OS label for GRUB
|
||||
menu entries, GRUB should instead use the value from /etc/SUSE-brand.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
util/grub-mkconfig.in | 18 +++++++++++++++++-
|
||||
1 file changed, 17 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
|
||||
index 31c4851aee..e11835ad69 100644
|
||||
--- a/util/grub-mkconfig.in
|
||||
+++ b/util/grub-mkconfig.in
|
||||
@@ -226,6 +226,17 @@ GRUB_ACTUAL_DEFAULT="$GRUB_DEFAULT"
|
||||
|
||||
if [ "x${GRUB_ACTUAL_DEFAULT}" = "xsaved" ] ; then GRUB_ACTUAL_DEFAULT="`"${grub_editenv}" - list | sed -n '/^saved_entry=/ s,^saved_entry=,,p'`" ; fi
|
||||
|
||||
+# Use /etc/SUSE-brand for os label (bsc#1239169)
|
||||
+grub_os_id () (
|
||||
+ VERSION=""
|
||||
+ GRUB_OS_ID=""
|
||||
+ # Source /etc/SUSE-brand only if it defines GRUB_OS_ID
|
||||
+ ! grep -q "^GRUB_OS_ID=" "${sysconfdir}/SUSE-brand" 2>/dev/null || source "${sysconfdir}/SUSE-brand"
|
||||
+ # Check VERSION is 16.0 or newer before applying for backward compatibility
|
||||
+ [ x"`echo -e "${VERSION}\n16.0" | sort -V | head -n1`" = x"16.0" ] || GRUB_OS_ID=""
|
||||
+ echo "$GRUB_OS_ID"
|
||||
+)
|
||||
+
|
||||
if [ x"${GRUB_DISTRIBUTOR}" = x ] ; then
|
||||
for i in "${sysconfdir}/os-release" "/usr/lib/os-release" ; do
|
||||
if [ -f "$i" ] ; then
|
||||
@@ -233,7 +244,12 @@ if [ x"${GRUB_DISTRIBUTOR}" = x ] ; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
- if [ x"${NAME}" != x ] && [ x"${VERSION}" != x ] ; then
|
||||
+
|
||||
+ OS_ID=`grub_os_id`
|
||||
+
|
||||
+ if [ x"${OS_ID}" != x ] ; then
|
||||
+ GRUB_DISTRIBUTOR="${OS_ID}"
|
||||
+ elif [ x"${NAME}" != x ] && [ x"${VERSION}" != x ] ; then
|
||||
GRUB_DISTRIBUTOR="${NAME} ${VERSION}"
|
||||
else
|
||||
GRUB_DISTRIBUTOR="${NAME}"
|
||||
--
|
||||
2.49.0
|
||||
|
@@ -1,171 +0,0 @@
|
||||
From 4b26a490def61786bfd5f66f0f68a33447dccb90 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 10 Feb 2025 18:20:28 +0800
|
||||
Subject: [PATCH] ofpath: Add error check in NVMEoF device translation
|
||||
|
||||
Signed-Off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 95 ++++++++++++++++++++++++----------
|
||||
1 file changed, 69 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
|
||||
index 66a256b18b..4b920ddc20 100644
|
||||
--- a/grub-core/osdep/linux/ofpath.c
|
||||
+++ b/grub-core/osdep/linux/ofpath.c
|
||||
@@ -536,52 +536,90 @@ of_path_get_nvmeof_adapter_info (char* sysfs_path,
|
||||
}
|
||||
|
||||
snprintf (buf, 512, "%s/subsysnqn", sysfs_path);
|
||||
- fp = fopen (buf, "r");
|
||||
- fscanf (fp, "%s", nvmeof_info->nqn);
|
||||
+ if (! (fp = fopen (buf, "r")) ||
|
||||
+ fscanf (fp, "%s", nvmeof_info->nqn) != 1)
|
||||
+ {
|
||||
+ if (fp)
|
||||
+ fclose (fp);
|
||||
+ free (nvmeof_info->host_wwpn);
|
||||
+ free (nvmeof_info->target_wwpn);
|
||||
+ free (nvmeof_info->nqn);
|
||||
+ free (buf);
|
||||
+ return -1;
|
||||
+ }
|
||||
fclose (fp);
|
||||
|
||||
snprintf (buf, 512, "%s/cntlid", sysfs_path);
|
||||
- fp = fopen (buf, "r");
|
||||
- fscanf (fp, "%u", &(nvmeof_info->cntlid));
|
||||
+ if (! (fp = fopen (buf, "r")) ||
|
||||
+ fscanf (fp, "%u", &(nvmeof_info->cntlid)) != 1)
|
||||
+ {
|
||||
+ if (fp)
|
||||
+ fclose (fp);
|
||||
+ free (nvmeof_info->host_wwpn);
|
||||
+ free (nvmeof_info->target_wwpn);
|
||||
+ free (nvmeof_info->nqn);
|
||||
+ free (buf);
|
||||
+ return -1;
|
||||
+ }
|
||||
fclose (fp);
|
||||
|
||||
snprintf (buf, 512, "%s/address", sysfs_path);
|
||||
- fp = fopen (buf, "r");
|
||||
- buf2 = malloc (sizeof (char) * 512);
|
||||
-
|
||||
- if (!buf2)
|
||||
+ buf2 = NULL;
|
||||
+ fp = NULL;
|
||||
+ if (! (buf2 = malloc (sizeof (char) * 512)) ||
|
||||
+ ! (fp = fopen (buf, "r")) ||
|
||||
+ fscanf (fp, "%s", buf2) != 1)
|
||||
{
|
||||
+ if (fp)
|
||||
+ fclose (fp);
|
||||
free (nvmeof_info->host_wwpn);
|
||||
free (nvmeof_info->target_wwpn);
|
||||
free (nvmeof_info->nqn);
|
||||
free (buf);
|
||||
+ free (buf2);
|
||||
return -1;
|
||||
}
|
||||
-
|
||||
- fscanf (fp, "%s", buf2);
|
||||
fclose (fp);
|
||||
|
||||
- buf3 = strrchr (buf2, '-') + 1;
|
||||
- grub_memcpy (nvmeof_info->host_wwpn, buf3, 256);
|
||||
- buf3=strchr (buf2, '-') + 1;
|
||||
- buf3=strchr (buf3, '-') + 1;
|
||||
- buf3=strchr (buf3, 'x') + 1;
|
||||
- grub_memcpy (nvmeof_info->target_wwpn, buf3, 256);
|
||||
+ if (! (buf3 = strrchr (buf2, '-')))
|
||||
+ {
|
||||
+ free (nvmeof_info->host_wwpn);
|
||||
+ free (nvmeof_info->target_wwpn);
|
||||
+ free (nvmeof_info->nqn);
|
||||
+ free (buf);
|
||||
+ free (buf2);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ grub_memcpy (nvmeof_info->host_wwpn, buf3 + 1, 256);
|
||||
+ if (! (buf3 = strchr (buf2, '-')) ||
|
||||
+ ! (buf3 = strchr (buf3 + 1, '-')) ||
|
||||
+ ! (buf3 = strchr (buf3 + 1, 'x')))
|
||||
+ {
|
||||
+ free (nvmeof_info->host_wwpn);
|
||||
+ free (nvmeof_info->target_wwpn);
|
||||
+ free (nvmeof_info->nqn);
|
||||
+ free (buf);
|
||||
+ free (buf2);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ grub_memcpy (nvmeof_info->target_wwpn, buf3 + 1, 256);
|
||||
buf3 = strchr (nvmeof_info->target_wwpn, ',');
|
||||
- *buf3 = '\0';
|
||||
+ if (buf3)
|
||||
+ *buf3 = '\0';
|
||||
free (buf);
|
||||
free (buf2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
-#define MAX_NVME_NSID_DIGITS 6
|
||||
+#define OFPATH_MAX_UINT_HEX_DIGITS 8
|
||||
+#define OFPATH_MAX_INT_DIGITS 10
|
||||
|
||||
static char *
|
||||
of_path_get_nvme_controller_name_node (const char* devname)
|
||||
{
|
||||
char *controller_node, *end;
|
||||
|
||||
- controller_node = strdup (devname);
|
||||
+ controller_node = xstrdup (devname);
|
||||
end = grub_strchr (controller_node + 1, 'n');
|
||||
if (end != NULL)
|
||||
{
|
||||
@@ -616,15 +654,20 @@ of_path_get_nvme_nsid (const char* devname)
|
||||
char *
|
||||
nvme_get_syspath (const char *nvmedev)
|
||||
{
|
||||
- char *sysfs_path, *controller_node;
|
||||
+ char *sysfs_path;
|
||||
|
||||
sysfs_path = block_device_get_sysfs_path_and_link (nvmedev);
|
||||
if (strstr (sysfs_path, "nvme-subsystem"))
|
||||
{
|
||||
- controller_node = of_path_get_nvme_controller_name_node (nvmedev);
|
||||
- strcat (sysfs_path, "/");
|
||||
- strcat (sysfs_path, controller_node);
|
||||
- sysfs_path = xrealpath (sysfs_path);
|
||||
+ char *controller_node = of_path_get_nvme_controller_name_node (nvmedev);
|
||||
+ char *buf = xmalloc (strlen (sysfs_path) + strlen ("/") + strlen (controller_node) + 1);
|
||||
+ strcpy (buf, sysfs_path);
|
||||
+ strcat (buf, "/");
|
||||
+ strcat (buf, controller_node);
|
||||
+ free (sysfs_path);
|
||||
+ free (controller_node);
|
||||
+ sysfs_path = xrealpath (buf);
|
||||
+ free (buf);
|
||||
}
|
||||
|
||||
return sysfs_path;
|
||||
@@ -693,7 +736,7 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
unsigned int nsid = of_path_get_nvme_nsid (nvmedev);
|
||||
if (nsid)
|
||||
{
|
||||
- snprintf (disk+chars_written, sizeof("/namespace@") + MAX_NVME_NSID_DIGITS,
|
||||
+ snprintf (disk+chars_written, sizeof("/namespace@") + OFPATH_MAX_UINT_HEX_DIGITS + OFPATH_MAX_INT_DIGITS,
|
||||
"/namespace@%x:%d", nsid, part);
|
||||
}
|
||||
free (nvmeof_info);
|
||||
@@ -734,7 +777,7 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
unsigned int nsid = of_path_get_nvme_nsid (device);
|
||||
if (nsid)
|
||||
{
|
||||
- snprintf (disk+chars_written,sizeof("/namespace@") + sizeof(char) * MAX_NVME_NSID_DIGITS,
|
||||
+ snprintf (disk+chars_written,sizeof("/namespace@") + sizeof(char) * OFPATH_MAX_UINT_HEX_DIGITS,
|
||||
"/namespace@%x", nsid);
|
||||
}
|
||||
free (nvmeof_info);
|
||||
--
|
||||
2.48.1
|
||||
|
@@ -1,102 +0,0 @@
|
||||
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
|
||||
|
@@ -1,61 +0,0 @@
|
||||
From e2ffbaf62f0a97caa1e4214be7ee71db0a49ad6c Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Tue, 14 Jan 2025 14:28:35 +0800
|
||||
Subject: [PATCH] prep_loadenv: Measure the environment block into PCR 9
|
||||
|
||||
Since the firmware is not aware of the environment block in the PReP
|
||||
partition, the measurement of PCR 4 does not include that block. To
|
||||
close the gap, prep_loadenv now measures the block into PCR 9.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
grub-core/commands/prep_loadenv.c | 19 +++++++++++++++++++
|
||||
1 file changed, 19 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/prep_loadenv.c b/grub-core/commands/prep_loadenv.c
|
||||
index 109b7ca5a..5b8ade8db 100644
|
||||
--- a/grub-core/commands/prep_loadenv.c
|
||||
+++ b/grub-core/commands/prep_loadenv.c
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/gpt_partition.h>
|
||||
#include <regex.h>
|
||||
+#include <grub/tpm.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -122,6 +123,7 @@ prep_read_envblk (const char *devname)
|
||||
char *buf = NULL;
|
||||
grub_device_t dev = NULL;
|
||||
grub_envblk_t envblk = NULL;
|
||||
+ grub_err_t err;
|
||||
|
||||
dev = grub_device_open (devname);
|
||||
if (!dev)
|
||||
@@ -140,6 +142,23 @@ prep_read_envblk (const char *devname)
|
||||
if (grub_disk_read (dev->disk, dev->disk->partition->len - (GRUB_ENVBLK_PREP_SIZE >> GRUB_DISK_SECTOR_BITS), 0, GRUB_ENVBLK_PREP_SIZE, buf))
|
||||
goto fail;
|
||||
|
||||
+ /*
|
||||
+ * Measure the environment block in the PReP partition
|
||||
+ * The firmware is not aware of this block, so the content of the environment
|
||||
+ * block is not measured into PCR 4.
|
||||
+ */
|
||||
+ if (grub_tpm_present () == true)
|
||||
+ {
|
||||
+ err = grub_tpm_measure ((unsigned char*)buf, GRUB_ENVBLK_PREP_SIZE, GRUB_BINARY_PCR, "PReP envblk");
|
||||
+ if (err != GRUB_ERR_NONE && grub_is_tpm_fail_fatal () == true)
|
||||
+ {
|
||||
+ grub_errno = err;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ else
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ }
|
||||
+
|
||||
envblk = grub_envblk_open (buf, GRUB_ENVBLK_PREP_SIZE);
|
||||
if (!envblk)
|
||||
{
|
||||
--
|
||||
2.43.0
|
||||
|
@@ -1,71 +0,0 @@
|
||||
From c6f690a50ab75edf06cd2a8d2100e9312a86decc Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Wed, 26 Feb 2025 16:35:14 +0800
|
||||
Subject: [PATCH] s390x-emu: Pass through PAES cipher as AES
|
||||
|
||||
Protected AES (PAES) enhances AES encryption with hardware key
|
||||
protection exclusively on IBM Z's s390x architecture.
|
||||
|
||||
This patch addresses issues in GRUB utilities that cannot handle
|
||||
PAES-encrypted volumes due to a lack of native cipher support. The
|
||||
solution works because, on s390x, grub-emu is used to boot the target
|
||||
via kexec. As a Linux userspace program, grub-emu leverages kernel
|
||||
support and bypasses the limitations of GRUB's built-in functionality.
|
||||
|
||||
We can pass through PAES as AES on Linux platforms since the underlying
|
||||
cipher appears as plain AES from a userland application's perspective.
|
||||
Additionally, GRUB's linux applications perform "cheat mount" that
|
||||
doesn't attempt to open the LUKS container. Instead, they initialize the
|
||||
cryptodisk structure using attributes from the LUKS header to obtain
|
||||
necessary information like crypto-uuid.
|
||||
|
||||
Furthermore, root probing for Btrfs can be skipped to avoid issues with
|
||||
unsupported devices, as grub-emu doesn't rely on GRUB's own
|
||||
configurations for booting Btrfs. Instead, it operates entirely from a
|
||||
Dracut initramfs.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/osdep/devmapper/getroot.c | 5 +++++
|
||||
util/grub-install.c | 6 ++++--
|
||||
2 files changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/grub-core/osdep/devmapper/getroot.c b/grub-core/osdep/devmapper/getroot.c
|
||||
index 3b37336bc9..344df9a589 100644
|
||||
--- a/grub-core/osdep/devmapper/getroot.c
|
||||
+++ b/grub-core/osdep/devmapper/getroot.c
|
||||
@@ -266,6 +266,11 @@ grub_util_pull_devmapper (const char *os_dev)
|
||||
remaining -= seek_head - c + 1;
|
||||
c = seek_head + 1;
|
||||
|
||||
+#if defined (__s390x__)
|
||||
+ if (grub_strcasecmp (cipher, "paes") == 0)
|
||||
+ grub_strcpy(cipher, "aes");
|
||||
+#endif
|
||||
+
|
||||
/* Now, the cipher mode. */
|
||||
seek_head = grub_memchr (c, ' ', remaining);
|
||||
if (seek_head == NULL)
|
||||
diff --git a/util/grub-install.c b/util/grub-install.c
|
||||
index a187a9c63c..0ab0cf8fe7 100644
|
||||
--- a/util/grub-install.c
|
||||
+++ b/util/grub-install.c
|
||||
@@ -1108,11 +1108,13 @@ main (int argc, char *argv[])
|
||||
char *t = grub_util_path_concat (2, "/", rootdir);
|
||||
|
||||
#ifdef __linux__
|
||||
- if (!grub_can_guess_from_mountinfo (t))
|
||||
+ if (!grub_can_guess_from_mountinfo (t) || platform == GRUB_INSTALL_PLATFORM_S390X_EMU)
|
||||
{
|
||||
free(t);
|
||||
/* We can safely ignore the root probe here; whichever cannot be
|
||||
- * reliably detected is irrelevant and of no interest */
|
||||
+ * reliably detected is irrelevant and of no interest.
|
||||
+ * Also the s390x-emu, this btrfs root detection can be omitted given
|
||||
+ * it is not relevant to the capability of linux host system */
|
||||
goto skip_root_probe;
|
||||
}
|
||||
#endif
|
||||
--
|
||||
2.48.1
|
||||
|
@@ -0,0 +1,60 @@
|
||||
From 72a582b1c3954f9b917a4d687c95fc94faf551c6 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Wed, 24 Jan 2024 18:03:51 +0800
|
||||
Subject: [PATCH] squash! ieee1275/ofpath: enable NVMeoF logical device
|
||||
translation
|
||||
|
||||
Fixes build error on gcc-14:
|
||||
|
||||
[ 73s] In file included from ../grub-core/osdep/ofpath.c:2:
|
||||
[ 73s] ../grub-core/osdep/linux/ofpath.c: In function 'of_find_fc_host':
|
||||
[ 73s] ../grub-core/osdep/linux/ofpath.c:427:22: error: allocation of insufficient size '8' for type 'struct ofpath_files_list_root' with size '16' [-Werror=alloc-size]
|
||||
[ 73s] 427 | portnames_file_list=malloc(sizeof(portnames_file_list));
|
||||
[ 73s] | ^
|
||||
[ 73s] ../grub-core/osdep/linux/ofpath.c: In function 'of_path_of_nvme':
|
||||
[ 73s] ../grub-core/osdep/linux/ofpath.c:589:21: error: allocation of insufficient size '8' for type 'struct ofpath_nvmeof_info' with size '32' [-Werror=alloc-size]
|
||||
[ 73s] 589 | nvmeof_info = malloc(sizeof(nvmeof_info));
|
||||
[ 73s] | ^
|
||||
[ 73s] ../grub-core/osdep/linux/ofpath.c:618:21: error: allocation of insufficient size '8' for type 'struct ofpath_nvmeof_info' with size '32' [-Werror=alloc-size]
|
||||
[ 73s] 618 | nvmeof_info = malloc(sizeof(nvmeof_info));
|
||||
[ 73s] | ^
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
|
||||
index 7129099db..55ed7ddf2 100644
|
||||
--- a/grub-core/osdep/linux/ofpath.c
|
||||
+++ b/grub-core/osdep/linux/ofpath.c
|
||||
@@ -424,7 +424,7 @@ of_find_fc_host(char* host_wwpn){
|
||||
|
||||
struct ofpath_files_list_root* portnames_file_list;
|
||||
|
||||
- portnames_file_list=malloc(sizeof(portnames_file_list));
|
||||
+ portnames_file_list=malloc(sizeof(*portnames_file_list));
|
||||
portnames_file_list->items=0;
|
||||
portnames_file_list->first=NULL;
|
||||
|
||||
@@ -586,7 +586,7 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
/* If is a NVMeoF */
|
||||
if(strstr(sysfs_path,"nvme-fabrics")){
|
||||
struct ofpath_nvmeof_info* nvmeof_info;
|
||||
- nvmeof_info = malloc(sizeof(nvmeof_info));
|
||||
+ nvmeof_info = malloc(sizeof(*nvmeof_info));
|
||||
|
||||
of_path_get_nvmeof_adapter_info(sysfs_path, nvmeof_info);
|
||||
|
||||
@@ -615,7 +615,7 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
sysfs_path = nvme_get_syspath (device);
|
||||
if(strstr(sysfs_path,"nvme-fabrics")){
|
||||
struct ofpath_nvmeof_info* nvmeof_info;
|
||||
- nvmeof_info = malloc(sizeof(nvmeof_info));
|
||||
+ nvmeof_info = malloc(sizeof(*nvmeof_info));
|
||||
|
||||
of_path_get_nvmeof_adapter_info(sysfs_path, nvmeof_info);
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@@ -1,67 +0,0 @@
|
||||
From 0a8f0e75151067a8b7c09a6ffdfa9558aa040d3b Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 14 Jul 2025 17:59:20 +0800
|
||||
Subject: [PATCH 1/4] test: Fix -f test on files over network
|
||||
|
||||
The "test -f ..." aka "if [ -f ... ]; " does not work for files over
|
||||
network in both TFTP and HTTP and always evaluates to false.
|
||||
|
||||
It is caused by network protocols like TFTP and HTTP are designed for
|
||||
transferring files and not a file system over network. In that way they
|
||||
do not have a way to list files in a directory and test their properties
|
||||
individually. The current logic in grub assumes that directory and file
|
||||
listing must be implemented, which applies to local file systems but not
|
||||
to file reading over the network. This logic should be adjusted to test
|
||||
network files.
|
||||
|
||||
This patch updates the logic to detect when the underlying device is a
|
||||
network device. If so, it attempts to test the file using
|
||||
grub_file_open. If the file opens successfully, the ctx->file_exists
|
||||
flag is set accordingly to true. Other properties that cannot be
|
||||
determined over the network, such as whether the file is a directory or
|
||||
whether the modification time is set, are conservatively set to false.
|
||||
|
||||
This means that -d cannot reliably detect directories on network
|
||||
devices, and -e may not work as expected if the target is a directory.
|
||||
In addition, comparisons such as -nt and -ot will not function
|
||||
correctly, since file timestamps are not available. Despite these
|
||||
limitations, this patch ensures that the -f test behaves correctly in
|
||||
the most common case: checking whether a "file" exists on a network
|
||||
device.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/test.c | 17 +++++++++++++++++
|
||||
1 file changed, 17 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/test.c b/grub-core/commands/test.c
|
||||
index 62d3fb398..541f36daf 100644
|
||||
--- a/grub-core/commands/test.c
|
||||
+++ b/grub-core/commands/test.c
|
||||
@@ -91,6 +91,23 @@ get_fileinfo (char *path, struct test_parse_ctx *ctx)
|
||||
return;
|
||||
}
|
||||
|
||||
+ if (! dev->disk && dev->net)
|
||||
+ {
|
||||
+ grub_file_t file;
|
||||
+
|
||||
+ file = grub_file_open (path , GRUB_FILE_TYPE_GET_SIZE
|
||||
+ | GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
+ ctx->file_exists = file ? 1 : 0;
|
||||
+ ctx->file_info.dir = 0;
|
||||
+ ctx->file_info.mtimeset = 0;
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ if (file)
|
||||
+ grub_file_close (file);
|
||||
+ grub_free (device_name);
|
||||
+ grub_device_close (dev);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
fs = grub_fs_probe (dev);
|
||||
if (! fs)
|
||||
{
|
||||
--
|
||||
2.50.0
|
||||
|
@@ -1,44 +0,0 @@
|
||||
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
|
||||
|
@@ -1,4 +1,4 @@
|
||||
From 53c3dc557890466757090ee390a2c5d241e50483 Mon Sep 17 00:00:00 2001
|
||||
From f41a45b080cb9c6f59879a3e23f9ec2380015a16 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Thu, 25 Apr 2024 16:21:45 +0800
|
||||
Subject: [PATCH] tpm2: Add extra RSA SRK types
|
||||
@@ -6,42 +6,41 @@ Subject: [PATCH] tpm2: Add extra RSA SRK types
|
||||
Since fde-tools may set RSA3072 and RSA4096 as the SRK type, grub2 has
|
||||
to support those parameters.
|
||||
|
||||
Also prevent RSA SRK type from being overwritten when 'rsaparent' is set
|
||||
in the key file.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
grub-core/commands/tpm2_key_protector/args.c | 10 ++++++++++
|
||||
grub-core/commands/tpm2_key_protector/module.c | 18 +++++++++++++++---
|
||||
util/grub-protect.c | 4 ++--
|
||||
3 files changed, 27 insertions(+), 5 deletions(-)
|
||||
grub-core/tpm2/args.c | 12 ++++++++++++
|
||||
grub-core/tpm2/module.c | 16 ++++++++++++++--
|
||||
util/grub-protect.c | 4 ++--
|
||||
3 files changed, 28 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/tpm2_key_protector/args.c b/grub-core/commands/tpm2_key_protector/args.c
|
||||
index 48c39de01..5781a31f1 100644
|
||||
--- a/grub-core/commands/tpm2_key_protector/args.c
|
||||
+++ b/grub-core/commands/tpm2_key_protector/args.c
|
||||
@@ -85,6 +85,16 @@ grub_tpm2_protector_parse_asymmetric (const char *value,
|
||||
diff --git a/grub-core/tpm2/args.c b/grub-core/tpm2/args.c
|
||||
index c11280ab9..d140364d2 100644
|
||||
--- a/grub-core/tpm2/args.c
|
||||
+++ b/grub-core/tpm2/args.c
|
||||
@@ -92,6 +92,18 @@ grub_tpm2_protector_parse_asymmetric (const char *value,
|
||||
srk_type->type = TPM_ALG_RSA;
|
||||
srk_type->detail.rsa_bits = 2048;
|
||||
}
|
||||
+ else if (grub_strcasecmp (value, "RSA3072") == 0)
|
||||
+ else if (grub_strcasecmp (value, "RSA") == 0 ||
|
||||
+ grub_strcasecmp (value, "RSA3072") == 0)
|
||||
+ {
|
||||
+ srk_type->type = TPM_ALG_RSA;
|
||||
+ srk_type->detail.rsa_bits = 3072;
|
||||
+ }
|
||||
+ else if (grub_strcasecmp (value, "RSA4096") == 0)
|
||||
+ else if (grub_strcasecmp (value, "RSA") == 0 ||
|
||||
+ grub_strcasecmp (value, "RSA4096") == 0)
|
||||
+ {
|
||||
+ srk_type->type = TPM_ALG_RSA;
|
||||
+ srk_type->detail.rsa_bits = 4096;
|
||||
+ }
|
||||
else
|
||||
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("value '%s' is not a valid asymmetric key type"), value);
|
||||
|
||||
diff --git a/grub-core/commands/tpm2_key_protector/module.c b/grub-core/commands/tpm2_key_protector/module.c
|
||||
index 74e79a545..1b2eb6b20 100644
|
||||
--- a/grub-core/commands/tpm2_key_protector/module.c
|
||||
+++ b/grub-core/commands/tpm2_key_protector/module.c
|
||||
@@ -138,8 +138,8 @@ static const struct grub_arg_option tpm2_protector_init_cmd_options[] =
|
||||
return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
N_("Value '%s' is not a valid asymmetric key type"),
|
||||
diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c
|
||||
index b754b38df..8b72ed6fa 100644
|
||||
--- a/grub-core/tpm2/module.c
|
||||
+++ b/grub-core/tpm2/module.c
|
||||
@@ -136,8 +136,8 @@ static const struct grub_arg_option grub_tpm2_protector_init_cmd_options[] =
|
||||
.arg = NULL,
|
||||
.type = ARG_TYPE_STRING,
|
||||
.doc =
|
||||
@@ -52,18 +51,18 @@ index 74e79a545..1b2eb6b20 100644
|
||||
},
|
||||
/* NV Index-mode options */
|
||||
{
|
||||
@@ -517,6 +517,10 @@ srk_type_to_name (grub_srk_type_t srk_type)
|
||||
return "ECC_NIST_P256";
|
||||
else if (srk_type.type == TPM_ALG_RSA && srk_type.detail.rsa_bits == 2048)
|
||||
return "RSA2048";
|
||||
+ else if (srk_type.type == TPM_ALG_RSA && srk_type.detail.rsa_bits == 3072)
|
||||
+ return "RSA3072";
|
||||
+ else if (srk_type.type == TPM_ALG_RSA && srk_type.detail.rsa_bits == 4096)
|
||||
+ return "RSA4096";
|
||||
@@ -541,6 +541,10 @@ srk_type_to_name (grub_srk_type_t srk_type)
|
||||
{
|
||||
case 2048:
|
||||
return "RSA2048";
|
||||
+ case 3072:
|
||||
+ return "RSA3072";
|
||||
+ case 4096:
|
||||
+ return "RSA4096";
|
||||
}
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
@@ -535,6 +539,14 @@ tpm2_protector_load_key (const tpm2_protector_context_t *ctx,
|
||||
@@ -561,6 +565,14 @@ grub_tpm2_protector_load_key (const struct grub_tpm2_protector_context *ctx,
|
||||
.type = TPM_ALG_ECC,
|
||||
.detail.ecc_curve = TPM_ECC_NIST_P256,
|
||||
},
|
||||
@@ -78,30 +77,21 @@ index 74e79a545..1b2eb6b20 100644
|
||||
{
|
||||
.type = TPM_ALG_RSA,
|
||||
.detail.rsa_bits = 2048,
|
||||
@@ -882,7 +894,7 @@ tpm2_protector_srk_recover (const tpm2_protector_context_t *ctx,
|
||||
if (err != GRUB_ERR_NONE)
|
||||
goto exit1;
|
||||
|
||||
- if (rsaparent == 1)
|
||||
+ if (rsaparent == 1 && ctx->srk_type.type != TPM_ALG_RSA)
|
||||
{
|
||||
tpm2_protector_context_t *ctx_w;
|
||||
|
||||
diff --git a/util/grub-protect.c b/util/grub-protect.c
|
||||
index 5b7e952f4..f1108f2c5 100644
|
||||
index 869f45861..00be03ca0 100644
|
||||
--- a/util/grub-protect.c
|
||||
+++ b/util/grub-protect.c
|
||||
@@ -202,8 +202,8 @@ static struct argp_option protect_options[] =
|
||||
@@ -199,8 +199,8 @@ static struct argp_option grub_protect_options[] =
|
||||
.arg = "TYPE",
|
||||
.flags = 0,
|
||||
.doc =
|
||||
- N_("Set the type of SRK: RSA (RSA2048) and ECC (ECC_NIST_P256)."
|
||||
- N_("The type of SRK: RSA (RSA2048) and ECC (ECC_NIST_P256)."
|
||||
- "(default: ECC)"),
|
||||
+ N_("Set the type of SRK: RSA (RSA2048), RSA3072, RSA4096, "
|
||||
+ N_("The type of SRK: RSA (RSA2048), RSA3072, RSA4096, "
|
||||
+ "and ECC (ECC_NIST_P256). (default: ECC)"),
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
--
|
||||
2.43.0
|
||||
2.35.3
|
||||
|
||||
|
@@ -1,12 +1,12 @@
|
||||
From 53e24662523d033ae3506b73787b972ef332db36 Mon Sep 17 00:00:00 2001
|
||||
From 947009d79e3f17b10a7753bdde8d3a4a7b757bed 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
|
||||
Subject: [PATCH 1/4] tpm2: 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
|
||||
Note: This only extends support on the unseal path. grub2_protect
|
||||
has not been updated. tpm2-tools can be used to insert a key into
|
||||
the NV index.
|
||||
|
||||
@@ -36,40 +36,41 @@ Then to unseal the key in grub, add this to grub.cfg:
|
||||
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(-)
|
||||
grub-core/tpm2/module.c | 25 ++++++++++++++++++++-----
|
||||
1 file changed, 20 insertions(+), 5 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)
|
||||
diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c
|
||||
index e83b02865..b754b38df 100644
|
||||
--- a/grub-core/tpm2/module.c
|
||||
+++ b/grub-core/tpm2/module.c
|
||||
@@ -1035,12 +1035,27 @@ static grub_err_t
|
||||
grub_tpm2_protector_nv_recover (const struct grub_tpm2_protector_context *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;
|
||||
- (void)ctx;
|
||||
- (void)key;
|
||||
- (void)key_size;
|
||||
+ TPM_HANDLE 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);
|
||||
+ err = grub_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);
|
||||
+ err = grub_tpm2_protector_unseal (policy_seq, sealed_handle, key, key_size);
|
||||
+
|
||||
+ exit:
|
||||
+ grub_tpm2_flushcontext (sealed_handle);
|
||||
+ /* Pop error messages on success */
|
||||
+ if (err == GRUB_ERR_NONE)
|
||||
+ while (grub_error_pop ());
|
||||
+
|
||||
+exit:
|
||||
+ TPM2_FlushContext (sealed_handle);
|
||||
|
||||
- return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
- N_("NV Index mode is not implemented yet"));
|
||||
+ grub_tpm2key_free_policy_seq (policy_seq);
|
||||
+
|
||||
+ return err;
|
||||
@@ -77,5 +78,5 @@ index 6b4b5d460..74e79a545 100644
|
||||
|
||||
static grub_err_t
|
||||
--
|
||||
2.43.0
|
||||
2.35.3
|
||||
|
171
0001-tpm2-Support-authorized-policy.patch
Normal file
171
0001-tpm2-Support-authorized-policy.patch
Normal file
@@ -0,0 +1,171 @@
|
||||
From 26a66098d5fa50b9462c8c815429a4c18f20310b 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: 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 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)/boot/grub2/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>
|
||||
---
|
||||
grub-core/tpm2/module.c | 84 +++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 84 insertions(+)
|
||||
|
||||
diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c
|
||||
index 3db25ceca..e83b02865 100644
|
||||
--- a/grub-core/tpm2/module.c
|
||||
+++ b/grub-core/tpm2/module.c
|
||||
@@ -650,6 +650,87 @@ grub_tpm2_protector_policypcr (TPMI_SH_AUTH_SESSION session,
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+grub_tpm2_protector_policyauthorize (TPMI_SH_AUTH_SESSION session,
|
||||
+ struct grub_tpm2_buffer *cmd_buf)
|
||||
+{
|
||||
+ TPM2B_PUBLIC pubkey;
|
||||
+ TPM2B_DIGEST policy_ref;
|
||||
+ TPMT_SIGNATURE signature;
|
||||
+ TPM2B_DIGEST pcr_policy;
|
||||
+ TPM2B_DIGEST pcr_policy_hash;
|
||||
+ TPMI_ALG_HASH sig_hash;
|
||||
+ TPMT_TK_VERIFIED verification_ticket;
|
||||
+ TPM_HANDLE pubkey_handle = 0;
|
||||
+ TPM2B_NAME pubname;
|
||||
+ TPM_RC rc;
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (cmd_buf, &pubkey);
|
||||
+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (cmd_buf, &policy_ref);
|
||||
+ grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal (cmd_buf, &signature);
|
||||
+ if (cmd_buf->error != 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("Failed to unmarshal the buffer for TPM2_PolicyAuthorize"));
|
||||
+
|
||||
+ /* Retrieve Policy Digest */
|
||||
+ rc = TPM2_PolicyGetDigest (session, NULL, &pcr_policy, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
+ N_("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,
|
||||
+ N_("Failed to get the hash algorithm of the signature"));
|
||||
+
|
||||
+ rc = TPM2_Hash (NULL, (TPM2B_MAX_BUFFER *)&pcr_policy, sig_hash,
|
||||
+ TPM_RH_NULL, &pcr_policy_hash, NULL, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
+ N_("Failed to create PCR policy hash (TPM2_Hash: 0x%x)"),
|
||||
+ rc);
|
||||
+
|
||||
+ /* Load the public key */
|
||||
+ rc = TPM2_LoadExternal (NULL, NULL, &pubkey, TPM_RH_OWNER,
|
||||
+ &pubkey_handle, &pubname, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
+ N_("Failed to load public key (TPM2_LoadExternal: 0x%x)"),
|
||||
+ rc);
|
||||
+
|
||||
+ /* Verify the signature against the public key and the policy digest */
|
||||
+ rc = TPM2_VerifySignature (pubkey_handle, NULL, &pcr_policy_hash, &signature,
|
||||
+ &verification_ticket, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ err = grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
+ N_("Failed to verify signature (TPM2_VerifySignature: 0x%x)"),
|
||||
+ rc);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ /* Authorize the signed policy with the public key and the verification ticket */
|
||||
+ rc = TPM2_PolicyAuthorize (session, NULL, &pcr_policy, &policy_ref, &pubname,
|
||||
+ &verification_ticket, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ err = grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
+ N_("Failed to authorize PCR policy (TPM2_PolicyAuthorize: 0x%x)"),
|
||||
+ rc);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ err = GRUB_ERR_NONE;
|
||||
+
|
||||
+error:
|
||||
+ TPM2_FlushContext (pubkey_handle);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSION session)
|
||||
{
|
||||
@@ -669,6 +750,9 @@ grub_tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSIO
|
||||
case TPM_CC_PolicyPCR:
|
||||
err = grub_tpm2_protector_policypcr (session, &buf);
|
||||
break;
|
||||
+ case TPM_CC_PolicyAuthorize:
|
||||
+ err = grub_tpm2_protector_policyauthorize (session, &buf);
|
||||
+ break;
|
||||
default:
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
N_("Unknown TPM Command: 0x%x"), policy->cmd_code);
|
||||
--
|
||||
2.35.3
|
||||
|
@@ -1,241 +0,0 @@
|
||||
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 */
|
@@ -1,253 +0,0 @@
|
||||
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
|
||||
|
@@ -1,158 +0,0 @@
|
||||
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
|
||||
|
@@ -1,101 +0,0 @@
|
||||
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
|
||||
|
411
0002-Add-BLS-support-to-grub-mkconfig.patch
Normal file
411
0002-Add-BLS-support-to-grub-mkconfig.patch
Normal file
@@ -0,0 +1,411 @@
|
||||
From 439de947262b0d8d4a02ca5afb1ef4f15853962c Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Fri, 9 Dec 2016 15:40:29 -0500
|
||||
Subject: [PATCH 2/9] Add BLS support to grub-mkconfig
|
||||
|
||||
GRUB now has BootLoaderSpec support, the user can choose to use this by
|
||||
setting GRUB_ENABLE_BLSCFG to true in /etc/default/grub. On this setup,
|
||||
the boot menu entries are not added to the grub.cfg, instead BLS config
|
||||
files are parsed by blscfg command and the entries created dynamically.
|
||||
|
||||
A 10_linux_bls grub.d snippet to generate menu entries from BLS files
|
||||
is also added that can be used on platforms where the bootloader doesn't
|
||||
have BLS support and only can parse a normal grub configuration file.
|
||||
|
||||
Portions of the 10_linux_bls were taken from the ostree-grub-generator
|
||||
script that's included in the OSTree project.
|
||||
|
||||
Fixes to support multi-devices and generate a BLS section even if no
|
||||
kernels are found in the boot directory were proposed by Yclept Nemo
|
||||
and Tom Gundersen respectively.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
[javierm: remove outdated URL for BLS document]
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
[iwienand@redhat.com: skip machine ID check when updating entries]
|
||||
Signed-off-by: Ian Wienand <iwienand@redhat.com>
|
||||
[rharwood: commit message composits, drop man pages]
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
util/grub-mkconfig.in | 9 +-
|
||||
util/grub-mkconfig_lib.in | 22 +++-
|
||||
util/grub.d/10_linux.in | 244 +++++++++++++++++++++++++++++++++++++-
|
||||
3 files changed, 269 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
|
||||
index cf5b79342..7af15df94 100644
|
||||
--- a/util/grub-mkconfig.in
|
||||
+++ b/util/grub-mkconfig.in
|
||||
@@ -49,6 +49,8 @@ grub_script_check="${bindir}/@grub_script_check@"
|
||||
export TEXTDOMAIN=@PACKAGE@
|
||||
export TEXTDOMAINDIR="@localedir@"
|
||||
|
||||
+export GRUB_GRUBENV_UPDATE="yes"
|
||||
+
|
||||
. "${pkgdatadir}/grub-mkconfig_lib"
|
||||
|
||||
# Usage: usage
|
||||
@@ -58,6 +60,7 @@ usage () {
|
||||
gettext "Generate a grub config file"; echo
|
||||
echo
|
||||
print_option_help "-o, --output=$(gettext FILE)" "$(gettext "output generated config to FILE [default=stdout]")"
|
||||
+ print_option_help "--no-grubenv-update" "$(gettext "do not update variables in the grubenv file")"
|
||||
print_option_help "-h, --help" "$(gettext "print this message and exit")"
|
||||
print_option_help "-V, --version" "$(gettext "print the version information and exit")"
|
||||
echo
|
||||
@@ -93,6 +96,9 @@ do
|
||||
--output=*)
|
||||
grub_cfg=`echo "$option" | sed 's/--output=//'`
|
||||
;;
|
||||
+ --no-grubenv-update)
|
||||
+ GRUB_GRUBENV_UPDATE="no"
|
||||
+ ;;
|
||||
-*)
|
||||
gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2
|
||||
usage
|
||||
@@ -300,7 +306,8 @@ export GRUB_DEFAULT \
|
||||
GRUB_DISABLE_SUBMENU \
|
||||
SUSE_BTRFS_SNAPSHOT_BOOTING \
|
||||
SUSE_CMDLINE_XENEFI \
|
||||
- SUSE_REMOVE_LINUX_ROOT_PARAM
|
||||
+ SUSE_REMOVE_LINUX_ROOT_PARAM \
|
||||
+ GRUB_ENABLE_BLSCFG
|
||||
|
||||
if test "x${grub_cfg}" != "x"; then
|
||||
rm -f "${grub_cfg}.new"
|
||||
diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in
|
||||
index 22fb7668f..5db4337c6 100644
|
||||
--- a/util/grub-mkconfig_lib.in
|
||||
+++ b/util/grub-mkconfig_lib.in
|
||||
@@ -30,6 +30,9 @@ fi
|
||||
if test "x$grub_file" = x; then
|
||||
grub_file="${bindir}/@grub_file@"
|
||||
fi
|
||||
+if test "x$grub_editenv" = x; then
|
||||
+ grub_editenv="${bindir}/@grub_editenv@"
|
||||
+fi
|
||||
if test "x$grub_mkrelpath" = x; then
|
||||
grub_mkrelpath="${bindir}/@grub_mkrelpath@"
|
||||
fi
|
||||
@@ -123,8 +126,19 @@ EOF
|
||||
fi
|
||||
}
|
||||
|
||||
+prepare_grub_to_access_device_with_variable ()
|
||||
+{
|
||||
+ device_variable="$1"
|
||||
+ shift
|
||||
+ prepare_grub_to_access_device "$@"
|
||||
+ unset "device_variable"
|
||||
+}
|
||||
+
|
||||
prepare_grub_to_access_device ()
|
||||
{
|
||||
+ if [ -z "$device_variable" ]; then
|
||||
+ device_variable="root"
|
||||
+ fi
|
||||
old_ifs="$IFS"
|
||||
IFS='
|
||||
'
|
||||
@@ -159,18 +173,18 @@ prepare_grub_to_access_device ()
|
||||
# otherwise set root as per value in device.map.
|
||||
fs_hint="`"${grub_probe}" --device $@ --target=compatibility_hint`"
|
||||
if [ "x$fs_hint" != x ]; then
|
||||
- echo "set root='$fs_hint'"
|
||||
+ echo "set ${device_variable}='$fs_hint'"
|
||||
fi
|
||||
if [ "x${GRUB_DISABLE_UUID}" != "xtrue" ] && fs_uuid="`"${grub_probe}" --device $@ --target=fs_uuid 2> /dev/null`" ; then
|
||||
hints="`"${grub_probe}" --device $@ --target=hints_string 2> /dev/null`" || hints=
|
||||
if [ "x$hints" != x ]; then
|
||||
echo "if [ x\$feature_platform_search_hint = xy ]; then"
|
||||
- echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}"
|
||||
+ echo " search --no-floppy --fs-uuid --set=${device_variable} ${hints} ${fs_uuid}"
|
||||
echo "else"
|
||||
- echo " search --no-floppy --fs-uuid --set=root ${fs_uuid}"
|
||||
+ echo " search --no-floppy --fs-uuid --set=${device_variable} ${fs_uuid}"
|
||||
echo "fi"
|
||||
else
|
||||
- echo "search --no-floppy --fs-uuid --set=root ${fs_uuid}"
|
||||
+ echo "search --no-floppy --fs-uuid --set=${device_variable} ${fs_uuid}"
|
||||
fi
|
||||
fi
|
||||
IFS="$old_ifs"
|
||||
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
|
||||
index 5531239eb..49eccbeaf 100644
|
||||
--- a/util/grub.d/10_linux.in
|
||||
+++ b/util/grub.d/10_linux.in
|
||||
@@ -91,6 +91,244 @@ if [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" = "xtrue" ]; then
|
||||
LINUX_ROOT_DEVICE=""
|
||||
fi
|
||||
|
||||
+populate_header_warn()
|
||||
+{
|
||||
+if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then
|
||||
+ bls_parser="10_linux script"
|
||||
+else
|
||||
+ bls_parser="blscfg command"
|
||||
+fi
|
||||
+cat <<EOF
|
||||
+
|
||||
+# This section was generated by a script. Do not modify the generated file - all changes
|
||||
+# will be lost the next time file is regenerated. Instead edit the BootLoaderSpec files.
|
||||
+#
|
||||
+# The $bls_parser parses the BootLoaderSpec files stored in /boot/loader/entries and
|
||||
+# populates the boot menu. Please refer to the Boot Loader Specification documentation
|
||||
+# for the files format: https://systemd.io/BOOT_LOADER_SPECIFICATION/.
|
||||
+
|
||||
+EOF
|
||||
+}
|
||||
+
|
||||
+read_config()
|
||||
+{
|
||||
+ config_file=${1}
|
||||
+ title=""
|
||||
+ initrd=""
|
||||
+ options=""
|
||||
+ linux=""
|
||||
+ grub_arg=""
|
||||
+
|
||||
+ while read -r line
|
||||
+ do
|
||||
+ record=$(echo ${line} | cut -f 1 -d ' ')
|
||||
+ value=$(echo ${line} | cut -s -f2- -d ' ')
|
||||
+ case "${record}" in
|
||||
+ "title")
|
||||
+ title=${value}
|
||||
+ ;;
|
||||
+ "initrd")
|
||||
+ initrd=${value}
|
||||
+ ;;
|
||||
+ "linux")
|
||||
+ linux=${value}
|
||||
+ ;;
|
||||
+ "options")
|
||||
+ options=${value}
|
||||
+ ;;
|
||||
+ "grub_arg")
|
||||
+ grub_arg=${value}
|
||||
+ ;;
|
||||
+ esac
|
||||
+ done < ${config_file}
|
||||
+}
|
||||
+
|
||||
+blsdir="/boot/loader/entries"
|
||||
+
|
||||
+get_sorted_bls()
|
||||
+{
|
||||
+ if ! [ -d "${blsdir}" ]; then
|
||||
+ return
|
||||
+ fi
|
||||
+
|
||||
+ local IFS=$'\n'
|
||||
+
|
||||
+ files=($(for bls in ${blsdir}/*.conf; do
|
||||
+ if ! [[ -e "${bls}" ]] ; then
|
||||
+ continue
|
||||
+ fi
|
||||
+ bls="${bls%.conf}"
|
||||
+ bls="${bls##*/}"
|
||||
+ echo "${bls}"
|
||||
+ done | ${kernel_sort} 2>/dev/null | tac)) || :
|
||||
+
|
||||
+ echo "${files[@]}"
|
||||
+}
|
||||
+
|
||||
+update_bls_cmdline()
|
||||
+{
|
||||
+ local cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
|
||||
+ local -a files=($(get_sorted_bls))
|
||||
+
|
||||
+ for bls in "${files[@]}"; do
|
||||
+ local options="${cmdline}"
|
||||
+ if [ -z "${bls##*debug*}" ]; then
|
||||
+ options="${options} ${GRUB_CMDLINE_LINUX_DEBUG}"
|
||||
+ fi
|
||||
+ options="$(echo "${options}" | sed -e 's/\//\\\//g')"
|
||||
+ sed -i -e "s/^options.*/options ${options}/" "${blsdir}/${bls}.conf"
|
||||
+ done
|
||||
+}
|
||||
+
|
||||
+populate_menu()
|
||||
+{
|
||||
+ local -a files=($(get_sorted_bls))
|
||||
+
|
||||
+ gettext_printf "Generating boot entries from BLS files...\n" >&2
|
||||
+
|
||||
+ for bls in "${files[@]}"; do
|
||||
+ read_config "${blsdir}/${bls}.conf"
|
||||
+
|
||||
+ menu="${menu}menuentry '${title}' ${grub_arg} --id=${bls} {\n"
|
||||
+ menu="${menu}\t linux ${linux} ${options}\n"
|
||||
+ if [ -n "${initrd}" ] ; then
|
||||
+ menu="${menu}\t initrd ${boot_prefix}${initrd}\n"
|
||||
+ fi
|
||||
+ menu="${menu}}\n\n"
|
||||
+ done
|
||||
+ # The printf command seems to be more reliable across shells for special character (\n, \t) evaluation
|
||||
+ printf "$menu"
|
||||
+}
|
||||
+
|
||||
+# Make BLS the default if GRUB_ENABLE_BLSCFG was not set and grubby is not installed.
|
||||
+if [ -z "${GRUB_ENABLE_BLSCFG}" ] && ! command -v new-kernel-pkg >/dev/null; then
|
||||
+ GRUB_ENABLE_BLSCFG="true"
|
||||
+fi
|
||||
+
|
||||
+if [ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]; then
|
||||
+ if [ x$dirname = x/ ]; then
|
||||
+ if [ -z "${prepare_root_cache}" ]; then
|
||||
+ prepare_grub_to_access_device ${GRUB_DEVICE}
|
||||
+ fi
|
||||
+ else
|
||||
+ if [ -z "${prepare_boot_cache}" ]; then
|
||||
+ prepare_grub_to_access_device ${GRUB_DEVICE_BOOT}
|
||||
+ fi
|
||||
+ fi
|
||||
+
|
||||
+ if [ -d /sys/firmware/efi ]; then
|
||||
+ bootefi_device="`${grub_probe} --target=device /boot/efi/`"
|
||||
+ prepare_grub_to_access_device_with_variable boot ${bootefi_device}
|
||||
+ else
|
||||
+ boot_device="`${grub_probe} --target=device /boot/`"
|
||||
+ prepare_grub_to_access_device_with_variable boot ${boot_device}
|
||||
+ fi
|
||||
+
|
||||
+ arch="$(uname -m)"
|
||||
+ if [ "x${arch}" = "xppc64le" ] && [ -d /sys/firmware/opal ]; then
|
||||
+
|
||||
+ BLS_POPULATE_MENU="true"
|
||||
+ petitboot_path="/sys/firmware/devicetree/base/ibm,firmware-versions/petitboot"
|
||||
+
|
||||
+ if test -e ${petitboot_path}; then
|
||||
+ read -r -d '' petitboot_version < ${petitboot_path}
|
||||
+ petitboot_version="$(echo ${petitboot_version//v})"
|
||||
+
|
||||
+ if test -n ${petitboot_version}; then
|
||||
+ major_version="$(echo ${petitboot_version} | cut -d . -f1)"
|
||||
+ minor_version="$(echo ${petitboot_version} | cut -d . -f2)"
|
||||
+
|
||||
+ re='^[0-9]+$'
|
||||
+ if [[ $major_version =~ $re ]] && [[ $minor_version =~ $re ]] &&
|
||||
+ ([[ ${major_version} -gt 1 ]] ||
|
||||
+ [[ ${major_version} -eq 1 &&
|
||||
+ ${minor_version} -ge 8 ]]); then
|
||||
+ BLS_POPULATE_MENU="false"
|
||||
+ fi
|
||||
+ fi
|
||||
+ fi
|
||||
+ fi
|
||||
+
|
||||
+ populate_header_warn
|
||||
+
|
||||
+ cat << EOF
|
||||
+# The kernelopts variable should be defined in the grubenv file. But to ensure that menu
|
||||
+# entries populated from BootLoaderSpec files that use this variable work correctly even
|
||||
+# without a grubenv file, define a fallback kernelopts variable if this has not been set.
|
||||
+#
|
||||
+# The kernelopts variable in the grubenv file can be modified using the grubby tool or by
|
||||
+# executing the grub2-mkconfig tool. For the latter, the values of the GRUB_CMDLINE_LINUX
|
||||
+# and GRUB_CMDLINE_LINUX_DEFAULT options from /etc/default/grub file are used to set both
|
||||
+# the kernelopts variable in the grubenv file and the fallback kernelopts variable.
|
||||
+if [ -z "\${kernelopts}" ]; then
|
||||
+ set kernelopts="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
|
||||
+fi
|
||||
+EOF
|
||||
+
|
||||
+ update_bls_cmdline
|
||||
+
|
||||
+ if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then
|
||||
+ populate_menu
|
||||
+ else
|
||||
+ cat << EOF
|
||||
+
|
||||
+insmod blscfg
|
||||
+blscfg
|
||||
+EOF
|
||||
+ fi
|
||||
+
|
||||
+ if [ "x${GRUB_GRUBENV_UPDATE}" = "xyes" ]; then
|
||||
+ blsdir="/boot/loader/entries"
|
||||
+ [ -d "${blsdir}" ] && GRUB_BLS_FS="$(${grub_probe} --target=fs ${blsdir})"
|
||||
+ if [ "x${GRUB_BLS_FS}" = "xbtrfs" ] || [ "x${GRUB_BLS_FS}" = "xzfs" ]; then
|
||||
+ blsdir=$(make_system_path_relative_to_its_root "${blsdir}")
|
||||
+ if [ "x${blsdir}" != "x/loader/entries" ] && [ "x${blsdir}" != "x/boot/loader/entries" ]; then
|
||||
+ ${grub_editenv} - set blsdir="${blsdir}"
|
||||
+ fi
|
||||
+ fi
|
||||
+
|
||||
+ if [ -n "${GRUB_EARLY_INITRD_LINUX_CUSTOM}" ]; then
|
||||
+ ${grub_editenv} - set early_initrd="${GRUB_EARLY_INITRD_LINUX_CUSTOM}"
|
||||
+ fi
|
||||
+
|
||||
+ if [ -n "${GRUB_DEFAULT_DTB}" ]; then
|
||||
+ ${grub_editenv} - set devicetree="${GRUB_DEFAULT_DTB}"
|
||||
+ fi
|
||||
+
|
||||
+ if [ -n "${GRUB_SAVEDEFAULT}" ]; then
|
||||
+ ${grub_editenv} - set save_default="${GRUB_SAVEDEFAULT}"
|
||||
+ fi
|
||||
+ fi
|
||||
+
|
||||
+ exit 0
|
||||
+fi
|
||||
+
|
||||
+mktitle ()
|
||||
+{
|
||||
+ local title_type
|
||||
+ local version
|
||||
+ local OS_NAME
|
||||
+ local OS_VERS
|
||||
+
|
||||
+ title_type=$1 && shift
|
||||
+ version=$1 && shift
|
||||
+
|
||||
+ OS_NAME="$(eval $(grep ^NAME= /etc/os-release) ; echo ${NAME})"
|
||||
+ OS_VERS="$(eval $(grep ^VERSION= /etc/os-release) ; echo ${VERSION})"
|
||||
+
|
||||
+ case $title_type in
|
||||
+ recovery)
|
||||
+ title=$(printf '%s (%s) %s (recovery mode)' \
|
||||
+ "${OS_NAME}" "${version}" "${OS_VERS}")
|
||||
+ ;;
|
||||
+ *)
|
||||
+ title=$(printf '%s (%s) %s' \
|
||||
+ "${OS_NAME}" "${version}" "${OS_VERS}")
|
||||
+ ;;
|
||||
+ esac
|
||||
+ echo -n ${title}
|
||||
+}
|
||||
+
|
||||
title_correction_code=
|
||||
|
||||
hotkey=1
|
||||
@@ -124,6 +362,7 @@ linux_entry ()
|
||||
if [ -z "$boot_device_id" ]; then
|
||||
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
|
||||
fi
|
||||
+
|
||||
if [ x$type != xsimple ] ; then
|
||||
case $type in
|
||||
recovery)
|
||||
@@ -298,6 +537,7 @@ fi
|
||||
is_top_level=true
|
||||
for linux in ${reverse_sorted_list}; do
|
||||
gettext_printf "Found linux image: %s\n" "$linux" >&2
|
||||
+
|
||||
basename=`basename $linux`
|
||||
dirname=`dirname $linux`
|
||||
rel_dirname=`make_system_path_relative_to_its_root $dirname`
|
||||
@@ -348,7 +588,9 @@ for linux in ${reverse_sorted_list}; do
|
||||
for i in ${initrd}; do
|
||||
initrd_display="${initrd_display} ${dirname}/${i}"
|
||||
done
|
||||
- gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2
|
||||
+ if [ "x${GRUB_ENABLE_BLSCFG}" != "xtrue" ]; then
|
||||
+ gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2
|
||||
+ fi
|
||||
fi
|
||||
|
||||
config=
|
||||
--
|
||||
2.44.0
|
||||
|
@@ -1,278 +0,0 @@
|
||||
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__) || \
|
197
0002-Restrict-file-access-on-cryptodisk-print.patch
Normal file
197
0002-Restrict-file-access-on-cryptodisk-print.patch
Normal file
@@ -0,0 +1,197 @@
|
||||
From 912384e63c1e3b6aa9d90effb71cd535a17da1e2 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Sat, 18 Nov 2023 19:02:31 +0800
|
||||
Subject: [PATCH 2/4] Restrict file access on cryptodisk print
|
||||
|
||||
When the encrypted partition is automatically unlocked by TPM, granting
|
||||
access to the system upon validation of its known good state, there's a
|
||||
potential vulnerability. Grub gains access to file systems that were
|
||||
previously inaccessible to the public, enabling certain commands from
|
||||
the grub console to print content. This arises due to grub lacking
|
||||
restrictions similar to those imposed by password authentication, which
|
||||
typically occurs before privileged access is granted.
|
||||
|
||||
Although the automatic unlocking process ensures system integrity and a
|
||||
secure environment for grub to operate in, it doesn't directly address
|
||||
the issue of authentication for viewing encrypted partition content.
|
||||
|
||||
This commit addresses this security loophole by implementing a file
|
||||
filter upon adding a TPM key. The newly added file filter will
|
||||
specifically verify if the disk is encrypted, denying access and
|
||||
returning an "Access Denied: prohibited to view encrypted data" error
|
||||
message to alert the user.
|
||||
|
||||
Since the policy to filter out unwanted commands from leaking encrypted
|
||||
content is irreversible, it is advisable to make the loaded module
|
||||
persistent to prevent its removal.
|
||||
|
||||
This enhancement aims to bolster security measures and prevent
|
||||
unauthorized access to encrypted data.
|
||||
|
||||
Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/crypttab.c | 35 ++++++++++++++++++++++++++++++++++-
|
||||
grub-core/disk/diskfilter.c | 35 +++++++++++++++++++++++++++++++++++
|
||||
include/grub/disk.h | 10 ++++++++++
|
||||
include/grub/file.h | 1 +
|
||||
4 files changed, 80 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/commands/crypttab.c b/grub-core/commands/crypttab.c
|
||||
index 9397bede9..d3acc4b59 100644
|
||||
--- a/grub-core/commands/crypttab.c
|
||||
+++ b/grub-core/commands/crypttab.c
|
||||
@@ -6,11 +6,39 @@
|
||||
#include <grub/mm.h>
|
||||
#include <grub/list.h>
|
||||
#include <grub/crypttab.h>
|
||||
+#include <grub/file.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
grub_crypto_key_list_t *cryptokey_lst;
|
||||
|
||||
+static grub_file_t
|
||||
+grub_nocat_open (grub_file_t io, enum grub_file_type type)
|
||||
+{
|
||||
+ grub_disk_t disk;
|
||||
+
|
||||
+ /* Network device */
|
||||
+ if (!io->device->disk)
|
||||
+ return io;
|
||||
+
|
||||
+ disk = io->device->disk;
|
||||
+
|
||||
+ if (grub_disk_is_crypto (disk))
|
||||
+ {
|
||||
+ switch (type & GRUB_FILE_TYPE_MASK)
|
||||
+ {
|
||||
+ case GRUB_FILE_TYPE_CAT:
|
||||
+ case GRUB_FILE_TYPE_HEXCAT:
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to view encrypted data"));
|
||||
+ return NULL;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return io;
|
||||
+}
|
||||
+
|
||||
grub_err_t
|
||||
grub_cryptokey_add_or_update (const char *uuid, const char *key, grub_size_t key_len, const char *path, int is_tpmkey)
|
||||
{
|
||||
@@ -48,7 +76,11 @@ grub_cryptokey_add_or_update (const char *uuid, const char *key, grub_size_t key
|
||||
}
|
||||
|
||||
if (is_tpmkey >= 0)
|
||||
- cur->is_tpmkey = is_tpmkey;
|
||||
+ {
|
||||
+ cur->is_tpmkey = is_tpmkey;
|
||||
+ if (is_tpmkey)
|
||||
+ grub_file_filter_register (GRUB_FILE_FILTER_NOCAT, grub_nocat_open);
|
||||
+ }
|
||||
|
||||
if (!cur->name)
|
||||
{
|
||||
@@ -121,6 +153,7 @@ GRUB_MOD_INIT(crypttab)
|
||||
{
|
||||
cmd = grub_register_command ("crypttab_entry", grub_cmd_crypttab_entry,
|
||||
N_("VOLUME-NAME ENCRYPTED-DEVICE KEY-FILE") , N_("No description"));
|
||||
+ grub_dl_set_persistent (mod);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(crypttab)
|
||||
diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c
|
||||
index 5c5fabe1a..b0c1c880d 100644
|
||||
--- a/grub-core/disk/diskfilter.c
|
||||
+++ b/grub-core/disk/diskfilter.c
|
||||
@@ -558,6 +558,39 @@ find_lv (const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static int
|
||||
+grub_diskfilter_has_cryptodisk (const struct grub_diskfilter_lv *lv)
|
||||
+{
|
||||
+ struct grub_diskfilter_pv *pv;
|
||||
+
|
||||
+ if (!lv)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (lv->vg->pvs)
|
||||
+ for (pv = lv->vg->pvs; pv; pv = pv->next)
|
||||
+ {
|
||||
+ if (!pv->disk)
|
||||
+ {
|
||||
+ grub_dprintf ("diskfilter", _("Couldn't find physical volume `%s'."
|
||||
+ " Some modules may be missing from core image."),
|
||||
+ pv->name);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ switch (pv->disk->dev->id)
|
||||
+ {
|
||||
+ case GRUB_DISK_DEVICE_CRYPTODISK_ID:
|
||||
+ return 1;
|
||||
+ case GRUB_DISK_DEVICE_DISKFILTER_ID:
|
||||
+ return grub_diskfilter_has_cryptodisk (pv->disk->data);
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_diskfilter_open (const char *name, grub_disk_t disk)
|
||||
{
|
||||
@@ -589,6 +622,8 @@ grub_diskfilter_open (const char *name, grub_disk_t disk)
|
||||
|
||||
disk->total_sectors = lv->size;
|
||||
disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE;
|
||||
+ disk->is_crypto_diskfilter = grub_diskfilter_has_cryptodisk (lv);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/include/grub/disk.h b/include/grub/disk.h
|
||||
index 3b3db6222..63982f16c 100644
|
||||
--- a/include/grub/disk.h
|
||||
+++ b/include/grub/disk.h
|
||||
@@ -147,6 +147,8 @@ struct grub_disk
|
||||
|
||||
/* Device-specific data. */
|
||||
void *data;
|
||||
+
|
||||
+ int is_crypto_diskfilter;
|
||||
};
|
||||
typedef struct grub_disk *grub_disk_t;
|
||||
|
||||
@@ -314,4 +316,12 @@ void grub_mdraid1x_fini (void);
|
||||
void grub_diskfilter_fini (void);
|
||||
#endif
|
||||
|
||||
+static inline int
|
||||
+grub_disk_is_crypto (grub_disk_t disk)
|
||||
+{
|
||||
+ return ((disk->is_crypto_diskfilter ||
|
||||
+ disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) ?
|
||||
+ 1 : 0);
|
||||
+}
|
||||
+
|
||||
#endif /* ! GRUB_DISK_HEADER */
|
||||
diff --git a/include/grub/file.h b/include/grub/file.h
|
||||
index fde58f0fa..fcfd32ce2 100644
|
||||
--- a/include/grub/file.h
|
||||
+++ b/include/grub/file.h
|
||||
@@ -185,6 +185,7 @@ extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook);
|
||||
/* Filters with lower ID are executed first. */
|
||||
typedef enum grub_file_filter_id
|
||||
{
|
||||
+ GRUB_FILE_FILTER_NOCAT,
|
||||
GRUB_FILE_FILTER_VERIFY,
|
||||
GRUB_FILE_FILTER_GZIO,
|
||||
GRUB_FILE_FILTER_XZIO,
|
||||
--
|
||||
2.42.1
|
||||
|
@@ -1,134 +0,0 @@
|
||||
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
|
||||
|
@@ -1,34 +0,0 @@
|
||||
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
|
||||
|
@@ -1,52 +0,0 @@
|
||||
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
|
||||
|
@@ -1,65 +0,0 @@
|
||||
From 6704d7715b6303f4b7e2cb9da7c6dcc3bfdd5726 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 14 Jul 2025 22:10:18 +0800
|
||||
Subject: [PATCH 2/4] http: Return HTTP status code in http_establish
|
||||
|
||||
Previously, using "test -s ..." or "test -f ..." on files served via
|
||||
HTTP would always return true, regardless of whether the target file
|
||||
actually existed. This is incorrect behavior, whereas the same tests
|
||||
work as expected with TFTP.
|
||||
|
||||
The issue stems from http_establish returning success (GRUB_ERR_NONE) as
|
||||
long as the HTTP connection was established, without considering the
|
||||
HTTP status code returned in the response. As a result, http_open would
|
||||
always report success, discarding error responses such as 404 Not Found.
|
||||
|
||||
The patch makes http_establish to return the HTTP status code as its
|
||||
return value when an error or unknown status code is encountered. It
|
||||
also sets data->first_line_recv = 1 in the parse_line()'s error code
|
||||
path to correctly reflect the parsing state and prevent reprocessing.
|
||||
|
||||
With this change, both -s and -f tests now behave correctly when used
|
||||
with the HTTP protocol, as http_establish returns error for failed HTTP
|
||||
status codes as well. As a result, http_open is no longer considered
|
||||
successful solely based on establishing the connection, it now also
|
||||
takes the HTTP status code into account.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/net/http.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/grub-core/net/http.c b/grub-core/net/http.c
|
||||
index 686949c17..c5509dc45 100644
|
||||
--- a/grub-core/net/http.c
|
||||
+++ b/grub-core/net/http.c
|
||||
@@ -125,6 +125,7 @@ parse_line (grub_file_t file, http_data_t data, char *ptr, grub_size_t len)
|
||||
case 404:
|
||||
data->err = GRUB_ERR_FILE_NOT_FOUND;
|
||||
data->errmsg = grub_xasprintf (_("file `%s' not found"), data->filename);
|
||||
+ data->first_line_recv = 1;
|
||||
return GRUB_ERR_NONE;
|
||||
default:
|
||||
data->err = GRUB_ERR_NET_UNKNOWN_ERROR;
|
||||
@@ -132,6 +133,7 @@ parse_line (grub_file_t file, http_data_t data, char *ptr, grub_size_t len)
|
||||
valid answers like 403 will trigger this very generic message. */
|
||||
data->errmsg = grub_xasprintf (_("unsupported HTTP error %d: %s"),
|
||||
code, ptr);
|
||||
+ data->first_line_recv = 1;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
data->first_line_recv = 1;
|
||||
@@ -444,6 +446,10 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial)
|
||||
}
|
||||
return grub_error (GRUB_ERR_TIMEOUT, N_("time out opening `%s'"), data->filename);
|
||||
}
|
||||
+
|
||||
+ if (data->err)
|
||||
+ return grub_error (data->err, N_("%s"), data->errmsg);
|
||||
+
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
--
|
||||
2.50.0
|
||||
|
@@ -1,216 +0,0 @@
|
||||
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
|
||||
|
@@ -1,20 +1,16 @@
|
||||
From ba5fee5cdbe6fa4871419c54008a7efb87d99e23 Mon Sep 17 00:00:00 2001
|
||||
From: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Date: Fri, 30 Aug 2024 17:11:04 +0530
|
||||
Subject: [PATCH 2/3] ieee1275: ofpath enable NVMeoF logical device translate
|
||||
From 9e61624db77e5073961126457f599bc70e877fd1 Mon Sep 17 00:00:00 2001
|
||||
From: Diego Domingos <diegodo@br.ibm.com>
|
||||
Date: Tue, 15 Mar 2022 15:59:41 -0400
|
||||
Subject: [PATCH 2/4] ieee1275/ofpath: enable NVMeoF logical device translation
|
||||
|
||||
This patch adds code to enable the translation of logical devices to the of NVMeoFC paths.
|
||||
|
||||
Signed-off-by: Diego Domingos <diegodo@br.ibm.com>
|
||||
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Link: https://lore.kernel.org/r/20240830114104.32234-6-avnish@linux.ibm.com
|
||||
This patch add code to enable the translation of logical devices to the of NVMeoFC paths.
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 370 ++++++++++++++++++++++++++++++++-
|
||||
include/grub/util/ofpath.h | 28 +++
|
||||
2 files changed, 389 insertions(+), 9 deletions(-)
|
||||
grub-core/osdep/linux/ofpath.c | 260 +++++++++++++++++++++++++++++++--
|
||||
include/grub/util/ofpath.h | 29 ++++
|
||||
2 files changed, 280 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
|
||||
index 89beceef4a..dd50d785dd 100644
|
||||
index 89beceef4..212782d3f 100644
|
||||
--- a/grub-core/osdep/linux/ofpath.c
|
||||
+++ b/grub-core/osdep/linux/ofpath.c
|
||||
@@ -137,7 +137,7 @@ trim_newline (char *path)
|
||||
@@ -26,358 +22,261 @@ index 89beceef4a..dd50d785dd 100644
|
||||
|
||||
static char *
|
||||
find_obppath (const char *sysfs_path_orig)
|
||||
@@ -313,6 +313,91 @@ get_basename(char *p)
|
||||
@@ -313,6 +313,69 @@ get_basename(char *p)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+int
|
||||
+add_filename_to_pile (char *filename, struct ofpath_files_list_root* root)
|
||||
+{
|
||||
+ struct ofpath_files_list_node* file;
|
||||
+
|
||||
+ file = malloc (sizeof (struct ofpath_files_list_node));
|
||||
+ if (!file)
|
||||
+ return -1;
|
||||
+void
|
||||
+add_filename_to_pile(char *filename, struct ofpath_files_list_root* root){
|
||||
+ struct ofpath_files_list_node* file;
|
||||
+
|
||||
+ file->filename = malloc (sizeof (char) * 1024);
|
||||
+ if (!file->filename)
|
||||
+ {
|
||||
+ free (file);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ file = malloc(sizeof(struct ofpath_files_list_node));
|
||||
+
|
||||
+ grub_strcpy (file->filename, filename);
|
||||
+ if (root->first == NULL)
|
||||
+ {
|
||||
+ file->filename = filename;
|
||||
+
|
||||
+ if(root->first == NULL){
|
||||
+ root->items = 1;
|
||||
+ root->first = file;
|
||||
+ file->next = NULL;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ } else {
|
||||
+ root->items++;
|
||||
+ file->next = root->first;
|
||||
+ root->first = file;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+void
|
||||
+find_file (char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth)
|
||||
+{
|
||||
+ struct dirent *ep;
|
||||
+ struct stat statbuf;
|
||||
+ DIR *dp;
|
||||
+ int ret_val=0;
|
||||
+ char* full_path;
|
||||
+find_file(char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth){
|
||||
+ struct dirent *ep;
|
||||
+ struct stat statbuf;
|
||||
+ DIR *dp;
|
||||
+
|
||||
+ if (depth > max_depth)
|
||||
+ {
|
||||
+ return;
|
||||
+ }
|
||||
+ if(depth > max_depth){
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if ((dp = opendir (directory)) == NULL)
|
||||
+ {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ full_path = malloc (1024 * sizeof (char));
|
||||
+ if (!full_path)
|
||||
+ if((dp = opendir(directory)) == NULL){
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ while ((ep = readdir(dp)) != NULL)
|
||||
+ {
|
||||
+ snprintf (full_path, 1024, "%s/%s", directory, ep->d_name);
|
||||
+ lstat (full_path, &statbuf);
|
||||
+ while((ep = readdir(dp)) != NULL){
|
||||
+
|
||||
+ if (S_ISLNK (statbuf.st_mode))
|
||||
+ {
|
||||
+ continue;
|
||||
+ }
|
||||
+ char* full_path = malloc(1024*sizeof(char));
|
||||
+ snprintf(full_path,1024,"%s/%s",directory,ep->d_name);
|
||||
+
|
||||
+ if (!strcmp (ep->d_name, ".") || !strcmp(ep->d_name, ".."))
|
||||
+ {
|
||||
+ continue;
|
||||
+ }
|
||||
+ lstat(full_path,&statbuf);
|
||||
+
|
||||
+ if (!strcmp (ep->d_name, filename))
|
||||
+ {
|
||||
+ ret_val = add_filename_to_pile (full_path, root);
|
||||
+ if (ret_val == -1)
|
||||
+ continue;
|
||||
+ }
|
||||
+ if(S_ISLNK(statbuf.st_mode)){
|
||||
+
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ find_file (filename, full_path, root, max_depth, depth+1);
|
||||
+ }
|
||||
+ if(!strcmp(ep->d_name,".") || !strcmp(ep->d_name,"..")){
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ free (full_path);
|
||||
+ closedir (dp);
|
||||
+ if(!strcmp(ep->d_name,filename)){
|
||||
+ add_filename_to_pile(full_path, root);
|
||||
+ }
|
||||
+
|
||||
+ find_file(filename, full_path, root, max_depth, depth+1);
|
||||
+
|
||||
+ }
|
||||
+ closedir(dp);
|
||||
+}
|
||||
+
|
||||
+
|
||||
static char *
|
||||
of_path_of_vdisk(const char *sys_devname __attribute__((unused)),
|
||||
const char *device,
|
||||
@@ -351,7 +436,200 @@ of_path_of_ide(const char *sys_devname __attribute__((unused)), const char *devi
|
||||
@@ -351,7 +414,142 @@ of_path_of_ide(const char *sys_devname __attribute__((unused)), const char *devi
|
||||
return ret;
|
||||
}
|
||||
|
||||
-#ifdef __sparc__
|
||||
+void
|
||||
+free_ofpath_files_list (struct ofpath_files_list_root* root)
|
||||
+{
|
||||
+ struct ofpath_files_list_node* node = root->first;
|
||||
+ struct ofpath_files_list_node* next;
|
||||
+
|
||||
+ while (node!=NULL)
|
||||
+ {
|
||||
+ next = node->next;
|
||||
+ free (node->filename);
|
||||
+ free (node);
|
||||
+ node = next;
|
||||
+ }
|
||||
+
|
||||
+ free (root);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+char*
|
||||
+of_find_fc_host (char* host_wwpn)
|
||||
+{
|
||||
+of_find_fc_host(char* host_wwpn){
|
||||
+
|
||||
+ FILE* fp;
|
||||
+ char *buf;
|
||||
+ char *ret_val;
|
||||
+ char portname_filename[sizeof ("port_name")] = "port_name";
|
||||
+ char devices_path[sizeof ("/sys/devices")] = "/sys/devices";
|
||||
+ char portname_filename[sizeof("port_name")] = "port_name";
|
||||
+ char devices_path[sizeof("/sys/devices")] = "/sys/devices";
|
||||
+
|
||||
+ struct ofpath_files_list_root* portnames_file_list;
|
||||
+ struct ofpath_files_list_node* node;
|
||||
+
|
||||
+ ret_val = malloc (sizeof (char) * 1024);
|
||||
+ if (!ret_val)
|
||||
+ return NULL;
|
||||
+ portnames_file_list=malloc(sizeof(portnames_file_list));
|
||||
+ portnames_file_list->items=0;
|
||||
+ portnames_file_list->first=NULL;
|
||||
+
|
||||
+ portnames_file_list = malloc (sizeof (struct ofpath_files_list_root));
|
||||
+ if (!portnames_file_list)
|
||||
+ {
|
||||
+ free (ret_val);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ portnames_file_list->items = 0;
|
||||
+ portnames_file_list->first = NULL;
|
||||
+ find_file (portname_filename, devices_path, portnames_file_list, 10, 0);
|
||||
+ node = portnames_file_list->first;
|
||||
+
|
||||
+ while (node != NULL)
|
||||
+ {
|
||||
+ fp = fopen(node->filename, "r");
|
||||
+ buf = malloc (sizeof (char) * 512);
|
||||
+ if (!buf)
|
||||
+ break;
|
||||
+
|
||||
+ fscanf (fp, "%s", buf);
|
||||
+ fclose (fp);
|
||||
+
|
||||
+ if ((strcmp (buf, host_wwpn) == 0) && grub_strstr (node->filename, "fc_host"))
|
||||
+ {
|
||||
+ free (buf);
|
||||
+ grub_strcpy (ret_val, node->filename);
|
||||
+ free_ofpath_files_list (portnames_file_list);
|
||||
+ return ret_val;
|
||||
+ }
|
||||
+ find_file(portname_filename, devices_path, portnames_file_list, 10, 0);
|
||||
+
|
||||
+ struct ofpath_files_list_node* node = portnames_file_list->first;
|
||||
+ while(node != NULL){
|
||||
+ fp = fopen(node->filename,"r");
|
||||
+ buf = malloc(sizeof(char)*512);
|
||||
+ fscanf(fp, "%s", buf);
|
||||
+ fclose(fp);
|
||||
+ if((strcmp(buf,host_wwpn) == 0) && grub_strstr(node->filename, "fc_host")){
|
||||
+ return node->filename;
|
||||
+ }
|
||||
+ node = node->next;
|
||||
+ free (buf);
|
||||
+ }
|
||||
+ free_ofpath_files_list (portnames_file_list);
|
||||
+ free (ret_val);
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+of_path_get_nvmeof_adapter_info (char* sysfs_path,
|
||||
+ struct ofpath_nvmeof_info* nvmeof_info)
|
||||
+{
|
||||
+void
|
||||
+of_path_get_nvmeof_adapter_info(char* sysfs_path,
|
||||
+ struct ofpath_nvmeof_info* nvmeof_info){
|
||||
+
|
||||
+ FILE *fp;
|
||||
+ char *buf, *buf2, *buf3;
|
||||
+
|
||||
+ nvmeof_info->host_wwpn = malloc (sizeof (char) * 256);
|
||||
+ nvmeof_info->target_wwpn = malloc (sizeof (char) * 256);
|
||||
+ nvmeof_info->nqn = malloc (sizeof (char) * 256);
|
||||
+ nvmeof_info->host_wwpn = malloc(sizeof(char)*256);
|
||||
+ nvmeof_info->target_wwpn = malloc(sizeof(char)*256);
|
||||
+ nvmeof_info->nqn = malloc(sizeof(char)*256);
|
||||
+
|
||||
+ if (nvmeof_info->host_wwpn == NULL || nvmeof_info->target_wwpn == NULL || nvmeof_info->nqn == NULL)
|
||||
+ {
|
||||
+ free (nvmeof_info->host_wwpn);
|
||||
+ free (nvmeof_info->target_wwpn);
|
||||
+ free (nvmeof_info->nqn);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ buf = malloc(sizeof(char)*512);
|
||||
+ snprintf(buf,512,"%s/subsysnqn",sysfs_path);
|
||||
+ fp = fopen(buf,"r");
|
||||
+ fscanf(fp, "%s", nvmeof_info->nqn);
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ buf = malloc (sizeof (char) * 512);
|
||||
+ if (!buf)
|
||||
+ {
|
||||
+ free (nvmeof_info->host_wwpn);
|
||||
+ free (nvmeof_info->target_wwpn);
|
||||
+ free (nvmeof_info->nqn);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ snprintf(buf,512,"%s/cntlid",sysfs_path);
|
||||
+ fp = fopen(buf,"r");
|
||||
+ fscanf(fp, "%u", &(nvmeof_info->cntlid));
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ snprintf (buf, 512, "%s/subsysnqn", sysfs_path);
|
||||
+ fp = fopen (buf, "r");
|
||||
+ fscanf (fp, "%s", nvmeof_info->nqn);
|
||||
+ fclose (fp);
|
||||
+ //snprintf(buf,512,"%s/nsid",sysfs_path);
|
||||
+ //fp = fopen(buf,"r");
|
||||
+ //fscanf(fp, "%u", &(nvmeof_info->nsid));
|
||||
+ //fclose(fp);
|
||||
+
|
||||
+ snprintf (buf, 512, "%s/cntlid", sysfs_path);
|
||||
+ fp = fopen (buf, "r");
|
||||
+ fscanf (fp, "%u", &(nvmeof_info->cntlid));
|
||||
+ fclose (fp);
|
||||
+ snprintf(buf,512,"%s/address",sysfs_path);
|
||||
+ fp = fopen(buf,"r");
|
||||
+ buf2 = malloc(sizeof(char)*512);
|
||||
+ fscanf(fp, "%s", buf2);
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ snprintf (buf, 512, "%s/address", sysfs_path);
|
||||
+ fp = fopen (buf, "r");
|
||||
+ buf2 = malloc (sizeof (char) * 512);
|
||||
+ nvmeof_info->host_wwpn = strrchr(buf2,'-')+1;
|
||||
+
|
||||
+ if (!buf2)
|
||||
+ {
|
||||
+ free (nvmeof_info->host_wwpn);
|
||||
+ free (nvmeof_info->target_wwpn);
|
||||
+ free (nvmeof_info->nqn);
|
||||
+ free (buf);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ fscanf (fp, "%s", buf2);
|
||||
+ fclose (fp);
|
||||
+
|
||||
+ buf3 = strrchr (buf2, '-') + 1;
|
||||
+ grub_memcpy (nvmeof_info->host_wwpn, buf3, 256);
|
||||
+ buf3=strchr (buf2, '-') + 1;
|
||||
+ buf3=strchr (buf3, '-') + 1;
|
||||
+ buf3=strchr (buf3, 'x') + 1;
|
||||
+ grub_memcpy (nvmeof_info->target_wwpn, buf3, 256);
|
||||
+ buf3 = strchr (nvmeof_info->target_wwpn, ',');
|
||||
+ buf3=strchr(buf2,'-')+1;
|
||||
+ buf3=strchr(buf3,'-')+1;
|
||||
+ nvmeof_info->target_wwpn = buf3;
|
||||
+ buf3 = strchr(nvmeof_info->target_wwpn,',');
|
||||
+ *buf3 = '\0';
|
||||
+ free (buf);
|
||||
+ free (buf2);
|
||||
+ return 0;
|
||||
+
|
||||
+
|
||||
+ free(buf);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+#define MAX_NVME_NSID_DIGITS 6
|
||||
+
|
||||
+static char *
|
||||
+of_path_get_nvme_controller_name_node (const char* devname)
|
||||
+of_path_get_nvme_controller_name_node(const char* devname)
|
||||
+{
|
||||
+ char *controller_node, *end;
|
||||
+
|
||||
+ controller_node = strdup (devname);
|
||||
+ end = grub_strchr (controller_node + 1, 'n');
|
||||
+ if (end != NULL)
|
||||
+ {
|
||||
+ *end = '\0';
|
||||
+ }
|
||||
+ controller_node = strdup(devname);
|
||||
+
|
||||
+ end = grub_strchr(controller_node+1, 'n');
|
||||
+
|
||||
+ if(end != NULL){
|
||||
+ *end = '\0';
|
||||
+ }
|
||||
+
|
||||
+ return controller_node;
|
||||
+}
|
||||
+
|
||||
+unsigned int
|
||||
+of_path_get_nvme_nsid (const char* devname)
|
||||
+of_path_get_nvme_nsid(const char* devname)
|
||||
+{
|
||||
+ unsigned int nsid;
|
||||
+ char *sysfs_path, *buf;
|
||||
+ FILE *fp;
|
||||
+
|
||||
+ buf = malloc (sizeof(char) * 512);
|
||||
+ if (!buf)
|
||||
+ return 0;
|
||||
+
|
||||
+ buf=malloc(sizeof(char)*512);
|
||||
+
|
||||
+ sysfs_path = block_device_get_sysfs_path_and_link (devname);
|
||||
+ snprintf (buf, 512, "%s/%s/nsid", sysfs_path, devname);
|
||||
+ fp = fopen(buf, "r");
|
||||
+ fscanf (fp, "%u", &(nsid));
|
||||
+ fclose (fp);
|
||||
+
|
||||
+ free (sysfs_path);
|
||||
+ free (buf);
|
||||
+ snprintf(buf,512,"%s/%s/nsid",sysfs_path,devname);
|
||||
+ fp = fopen(buf,"r");
|
||||
+ fscanf(fp, "%u", &(nsid));
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ free(sysfs_path);
|
||||
+ free(buf);
|
||||
+
|
||||
+ return nsid;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static char *
|
||||
+nvme_get_syspath (const char *nvmedev)
|
||||
+nvme_get_syspath(const char *nvmedev)
|
||||
+{
|
||||
+ char *sysfs_path, *controller_node;
|
||||
+
|
||||
+ sysfs_path = block_device_get_sysfs_path_and_link (nvmedev);
|
||||
+ if (strstr (sysfs_path, "nvme-subsystem"))
|
||||
+ {
|
||||
+ controller_node = of_path_get_nvme_controller_name_node (nvmedev);
|
||||
+ strcat (sysfs_path, "/");
|
||||
+ strcat (sysfs_path, controller_node);
|
||||
+ sysfs_path = xrealpath (sysfs_path);
|
||||
+ }
|
||||
+
|
||||
+ if(strstr(sysfs_path,"nvme-subsystem")){
|
||||
+ controller_node = of_path_get_nvme_controller_name_node(nvmedev);
|
||||
+ strcat(sysfs_path,"/");
|
||||
+ strcat(sysfs_path,controller_node);
|
||||
+ sysfs_path = xrealpath(sysfs_path);
|
||||
+ }
|
||||
+
|
||||
+ return sysfs_path;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static char *
|
||||
of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
const char *device,
|
||||
@@ -360,6 +638,8 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
@@ -360,6 +558,7 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
{
|
||||
char *sysfs_path, *of_path, disk[MAX_DISK_CAT];
|
||||
const char *digit_string, *part_end;
|
||||
+ int chars_written, ret_val;
|
||||
+ struct ofpath_nvmeof_info* nvmeof_info;
|
||||
+ int chars_written;
|
||||
|
||||
digit_string = trailing_digits (device);
|
||||
part_end = devicenode + strlen (devicenode) - 1;
|
||||
@@ -379,15 +659,90 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
@@ -379,15 +578,61 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
/* Remove the p. */
|
||||
*end = '\0';
|
||||
sscanf (digit_string, "%d", &part);
|
||||
- snprintf (disk, sizeof (disk), "/disk@1:%c", 'a' + (part - 1));
|
||||
- sysfs_path = block_device_get_sysfs_path_and_link (nvmedev);
|
||||
+ sysfs_path = nvme_get_syspath (nvmedev);
|
||||
+
|
||||
+ sysfs_path = nvme_get_syspath(nvmedev);
|
||||
+
|
||||
+ /* If is a NVMeoF */
|
||||
+ if (strstr (sysfs_path, "nvme-fabrics"))
|
||||
+ {
|
||||
+ nvmeof_info = malloc (sizeof (struct ofpath_nvmeof_info));
|
||||
+ if (!nvmeof_info)
|
||||
+ {
|
||||
+ free (nvmedev);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ if(strstr(sysfs_path,"nvme-fabrics")){
|
||||
+ struct ofpath_nvmeof_info* nvmeof_info;
|
||||
+ nvmeof_info = malloc(sizeof(nvmeof_info));
|
||||
+
|
||||
+ ret_val = of_path_get_nvmeof_adapter_info (sysfs_path, nvmeof_info);
|
||||
+ if (ret_val == -1)
|
||||
+ {
|
||||
+ free (nvmedev);
|
||||
+ free (nvmeof_info);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ of_path_get_nvmeof_adapter_info(sysfs_path, nvmeof_info);
|
||||
+
|
||||
+ sysfs_path = of_find_fc_host (nvmeof_info->host_wwpn);
|
||||
+ if (!sysfs_path)
|
||||
+ {
|
||||
+ free (nvmedev);
|
||||
+ free (nvmeof_info);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ sysfs_path = of_find_fc_host(nvmeof_info->host_wwpn);
|
||||
+
|
||||
+ chars_written = snprintf (disk,sizeof(disk), "/nvme-of/controller@%s,%x:nqn=%s",
|
||||
+ nvmeof_info->target_wwpn,0xffff,
|
||||
+ nvmeof_info->nqn);
|
||||
+ unsigned int nsid = of_path_get_nvme_nsid (nvmedev);
|
||||
+ if (nsid)
|
||||
+ {
|
||||
+ snprintf (disk+chars_written, sizeof("/namespace@") + MAX_NVME_NSID_DIGITS,
|
||||
+ "/namespace@%x:%d", nsid, part);
|
||||
+ }
|
||||
+ free (nvmeof_info);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ snprintf (disk, sizeof (disk), "/disk@1:%c", 'a' + (part - 1));
|
||||
+ chars_written = snprintf(disk,sizeof(disk),"/nvme-of/controller@%s,%x:nqn=%s",
|
||||
+ nvmeof_info->target_wwpn,
|
||||
+ 0xffff,
|
||||
+ nvmeof_info->nqn);
|
||||
+
|
||||
+ unsigned int nsid = of_path_get_nvme_nsid(nvmedev);
|
||||
+
|
||||
+ if(nsid){
|
||||
+ snprintf(disk+chars_written,sizeof(disk) - chars_written,
|
||||
+ "/namespace@%x:%d",nsid, part);
|
||||
+ }
|
||||
+
|
||||
+ } else {
|
||||
+ snprintf (disk, sizeof (disk), "/disk@1:%c", 'a' + (part - 1));
|
||||
+ }
|
||||
free (nvmedev);
|
||||
}
|
||||
else
|
||||
@@ -386,45 +285,32 @@ index 89beceef4a..dd50d785dd 100644
|
||||
- snprintf (disk, sizeof (disk), "/disk@1");
|
||||
- sysfs_path = block_device_get_sysfs_path_and_link (device);
|
||||
+ sysfs_path = nvme_get_syspath (device);
|
||||
+ if (strstr (sysfs_path, "nvme-fabrics"))
|
||||
+ {
|
||||
+ nvmeof_info = malloc (sizeof (struct ofpath_nvmeof_info));
|
||||
+ if (!nvmeof_info)
|
||||
+ return NULL;
|
||||
+ if(strstr(sysfs_path,"nvme-fabrics")){
|
||||
+ struct ofpath_nvmeof_info* nvmeof_info;
|
||||
+ nvmeof_info = malloc(sizeof(nvmeof_info));
|
||||
+
|
||||
+ ret_val = of_path_get_nvmeof_adapter_info (sysfs_path, nvmeof_info);
|
||||
+ if (ret_val == -1)
|
||||
+ {
|
||||
+ free (nvmeof_info);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ of_path_get_nvmeof_adapter_info(sysfs_path, nvmeof_info);
|
||||
+
|
||||
+ sysfs_path = of_find_fc_host(nvmeof_info->host_wwpn);
|
||||
+
|
||||
+ sysfs_path = of_find_fc_host (nvmeof_info->host_wwpn);
|
||||
+ if (!sysfs_path)
|
||||
+ {
|
||||
+ free (nvmeof_info);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ chars_written = snprintf(disk,sizeof(disk),"/nvme-of/controller@%s,%x:nqn=%s",
|
||||
+ nvmeof_info->target_wwpn,
|
||||
+ 0xffff,
|
||||
+ nvmeof_info->nqn);
|
||||
+
|
||||
+ unsigned int nsid = of_path_get_nvme_nsid(device);
|
||||
+ if(nsid){
|
||||
+ snprintf(disk+chars_written,sizeof(disk) - chars_written,
|
||||
+ "/namespace@%x",nsid);
|
||||
+ }
|
||||
+ } else {
|
||||
+ snprintf (disk, sizeof (disk), "/disk@1");
|
||||
+ }
|
||||
+
|
||||
+ chars_written = snprintf (disk,sizeof(disk), "/nvme-of/controller@%s,%x:nqn=%s",
|
||||
+ nvmeof_info->target_wwpn, 0xffff,
|
||||
+ nvmeof_info->nqn);
|
||||
+ unsigned int nsid = of_path_get_nvme_nsid (device);
|
||||
+ if (nsid)
|
||||
+ {
|
||||
+ snprintf (disk+chars_written,sizeof("/namespace@") + sizeof(char) * MAX_NVME_NSID_DIGITS,
|
||||
+ "/namespace@%x", nsid);
|
||||
+ }
|
||||
+ free (nvmeof_info);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ snprintf (disk, sizeof (disk), "/disk@1");
|
||||
+ }
|
||||
}
|
||||
|
||||
of_path = find_obppath (sysfs_path);
|
||||
@@ -398,7 +753,6 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
@@ -398,7 +643,6 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
free (sysfs_path);
|
||||
return of_path;
|
||||
}
|
||||
@@ -432,7 +318,7 @@ index 89beceef4a..dd50d785dd 100644
|
||||
|
||||
static void
|
||||
of_fc_port_name(const char *path, const char *subpath, char *port_name)
|
||||
@@ -840,11 +1194,9 @@ grub_util_devname_to_ofpath (const char *sys_devname)
|
||||
@@ -840,11 +1084,9 @@ grub_util_devname_to_ofpath (const char *sys_devname)
|
||||
/* All the models I've seen have a devalias "floppy".
|
||||
New models have no floppy at all. */
|
||||
ofpath = xstrdup ("floppy");
|
||||
@@ -445,27 +331,24 @@ index 89beceef4a..dd50d785dd 100644
|
||||
{
|
||||
grub_util_warn (_("unknown device type %s"), device);
|
||||
diff --git a/include/grub/util/ofpath.h b/include/grub/util/ofpath.h
|
||||
index b43c523cb2..7ab377c7cc 100644
|
||||
index b43c523cb..a0ec30620 100644
|
||||
--- a/include/grub/util/ofpath.h
|
||||
+++ b/include/grub/util/ofpath.h
|
||||
@@ -3,4 +3,32 @@
|
||||
@@ -3,4 +3,33 @@
|
||||
|
||||
char *grub_util_devname_to_ofpath (const char *devname);
|
||||
|
||||
+struct ofpath_files_list_node
|
||||
+{
|
||||
+struct ofpath_files_list_node {
|
||||
+ char* filename;
|
||||
+ struct ofpath_files_list_node* next;
|
||||
+};
|
||||
+
|
||||
+struct ofpath_files_list_root
|
||||
+{
|
||||
+struct ofpath_files_list_root {
|
||||
+ int items;
|
||||
+ struct ofpath_files_list_node* first;
|
||||
+};
|
||||
+
|
||||
+struct ofpath_nvmeof_info
|
||||
+{
|
||||
+struct ofpath_nvmeof_info {
|
||||
+ char* host_wwpn;
|
||||
+ char* target_wwpn;
|
||||
+ char* nqn;
|
||||
@@ -473,14 +356,18 @@ index b43c523cb2..7ab377c7cc 100644
|
||||
+ int nsid;
|
||||
+};
|
||||
+
|
||||
+int of_path_get_nvmeof_adapter_info (char* sysfs_path, struct ofpath_nvmeof_info* nvmeof_info);
|
||||
+unsigned int of_path_get_nvme_nsid (const char* devname);
|
||||
+int add_filename_to_pile (char *filename, struct ofpath_files_list_root* root);
|
||||
+void find_file (char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth);
|
||||
+char* of_find_fc_host (char* host_wwpn);
|
||||
+void free_ofpath_files_list (struct ofpath_files_list_root* root);
|
||||
+void of_path_get_nvmeof_adapter_info(char* sysfs_path,
|
||||
+ struct ofpath_nvmeof_info* nvmeof_info);
|
||||
+
|
||||
+unsigned int of_path_get_nvme_nsid(const char* devname);
|
||||
+
|
||||
+void add_filename_to_pile(char *filename, struct ofpath_files_list_root* root);
|
||||
+
|
||||
+void find_file(char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth);
|
||||
+
|
||||
+char* of_find_fc_host(char* host_wwpn);
|
||||
+
|
||||
#endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */
|
||||
--
|
||||
2.48.1
|
||||
2.35.3
|
||||
|
||||
|
@@ -1,31 +0,0 @@
|
||||
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
|
||||
|
4489
0002-tpm2-Add-TPM-Software-Stack-TSS.patch
Normal file
4489
0002-tpm2-Add-TPM-Software-Stack-TSS.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,84 +0,0 @@
|
||||
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);
|
||||
}
|
385
0003-Add-grub2-switch-to-blscfg.patch
Normal file
385
0003-Add-grub2-switch-to-blscfg.patch
Normal file
@@ -0,0 +1,385 @@
|
||||
From 90153f1c9631498723450d84e014e25865fecc1b Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Thu, 15 Mar 2018 14:12:40 -0400
|
||||
Subject: [PATCH 3/9] Add grub2-switch-to-blscfg
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
[jhlavac: Use ${etcdefaultgrub} instead of /etc/default/grub]
|
||||
Signed-off-by: Jan Hlavac <jhlavac@redhat.com>
|
||||
[rharwood: skip on ostree installations, migrate man to h2m]
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
Makefile.util.def | 7 +
|
||||
docs/man/grub-switch-to-blscfg.h2m | 2 +
|
||||
util/grub-switch-to-blscfg.in | 317 +++++++++++++++++++++++++++++
|
||||
util/grub.d/10_linux.in | 2 +-
|
||||
4 files changed, 327 insertions(+), 1 deletion(-)
|
||||
create mode 100644 docs/man/grub-switch-to-blscfg.h2m
|
||||
create mode 100644 util/grub-switch-to-blscfg.in
|
||||
|
||||
diff --git a/Makefile.util.def b/Makefile.util.def
|
||||
index 6bb30c165..ffedea24a 100644
|
||||
--- a/Makefile.util.def
|
||||
+++ b/Makefile.util.def
|
||||
@@ -1460,6 +1460,13 @@ program = {
|
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
|
||||
};
|
||||
|
||||
+script = {
|
||||
+ name = grub-switch-to-blscfg;
|
||||
+ common = util/grub-switch-to-blscfg.in;
|
||||
+ mansection = 8;
|
||||
+ installdir = sbin;
|
||||
+};
|
||||
+
|
||||
program = {
|
||||
name = grub-glue-efi;
|
||||
mansection = 1;
|
||||
diff --git a/docs/man/grub-switch-to-blscfg.h2m b/docs/man/grub-switch-to-blscfg.h2m
|
||||
new file mode 100644
|
||||
index 000000000..fa341426a
|
||||
--- /dev/null
|
||||
+++ b/docs/man/grub-switch-to-blscfg.h2m
|
||||
@@ -0,0 +1,2 @@
|
||||
+[NAME]
|
||||
+grub-switch-to-blscfg \- switch to using BLS config files
|
||||
diff --git a/util/grub-switch-to-blscfg.in b/util/grub-switch-to-blscfg.in
|
||||
new file mode 100644
|
||||
index 000000000..a851424be
|
||||
--- /dev/null
|
||||
+++ b/util/grub-switch-to-blscfg.in
|
||||
@@ -0,0 +1,317 @@
|
||||
+#! /bin/sh
|
||||
+#
|
||||
+# Set a default boot entry for GRUB.
|
||||
+# Copyright (C) 2004,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/>.
|
||||
+
|
||||
+#set -eu
|
||||
+
|
||||
+# Initialize some variables.
|
||||
+prefix=@prefix@
|
||||
+exec_prefix=@exec_prefix@
|
||||
+sbindir=@sbindir@
|
||||
+bindir=@bindir@
|
||||
+sysconfdir="@sysconfdir@"
|
||||
+PACKAGE_NAME=@PACKAGE_NAME@
|
||||
+PACKAGE_VERSION=@PACKAGE_VERSION@
|
||||
+datarootdir="@datarootdir@"
|
||||
+datadir="@datadir@"
|
||||
+if [ ! -v pkgdatadir ]; then
|
||||
+ pkgdatadir="${datadir}/@PACKAGE@"
|
||||
+fi
|
||||
+
|
||||
+self=`basename $0`
|
||||
+
|
||||
+grub_get_kernel_settings="${sbindir}/@grub_get_kernel_settings@"
|
||||
+grub_editenv=${bindir}/@grub_editenv@
|
||||
+etcdefaultgrub=/etc/default/grub
|
||||
+
|
||||
+eval "$("${grub_get_kernel_settings}")" || true
|
||||
+
|
||||
+EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 's/\"//g')
|
||||
+if [ -d /sys/firmware/efi/efivars/ ]; then
|
||||
+ startlink=/etc/grub2-efi.cfg
|
||||
+ grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'`
|
||||
+else
|
||||
+ startlink=/etc/grub2.cfg
|
||||
+ grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`
|
||||
+fi
|
||||
+
|
||||
+blsdir=`echo "/@bootdirname@/loader/entries" | sed 's,//*,/,g'`
|
||||
+
|
||||
+backupsuffix=.bak
|
||||
+
|
||||
+arch="$(uname -m)"
|
||||
+
|
||||
+export TEXTDOMAIN=@PACKAGE@
|
||||
+export TEXTDOMAINDIR="@localedir@"
|
||||
+
|
||||
+. "${pkgdatadir}/grub-mkconfig_lib"
|
||||
+
|
||||
+# Usage: usage
|
||||
+# Print the usage.
|
||||
+usage () {
|
||||
+ gettext_printf "Usage: %s\n" "$self"
|
||||
+ gettext "Switch to BLS config files.\n"; echo
|
||||
+ echo
|
||||
+ print_option_help "-h, --help" "$(gettext "print this message and exit")"
|
||||
+ print_option_help "-V, --version" "$(gettext "print the version information and exit")"
|
||||
+ echo
|
||||
+ print_option_help "--backup-suffix=$(gettext "SUFFIX")" "$backupsuffix"
|
||||
+ print_option_help "--bls-directory=$(gettext "DIR")" "$blsdir"
|
||||
+ print_option_help "--config-file=$(gettext "FILE")" "$startlink"
|
||||
+ print_option_help "--grub-defaults=$(gettext "FILE")" "$etcdefaultgrub"
|
||||
+ print_option_help "--grub-directory=$(gettext "DIR")" "$grubdir"
|
||||
+ # echo
|
||||
+ # gettext "Report bugs to <bug-grub@gnu.org>."; echo
|
||||
+}
|
||||
+
|
||||
+argument () {
|
||||
+ opt=$1
|
||||
+ shift
|
||||
+
|
||||
+ if test $# -eq 0; then
|
||||
+ gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" "$opt" 1>&2
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ echo $1
|
||||
+}
|
||||
+
|
||||
+# Check the arguments.
|
||||
+while test $# -gt 0
|
||||
+do
|
||||
+ option=$1
|
||||
+ shift
|
||||
+
|
||||
+ case "$option" in
|
||||
+ -h | --help)
|
||||
+ usage
|
||||
+ exit 0 ;;
|
||||
+ -V | --version)
|
||||
+ echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
|
||||
+ exit 0 ;;
|
||||
+
|
||||
+ --backup-suffix)
|
||||
+ backupsuffix=`argument $option "$@"`
|
||||
+ shift
|
||||
+ ;;
|
||||
+ --backup-suffix=*)
|
||||
+ backupsuffix=`echo "$option" | sed 's/--backup-suffix=//'`
|
||||
+ ;;
|
||||
+
|
||||
+ --bls-directory)
|
||||
+ blsdir=`argument $option "$@"`
|
||||
+ shift
|
||||
+ ;;
|
||||
+ --bls-directory=*)
|
||||
+ blsdir=`echo "$option" | sed 's/--bls-directory=//'`
|
||||
+ ;;
|
||||
+
|
||||
+ --config-file)
|
||||
+ startlink=`argument $option "$@"`
|
||||
+ shift
|
||||
+ ;;
|
||||
+ --config-file=*)
|
||||
+ startlink=`echo "$option" | sed 's/--config-file=//'`
|
||||
+ ;;
|
||||
+
|
||||
+ --grub-defaults)
|
||||
+ etcdefaultgrub=`argument $option "$@"`
|
||||
+ shift
|
||||
+ ;;
|
||||
+ --grub-defaults=*)
|
||||
+ etcdefaultgrub=`echo "$option" | sed 's/--grub-defaults=//'`
|
||||
+ ;;
|
||||
+
|
||||
+ --grub-directory)
|
||||
+ grubdir=`argument $option "$@"`
|
||||
+ shift
|
||||
+ ;;
|
||||
+ --grub-directory=*)
|
||||
+ grubdir=`echo "$option" | sed 's/--grub-directory=//'`
|
||||
+ ;;
|
||||
+
|
||||
+ *)
|
||||
+ gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ ;;
|
||||
+ esac
|
||||
+done
|
||||
+
|
||||
+find_grub_cfg() {
|
||||
+ local candidate=""
|
||||
+ while [ -e "${candidate}" -o $# -gt 0 ]
|
||||
+ do
|
||||
+ if [ ! -e "${candidate}" ] ; then
|
||||
+ candidate="$1"
|
||||
+ shift
|
||||
+ fi
|
||||
+
|
||||
+ if [ -L "${candidate}" ]; then
|
||||
+ candidate="$(realpath "${candidate}")"
|
||||
+ fi
|
||||
+
|
||||
+ if [ -f "${candidate}" ]; then
|
||||
+ export GRUB_CONFIG_FILE="${candidate}"
|
||||
+ return 0
|
||||
+ fi
|
||||
+ done
|
||||
+ return 1
|
||||
+}
|
||||
+
|
||||
+if ! find_grub_cfg ${startlink} ${grubdir}/grub.cfg ; then
|
||||
+ gettext_printf "Couldn't find config file\n" 1>&2
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
+if [ ! -d "${blsdir}" ]; then
|
||||
+ install -m 700 -d "${blsdir}"
|
||||
+fi
|
||||
+
|
||||
+if [ -f /etc/machine-id ]; then
|
||||
+ MACHINE_ID=$(cat /etc/machine-id)
|
||||
+else
|
||||
+ MACHINE_ID=$(dmesg | sha256sum)
|
||||
+fi
|
||||
+
|
||||
+mkbls() {
|
||||
+ local kernelver=$1 && shift
|
||||
+ local datetime=$1 && shift
|
||||
+ local kernelopts=$1 && shift
|
||||
+
|
||||
+ local debugname=""
|
||||
+ local debugid=""
|
||||
+ local flavor=""
|
||||
+
|
||||
+ if [ "$kernelver" == *\+* ] ; then
|
||||
+ local flavor=-"${kernelver##*+}"
|
||||
+ if [ "${flavor}" == "-debug" ]; then
|
||||
+ local debugname=" with debugging"
|
||||
+ local debugid="-debug"
|
||||
+ fi
|
||||
+ fi
|
||||
+ (
|
||||
+ source /etc/os-release
|
||||
+
|
||||
+ cat <<EOF
|
||||
+title ${NAME} (${kernelver}) ${VERSION}${debugname}
|
||||
+version ${kernelver}${debugid}
|
||||
+linux /vmlinuz-${kernelver}
|
||||
+initrd /initramfs-${kernelver}.img
|
||||
+options ${kernelopts}
|
||||
+grub_users \$grub_users
|
||||
+grub_arg --unrestricted
|
||||
+grub_class kernel${flavor}
|
||||
+EOF
|
||||
+ ) | cat
|
||||
+}
|
||||
+
|
||||
+copy_bls() {
|
||||
+ for kernelver in $(cd /lib/modules/ ; ls -1) "" ; do
|
||||
+ bls_target="${blsdir}/${MACHINE_ID}-${kernelver}.conf"
|
||||
+ linux="/vmlinuz-${kernelver}"
|
||||
+ linux_path="/boot${linux}"
|
||||
+ kernel_dir="/lib/modules/${kernelver}"
|
||||
+
|
||||
+ if [ ! -d "${kernel_dir}" ] ; then
|
||||
+ continue
|
||||
+ fi
|
||||
+ if [ ! -f "${linux_path}" ]; then
|
||||
+ continue
|
||||
+ fi
|
||||
+
|
||||
+ linux_relpath="$("${grub_mkrelpath}" "${linux_path}")"
|
||||
+ bootprefix="${linux_relpath%%"${linux}"}"
|
||||
+ cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
|
||||
+
|
||||
+ mkbls "${kernelver}" \
|
||||
+ "$(date -u +%Y%m%d%H%M%S -d "$(stat -c '%y' "${kernel_dir}")")" \
|
||||
+ "${bootprefix}" "${cmdline}" >"${bls_target}"
|
||||
+
|
||||
+ if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then
|
||||
+ bls_debug="$(echo ${bls_target} | sed -e "s/${kernelver}/${kernelver}~debug/")"
|
||||
+ cp -aT "${bls_target}" "${bls_debug}"
|
||||
+ title="$(grep '^title[ \t]' "${bls_debug}" | sed -e 's/^title[ \t]*//')"
|
||||
+ options="$(echo "${cmdline} ${GRUB_CMDLINE_LINUX_DEBUG}" | sed -e 's/\//\\\//g')"
|
||||
+ sed -i -e "s/^title.*/title ${title}${GRUB_LINUX_DEBUG_TITLE_POSTFIX}/" "${bls_debug}"
|
||||
+ sed -i -e "s/^options.*/options ${options}/" "${bls_debug}"
|
||||
+ fi
|
||||
+ done
|
||||
+
|
||||
+ if [ -f "/boot/vmlinuz-0-rescue-${MACHINE_ID}" ]; then
|
||||
+ mkbls "0-rescue-${MACHINE_ID}" "0" "${bootprefix}" >"${blsdir}/${MACHINE_ID}-0-rescue.conf"
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
+# The grub2 EFI binary is not copied to the ESP as a part of an ostree
|
||||
+# transaction. Make sure a grub2 version with BLS support is installed
|
||||
+# but only do this if the blsdir is not set, to make sure that the BLS
|
||||
+# parsing module will search for the BLS snippets in the default path.
|
||||
+if test -f /run/ostree-booted && test -d /sys/firmware/efi/efivars && \
|
||||
+ ! ${grub_editenv} - list | grep -q blsdir && \
|
||||
+ mountpoint -q /boot; then
|
||||
+ grub_binary="$(find /usr/lib/ostree-boot/efi/EFI/${EFIDIR}/ -name grub*.efi)"
|
||||
+ install -m 700 ${grub_binary} ${grubdir} || exit 1
|
||||
+ # Create a hidden file to indicate that grub2 now has BLS support.
|
||||
+ touch /boot/grub2/.grub2-blscfg-supported
|
||||
+fi
|
||||
+
|
||||
+GENERATE=0
|
||||
+if grep '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" \
|
||||
+ | grep -vq '^GRUB_ENABLE_BLSCFG="*true"*\s*$' ; then
|
||||
+ if ! sed -i"${backupsuffix}" \
|
||||
+ -e 's,^GRUB_ENABLE_BLSCFG=.*,GRUB_ENABLE_BLSCFG=true,' \
|
||||
+ "${etcdefaultgrub}" ; then
|
||||
+ gettext_printf "Updating %s failed\n" "${etcdefaultgrub}"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ GENERATE=1
|
||||
+elif ! grep -q '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" ; then
|
||||
+ if ! echo 'GRUB_ENABLE_BLSCFG=true' >> "${etcdefaultgrub}" ; then
|
||||
+ gettext_printf "Updating %s failed\n" "${etcdefaultgrub}"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ GENERATE=1
|
||||
+fi
|
||||
+
|
||||
+if [ "${GENERATE}" -eq 1 ] ; then
|
||||
+ copy_bls
|
||||
+
|
||||
+ if [ $arch = "x86_64" ] && [ ! -d /sys/firmware/efi ]; then
|
||||
+ mod_dir="i386-pc"
|
||||
+ elif [ $arch = "ppc64" -o $arch = "ppc64le" ] && [ ! -d /sys/firmware/opal ]; then
|
||||
+ mod_dir="powerpc-ieee1275"
|
||||
+ fi
|
||||
+
|
||||
+ if [ -n "${mod_dir}" ]; then
|
||||
+ for mod in blscfg increment; do
|
||||
+ install -m 700 ${prefix}/lib/grub/${mod_dir}/${mod}.mod ${grubdir}/$mod_dir/ || exit 1
|
||||
+ done
|
||||
+ fi
|
||||
+
|
||||
+ cp -af "${GRUB_CONFIG_FILE}" "${GRUB_CONFIG_FILE}${backupsuffix}"
|
||||
+ if ! grub2-mkconfig -o "${GRUB_CONFIG_FILE}" ; then
|
||||
+ install -m 700 "${GRUB_CONFIG_FILE}${backupsuffix}" "${GRUB_CONFIG_FILE}"
|
||||
+ sed -i"${backupsuffix}" \
|
||||
+ -e 's,^GRUB_ENABLE_BLSCFG=.*,GRUB_ENABLE_BLSCFG=false,' \
|
||||
+ "${etcdefaultgrub}"
|
||||
+ gettext_printf "Updating %s failed\n" "${GRUB_CONFIG_FILE}"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+# Bye.
|
||||
+exit 0
|
||||
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
|
||||
index 49eccbeaf..45eefb332 100644
|
||||
--- a/util/grub.d/10_linux.in
|
||||
+++ b/util/grub.d/10_linux.in
|
||||
@@ -147,7 +147,7 @@ blsdir="/boot/loader/entries"
|
||||
|
||||
get_sorted_bls()
|
||||
{
|
||||
- if ! [ -d "${blsdir}" ]; then
|
||||
+ if ! [ -d "${blsdir}" ] || [ -f /run/ostree-booted ] || [ -d /ostree/repo ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
--
|
||||
2.44.0
|
||||
|
117
0003-Restrict-ls-and-auto-file-completion-on-cryptodisk-p.patch
Normal file
117
0003-Restrict-ls-and-auto-file-completion-on-cryptodisk-p.patch
Normal file
@@ -0,0 +1,117 @@
|
||||
From 6c8d390809956d355fed8bc830f64e86838e3e82 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Sat, 18 Nov 2023 21:42:00 +0800
|
||||
Subject: [PATCH 3/4] Restrict 'ls' and auto file completion on cryptodisk
|
||||
print
|
||||
|
||||
The 'ls' command allows file listing, while file completion assists in
|
||||
providing matched file names by partially inputting via the TAB key.
|
||||
Both functionalities should be restricted when the disk is automatically
|
||||
unlocked for the same reasons as highlighted in the previous patch
|
||||
addressing the limitation on file access to the cryptodisk.
|
||||
|
||||
Given that no file is explicitly opened for listing, employing file
|
||||
filters becomes impractical. Consequently, this patch focuses on
|
||||
modifying relevant routines separately to incorporate necessary checks.
|
||||
The objective is to introduce measures that prevent 'ls' and auto file
|
||||
completion from accessing encrypted data when the disk is automatically
|
||||
unlocked.
|
||||
|
||||
By implementing these modifications, any attempt to utilize 'ls' or file
|
||||
completion on the cryptodisk will result in an "Access Denied:
|
||||
prohibited to browse encrypted data" error message, thus effectively
|
||||
alerting the user about the restricted access.
|
||||
|
||||
While protecting content within disk files from viewing is essential,
|
||||
it's equally crucial to restrict access to in-memory content. This
|
||||
includes prohibiting access to the decrypted in-memory copies of disk
|
||||
files.
|
||||
|
||||
This enhancement aims to fortify security protocols by extending
|
||||
restrictions to additional functionalities beyond direct file access.
|
||||
|
||||
Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/ls.c | 8 ++++++++
|
||||
grub-core/commands/minicmd.c | 6 ++++++
|
||||
grub-core/kern/corecmd.c | 8 ++++++++
|
||||
grub-core/normal/completion.c | 8 ++++++++
|
||||
4 files changed, 30 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c
|
||||
index 8e98c73cc..aeb336a73 100644
|
||||
--- a/grub-core/commands/ls.c
|
||||
+++ b/grub-core/commands/ls.c
|
||||
@@ -183,6 +183,14 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
|
||||
if (! dev)
|
||||
goto fail;
|
||||
|
||||
+ if (dev->disk &&
|
||||
+ grub_disk_is_crypto (dev->disk) &&
|
||||
+ grub_file_filters[GRUB_FILE_FILTER_NOCAT])
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to browse encrypted content"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
fs = grub_fs_probe (dev);
|
||||
path = grub_strchr (dirname, ')');
|
||||
if (! path)
|
||||
diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c
|
||||
index fa498931e..8f2ac0539 100644
|
||||
--- a/grub-core/commands/minicmd.c
|
||||
+++ b/grub-core/commands/minicmd.c
|
||||
@@ -101,6 +101,12 @@ grub_mini_cmd_dump (struct grub_command *cmd __attribute__ ((unused)),
|
||||
if (argc == 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no address specified");
|
||||
|
||||
+ /* NOCAT filter is applied to prevent cat alike command from revealing file
|
||||
+ * content, the dump command should also be prohibited to revealing memory
|
||||
+ * content as well */
|
||||
+ if (grub_file_filters[GRUB_FILE_FILTER_NOCAT])
|
||||
+ return grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited by security policy"));
|
||||
+
|
||||
#if GRUB_CPU_SIZEOF_VOID_P == GRUB_CPU_SIZEOF_LONG
|
||||
#define grub_strtoaddr grub_strtoul
|
||||
#else
|
||||
diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c
|
||||
index 62d434ba9..b639bc3ae 100644
|
||||
--- a/grub-core/kern/corecmd.c
|
||||
+++ b/grub-core/kern/corecmd.c
|
||||
@@ -135,6 +135,14 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)),
|
||||
if (! dev)
|
||||
goto fail;
|
||||
|
||||
+ if (dev->disk &&
|
||||
+ grub_disk_is_crypto (dev->disk) &&
|
||||
+ grub_file_filters[GRUB_FILE_FILTER_NOCAT])
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to browse encrypted content"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
fs = grub_fs_probe (dev);
|
||||
path = grub_strchr (argv[0], ')');
|
||||
if (! path)
|
||||
diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c
|
||||
index 18cadfa85..d003ec37d 100644
|
||||
--- a/grub-core/normal/completion.c
|
||||
+++ b/grub-core/normal/completion.c
|
||||
@@ -259,6 +259,14 @@ complete_file (void)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ if (dev->disk &&
|
||||
+ grub_disk_is_crypto (dev->disk) &&
|
||||
+ grub_file_filters[GRUB_FILE_FILTER_NOCAT])
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to browse encrypted content"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
fs = grub_fs_probe (dev);
|
||||
if (! fs)
|
||||
{
|
||||
--
|
||||
2.42.1
|
||||
|
@@ -1,136 +0,0 @@
|
||||
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,34 +0,0 @@
|
||||
From a0bcce49bc285fb71c572963e662db3d88bcd563 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Wed, 16 Jul 2025 17:52:03 +0800
|
||||
Subject: [PATCH 3/4] docs: Clarify test for files on TFTP and HTTP
|
||||
|
||||
---
|
||||
docs/grub.texi | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index 9aaea7282..4b947e942 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -5887,13 +5887,13 @@ the strings are not equal
|
||||
@item @var{prefix}@var{integer1} @code{-plt} @var{prefix}@var{integer2}
|
||||
@var{integer1} is less than @var{integer2} after stripping off common non-numeric @var{prefix}.
|
||||
@item @var{file1} @code{-nt} @var{file2}
|
||||
-@var{file1} is newer than @var{file2} (modification time). Optionally numeric @var{bias} may be directly appended to @code{-nt} in which case it is added to the first file modification time.
|
||||
+@var{file1} is newer than @var{file2} (modification time). Optionally numeric @var{bias} may be directly appended to @code{-nt} in which case it is added to the first file modification time. For @var{file} on TFTP or HTTP servers, this operation may not work as expected.
|
||||
@item @var{file1} @code{-ot} @var{file2}
|
||||
-@var{file1} is older than @var{file2} (modification time). Optionally numeric @var{bias} may be directly appended to @code{-ot} in which case it is added to the first file modification time.
|
||||
+@var{file1} is older than @var{file2} (modification time). Optionally numeric @var{bias} may be directly appended to @code{-ot} in which case it is added to the first file modification time. For @var{file} on TFTP or HTTP servers, this operation may not work as expected.
|
||||
@item @code{-d} @var{file}
|
||||
-@var{file} exists and is a directory
|
||||
+@var{file} exists and is a directory. For @var{file} on TFTP or HTTP servers, the test is unreliable because these protocols are designed for file transport, and GRUB’s netfs does not implement directory listing for them.
|
||||
@item @code{-e} @var{file}
|
||||
-@var{file} exists
|
||||
+@var{file} exists. For @var{file} on TFTP or HTTP servers, the result is the same as @code{-f} because these protocols are designed for file transport, and GRUB’s netfs lacks directory support to distinguish between files and directories.
|
||||
@item @code{-f} @var{file}
|
||||
@var{file} exists and is not a directory
|
||||
@item @code{-s} @var{file}
|
||||
--
|
||||
2.50.0
|
||||
|
@@ -1,34 +0,0 @@
|
||||
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
|
||||
|
@@ -1,49 +0,0 @@
|
||||
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
|
||||
|
@@ -1,95 +0,0 @@
|
||||
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
|
||||
|
@@ -1,693 +0,0 @@
|
||||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,66 +0,0 @@
|
||||
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
|
||||
|
@@ -1,7 +1,7 @@
|
||||
From 977f8c63d9d85fd101e989310ac0ba011f252df1 Mon Sep 17 00:00:00 2001
|
||||
From 6547d22fc9e20720d1a896be82b2d50d842f86b0 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 20 Nov 2023 09:25:53 +0800
|
||||
Subject: [PATCH 2/2] Key revocation on out of bound file access
|
||||
Subject: [PATCH 4/4] Key revocation on out of bound file access
|
||||
|
||||
After successful disk unlocking, grub now takes on the responsibility of
|
||||
safeguarding passwords or TPM keys exclusively within authenticated
|
||||
@@ -14,71 +14,17 @@ system boot files, except for essential internal processes like memdisk
|
||||
and procfs, ensuring key protection against potential breaches due to
|
||||
inadvertent customizations in grub.cfg.
|
||||
|
||||
v2: use cryptocheck command
|
||||
The grub_disk_is_crypto() function duplicates the purpose of the
|
||||
cryptocheck command and is therefore removed. A new check function now
|
||||
calls cryptocheck directly to improve code reuse.
|
||||
|
||||
Signed-Off-by: Michael Chang <mchang@suse.com>
|
||||
Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/crypttab.c | 76 +++++++++++++++++++++++++++++++++++
|
||||
grub-core/disk/diskfilter.c | 1 +
|
||||
grub-core/commands/crypttab.c | 36 +++++++++++++++++++++++++++++++++++
|
||||
include/grub/file.h | 1 +
|
||||
3 files changed, 78 insertions(+)
|
||||
2 files changed, 37 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/crypttab.c b/grub-core/commands/crypttab.c
|
||||
index 9397bede9e..f104154e23 100644
|
||||
index d3acc4b59..e09296c57 100644
|
||||
--- a/grub-core/commands/crypttab.c
|
||||
+++ b/grub-core/commands/crypttab.c
|
||||
@@ -6,11 +6,47 @@
|
||||
#include <grub/mm.h>
|
||||
#include <grub/list.h>
|
||||
#include <grub/crypttab.h>
|
||||
+#include <grub/file.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
grub_crypto_key_list_t *cryptokey_lst;
|
||||
|
||||
+static int
|
||||
+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 0; /* This is (crypto*) disk */
|
||||
+
|
||||
+ if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID)
|
||||
+ {
|
||||
+ char opt[] = "--quiet";
|
||||
+ char *args[2];
|
||||
+
|
||||
+ cmd = grub_command_find ("cryptocheck");
|
||||
+ if (!cmd) /* No diskfilter module loaded for some reason */
|
||||
+ return 1;
|
||||
+
|
||||
+ disk_str_len = grub_strlen (disk->name) + 2 + 1;
|
||||
+ disk_str = grub_malloc (disk_str_len);
|
||||
+ if (!disk_str) /* Something is wrong, better report as unencrypted */
|
||||
+ return 1;
|
||||
+
|
||||
+ grub_snprintf (disk_str, disk_str_len, "(%s)", disk->name);
|
||||
+ args[0] = opt;
|
||||
+ args[1] = disk_str;
|
||||
+ res = cmd->func (cmd, 2, args);
|
||||
+ grub_free (disk_str);
|
||||
+ return (res != GRUB_ERR_NONE); /* GRUB_ERR_NONE for encrypted */
|
||||
+ }
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
grub_err_t
|
||||
grub_cryptokey_add_or_update (const char *uuid, const char *key, grub_size_t key_len, const char *path, int is_tpmkey)
|
||||
{
|
||||
@@ -89,6 +125,44 @@ grub_cryptokey_tpmkey_discard (void)
|
||||
@@ -121,6 +121,41 @@ grub_cryptokey_tpmkey_discard (void)
|
||||
grub_cryptokey_discard();
|
||||
}
|
||||
|
||||
@@ -107,11 +53,8 @@ index 9397bede9e..f104154e23 100644
|
||||
+ case GRUB_FILE_TYPE_LINUX_INITRD:
|
||||
+ case GRUB_FILE_TYPE_LOADENV:
|
||||
+ case GRUB_FILE_TYPE_THEME:
|
||||
+ if (!disk || is_unencrypted_disk (disk))
|
||||
+ {
|
||||
+ grub_cryptokey_discard ();
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ }
|
||||
+ if (!disk || !grub_disk_is_crypto (disk))
|
||||
+ grub_cryptokey_discard ();
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
@@ -123,29 +66,16 @@ index 9397bede9e..f104154e23 100644
|
||||
static grub_err_t
|
||||
grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **argv)
|
||||
@@ -121,6 +195,8 @@ GRUB_MOD_INIT(crypttab)
|
||||
@@ -153,6 +188,7 @@ GRUB_MOD_INIT(crypttab)
|
||||
{
|
||||
cmd = grub_register_command ("crypttab_entry", grub_cmd_crypttab_entry,
|
||||
N_("VOLUME-NAME ENCRYPTED-DEVICE KEY-FILE") , N_("No description"));
|
||||
+ grub_file_filter_register (GRUB_FILE_FILTER_DISTRUST, grub_distrust_open);
|
||||
+ grub_dl_set_persistent (mod);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(crypttab)
|
||||
diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c
|
||||
index b1d5d464f5..e23215486d 100644
|
||||
--- a/grub-core/disk/diskfilter.c
|
||||
+++ b/grub-core/disk/diskfilter.c
|
||||
@@ -590,6 +590,7 @@ grub_diskfilter_open (const char *name, grub_disk_t disk)
|
||||
|
||||
disk->total_sectors = lv->size;
|
||||
disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE;
|
||||
+
|
||||
return 0;
|
||||
grub_dl_set_persistent (mod);
|
||||
}
|
||||
|
||||
diff --git a/include/grub/file.h b/include/grub/file.h
|
||||
index c463e4f992..804d512231 100644
|
||||
index fcfd32ce2..daf23a9c9 100644
|
||||
--- a/include/grub/file.h
|
||||
+++ b/include/grub/file.h
|
||||
@@ -185,6 +185,7 @@ extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook);
|
||||
@@ -153,9 +83,9 @@ index c463e4f992..804d512231 100644
|
||||
typedef enum grub_file_filter_id
|
||||
{
|
||||
+ GRUB_FILE_FILTER_DISTRUST,
|
||||
GRUB_FILE_FILTER_NOCAT,
|
||||
GRUB_FILE_FILTER_VERIFY,
|
||||
GRUB_FILE_FILTER_GZIO,
|
||||
GRUB_FILE_FILTER_XZIO,
|
||||
--
|
||||
2.49.0
|
||||
2.42.1
|
||||
|
||||
|
@@ -1,798 +0,0 @@
|
||||
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
|
||||
|
@@ -1,70 +0,0 @@
|
||||
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
|
||||
|
@@ -1,92 +0,0 @@
|
||||
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
|
||||
|
@@ -1,218 +0,0 @@
|
||||
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
|
||||
|
28
0004-ofpath-controller-name-update.patch
Normal file
28
0004-ofpath-controller-name-update.patch
Normal file
@@ -0,0 +1,28 @@
|
||||
From 7717cd9c27f18703287403af1a955588e3d0261f Mon Sep 17 00:00:00 2001
|
||||
From: mamatha <mainamdar@in.ibm.com>
|
||||
Date: Sat, 24 Sep 2022 11:22:39 +0530
|
||||
Subject: [PATCH 4/4] ofpath controller name update
|
||||
|
||||
patch to update ofpath controller name
|
||||
|
||||
Signed-off-by: mamatha <mainamdar@in.ibm.com>
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
|
||||
index 212782d3f..7d31cfd0f 100644
|
||||
--- a/grub-core/osdep/linux/ofpath.c
|
||||
+++ b/grub-core/osdep/linux/ofpath.c
|
||||
@@ -483,6 +483,8 @@ of_path_get_nvmeof_adapter_info(char* sysfs_path,
|
||||
buf3=strchr(buf2,'-')+1;
|
||||
buf3=strchr(buf3,'-')+1;
|
||||
nvmeof_info->target_wwpn = buf3;
|
||||
+ buf3=strchr(buf3,'x')+1;
|
||||
+ nvmeof_info->target_wwpn = buf3;
|
||||
buf3 = strchr(nvmeof_info->target_wwpn,',');
|
||||
*buf3 = '\0';
|
||||
|
||||
--
|
||||
2.35.3
|
||||
|
@@ -1,59 +0,0 @@
|
||||
From 9f8f5e0d45165b99d0f3ce9bf37382738e0bddb7 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 17 Jul 2025 13:29:48 +0800
|
||||
Subject: [PATCH 4/4] tftp: Fix hang when file is a directory
|
||||
|
||||
We observed an issue when accessing a remote directory via TFTP: GRUB
|
||||
hangs indefinitely instead of returning an error immediately.
|
||||
|
||||
The packet capture [1] shows that the server doesn't send an error
|
||||
packet right after the RRQ. Instead, it first replies with an OACK
|
||||
indicating tsize=22, as if the target were a regular file. After GRUB
|
||||
sends its ACK, the server then sends an error "Is a directory". GRUB
|
||||
ignores this delayed error and hangs while waiting for data that never
|
||||
arrives.
|
||||
|
||||
This happens because GRUB currently assumes any error must follow the
|
||||
RRQ immediately, before data transfer begins. Once it receives an OACK,
|
||||
it switches to expecting data packets and neglects any error that
|
||||
arrives afterward.
|
||||
|
||||
To work around this, we detect an error on block 0 immediately after
|
||||
OACK, set the eof and stall flags to break out of the receive loop, and
|
||||
close the socket (so that tftp_close() won't send another error). GRUB
|
||||
will then report the error and exit properly.
|
||||
|
||||
[1]
|
||||
Source Destination Info
|
||||
192.168.100.122 192.168.100.2 Read Request, File: /grub/i386-pc, Transfer type: octet, blksize=1024, tsize=0
|
||||
192.168.100.2 192.168.100.122 Option Acknowledgement, blksize=1024, tsize=22
|
||||
192.168.100.122 192.168.100.2 Acknowledgement, Block: 0
|
||||
192.168.100.2 192.168.100.122 Error Code, Code: Not defined, Message: Is a directory
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/net/tftp.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c
|
||||
index 409b1d09b..93452fe3b 100644
|
||||
--- a/grub-core/net/tftp.c
|
||||
+++ b/grub-core/net/tftp.c
|
||||
@@ -250,6 +250,14 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)),
|
||||
grub_netbuff_free (nb);
|
||||
return GRUB_ERR_NONE;
|
||||
case TFTP_ERROR:
|
||||
+ if (data->have_oack == 1 && data->block == 0)
|
||||
+ {
|
||||
+ file->device->net->eof = 1;
|
||||
+ file->device->net->stall = 1;
|
||||
+ /* Do not send closed error code back to server in tftp_close() */
|
||||
+ grub_net_udp_close (data->sock);
|
||||
+ data->sock = NULL;
|
||||
+ }
|
||||
data->have_oack = 1;
|
||||
grub_error (GRUB_ERR_IO, "%s", tftph->u.err.errmsg);
|
||||
grub_error_save (&data->save_err);
|
||||
--
|
||||
2.50.0
|
||||
|
@@ -1,413 +0,0 @@
|
||||
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
|
||||
|
@@ -1,255 +0,0 @@
|
||||
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
|
||||
|
@@ -1,71 +0,0 @@
|
||||
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
|
||||
|
@@ -1,38 +0,0 @@
|
||||
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
|
||||
|
@@ -1,109 +0,0 @@
|
||||
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
|
||||
|
@@ -1,200 +0,0 @@
|
||||
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;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -1,150 +0,0 @@
|
||||
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
|
||||
|
@@ -1,161 +0,0 @@
|
||||
From ff14b89bda0445b97ad43b7cdbc5f20345f20006 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Date: Tue, 26 Nov 2024 15:39:45 -0500
|
||||
Subject: [PATCH 6/7] ieee1275/tcg2: Add TCG2 driver for ieee1275 PowerPC
|
||||
firmware
|
||||
|
||||
Follow recent extensions of EFI support providing a TCG2 driver with
|
||||
a public API for getting the maximum TPM command size and passing a TPM
|
||||
command through to the TPM 2. Implement this functionality using ieee1275
|
||||
PowerPC firmware API calls. Move tcg2.c into the TCG2 driver.
|
||||
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 3 +-
|
||||
grub-core/lib/ieee1275/tcg2.c | 102 ++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 104 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index c5fd796d4..8ecedf986 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1155,7 +1155,6 @@ module = {
|
||||
name = tpm;
|
||||
common = commands/tpm.c;
|
||||
ieee1275 = commands/ieee1275/ibmvtpm.c;
|
||||
- ieee1275 = lib/ieee1275/tcg2.c;
|
||||
enable = powerpc_ieee1275;
|
||||
};
|
||||
|
||||
@@ -2576,8 +2575,10 @@ module = {
|
||||
common = lib/tss2/tss2.c;
|
||||
efi = lib/efi/tcg2.c;
|
||||
emu = lib/tss2/tcg2_emu.c;
|
||||
+ powerpc_ieee1275 = lib/ieee1275/tcg2.c;
|
||||
enable = efi;
|
||||
enable = emu;
|
||||
+ enable = powerpc_ieee1275;
|
||||
cppflags = '-I$(srcdir)/lib/tss2';
|
||||
};
|
||||
|
||||
diff --git a/grub-core/lib/ieee1275/tcg2.c b/grub-core/lib/ieee1275/tcg2.c
|
||||
index ea01a30eb..40161c2f9 100644
|
||||
--- a/grub-core/lib/ieee1275/tcg2.c
|
||||
+++ b/grub-core/lib/ieee1275/tcg2.c
|
||||
@@ -23,6 +23,8 @@
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
|
||||
+#include <tcg2.h>
|
||||
+
|
||||
grub_ieee1275_ihandle_t grub_ieee1275_tpm_ihandle = GRUB_IEEE1275_IHANDLE_INVALID;
|
||||
|
||||
grub_err_t
|
||||
@@ -53,3 +55,103 @@ grub_ieee1275_tpm_init (void)
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_tcg2_get_max_output_size (grub_size_t *size)
|
||||
+{
|
||||
+ struct tpm_get_maximum_cmd_size
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t method;
|
||||
+ grub_ieee1275_cell_t ihandle;
|
||||
+ grub_ieee1275_cell_t catch_result;
|
||||
+ grub_ieee1275_cell_t size;
|
||||
+ };
|
||||
+ struct tpm_get_maximum_cmd_size args;
|
||||
+ static bool error_displayed = false;
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ err = grub_ieee1275_tpm_init ();
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ return err;
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 2);
|
||||
+ args.method = (grub_ieee1275_cell_t) "get-maximum-cmd-size";
|
||||
+ args.ihandle = grub_ieee1275_tpm_ihandle;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||||
+ return GRUB_ERR_INVALID_COMMAND;
|
||||
+
|
||||
+ /*
|
||||
+ * args.catch_result is set if firmware does not support get-maximum-cmd-size.
|
||||
+ * rc is GRUB_IEEE1275_CELL_FALSE (0) on failure.
|
||||
+ */
|
||||
+ if (args.catch_result)
|
||||
+ {
|
||||
+ if (error_displayed == false)
|
||||
+ {
|
||||
+ error_displayed = true;
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
+ "get-maximum-cmd-size failed: Firmware is likely too old");
|
||||
+ }
|
||||
+ return GRUB_ERR_INVALID_COMMAND;
|
||||
+ }
|
||||
+
|
||||
+ *size = args.size;
|
||||
+
|
||||
+ 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)
|
||||
+{
|
||||
+ struct tpm_pass_through_to_tpm
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t method;
|
||||
+ grub_ieee1275_cell_t ihandle;
|
||||
+ grub_ieee1275_cell_t buf_size;
|
||||
+ grub_ieee1275_cell_t buf_addr;
|
||||
+ grub_ieee1275_cell_t catch_result;
|
||||
+ grub_ieee1275_cell_t resp_size;
|
||||
+ };
|
||||
+ struct tpm_pass_through_to_tpm args;
|
||||
+ static bool error_displayed = false;
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ if (input_size == 0 || input == NULL ||
|
||||
+ output_size == 0 || output == NULL)
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+
|
||||
+ err = grub_ieee1275_tpm_init ();
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ return err;
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&args.common, "call-method", 4, 2);
|
||||
+ args.method = (grub_ieee1275_cell_t) "pass-through-to-tpm";
|
||||
+ args.ihandle = grub_ieee1275_tpm_ihandle;
|
||||
+ args.buf_size = (grub_ieee1275_cell_t) input_size;
|
||||
+ args.buf_addr = (grub_ieee1275_cell_t) input;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||||
+ return GRUB_ERR_INVALID_COMMAND;
|
||||
+
|
||||
+ /* args.catch_result is set if firmware does not support pass-through-to-tpm. */
|
||||
+ if (args.catch_result)
|
||||
+ {
|
||||
+ if (error_displayed == false)
|
||||
+ {
|
||||
+ error_displayed = true;
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
+ "pass-through-to-tpm failed: Firmware is likely too old");
|
||||
+ }
|
||||
+ return GRUB_ERR_INVALID_COMMAND;
|
||||
+ }
|
||||
+
|
||||
+ grub_memcpy (output, input, args.resp_size);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
--
|
||||
2.43.0
|
||||
|
@@ -1,35 +0,0 @@
|
||||
From 07482c2ab034df5069761319e4969551c3dcc6e1 Mon Sep 17 00:00:00 2001
|
||||
From: B Horn <b@horn.uk>
|
||||
Date: Sun, 12 May 2024 03:01:40 +0100
|
||||
Subject: [PATCH 06/20] kern/file: Ensure file->data is set
|
||||
|
||||
This is to avoid a generic issue were some filesystems would not set
|
||||
data and also not set a grub_errno. This meant it was possible for many
|
||||
filesystems to grub_dl_unref() themselves multiple times resulting in
|
||||
it being possible to unload the filesystems while there were still
|
||||
references to them, e.g., via a loopback.
|
||||
|
||||
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/kern/file.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c
|
||||
index 750177248f..e990507fca 100644
|
||||
--- a/grub-core/kern/file.c
|
||||
+++ b/grub-core/kern/file.c
|
||||
@@ -114,6 +114,9 @@ grub_file_open (const char *name, enum grub_file_type type)
|
||||
if ((file->fs->fs_open) (file, file_name) != GRUB_ERR_NONE)
|
||||
goto fail;
|
||||
|
||||
+ if (file->data == NULL)
|
||||
+ goto fail;
|
||||
+
|
||||
file->name = grub_strdup (name);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
||||
--
|
||||
2.48.1
|
||||
|
@@ -1,109 +0,0 @@
|
||||
From eeb78a4bd82a1c83e3bbe5a4faf9b2c2e8023445 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Tue, 25 Feb 2025 01:45:35 +0530
|
||||
Subject: [PATCH 6/9] powerpc_ieee1275: set use_static_keys flag
|
||||
|
||||
Introduce the use_static_keys flag to indicate that static keys are to be used
|
||||
rather than keys from the PKS storage's DB variable. This variable is set when
|
||||
Secure Boot is enabled with PKS but the DB variable is not present in the PKS storage.
|
||||
The appendedsig module would use this variable to extract the default DB keys from
|
||||
the ELF note and store the keys found there in the trustedlist.
|
||||
|
||||
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>
|
||||
---
|
||||
.../kern/powerpc/ieee1275/platform_keystore.c | 15 ++++++++++++++-
|
||||
grub-core/term/tparm.c | 1 -
|
||||
include/grub/powerpc/ieee1275/platform_keystore.h | 11 ++++++-----
|
||||
include/grub/types.h | 2 ++
|
||||
4 files changed, 22 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/powerpc/ieee1275/platform_keystore.c b/grub-core/kern/powerpc/ieee1275/platform_keystore.c
|
||||
index ea9f27eb22..81e40632b2 100644
|
||||
--- a/grub-core/kern/powerpc/ieee1275/platform_keystore.c
|
||||
+++ b/grub-core/kern/powerpc/ieee1275/platform_keystore.c
|
||||
@@ -34,7 +34,11 @@
|
||||
/* 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 };
|
||||
+grub_pks_t grub_pks_keystore = { .db = NULL,
|
||||
+ .dbx = NULL,
|
||||
+ .db_entries = 0,
|
||||
+ .dbx_entries = 0,
|
||||
+ .use_static_keys = false };
|
||||
|
||||
/* Convert the esl data into the ESL */
|
||||
static grub_esl_t *
|
||||
@@ -315,6 +319,15 @@ grub_pks_keystore_init (void)
|
||||
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 == PKS_OBJECT_NOT_FOUND)
|
||||
+ {
|
||||
+ rc = GRUB_ERR_NONE;
|
||||
+ /*
|
||||
+ * DB variable won't be available by default in PKS.
|
||||
+ * So, it will load the Default Keys from ELF Note */
|
||||
+ grub_pks_keystore.use_static_keys = true;
|
||||
+ }
|
||||
+
|
||||
if (rc == GRUB_ERR_NONE)
|
||||
{
|
||||
/* DBX */
|
||||
diff --git a/grub-core/term/tparm.c b/grub-core/term/tparm.c
|
||||
index fb5b15a88d..f2db325f6e 100644
|
||||
--- a/grub-core/term/tparm.c
|
||||
+++ b/grub-core/term/tparm.c
|
||||
@@ -46,7 +46,6 @@
|
||||
/*
|
||||
* Common/troublesome character definitions
|
||||
*/
|
||||
-typedef char grub_bool_t;
|
||||
#ifndef FALSE
|
||||
# define FALSE (0)
|
||||
#endif
|
||||
diff --git a/include/grub/powerpc/ieee1275/platform_keystore.h b/include/grub/powerpc/ieee1275/platform_keystore.h
|
||||
index 0641adb0f1..870fb8cc51 100644
|
||||
--- a/include/grub/powerpc/ieee1275/platform_keystore.h
|
||||
+++ b/include/grub/powerpc/ieee1275/platform_keystore.h
|
||||
@@ -199,10 +199,11 @@ struct grub_pks_sd
|
||||
/* 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_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_bool_t use_static_keys;/* flag to indicate use of static keys */
|
||||
} GRUB_PACKED;
|
||||
|
||||
#ifdef __powerpc__
|
||||
@@ -217,7 +218,7 @@ 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};
|
||||
+grub_pks_t grub_pks_keystore = {NULL, NULL, 0, 0, false};
|
||||
void grub_pks_free_keystore (void);
|
||||
|
||||
#endif
|
||||
diff --git a/include/grub/types.h b/include/grub/types.h
|
||||
index 5542b9aa09..573a614fa6 100644
|
||||
--- a/include/grub/types.h
|
||||
+++ b/include/grub/types.h
|
||||
@@ -397,4 +397,6 @@ struct grub_uuid
|
||||
grub_uint8_t b[GRUB_UUID_SIZE];
|
||||
};
|
||||
|
||||
+typedef char grub_bool_t;
|
||||
+
|
||||
#endif /* ! GRUB_TYPES_HEADER */
|
||||
--
|
||||
2.48.1
|
||||
|
@@ -1,147 +0,0 @@
|
||||
From cd9cb944d973da6a031d06183cc6da974beb4bae Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Mon, 7 Apr 2025 16:29:20 +0800
|
||||
Subject: [PATCH 6/7] tpm2_key_protector: Support NV index handles
|
||||
|
||||
Previously, NV index mode only supported persistent handles which are
|
||||
only for TPM objects.
|
||||
|
||||
On the other hand, the "NV index" handle allows the user-defined data,
|
||||
so it can be an alternative to the key file and support TPM 2.0 Key
|
||||
File format immediately.
|
||||
|
||||
The following tpm2-tools commands store the given key file, sealed.tpm,
|
||||
in either TPM 2.0 Key File format or the raw format into the NV index
|
||||
handle 0x1000000.
|
||||
|
||||
# tpm2_nvdefine -C o \
|
||||
-a "ownerread|ownerwrite" \
|
||||
-s $(stat -c %s sealed.tpm) \
|
||||
0x1000000
|
||||
# tpm2_nvwrite -C o -i sealed.tpm 0x1000000
|
||||
|
||||
To unseal the key in GRUB, add the "tpm2_key_protector_init" command to
|
||||
grub.cfg:
|
||||
|
||||
tpm2_key_protector_init --mode=nv --nvindex=0x1000000
|
||||
cryptomount -u <UUID> --protector tpm2
|
||||
|
||||
To remove the NV index handle:
|
||||
|
||||
# tpm2_nvundefine -C o 0x1000000
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
.../commands/tpm2_key_protector/module.c | 70 ++++++++++++++++---
|
||||
1 file changed, 60 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/tpm2_key_protector/module.c b/grub-core/commands/tpm2_key_protector/module.c
|
||||
index 795f61518..857f3753f 100644
|
||||
--- a/grub-core/commands/tpm2_key_protector/module.c
|
||||
+++ b/grub-core/commands/tpm2_key_protector/module.c
|
||||
@@ -1133,10 +1133,9 @@ tpm2_protector_srk_recover (const tpm2_protector_context_t *ctx,
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-tpm2_protector_nv_recover (const tpm2_protector_context_t *ctx,
|
||||
- grub_uint8_t **key, grub_size_t *key_size)
|
||||
+tpm2_protector_load_persistent (const tpm2_protector_context_t *ctx, TPM_HANDLE_t sealed_handle,
|
||||
+ grub_uint8_t **key, grub_size_t *key_size)
|
||||
{
|
||||
- TPM_HANDLE_t sealed_handle = ctx->nv;
|
||||
tpm2key_policy_t policy_seq = NULL;
|
||||
bool dump_pcr = false;
|
||||
grub_err_t err;
|
||||
@@ -1163,6 +1162,51 @@ tpm2_protector_nv_recover (const tpm2_protector_context_t *ctx,
|
||||
return err;
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+tpm2_protector_key_from_nvindex (const tpm2_protector_context_t *ctx, TPM_HANDLE_t nvindex,
|
||||
+ grub_uint8_t **key, grub_size_t *key_size)
|
||||
+{
|
||||
+ TPMS_AUTH_COMMAND_t authCmd = {0};
|
||||
+ TPM2B_NV_PUBLIC_t nv_public;
|
||||
+ TPM2B_NAME_t nv_name;
|
||||
+ grub_uint16_t data_size;
|
||||
+ TPM2B_MAX_NV_BUFFER_t data;
|
||||
+ TPM_RC_t rc;
|
||||
+
|
||||
+ /* Get the data size in the NV index handle */
|
||||
+ rc = grub_tpm2_nv_readpublic (nvindex, NULL, &nv_public, &nv_name);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to retrieve info from 0x%x (TPM2_NV_ReadPublic: 0x%x)", nvindex, rc);
|
||||
+
|
||||
+ data_size = nv_public.nvPublic.dataSize;
|
||||
+ if (data_size > TPM_MAX_NV_BUFFER_SIZE)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "insufficient data buffer");
|
||||
+
|
||||
+ /* Read the data from the NV index handle */
|
||||
+ authCmd.sessionHandle = TPM_RS_PW;
|
||||
+ rc = grub_tpm2_nv_read (TPM_RH_OWNER, nvindex, &authCmd, data_size, 0, &data);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to read data from 0x%x (TPM2_NV_Read: 0x%x)", nvindex, rc);
|
||||
+
|
||||
+ return tpm2_protector_key_from_buffer (ctx, data.buffer, data_size, key, key_size);
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+tpm2_protector_nv_recover (const tpm2_protector_context_t *ctx,
|
||||
+ grub_uint8_t **key, grub_size_t *key_size)
|
||||
+{
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ if (TPM_HT_IS_PERSISTENT (ctx->nv) == true)
|
||||
+ err = tpm2_protector_load_persistent (ctx, ctx->nv, key, key_size);
|
||||
+ else if (TPM_HT_IS_NVINDEX (ctx->nv) == true)
|
||||
+ err = tpm2_protector_key_from_nvindex (ctx, ctx->nv, key, key_size);
|
||||
+ else
|
||||
+ err = GRUB_ERR_BAD_ARGUMENT;
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
tpm2_protector_recover (const tpm2_protector_context_t *ctx,
|
||||
grub_uint8_t **key, grub_size_t *key_size)
|
||||
@@ -1215,14 +1259,15 @@ tpm2_protector_check_args (tpm2_protector_context_t *ctx)
|
||||
|
||||
if (ctx->mode == TPM2_PROTECTOR_MODE_NV &&
|
||||
(ctx->tpm2key != NULL || ctx->keyfile != NULL))
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("in NV Index mode, a keyfile cannot be specified"));
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("a key file cannot be specified when using NV index mode"));
|
||||
|
||||
- if (ctx->mode == TPM2_PROTECTOR_MODE_NV && ctx->srk != 0)
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("in NV Index mode, an SRK cannot be specified"));
|
||||
+ if (ctx->mode == TPM2_PROTECTOR_MODE_NV && TPM_HT_IS_PERSISTENT (ctx->nv) == true &&
|
||||
+ (ctx->srk != 0 || ctx->srk_type.type != TPM_ALG_ERROR))
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("an SRK cannot be specified when using NV index mode with a persistent handle"));
|
||||
|
||||
if (ctx->mode == TPM2_PROTECTOR_MODE_NV &&
|
||||
- ctx->srk_type.type != TPM_ALG_ERROR)
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("in NV Index mode, an asymmetric key type cannot be specified"));
|
||||
+ (TPM_HT_IS_PERSISTENT (ctx->nv) == false && TPM_HT_IS_NVINDEX (ctx->nv) == false))
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("an NV index must be either a persistent handle or an NV index handle when using NV index mode"));
|
||||
|
||||
/* Defaults assignment */
|
||||
if (ctx->bank == TPM_ALG_ERROR)
|
||||
@@ -1234,8 +1279,13 @@ tpm2_protector_check_args (tpm2_protector_context_t *ctx)
|
||||
ctx->pcr_count = 1;
|
||||
}
|
||||
|
||||
- if (ctx->mode == TPM2_PROTECTOR_MODE_SRK &&
|
||||
- ctx->srk_type.type == TPM_ALG_ERROR)
|
||||
+ /*
|
||||
+ * Set ECC_NIST_P256 as the default SRK when using SRK mode or NV mode with
|
||||
+ * an NV index handle
|
||||
+ */
|
||||
+ if (ctx->srk_type.type == TPM_ALG_ERROR &&
|
||||
+ (ctx->mode == TPM2_PROTECTOR_MODE_SRK ||
|
||||
+ (ctx->mode == TPM2_PROTECTOR_MODE_NV && TPM_HT_IS_NVINDEX (ctx->nv) == true)))
|
||||
{
|
||||
ctx->srk_type.type = TPM_ALG_ECC;
|
||||
ctx->srk_type.detail.ecc_curve = TPM_ECC_NIST_P256;
|
||||
--
|
||||
2.43.0
|
||||
|
@@ -1,111 +0,0 @@
|
||||
From 9dce8958d674c09a93c893a5ef36807e6f286c45 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Tue, 25 Feb 2025 02:20:20 +0530
|
||||
Subject: [PATCH 7/9] appendedsig: Reads the default DB keys from ELF Note
|
||||
|
||||
If Secure Boot is enabled with PKS and the use_static_keys flag is set,
|
||||
then read the DB default keys from the ELF note and store them in the trusted list 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 | 56 ++++++++++++++------
|
||||
1 file changed, 40 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/appendedsig/appendedsig.c b/grub-core/commands/appendedsig/appendedsig.c
|
||||
index b6daccd3d7..3cbe51ec13 100644
|
||||
--- a/grub-core/commands/appendedsig/appendedsig.c
|
||||
+++ b/grub-core/commands/appendedsig/appendedsig.c
|
||||
@@ -1073,7 +1073,7 @@ create_distrusted_list (void)
|
||||
* parse it, and add it to the trusted list.
|
||||
*/
|
||||
static grub_err_t
|
||||
-build_static_trusted_list (const struct grub_module_header *header)
|
||||
+build_static_trusted_list (const struct grub_module_header *header, const grub_bool_t is_pks)
|
||||
{
|
||||
grub_err_t err = GRUB_ERR_NONE;
|
||||
struct grub_file pseudo_file;
|
||||
@@ -1092,6 +1092,13 @@ build_static_trusted_list (const struct grub_module_header *header)
|
||||
if (err != GRUB_ERR_NONE)
|
||||
return err;
|
||||
|
||||
+ if (is_pks)
|
||||
+ {
|
||||
+ err = is_distrusted_cert_hash (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);
|
||||
|
||||
@@ -1144,6 +1151,22 @@ free_distrusted_list (void)
|
||||
grub_memset (&dbx, 0, sizeof (dbx));
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+load_static_keys (const struct grub_module_header *header, const grub_bool_t is_pks)
|
||||
+{
|
||||
+ int rc = GRUB_ERR_NONE;
|
||||
+ FOR_MODULES (header)
|
||||
+ {
|
||||
+ /* Not an ELF module, skip. */
|
||||
+ if (header->type != OBJ_TYPE_X509_PUBKEY)
|
||||
+ continue;
|
||||
+ rc = build_static_trusted_list (header, is_pks);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ return rc;
|
||||
+ }
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
GRUB_MOD_INIT (appendedsig)
|
||||
{
|
||||
int rc;
|
||||
@@ -1163,26 +1186,27 @@ GRUB_MOD_INIT (appendedsig)
|
||||
|
||||
if (!grub_pks_use_keystore && check_sigs == check_sigs_forced)
|
||||
{
|
||||
- FOR_MODULES (header)
|
||||
+ rc = load_static_keys (header, false);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
{
|
||||
- /* 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);
|
||||
+ 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 (grub_pks_keystore.use_static_keys)
|
||||
+ {
|
||||
+ grub_printf ("Warning: db variable is not available at PKS and using a static keys "
|
||||
+ "as a default key in trusted list\n");
|
||||
+ rc = load_static_keys (header, grub_pks_keystore.use_static_keys);
|
||||
+ }
|
||||
+ else
|
||||
+ rc = create_trusted_list ();
|
||||
+
|
||||
if (rc != GRUB_ERR_NONE)
|
||||
{
|
||||
free_trusted_list ();
|
||||
--
|
||||
2.48.1
|
||||
|
@@ -1,32 +0,0 @@
|
||||
From d5a155864230964878280a52dc82392382af1c5d Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Thu, 8 May 2025 19:02:13 +0200
|
||||
Subject: [PATCH 7/8] disk/cryptodisk: Wipe the passphrase from memory
|
||||
|
||||
Switching to another EFI boot application while there are secrets in
|
||||
RAM is dangerous, because not all firmware is wiping memory on free.
|
||||
|
||||
To reduce the attack surface, wipe the passphrase acquired when
|
||||
unlocking an encrypted volume.
|
||||
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/disk/cryptodisk.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index f9ae750f85..cb87d337ac 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1251,6 +1251,7 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
#endif
|
||||
if (askpass)
|
||||
{
|
||||
+ grub_memset (cargs->key_data, 0, cargs->key_len);
|
||||
cargs->key_len = 0;
|
||||
grub_free (cargs->key_data);
|
||||
}
|
||||
--
|
||||
2.49.0
|
||||
|
@@ -1,216 +0,0 @@
|
||||
From 6701b4a9e1994c8a05c87a7167694bc3dd71e7d6 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Wed, 23 Oct 2024 17:54:32 +0530
|
||||
Subject: [PATCH 7/8] grub-mkimage: Create new ELF note for SBAT
|
||||
|
||||
In order to store the SBAT data we create a new ELF note. The string
|
||||
".sbat", zero-padded to 4 byte alignment, shall be entered in the name
|
||||
field. The string "SBAT"'s ASCII values, 0x53424154, should be entered
|
||||
in the type field.
|
||||
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
include/grub/util/mkimage.h | 4 +-
|
||||
util/grub-mkimagexx.c | 92 +++++++++++++++++++++++++++----------
|
||||
util/mkimage.c | 5 +-
|
||||
3 files changed, 74 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/include/grub/util/mkimage.h b/include/grub/util/mkimage.h
|
||||
index 6f1da89b9..881e3031f 100644
|
||||
--- a/include/grub/util/mkimage.h
|
||||
+++ b/include/grub/util/mkimage.h
|
||||
@@ -51,12 +51,12 @@ grub_mkimage_load_image64 (const char *kernel_path,
|
||||
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, size_t appsig_size, char **core_img, size_t *core_size,
|
||||
+ int note, size_t appsig_size, char *sbat, 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, size_t appsig_size, char **core_img, size_t *core_size,
|
||||
+ int note, size_t appsig_size, char *sbat, char **core_img, size_t *core_size,
|
||||
Elf64_Addr target_addr,
|
||||
struct grub_mkimage_layout *layout);
|
||||
|
||||
diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c
|
||||
index 9488f0525..b507d4ade 100644
|
||||
--- a/util/grub-mkimagexx.c
|
||||
+++ b/util/grub-mkimagexx.c
|
||||
@@ -116,6 +116,14 @@ struct section_metadata
|
||||
const char *strtab;
|
||||
};
|
||||
|
||||
+#define GRUB_SBAT_NOTE_NAME ".sbat"
|
||||
+#define GRUB_SBAT_NOTE_TYPE 0x53424154 /* "SBAT" */
|
||||
+
|
||||
+struct grub_sbat_note {
|
||||
+ Elf32_Nhdr header;
|
||||
+ char name[ALIGN_UP(sizeof(GRUB_SBAT_NOTE_NAME), 4)];
|
||||
+};
|
||||
+
|
||||
static int
|
||||
is_relocatable (const struct grub_install_image_target_desc *image_target)
|
||||
{
|
||||
@@ -217,7 +225,7 @@ grub_arm_reloc_jump24 (grub_uint32_t *target, Elf32_Addr sym_addr)
|
||||
|
||||
void
|
||||
SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc *image_target,
|
||||
- int note, size_t appsig_size, char **core_img, size_t *core_size,
|
||||
+ int note, size_t appsig_size, char *sbat, char **core_img, size_t *core_size,
|
||||
Elf_Addr target_addr,
|
||||
struct grub_mkimage_layout *layout)
|
||||
{
|
||||
@@ -226,10 +234,17 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
|
||||
Elf_Ehdr *ehdr;
|
||||
Elf_Phdr *phdr;
|
||||
Elf_Shdr *shdr;
|
||||
- int header_size, footer_size = 0;
|
||||
+ int header_size, footer_size = 0, footer_offset = 0;
|
||||
int phnum = 1;
|
||||
int shnum = 4;
|
||||
int string_size = sizeof (".text") + sizeof ("mods") + 1;
|
||||
+ char *footer;
|
||||
+
|
||||
+ if (sbat)
|
||||
+ {
|
||||
+ phnum++;
|
||||
+ footer_size += ALIGN_UP (sizeof (struct grub_sbat_note) + layout->sbat_size, 4);
|
||||
+ }
|
||||
|
||||
if (appsig_size)
|
||||
{
|
||||
@@ -263,6 +278,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
|
||||
ehdr = (void *) elf_img;
|
||||
phdr = (void *) (elf_img + sizeof (*ehdr));
|
||||
shdr = (void *) (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr));
|
||||
+ footer = elf_img + program_size + header_size;
|
||||
memcpy (ehdr->e_ident, ELFMAG, SELFMAG);
|
||||
ehdr->e_ident[EI_CLASS] = ELFCLASSXX;
|
||||
if (!image_target->bigendian)
|
||||
@@ -435,6 +451,8 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
|
||||
phdr->p_filesz = grub_host_to_target32 (XEN_NOTE_SIZE);
|
||||
phdr->p_memsz = 0;
|
||||
phdr->p_offset = grub_host_to_target32 (header_size + program_size);
|
||||
+ footer = ptr;
|
||||
+ footer_offset = XEN_NOTE_SIZE;
|
||||
}
|
||||
|
||||
if (image_target->id == IMAGE_XEN_PVH)
|
||||
@@ -468,6 +486,8 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
|
||||
phdr->p_filesz = grub_host_to_target32 (XEN_PVH_NOTE_SIZE);
|
||||
phdr->p_memsz = 0;
|
||||
phdr->p_offset = grub_host_to_target32 (header_size + program_size);
|
||||
+ footer = ptr;
|
||||
+ footer_offset = XEN_PVH_NOTE_SIZE;
|
||||
}
|
||||
|
||||
if (note)
|
||||
@@ -498,29 +518,55 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
|
||||
phdr->p_filesz = grub_host_to_target32 (note_size);
|
||||
phdr->p_memsz = 0;
|
||||
phdr->p_offset = grub_host_to_target32 (header_size + program_size);
|
||||
+ footer = (elf_img + program_size + header_size + note_size);
|
||||
+ footer_offset += note_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));
|
||||
- }
|
||||
+ if (sbat)
|
||||
+ {
|
||||
+ int note_size = ALIGN_UP (sizeof (struct grub_sbat_note) + layout->sbat_size, 4);
|
||||
+ struct grub_sbat_note *note_ptr = (struct grub_sbat_note *) footer;
|
||||
+
|
||||
+ note_ptr->header.n_namesz = grub_host_to_target32 (sizeof (GRUB_SBAT_NOTE_NAME));
|
||||
+ note_ptr->header.n_descsz = grub_host_to_target32 (ALIGN_UP(layout->sbat_size, 4));
|
||||
+ note_ptr->header.n_type = grub_host_to_target32 (GRUB_SBAT_NOTE_TYPE);
|
||||
+ memcpy (note_ptr->name, GRUB_SBAT_NOTE_NAME, sizeof (GRUB_SBAT_NOTE_NAME));
|
||||
+ memcpy ((char *)(note_ptr + 1), sbat, layout->sbat_size);
|
||||
+
|
||||
+ 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 + footer_offset);
|
||||
+
|
||||
+ footer += note_size;
|
||||
+ footer_offset += note_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 *)footer;
|
||||
+ 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 + footer_offset);
|
||||
+ }
|
||||
|
||||
{
|
||||
char *str_start = (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr)
|
||||
diff --git a/util/mkimage.c b/util/mkimage.c
|
||||
index 0737935fd..be7f02c5c 100644
|
||||
--- a/util/mkimage.c
|
||||
+++ b/util/mkimage.c
|
||||
@@ -1835,6 +1835,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
case IMAGE_I386_IEEE1275:
|
||||
{
|
||||
grub_uint64_t target_addr;
|
||||
+ char *sbat = NULL;
|
||||
if (image_target->id == IMAGE_LOONGSON_ELF)
|
||||
{
|
||||
if (comp == GRUB_COMPRESSION_NONE)
|
||||
@@ -1846,10 +1847,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
else
|
||||
target_addr = image_target->link_addr;
|
||||
if (image_target->voidp_sizeof == 4)
|
||||
- grub_mkimage_generate_elf32 (image_target, note, appsig_size, &core_img,
|
||||
+ grub_mkimage_generate_elf32 (image_target, note, appsig_size, sbat, &core_img,
|
||||
&core_size, target_addr, &layout);
|
||||
else
|
||||
- grub_mkimage_generate_elf64 (image_target, note, appsig_size, &core_img,
|
||||
+ grub_mkimage_generate_elf64 (image_target, note, appsig_size, sbat, &core_img,
|
||||
&core_size, target_addr, &layout);
|
||||
}
|
||||
break;
|
||||
--
|
||||
2.47.1
|
||||
|
279
0007-grub-switch-to-blscfg-adapt-to-openSUSE.patch
Normal file
279
0007-grub-switch-to-blscfg-adapt-to-openSUSE.patch
Normal file
@@ -0,0 +1,279 @@
|
||||
From 96e5a28d120856057fe7fc9b281f11f8933063b7 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 30 Jun 2023 14:37:41 +0800
|
||||
Subject: [PATCH 7/9] grub-switch-to-blscfg: adapt to openSUSE
|
||||
|
||||
A few tweaks to make it 'just works' for openSUSE:
|
||||
|
||||
- remove RHEL specific $grub_get_kernel_settings and all reference to it.
|
||||
- make $grubdir and $startlink to the path in openSUSE
|
||||
- change the bls template to openSUSE
|
||||
- make $cmdline account for btrfs subvolumes, among others
|
||||
- remove RHEL specific $GRUB_LINUX_MAKE_DEBUG and all related code
|
||||
- remove ostree specific hack
|
||||
- ignore increment.mod
|
||||
- fix error in dash shell script
|
||||
- fix kernel flavor parsing in openSUSE
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
util/grub-switch-to-blscfg.in | 156 ++++++++++++++++++++--------------
|
||||
1 file changed, 94 insertions(+), 62 deletions(-)
|
||||
|
||||
diff --git a/util/grub-switch-to-blscfg.in b/util/grub-switch-to-blscfg.in
|
||||
index a851424be..145c22add 100644
|
||||
--- a/util/grub-switch-to-blscfg.in
|
||||
+++ b/util/grub-switch-to-blscfg.in
|
||||
@@ -28,27 +28,24 @@ PACKAGE_NAME=@PACKAGE_NAME@
|
||||
PACKAGE_VERSION=@PACKAGE_VERSION@
|
||||
datarootdir="@datarootdir@"
|
||||
datadir="@datadir@"
|
||||
-if [ ! -v pkgdatadir ]; then
|
||||
+if [ -z "${pkgdatadir+x}" ]; then
|
||||
pkgdatadir="${datadir}/@PACKAGE@"
|
||||
fi
|
||||
|
||||
self=`basename $0`
|
||||
|
||||
-grub_get_kernel_settings="${sbindir}/@grub_get_kernel_settings@"
|
||||
grub_editenv=${bindir}/@grub_editenv@
|
||||
-etcdefaultgrub=/etc/default/grub
|
||||
+grub_probe="${sbindir}/@grub_probe@"
|
||||
+etcdefaultgrub=${sysconfdir}/default/grub
|
||||
|
||||
-eval "$("${grub_get_kernel_settings}")" || true
|
||||
-
|
||||
-EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 's/\"//g')
|
||||
-if [ -d /sys/firmware/efi/efivars/ ]; then
|
||||
- startlink=/etc/grub2-efi.cfg
|
||||
- grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'`
|
||||
-else
|
||||
- startlink=/etc/grub2.cfg
|
||||
- grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`
|
||||
+if test -f "$etcdefaultgrub" ; then
|
||||
+ # shellcheck source=/etc/default/grub
|
||||
+ . "$etcdefaultgrub"
|
||||
fi
|
||||
|
||||
+grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`
|
||||
+startlink="${grubdir}/grub.cfg"
|
||||
+
|
||||
blsdir=`echo "/@bootdirname@/loader/entries" | sed 's,//*,/,g'`
|
||||
|
||||
backupsuffix=.bak
|
||||
@@ -58,19 +55,80 @@ arch="$(uname -m)"
|
||||
export TEXTDOMAIN=@PACKAGE@
|
||||
export TEXTDOMAINDIR="@localedir@"
|
||||
|
||||
+# shellcheck source=/usr/share/grub2/grub-mkconfig_lib
|
||||
. "${pkgdatadir}/grub-mkconfig_lib"
|
||||
|
||||
+# FIXME: Abort if grub_probe fails
|
||||
+
|
||||
+GRUB_DEVICE="`${grub_probe} --target=device /`"
|
||||
+GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || true
|
||||
+GRUB_DEVICE_PARTUUID="`${grub_probe} --device ${GRUB_DEVICE} --target=partuuid 2> /dev/null`" || true
|
||||
+GRUB_FS="`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2> /dev/null || echo unknown`"
|
||||
+
|
||||
+# loop-AES arranges things so that /dev/loop/X can be our root device, but
|
||||
+# the initrds that Linux uses don't like that.
|
||||
+case ${GRUB_DEVICE} in
|
||||
+ /dev/loop/*|/dev/loop[0-9])
|
||||
+ GRUB_DEVICE=$(losetup "${GRUB_DEVICE}" | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/")
|
||||
+ ;;
|
||||
+esac
|
||||
+
|
||||
+# Default to disabling partition uuid support to maintian compatibility with
|
||||
+# older kernels.
|
||||
+GRUB_DISABLE_LINUX_PARTUUID=${GRUB_DISABLE_LINUX_PARTUUID-true}
|
||||
+
|
||||
+# btrfs may reside on multiple devices. We cannot pass them as value of root= parameter
|
||||
+# and mounting btrfs requires user space scanning, so force UUID in this case.
|
||||
+if ( [ "x${GRUB_DEVICE_UUID}" = "x" ] && [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] ) \
|
||||
+ || ( [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
|
||||
+ && [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ] ) \
|
||||
+ || ( ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \
|
||||
+ && ! test -e "/dev/disk/by-partuuid/${GRUB_DEVICE_PARTUUID}" ) \
|
||||
+ || ( test -e "${GRUB_DEVICE}" && uses_abstraction "${GRUB_DEVICE}" lvm ); then
|
||||
+ LINUX_ROOT_DEVICE=${GRUB_DEVICE}
|
||||
+elif [ "x${GRUB_DEVICE_UUID}" = "x" ] \
|
||||
+ || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ]; then
|
||||
+ LINUX_ROOT_DEVICE=PARTUUID=${GRUB_DEVICE_PARTUUID}
|
||||
+else
|
||||
+ LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
|
||||
+fi
|
||||
+
|
||||
+if [ "x$GRUB_CONMODE" != "x" ]; then
|
||||
+ GRUB_CMDLINE_LINUX="conmode=${GRUB_CONMODE} ${GRUB_CMDLINE_LINUX}"
|
||||
+fi
|
||||
+
|
||||
+case x"$GRUB_FS" in
|
||||
+ xbtrfs)
|
||||
+ if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" != "xtrue" ]; then
|
||||
+ rootsubvol="`make_system_path_relative_to_its_root /`"
|
||||
+ rootsubvol="${rootsubvol#/}"
|
||||
+ if [ "x${rootsubvol}" != x ] && [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" != "xtrue" ]; then
|
||||
+ GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}"
|
||||
+ fi
|
||||
+ fi
|
||||
+ ;;
|
||||
+ xzfs)
|
||||
+ rpool=`${grub_probe} --device ${GRUB_DEVICE} --target=fs_label 2>/dev/null || true`
|
||||
+ bootfs="`make_system_path_relative_to_its_root / | sed -e "s,@$,,"`"
|
||||
+ LINUX_ROOT_DEVICE="ZFS=${rpool}${bootfs%/}"
|
||||
+ ;;
|
||||
+esac
|
||||
+
|
||||
+if [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" = "xtrue" ]; then
|
||||
+ LINUX_ROOT_DEVICE=""
|
||||
+fi
|
||||
+
|
||||
# Usage: usage
|
||||
# Print the usage.
|
||||
usage () {
|
||||
gettext_printf "Usage: %s\n" "$self"
|
||||
- gettext "Switch to BLS config files.\n"; echo
|
||||
+ gettext "Switch to BLS config files. Only for testing purpose !!!\n"; echo
|
||||
echo
|
||||
print_option_help "-h, --help" "$(gettext "print this message and exit")"
|
||||
print_option_help "-V, --version" "$(gettext "print the version information and exit")"
|
||||
echo
|
||||
print_option_help "--backup-suffix=$(gettext "SUFFIX")" "$backupsuffix"
|
||||
- print_option_help "--bls-directory=$(gettext "DIR")" "$blsdir"
|
||||
+ print_option_help "--bls-directory=$(gettext "DIR")" "Noop, always $blsdir"
|
||||
print_option_help "--config-file=$(gettext "FILE")" "$startlink"
|
||||
print_option_help "--grub-defaults=$(gettext "FILE")" "$etcdefaultgrub"
|
||||
print_option_help "--grub-directory=$(gettext "DIR")" "$grubdir"
|
||||
@@ -112,11 +170,15 @@ do
|
||||
;;
|
||||
|
||||
--bls-directory)
|
||||
- blsdir=`argument $option "$@"`
|
||||
+ # blsdir=`argument $option "$@"`
|
||||
+ gettext_printf "WARN: --bls-directory is currently disabled, it's always $blsdir !!!\n"
|
||||
+ gettext_printf "WARN: use kernel-install instead if you want to test bls directory on ESP !!!\n"
|
||||
shift
|
||||
;;
|
||||
--bls-directory=*)
|
||||
- blsdir=`echo "$option" | sed 's/--bls-directory=//'`
|
||||
+ # blsdir=`echo "$option" | sed 's/--bls-directory=//'`
|
||||
+ gettext_printf "WARN: --bls-directory is currently disabled, it's always $blsdir !!!\n"
|
||||
+ gettext_printf "WARN: use kernel-install instead if you want to test bls directory on ESP !!!\n"
|
||||
;;
|
||||
|
||||
--config-file)
|
||||
@@ -172,7 +234,7 @@ find_grub_cfg() {
|
||||
return 1
|
||||
}
|
||||
|
||||
-if ! find_grub_cfg ${startlink} ${grubdir}/grub.cfg ; then
|
||||
+if ! find_grub_cfg "${startlink}" ; then
|
||||
gettext_printf "Couldn't find config file\n" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
@@ -190,27 +252,24 @@ fi
|
||||
mkbls() {
|
||||
local kernelver=$1 && shift
|
||||
local datetime=$1 && shift
|
||||
+ local prefix=$1 && shift
|
||||
local kernelopts=$1 && shift
|
||||
|
||||
- local debugname=""
|
||||
- local debugid=""
|
||||
local flavor=""
|
||||
|
||||
- if [ "$kernelver" == *\+* ] ; then
|
||||
- local flavor=-"${kernelver##*+}"
|
||||
- if [ "${flavor}" == "-debug" ]; then
|
||||
- local debugname=" with debugging"
|
||||
- local debugid="-debug"
|
||||
- fi
|
||||
- fi
|
||||
+ case "$kernelver" in
|
||||
+ *-*-*)
|
||||
+ flavor=-"${kernelver##*-}"
|
||||
+ ;;
|
||||
+ esac
|
||||
(
|
||||
- source /etc/os-release
|
||||
+ . /etc/os-release
|
||||
|
||||
cat <<EOF
|
||||
-title ${NAME} (${kernelver}) ${VERSION}${debugname}
|
||||
-version ${kernelver}${debugid}
|
||||
-linux /vmlinuz-${kernelver}
|
||||
-initrd /initramfs-${kernelver}.img
|
||||
+title ${NAME} (${kernelver}) ${VERSION}
|
||||
+version ${kernelver}
|
||||
+linux ${prefix}/vmlinuz-${kernelver}
|
||||
+initrd ${prefix}/initrd-${kernelver}
|
||||
options ${kernelopts}
|
||||
grub_users \$grub_users
|
||||
grub_arg --unrestricted
|
||||
@@ -233,42 +292,15 @@ copy_bls() {
|
||||
continue
|
||||
fi
|
||||
|
||||
- linux_relpath="$("${grub_mkrelpath}" "${linux_path}")"
|
||||
- bootprefix="${linux_relpath%%"${linux}"}"
|
||||
+ bootprefix="$(make_system_path_relative_to_its_root /boot)"
|
||||
cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
|
||||
|
||||
mkbls "${kernelver}" \
|
||||
"$(date -u +%Y%m%d%H%M%S -d "$(stat -c '%y' "${kernel_dir}")")" \
|
||||
"${bootprefix}" "${cmdline}" >"${bls_target}"
|
||||
-
|
||||
- if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then
|
||||
- bls_debug="$(echo ${bls_target} | sed -e "s/${kernelver}/${kernelver}~debug/")"
|
||||
- cp -aT "${bls_target}" "${bls_debug}"
|
||||
- title="$(grep '^title[ \t]' "${bls_debug}" | sed -e 's/^title[ \t]*//')"
|
||||
- options="$(echo "${cmdline} ${GRUB_CMDLINE_LINUX_DEBUG}" | sed -e 's/\//\\\//g')"
|
||||
- sed -i -e "s/^title.*/title ${title}${GRUB_LINUX_DEBUG_TITLE_POSTFIX}/" "${bls_debug}"
|
||||
- sed -i -e "s/^options.*/options ${options}/" "${bls_debug}"
|
||||
- fi
|
||||
done
|
||||
-
|
||||
- if [ -f "/boot/vmlinuz-0-rescue-${MACHINE_ID}" ]; then
|
||||
- mkbls "0-rescue-${MACHINE_ID}" "0" "${bootprefix}" >"${blsdir}/${MACHINE_ID}-0-rescue.conf"
|
||||
- fi
|
||||
}
|
||||
|
||||
-# The grub2 EFI binary is not copied to the ESP as a part of an ostree
|
||||
-# transaction. Make sure a grub2 version with BLS support is installed
|
||||
-# but only do this if the blsdir is not set, to make sure that the BLS
|
||||
-# parsing module will search for the BLS snippets in the default path.
|
||||
-if test -f /run/ostree-booted && test -d /sys/firmware/efi/efivars && \
|
||||
- ! ${grub_editenv} - list | grep -q blsdir && \
|
||||
- mountpoint -q /boot; then
|
||||
- grub_binary="$(find /usr/lib/ostree-boot/efi/EFI/${EFIDIR}/ -name grub*.efi)"
|
||||
- install -m 700 ${grub_binary} ${grubdir} || exit 1
|
||||
- # Create a hidden file to indicate that grub2 now has BLS support.
|
||||
- touch /boot/grub2/.grub2-blscfg-supported
|
||||
-fi
|
||||
-
|
||||
GENERATE=0
|
||||
if grep '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" \
|
||||
| grep -vq '^GRUB_ENABLE_BLSCFG="*true"*\s*$' ; then
|
||||
@@ -297,9 +329,7 @@ if [ "${GENERATE}" -eq 1 ] ; then
|
||||
fi
|
||||
|
||||
if [ -n "${mod_dir}" ]; then
|
||||
- for mod in blscfg increment; do
|
||||
- install -m 700 ${prefix}/lib/grub/${mod_dir}/${mod}.mod ${grubdir}/$mod_dir/ || exit 1
|
||||
- done
|
||||
+ install -m 700 "${pkgdatadir}/${mod_dir}/blscfg.mod" "${grubdir}/$mod_dir/" || exit 1
|
||||
fi
|
||||
|
||||
cp -af "${GRUB_CONFIG_FILE}" "${GRUB_CONFIG_FILE}${backupsuffix}"
|
||||
@@ -311,6 +341,8 @@ if [ "${GENERATE}" -eq 1 ] ; then
|
||||
gettext_printf "Updating %s failed\n" "${GRUB_CONFIG_FILE}"
|
||||
exit 1
|
||||
fi
|
||||
+else
|
||||
+ gettext_printf "Do nothing because \$GRUB_ENABLE_BLSCFG is already true in %s\n" "${GRUB_CONFIG_FILE}"
|
||||
fi
|
||||
|
||||
# Bye.
|
||||
--
|
||||
2.45.2
|
||||
|
@@ -1,443 +0,0 @@
|
||||
From 8e9240826c7d230cab6d52724d2cf3759e6f0d3f Mon Sep 17 00:00:00 2001
|
||||
From: B Horn <b@horn.uk>
|
||||
Date: Sun, 12 May 2024 10:15:03 +0100
|
||||
Subject: [PATCH 07/20] kern/file: Implement filesystem reference counting
|
||||
|
||||
The grub_file_open() and grub_file_close() should be the only places
|
||||
that allow a reference to a filesystem to stay open. So, add grub_dl_t
|
||||
to grub_fs_t and set this in the GRUB_MOD_INIT() for each filesystem to
|
||||
avoid issues when filesystems forget to do it themselves or do not track
|
||||
their own references, e.g. squash4.
|
||||
|
||||
The fs_label(), fs_uuid(), fs_mtime() and fs_read() should all ref and
|
||||
unref in the same function but it is essentially redundant in GRUB
|
||||
single threaded model.
|
||||
|
||||
Signed-off-by: B Horn <b@horn.uk>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/fs/affs.c | 1 +
|
||||
grub-core/fs/bfs.c | 1 +
|
||||
grub-core/fs/btrfs.c | 1 +
|
||||
grub-core/fs/cbfs.c | 1 +
|
||||
grub-core/fs/cpio.c | 1 +
|
||||
grub-core/fs/cpio_be.c | 1 +
|
||||
grub-core/fs/ext2.c | 1 +
|
||||
grub-core/fs/f2fs.c | 1 +
|
||||
grub-core/fs/fat.c | 1 +
|
||||
grub-core/fs/hfs.c | 1 +
|
||||
grub-core/fs/hfsplus.c | 1 +
|
||||
grub-core/fs/iso9660.c | 1 +
|
||||
grub-core/fs/jfs.c | 1 +
|
||||
grub-core/fs/minix.c | 1 +
|
||||
grub-core/fs/newc.c | 1 +
|
||||
grub-core/fs/nilfs2.c | 1 +
|
||||
grub-core/fs/ntfs.c | 1 +
|
||||
grub-core/fs/odc.c | 1 +
|
||||
grub-core/fs/proc.c | 1 +
|
||||
grub-core/fs/reiserfs.c | 1 +
|
||||
grub-core/fs/romfs.c | 1 +
|
||||
grub-core/fs/sfs.c | 1 +
|
||||
grub-core/fs/squash4.c | 1 +
|
||||
grub-core/fs/tar.c | 1 +
|
||||
grub-core/fs/udf.c | 1 +
|
||||
grub-core/fs/ufs.c | 1 +
|
||||
grub-core/fs/xfs.c | 1 +
|
||||
grub-core/fs/zfs/zfs.c | 1 +
|
||||
grub-core/kern/file.c | 7 +++++++
|
||||
include/grub/fs.h | 4 ++++
|
||||
30 files changed, 39 insertions(+)
|
||||
|
||||
diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c
|
||||
index ed606b3f15..9b0afb9541 100644
|
||||
--- a/grub-core/fs/affs.c
|
||||
+++ b/grub-core/fs/affs.c
|
||||
@@ -703,6 +703,7 @@ static struct grub_fs grub_affs_fs =
|
||||
|
||||
GRUB_MOD_INIT(affs)
|
||||
{
|
||||
+ grub_affs_fs.mod = mod;
|
||||
grub_fs_register (&grub_affs_fs);
|
||||
my_mod = mod;
|
||||
}
|
||||
diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c
|
||||
index 07cb3e3acf..f37b168958 100644
|
||||
--- a/grub-core/fs/bfs.c
|
||||
+++ b/grub-core/fs/bfs.c
|
||||
@@ -1106,6 +1106,7 @@ GRUB_MOD_INIT (bfs)
|
||||
{
|
||||
COMPILE_TIME_ASSERT (1 << LOG_EXTENT_SIZE ==
|
||||
sizeof (struct grub_bfs_extent));
|
||||
+ grub_bfs_fs.mod = mod;
|
||||
grub_fs_register (&grub_bfs_fs);
|
||||
}
|
||||
|
||||
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
|
||||
index 7e12dce9c2..0dd9a817ee 100644
|
||||
--- a/grub-core/fs/btrfs.c
|
||||
+++ b/grub-core/fs/btrfs.c
|
||||
@@ -3565,6 +3565,7 @@ relpath_set_env (struct grub_env_var *var,
|
||||
|
||||
GRUB_MOD_INIT (btrfs)
|
||||
{
|
||||
+ grub_btrfs_fs.mod = mod;
|
||||
grub_fs_register (&grub_btrfs_fs);
|
||||
cmd_info = grub_register_command("btrfs-info", grub_cmd_btrfs_info,
|
||||
"DEVICE",
|
||||
diff --git a/grub-core/fs/cbfs.c b/grub-core/fs/cbfs.c
|
||||
index 8ab7106afb..2332745fe8 100644
|
||||
--- a/grub-core/fs/cbfs.c
|
||||
+++ b/grub-core/fs/cbfs.c
|
||||
@@ -390,6 +390,7 @@ GRUB_MOD_INIT (cbfs)
|
||||
#if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN)
|
||||
init_cbfsdisk ();
|
||||
#endif
|
||||
+ grub_cbfs_fs.mod = mod;
|
||||
grub_fs_register (&grub_cbfs_fs);
|
||||
}
|
||||
|
||||
diff --git a/grub-core/fs/cpio.c b/grub-core/fs/cpio.c
|
||||
index dab5f98988..1799f7ff5a 100644
|
||||
--- a/grub-core/fs/cpio.c
|
||||
+++ b/grub-core/fs/cpio.c
|
||||
@@ -52,6 +52,7 @@ read_number (const grub_uint16_t *arr, grub_size_t size)
|
||||
|
||||
GRUB_MOD_INIT (cpio)
|
||||
{
|
||||
+ grub_cpio_fs.mod = mod;
|
||||
grub_fs_register (&grub_cpio_fs);
|
||||
}
|
||||
|
||||
diff --git a/grub-core/fs/cpio_be.c b/grub-core/fs/cpio_be.c
|
||||
index 8465488921..7bed1b848c 100644
|
||||
--- a/grub-core/fs/cpio_be.c
|
||||
+++ b/grub-core/fs/cpio_be.c
|
||||
@@ -52,6 +52,7 @@ read_number (const grub_uint16_t *arr, grub_size_t size)
|
||||
|
||||
GRUB_MOD_INIT (cpio_be)
|
||||
{
|
||||
+ grub_cpio_fs.mod = mod;
|
||||
grub_fs_register (&grub_cpio_fs);
|
||||
}
|
||||
|
||||
diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c
|
||||
index e1cc5e62aa..04f5d04e14 100644
|
||||
--- a/grub-core/fs/ext2.c
|
||||
+++ b/grub-core/fs/ext2.c
|
||||
@@ -1123,6 +1123,7 @@ static struct grub_fs grub_ext2_fs =
|
||||
|
||||
GRUB_MOD_INIT(ext2)
|
||||
{
|
||||
+ grub_ext2_fs.mod = mod;
|
||||
grub_fs_register (&grub_ext2_fs);
|
||||
my_mod = mod;
|
||||
}
|
||||
diff --git a/grub-core/fs/f2fs.c b/grub-core/fs/f2fs.c
|
||||
index 855e24618c..7e48796036 100644
|
||||
--- a/grub-core/fs/f2fs.c
|
||||
+++ b/grub-core/fs/f2fs.c
|
||||
@@ -1350,6 +1350,7 @@ static struct grub_fs grub_f2fs_fs = {
|
||||
|
||||
GRUB_MOD_INIT (f2fs)
|
||||
{
|
||||
+ grub_f2fs_fs.mod = mod;
|
||||
grub_fs_register (&grub_f2fs_fs);
|
||||
my_mod = mod;
|
||||
}
|
||||
diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c
|
||||
index c5efed7241..6e62b915dd 100644
|
||||
--- a/grub-core/fs/fat.c
|
||||
+++ b/grub-core/fs/fat.c
|
||||
@@ -1312,6 +1312,7 @@ GRUB_MOD_INIT(fat)
|
||||
#endif
|
||||
{
|
||||
COMPILE_TIME_ASSERT (sizeof (struct grub_fat_dir_entry) == 32);
|
||||
+ grub_fat_fs.mod = mod;
|
||||
grub_fs_register (&grub_fat_fs);
|
||||
my_mod = mod;
|
||||
}
|
||||
diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c
|
||||
index 920112b03e..ce7581dd5f 100644
|
||||
--- a/grub-core/fs/hfs.c
|
||||
+++ b/grub-core/fs/hfs.c
|
||||
@@ -1434,6 +1434,7 @@ static struct grub_fs grub_hfs_fs =
|
||||
|
||||
GRUB_MOD_INIT(hfs)
|
||||
{
|
||||
+ grub_hfs_fs.mod = mod;
|
||||
if (!grub_is_lockdown ())
|
||||
grub_fs_register (&grub_hfs_fs);
|
||||
my_mod = mod;
|
||||
diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c
|
||||
index de71fd486b..3f203abccd 100644
|
||||
--- a/grub-core/fs/hfsplus.c
|
||||
+++ b/grub-core/fs/hfsplus.c
|
||||
@@ -1176,6 +1176,7 @@ static struct grub_fs grub_hfsplus_fs =
|
||||
|
||||
GRUB_MOD_INIT(hfsplus)
|
||||
{
|
||||
+ grub_hfsplus_fs.mod = mod;
|
||||
grub_fs_register (&grub_hfsplus_fs);
|
||||
my_mod = mod;
|
||||
}
|
||||
diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c
|
||||
index 8c348b59a5..5aabca284b 100644
|
||||
--- a/grub-core/fs/iso9660.c
|
||||
+++ b/grub-core/fs/iso9660.c
|
||||
@@ -1247,6 +1247,7 @@ static struct grub_fs grub_iso9660_fs =
|
||||
|
||||
GRUB_MOD_INIT(iso9660)
|
||||
{
|
||||
+ grub_iso9660_fs.mod = mod;
|
||||
grub_fs_register (&grub_iso9660_fs);
|
||||
my_mod = mod;
|
||||
}
|
||||
diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c
|
||||
index 6f7c439049..3139e53329 100644
|
||||
--- a/grub-core/fs/jfs.c
|
||||
+++ b/grub-core/fs/jfs.c
|
||||
@@ -963,6 +963,7 @@ static struct grub_fs grub_jfs_fs =
|
||||
|
||||
GRUB_MOD_INIT(jfs)
|
||||
{
|
||||
+ grub_jfs_fs.mod = mod;
|
||||
grub_fs_register (&grub_jfs_fs);
|
||||
my_mod = mod;
|
||||
}
|
||||
diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c
|
||||
index 5354951d10..b7679c3e25 100644
|
||||
--- a/grub-core/fs/minix.c
|
||||
+++ b/grub-core/fs/minix.c
|
||||
@@ -734,6 +734,7 @@ GRUB_MOD_INIT(minix)
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
+ grub_minix_fs.mod = mod;
|
||||
grub_fs_register (&grub_minix_fs);
|
||||
my_mod = mod;
|
||||
}
|
||||
diff --git a/grub-core/fs/newc.c b/grub-core/fs/newc.c
|
||||
index 4fb8b2e3d2..43b7f8b642 100644
|
||||
--- a/grub-core/fs/newc.c
|
||||
+++ b/grub-core/fs/newc.c
|
||||
@@ -64,6 +64,7 @@ read_number (const char *str, grub_size_t size)
|
||||
|
||||
GRUB_MOD_INIT (newc)
|
||||
{
|
||||
+ grub_cpio_fs.mod = mod;
|
||||
grub_fs_register (&grub_cpio_fs);
|
||||
}
|
||||
|
||||
diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c
|
||||
index fc7374ead4..4e1e717386 100644
|
||||
--- a/grub-core/fs/nilfs2.c
|
||||
+++ b/grub-core/fs/nilfs2.c
|
||||
@@ -1231,6 +1231,7 @@ GRUB_MOD_INIT (nilfs2)
|
||||
grub_nilfs2_dat_entry));
|
||||
COMPILE_TIME_ASSERT (1 << LOG_INODE_SIZE
|
||||
== sizeof (struct grub_nilfs2_inode));
|
||||
+ grub_nilfs2_fs.mod = mod;
|
||||
grub_fs_register (&grub_nilfs2_fs);
|
||||
my_mod = mod;
|
||||
}
|
||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
||||
index de435aa14d..560917dc2c 100644
|
||||
--- a/grub-core/fs/ntfs.c
|
||||
+++ b/grub-core/fs/ntfs.c
|
||||
@@ -1320,6 +1320,7 @@ static struct grub_fs grub_ntfs_fs =
|
||||
|
||||
GRUB_MOD_INIT (ntfs)
|
||||
{
|
||||
+ grub_ntfs_fs.mod = mod;
|
||||
grub_fs_register (&grub_ntfs_fs);
|
||||
my_mod = mod;
|
||||
}
|
||||
diff --git a/grub-core/fs/odc.c b/grub-core/fs/odc.c
|
||||
index 790000622d..8e4e8aeac8 100644
|
||||
--- a/grub-core/fs/odc.c
|
||||
+++ b/grub-core/fs/odc.c
|
||||
@@ -52,6 +52,7 @@ read_number (const char *str, grub_size_t size)
|
||||
|
||||
GRUB_MOD_INIT (odc)
|
||||
{
|
||||
+ grub_cpio_fs.mod = mod;
|
||||
grub_fs_register (&grub_cpio_fs);
|
||||
}
|
||||
|
||||
diff --git a/grub-core/fs/proc.c b/grub-core/fs/proc.c
|
||||
index 5f516502d4..bcde433495 100644
|
||||
--- a/grub-core/fs/proc.c
|
||||
+++ b/grub-core/fs/proc.c
|
||||
@@ -192,6 +192,7 @@ static struct grub_fs grub_procfs_fs =
|
||||
|
||||
GRUB_MOD_INIT (procfs)
|
||||
{
|
||||
+ grub_procfs_fs.mod = mod;
|
||||
grub_disk_dev_register (&grub_procfs_dev);
|
||||
grub_fs_register (&grub_procfs_fs);
|
||||
}
|
||||
diff --git a/grub-core/fs/reiserfs.c b/grub-core/fs/reiserfs.c
|
||||
index 36b26ac98a..c3850e0138 100644
|
||||
--- a/grub-core/fs/reiserfs.c
|
||||
+++ b/grub-core/fs/reiserfs.c
|
||||
@@ -1417,6 +1417,7 @@ static struct grub_fs grub_reiserfs_fs =
|
||||
|
||||
GRUB_MOD_INIT(reiserfs)
|
||||
{
|
||||
+ grub_reiserfs_fs.mod = mod;
|
||||
grub_fs_register (&grub_reiserfs_fs);
|
||||
my_mod = mod;
|
||||
}
|
||||
diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c
|
||||
index 1f7dcfca1d..56b0b2b2f3 100644
|
||||
--- a/grub-core/fs/romfs.c
|
||||
+++ b/grub-core/fs/romfs.c
|
||||
@@ -475,6 +475,7 @@ static struct grub_fs grub_romfs_fs =
|
||||
|
||||
GRUB_MOD_INIT(romfs)
|
||||
{
|
||||
+ grub_romfs_fs.mod = mod;
|
||||
grub_fs_register (&grub_romfs_fs);
|
||||
}
|
||||
|
||||
diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c
|
||||
index 983e880088..f0d7cac435 100644
|
||||
--- a/grub-core/fs/sfs.c
|
||||
+++ b/grub-core/fs/sfs.c
|
||||
@@ -779,6 +779,7 @@ static struct grub_fs grub_sfs_fs =
|
||||
|
||||
GRUB_MOD_INIT(sfs)
|
||||
{
|
||||
+ grub_sfs_fs.mod = mod;
|
||||
grub_fs_register (&grub_sfs_fs);
|
||||
my_mod = mod;
|
||||
}
|
||||
diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c
|
||||
index a30e6ebe14..6e9d63874c 100644
|
||||
--- a/grub-core/fs/squash4.c
|
||||
+++ b/grub-core/fs/squash4.c
|
||||
@@ -1044,6 +1044,7 @@ static struct grub_fs grub_squash_fs =
|
||||
|
||||
GRUB_MOD_INIT(squash4)
|
||||
{
|
||||
+ grub_squash_fs.mod = mod;
|
||||
grub_fs_register (&grub_squash_fs);
|
||||
}
|
||||
|
||||
diff --git a/grub-core/fs/tar.c b/grub-core/fs/tar.c
|
||||
index a9e39b0eb6..a608ac9c9f 100644
|
||||
--- a/grub-core/fs/tar.c
|
||||
+++ b/grub-core/fs/tar.c
|
||||
@@ -349,6 +349,7 @@ static struct grub_fs grub_cpio_fs = {
|
||||
|
||||
GRUB_MOD_INIT (tar)
|
||||
{
|
||||
+ grub_cpio_fs.mod = mod;
|
||||
grub_fs_register (&grub_cpio_fs);
|
||||
}
|
||||
|
||||
diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c
|
||||
index b836e61075..8765c633c6 100644
|
||||
--- a/grub-core/fs/udf.c
|
||||
+++ b/grub-core/fs/udf.c
|
||||
@@ -1455,6 +1455,7 @@ static struct grub_fs grub_udf_fs = {
|
||||
|
||||
GRUB_MOD_INIT (udf)
|
||||
{
|
||||
+ grub_udf_fs.mod = mod;
|
||||
grub_fs_register (&grub_udf_fs);
|
||||
my_mod = mod;
|
||||
}
|
||||
diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c
|
||||
index 01235101b4..e82d9356d7 100644
|
||||
--- a/grub-core/fs/ufs.c
|
||||
+++ b/grub-core/fs/ufs.c
|
||||
@@ -899,6 +899,7 @@ GRUB_MOD_INIT(ufs1)
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
+ grub_ufs_fs.mod = mod;
|
||||
grub_fs_register (&grub_ufs_fs);
|
||||
my_mod = mod;
|
||||
}
|
||||
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
|
||||
index 1ce5fa4fc4..c17e54e447 100644
|
||||
--- a/grub-core/fs/xfs.c
|
||||
+++ b/grub-core/fs/xfs.c
|
||||
@@ -1281,6 +1281,7 @@ static struct grub_fs grub_xfs_fs =
|
||||
|
||||
GRUB_MOD_INIT(xfs)
|
||||
{
|
||||
+ grub_xfs_fs.mod = mod;
|
||||
grub_fs_register (&grub_xfs_fs);
|
||||
my_mod = mod;
|
||||
}
|
||||
diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
|
||||
index b5453e0062..a497b18695 100644
|
||||
--- a/grub-core/fs/zfs/zfs.c
|
||||
+++ b/grub-core/fs/zfs/zfs.c
|
||||
@@ -4424,6 +4424,7 @@ static struct grub_fs grub_zfs_fs = {
|
||||
GRUB_MOD_INIT (zfs)
|
||||
{
|
||||
COMPILE_TIME_ASSERT (sizeof (zap_leaf_chunk_t) == ZAP_LEAF_CHUNKSIZE);
|
||||
+ grub_zfs_fs.mod = mod;
|
||||
grub_fs_register (&grub_zfs_fs);
|
||||
#ifndef GRUB_UTIL
|
||||
my_mod = mod;
|
||||
diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c
|
||||
index e990507fca..6e7efe89ab 100644
|
||||
--- a/grub-core/kern/file.c
|
||||
+++ b/grub-core/kern/file.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <grub/fs.h>
|
||||
#include <grub/device.h>
|
||||
#include <grub/i18n.h>
|
||||
+#include <grub/dl.h>
|
||||
|
||||
void (*EXPORT_VAR (grub_grubnet_fini)) (void);
|
||||
|
||||
@@ -117,6 +118,9 @@ grub_file_open (const char *name, enum grub_file_type type)
|
||||
if (file->data == NULL)
|
||||
goto fail;
|
||||
|
||||
+ if (file->fs->mod)
|
||||
+ grub_dl_ref (file->fs->mod);
|
||||
+
|
||||
file->name = grub_strdup (name);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
||||
@@ -197,6 +201,9 @@ 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);
|
||||
|
||||
diff --git a/include/grub/fs.h b/include/grub/fs.h
|
||||
index 4c380e3341..9c8206133d 100644
|
||||
--- a/include/grub/fs.h
|
||||
+++ b/include/grub/fs.h
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <grub/device.h>
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/types.h>
|
||||
+#include <grub/dl.h>
|
||||
|
||||
#include <grub/list.h>
|
||||
/* For embedding types. */
|
||||
@@ -57,6 +58,9 @@ struct grub_fs
|
||||
/* My name. */
|
||||
const char *name;
|
||||
|
||||
+ /* My module */
|
||||
+ grub_dl_t mod;
|
||||
+
|
||||
/* Call HOOK with each file under DIR. */
|
||||
grub_err_t (*fs_dir) (grub_device_t device, const char *path,
|
||||
grub_fs_dir_hook_t hook, void *hook_data);
|
||||
--
|
||||
2.48.1
|
||||
|
@@ -1,23 +0,0 @@
|
||||
From 6811f6f09d61996a3acbc4fc0414e45964f0e2d9 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Date: Tue, 26 Nov 2024 15:39:46 -0500
|
||||
Subject: [PATCH 7/7] tpm2_key_protector: Enable build for powerpc_ieee1275
|
||||
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
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
|
||||
@@ -2645,6 +2645,7 @@ module = {
|
||||
/* The plaform support of tpm2_key_protector depends on the tcg2 implementation in tss2. */
|
||||
enable = efi;
|
||||
enable = emu;
|
||||
+ enable = powerpc_ieee1275;
|
||||
cppflags = '-I$(srcdir)/lib/tss2';
|
||||
};
|
||||
|
@@ -1,579 +0,0 @@
|
||||
From 5934bf51cbdf820c71eeed4bbbbcf23756e96217 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Mon, 7 Apr 2025 16:29:21 +0800
|
||||
Subject: [PATCH 7/7] util/grub-protect: Support NV index mode
|
||||
|
||||
This commit implements the missing NV index mode support in grub-protect.
|
||||
NV index mode stores the sealed key in the TPM non-volatile memory (NVRAM)
|
||||
instead of a file. There are two supported types of TPM handles.
|
||||
|
||||
1. Persistent handle (0x81000000~0x81FFFFFF)
|
||||
Only the raw format is supported due to the limitation of persistent
|
||||
handles. This grub-protect command seals the key into the
|
||||
persistent handle 0x81000000.
|
||||
|
||||
# grub-protect \
|
||||
--protector=tpm2 \
|
||||
--action=add \
|
||||
--tpm2-bank=sha256 \
|
||||
--tpm2-pcrs=7,11 \
|
||||
--tpm2-keyfile=luks-key \
|
||||
--tpm2-nvindex=0x81000000
|
||||
|
||||
2. NV index handle (0x1000000~0x1FFFFFF)
|
||||
Both TPM 2.0 Key File format and the raw format are supported by NV
|
||||
index handles. Here is the grub-protect command to seal the key in
|
||||
TPM 2.0 Key File format into the NV index handle 0x1000000.
|
||||
|
||||
# grub-protect \
|
||||
--protector=tpm2 \
|
||||
--action=add \
|
||||
--tpm2key \
|
||||
--tpm2-bank=sha256 \
|
||||
--tpm2-pcrs=7,11 \
|
||||
--tpm2-keyfile=luks-key \
|
||||
--tpm2-nvindex=0x1000000
|
||||
|
||||
Besides the "add" action, the corresponding "remove" action is also
|
||||
introduced. To remove the data from a persistent or NV index handle,
|
||||
just use "--tpm2-nvindex=HANDLE" combining with "--tpm2-evict". This
|
||||
sample command removes the data from the NV index handle 0x1000000.
|
||||
|
||||
# grub-protect \
|
||||
--protector=tpm2 \
|
||||
--action=remove \
|
||||
--tpm2-evict \
|
||||
--tpm2-nvindex=0x1000000
|
||||
|
||||
Also set and check the boolean variables with true/false instead of 1/0.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
util/grub-protect.c | 343 ++++++++++++++++++++++++++++++++++++--------
|
||||
1 file changed, 287 insertions(+), 56 deletions(-)
|
||||
|
||||
diff --git a/util/grub-protect.c b/util/grub-protect.c
|
||||
index 5b7e952f4..40d4a3fc5 100644
|
||||
--- a/util/grub-protect.c
|
||||
+++ b/util/grub-protect.c
|
||||
@@ -61,7 +61,8 @@ typedef enum protect_opt
|
||||
PROTECT_OPT_TPM2_KEYFILE,
|
||||
PROTECT_OPT_TPM2_OUTFILE,
|
||||
PROTECT_OPT_TPM2_EVICT,
|
||||
- PROTECT_OPT_TPM2_TPM2KEY
|
||||
+ PROTECT_OPT_TPM2_TPM2KEY,
|
||||
+ PROTECT_OPT_TPM2_NVINDEX,
|
||||
} protect_opt_t;
|
||||
|
||||
/* Option flags to keep track of specified arguments */
|
||||
@@ -79,7 +80,8 @@ typedef enum protect_arg
|
||||
PROTECT_ARG_TPM2_KEYFILE = 1 << 7,
|
||||
PROTECT_ARG_TPM2_OUTFILE = 1 << 8,
|
||||
PROTECT_ARG_TPM2_EVICT = 1 << 9,
|
||||
- PROTECT_ARG_TPM2_TPM2KEY = 1 << 10
|
||||
+ PROTECT_ARG_TPM2_TPM2KEY = 1 << 10,
|
||||
+ PROTECT_ARG_TPM2_NVINDEX = 1 << 11
|
||||
} protect_arg_t;
|
||||
|
||||
typedef enum protect_protector
|
||||
@@ -111,6 +113,7 @@ typedef struct protect_args
|
||||
const char *tpm2_outfile;
|
||||
bool tpm2_evict;
|
||||
bool tpm2_tpm2key;
|
||||
+ TPM_HANDLE_t tpm2_nvindex;
|
||||
} protect_args_t;
|
||||
|
||||
static struct argp_option protect_options[] =
|
||||
@@ -224,6 +227,15 @@ static struct argp_option protect_options[] =
|
||||
N_("Use TPM 2.0 Key File format."),
|
||||
.group = 0
|
||||
},
|
||||
+ {
|
||||
+ .name = "tpm2-nvindex",
|
||||
+ .key = PROTECT_OPT_TPM2_NVINDEX,
|
||||
+ .arg = "NUM",
|
||||
+ .flags = 0,
|
||||
+ .doc =
|
||||
+ N_("Store the sealed key in a persistent or NV index handle."),
|
||||
+ .group = 0
|
||||
+ },
|
||||
/* End of list */
|
||||
{ 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
@@ -668,8 +680,8 @@ extern asn1_static_node tpm2key_asn1_tab[];
|
||||
#define TPM2KEY_SEALED_KEY_OID "2.23.133.10.1.5"
|
||||
|
||||
static grub_err_t
|
||||
-protect_tpm2_export_tpm2key (const protect_args_t *args,
|
||||
- tpm2_sealed_key_t *sealed_key)
|
||||
+protect_tpm2_export_tpm2key (const protect_args_t *args, tpm2_sealed_key_t *sealed_key,
|
||||
+ void **der_buf, int *der_buf_size)
|
||||
{
|
||||
const char *sealed_key_oid = TPM2KEY_SEALED_KEY_OID;
|
||||
asn1_node asn1_def = NULL;
|
||||
@@ -689,12 +701,13 @@ protect_tpm2_export_tpm2key (const protect_args_t *args,
|
||||
};
|
||||
struct grub_tpm2_buffer pub_buf;
|
||||
struct grub_tpm2_buffer priv_buf;
|
||||
- void *der_buf = NULL;
|
||||
- int der_buf_size = 0;
|
||||
int i;
|
||||
int ret;
|
||||
grub_err_t err;
|
||||
|
||||
+ if (der_buf == NULL)
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+
|
||||
for (i = 0; i < args->tpm2_pcr_count; i++)
|
||||
TPMS_PCR_SELECTION_SelectPCR (&pcr_sel.pcrSelections[0], args->tpm2_pcrs[i]);
|
||||
|
||||
@@ -844,8 +857,8 @@ protect_tpm2_export_tpm2key (const protect_args_t *args,
|
||||
}
|
||||
|
||||
/* Create the DER binary */
|
||||
- der_buf_size = 0;
|
||||
- ret = asn1_der_coding (tpm2key, "", NULL, &der_buf_size, NULL);
|
||||
+ *der_buf_size = 0;
|
||||
+ ret = asn1_der_coding (tpm2key, "", NULL, der_buf_size, NULL);
|
||||
if (ret != ASN1_MEM_ERROR)
|
||||
{
|
||||
fprintf (stderr, "Failed to get DER size: 0x%x\n", ret);
|
||||
@@ -853,15 +866,15 @@ protect_tpm2_export_tpm2key (const protect_args_t *args,
|
||||
goto error;
|
||||
}
|
||||
|
||||
- der_buf = grub_malloc (der_buf_size);
|
||||
- if (der_buf == NULL)
|
||||
+ *der_buf = grub_malloc (*der_buf_size);
|
||||
+ if (*der_buf == NULL)
|
||||
{
|
||||
fprintf (stderr, "Failed to allocate memory for DER encoding\n");
|
||||
err = GRUB_ERR_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
|
||||
- ret = asn1_der_coding (tpm2key, "", der_buf, &der_buf_size, NULL);
|
||||
+ ret = asn1_der_coding (tpm2key, "", *der_buf, der_buf_size, NULL);
|
||||
if (ret != ASN1_SUCCESS)
|
||||
{
|
||||
fprintf (stderr, "DER coding error: 0x%x\n", ret);
|
||||
@@ -869,13 +882,7 @@ protect_tpm2_export_tpm2key (const protect_args_t *args,
|
||||
goto error;
|
||||
}
|
||||
|
||||
- err = protect_write_file (args->tpm2_outfile, der_buf, der_buf_size);
|
||||
- if (err != GRUB_ERR_NONE)
|
||||
- fprintf (stderr, N_("Could not write tpm2key file (%s).\n"), strerror (errno));
|
||||
-
|
||||
error:
|
||||
- grub_free (der_buf);
|
||||
-
|
||||
if (tpm2key)
|
||||
asn1_delete_structure (&tpm2key);
|
||||
|
||||
@@ -883,10 +890,8 @@ protect_tpm2_export_tpm2key (const protect_args_t *args,
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-protect_tpm2_export_sealed_key (const char *filepath,
|
||||
- tpm2_sealed_key_t *sealed_key)
|
||||
+protect_tpm2_export_raw (tpm2_sealed_key_t *sealed_key, void **out_buf, int *out_buf_size)
|
||||
{
|
||||
- grub_err_t err;
|
||||
struct grub_tpm2_buffer buf;
|
||||
|
||||
grub_tpm2_buffer_init (&buf);
|
||||
@@ -896,13 +901,98 @@ protect_tpm2_export_sealed_key (const char *filepath,
|
||||
if (buf.error != 0)
|
||||
return GRUB_ERR_BAD_ARGUMENT;
|
||||
|
||||
- err = protect_write_file (filepath, buf.data, buf.size);
|
||||
- if (err != GRUB_ERR_NONE)
|
||||
- fprintf (stderr, N_("Could not write sealed key file (%s).\n"), strerror (errno));
|
||||
+ *out_buf_size = buf.size;
|
||||
+ *out_buf = grub_malloc (buf.size);
|
||||
+
|
||||
+ if (*out_buf == NULL)
|
||||
+ {
|
||||
+ fprintf (stderr, N_("Could not allocate memory for the raw format key.\n"));
|
||||
+ return GRUB_ERR_OUT_OF_MEMORY;
|
||||
+ }
|
||||
+
|
||||
+ grub_memcpy (*out_buf, buf.data, buf.size);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+protect_tpm2_export_persistent (protect_args_t *args,
|
||||
+ TPM_HANDLE_t srk_handle,
|
||||
+ tpm2_sealed_key_t *sealed_key)
|
||||
+{
|
||||
+ TPMS_AUTH_COMMAND_t authCmd = {0};
|
||||
+ TPM2B_NAME_t name = {0};
|
||||
+ TPM_HANDLE_t sealed_handle;
|
||||
+ TPM_RC_t rc;
|
||||
+ grub_err_t err = GRUB_ERR_NONE;
|
||||
+
|
||||
+ /* Load the sealed key and associate it with the SRK */
|
||||
+ authCmd.sessionHandle = TPM_RS_PW;
|
||||
+ rc = grub_tpm2_load (srk_handle, &authCmd, &sealed_key->private, &sealed_key->public,
|
||||
+ &sealed_handle, &name, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ fprintf (stderr, "Failed to load sealed key (TPM2_Load: %x).\n", rc);
|
||||
+ return GRUB_ERR_BAD_DEVICE;
|
||||
+ }
|
||||
+
|
||||
+ /* Make the sealed key object persistent */
|
||||
+ authCmd.sessionHandle = TPM_RS_PW;
|
||||
+ rc = grub_tpm2_evictcontrol (TPM_RH_OWNER, sealed_handle, &authCmd, args->tpm2_nvindex, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ fprintf (stderr, "Failed to make sealed key persistent with handle 0x%x (TPM2_EvictControl: 0x%x).\n", args->tpm2_nvindex, rc);
|
||||
+ err = GRUB_ERR_BAD_DEVICE;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ exit:
|
||||
+ grub_tpm2_flushcontext (sealed_handle);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+protect_tpm2_export_nvindex (protect_args_t *args, void *data, int data_size)
|
||||
+{
|
||||
+ TPMS_AUTH_COMMAND_t authCmd = {0};
|
||||
+ TPM2B_NV_PUBLIC_t pub_info = {0};
|
||||
+ TPM2B_MAX_NV_BUFFER_t nv_data = {0};
|
||||
+ TPM_RC_t rc;
|
||||
+
|
||||
+ if (data_size > TPM_MAX_NV_BUFFER_SIZE || data_size < 0)
|
||||
+ {
|
||||
+ fprintf (stderr, N_("Invalid tpm2key size for TPM NV buffer\n"));
|
||||
+ return GRUB_ERR_OUT_OF_RANGE;
|
||||
+ }
|
||||
+
|
||||
+ pub_info.nvPublic.nvIndex = args->tpm2_nvindex;
|
||||
+ pub_info.nvPublic.nameAlg = TPM_ALG_SHA256;
|
||||
+ pub_info.nvPublic.attributes = TPMA_NV_OWNERWRITE | TPMA_NV_OWNERREAD;
|
||||
+ pub_info.nvPublic.dataSize = (grub_uint16_t) data_size;
|
||||
+
|
||||
+ authCmd.sessionHandle = TPM_RS_PW;
|
||||
+ rc = grub_tpm2_nv_definespace (TPM_RH_OWNER, &authCmd, NULL, &pub_info);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ fprintf (stderr, "Failed to define NV space for 0x%x (TPM2_NV_DefineSpace: 0x%x)\n", args->tpm2_nvindex, rc);
|
||||
+ return GRUB_ERR_BAD_DEVICE;
|
||||
+ }
|
||||
+
|
||||
+ authCmd.sessionHandle = TPM_RS_PW;
|
||||
+ grub_memcpy (nv_data.buffer, data, data_size);
|
||||
+ nv_data.size = (grub_uint16_t) data_size;
|
||||
+
|
||||
+ rc = grub_tpm2_nv_write (TPM_RH_OWNER, args->tpm2_nvindex, &authCmd, &nv_data, 0);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ fprintf (stderr, "Failed to write data into 0x%x (TPM2_NV_Write: 0x%x)\n", args->tpm2_nvindex, rc);
|
||||
+ return GRUB_ERR_BAD_DEVICE;
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
protect_tpm2_add (protect_args_t *args)
|
||||
{
|
||||
@@ -911,6 +1001,8 @@ protect_tpm2_add (protect_args_t *args)
|
||||
grub_size_t key_size;
|
||||
TPM_HANDLE_t srk;
|
||||
TPM2B_DIGEST_t policy_digest;
|
||||
+ void *out_buf = NULL;
|
||||
+ int out_buf_size;
|
||||
tpm2_sealed_key_t sealed_key;
|
||||
|
||||
err = protect_tpm2_open_device (args->tpm2_device);
|
||||
@@ -940,15 +1032,51 @@ protect_tpm2_add (protect_args_t *args)
|
||||
if (err != GRUB_ERR_NONE)
|
||||
goto exit3;
|
||||
|
||||
- if (args->tpm2_tpm2key != 0)
|
||||
- err = protect_tpm2_export_tpm2key (args, &sealed_key);
|
||||
+ if (args->tpm2_tpm2key == true)
|
||||
+ {
|
||||
+ err = protect_tpm2_export_tpm2key (args, &sealed_key, &out_buf, &out_buf_size);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ fprintf (stderr, N_("Could not export to TPM 2.0 Key File format\n"));
|
||||
+ goto exit3;
|
||||
+ }
|
||||
+ }
|
||||
else
|
||||
- err = protect_tpm2_export_sealed_key (args->tpm2_outfile, &sealed_key);
|
||||
- if (err != GRUB_ERR_NONE)
|
||||
- goto exit3;
|
||||
+ {
|
||||
+ err = protect_tpm2_export_raw (&sealed_key, &out_buf, &out_buf_size);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ fprintf (stderr, N_("Could not export to the raw format\n"));
|
||||
+ goto exit3;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (args->tpm2_outfile != NULL)
|
||||
+ {
|
||||
+ err = protect_write_file (args->tpm2_outfile, out_buf, out_buf_size);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ fprintf (stderr, N_("Could not write key file (%s).\n"), strerror (errno));
|
||||
+ goto exit3;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (TPM_HT_IS_NVINDEX (args->tpm2_nvindex) == true)
|
||||
+ {
|
||||
+ err = protect_tpm2_export_nvindex (args, out_buf, out_buf_size);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ goto exit3;
|
||||
+ }
|
||||
+ else if (TPM_HT_IS_PERSISTENT (args->tpm2_nvindex) == true)
|
||||
+ {
|
||||
+ err = protect_tpm2_export_persistent (args, srk, &sealed_key);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ goto exit3;
|
||||
+ }
|
||||
|
||||
exit3:
|
||||
grub_tpm2_flushcontext (srk);
|
||||
+ grub_free (out_buf);
|
||||
|
||||
exit2:
|
||||
grub_free (key);
|
||||
@@ -960,14 +1088,66 @@ protect_tpm2_add (protect_args_t *args)
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-protect_tpm2_remove (protect_args_t *args)
|
||||
+protect_tpm2_evict (TPM_HANDLE_t handle)
|
||||
{
|
||||
TPM_RC_t rc;
|
||||
TPM2B_PUBLIC_t public;
|
||||
- TPMS_AUTH_COMMAND_t authCommand = {0};
|
||||
+ TPMS_AUTH_COMMAND_t authCmd = {0};
|
||||
+
|
||||
+ /* Find the persistent handle */
|
||||
+ rc = grub_tpm2_readpublic (handle, NULL, &public);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ fprintf (stderr, "Handle 0x%x not found.\n", handle);
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ /* Evict the persistent handle */
|
||||
+ authCmd.sessionHandle = TPM_RS_PW;
|
||||
+ rc = grub_tpm2_evictcontrol (TPM_RH_OWNER, handle, &authCmd, handle, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ fprintf (stderr, "Failed to evict handle 0x%x (TPM2_EvictControl: 0x%x).\n", handle, rc);
|
||||
+ return GRUB_ERR_BAD_DEVICE;
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+protect_tpm2_nv_undefine (TPM_HANDLE_t handle)
|
||||
+{
|
||||
+ TPM_RC_t rc;
|
||||
+ TPM2B_NV_PUBLIC_t nv_public;
|
||||
+ TPMS_AUTH_COMMAND_t authCmd = {0};
|
||||
+ TPM2B_NAME_t nv_name;
|
||||
+
|
||||
+ /* Find the nvindex handle */
|
||||
+ rc = grub_tpm2_nv_readpublic (handle, NULL, &nv_public, &nv_name);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ fprintf (stderr, "Handle 0x%x not found.\n", handle);
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ /* Undefine the nvindex handle */
|
||||
+ authCmd.sessionHandle = TPM_RS_PW;
|
||||
+ rc = grub_tpm2_nv_undefinespace (TPM_RH_OWNER, handle, &authCmd);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ fprintf (stderr, "Failed to undefine handle 0x%x (TPM2_NV_UndefineSpace: 0x%x).\n", handle, rc);
|
||||
+ return GRUB_ERR_BAD_DEVICE;
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+protect_tpm2_remove (protect_args_t *args)
|
||||
+{
|
||||
grub_err_t err;
|
||||
|
||||
- if (args->tpm2_evict == 0)
|
||||
+ if (args->tpm2_evict == false)
|
||||
{
|
||||
printf ("--tpm2-evict not specified, nothing to do.\n");
|
||||
return GRUB_ERR_NONE;
|
||||
@@ -977,35 +1157,41 @@ protect_tpm2_remove (protect_args_t *args)
|
||||
if (err != GRUB_ERR_NONE)
|
||||
return err;
|
||||
|
||||
- /* Find SRK */
|
||||
- rc = grub_tpm2_readpublic (args->tpm2_srk, NULL, &public);
|
||||
- if (rc != TPM_RC_SUCCESS)
|
||||
+ if (args->tpm2_srk != 0)
|
||||
{
|
||||
- fprintf (stderr, "SRK with handle 0x%x not found.\n", args->tpm2_srk);
|
||||
- err = GRUB_ERR_BAD_ARGUMENT;
|
||||
- goto exit1;
|
||||
+ err = protect_tpm2_evict (args->tpm2_srk);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ goto exit;
|
||||
}
|
||||
|
||||
- /* Evict SRK */
|
||||
- authCommand.sessionHandle = TPM_RS_PW;
|
||||
-
|
||||
- rc = grub_tpm2_evictcontrol (TPM_RH_OWNER, args->tpm2_srk, &authCommand, args->tpm2_srk, NULL);
|
||||
- if (rc != TPM_RC_SUCCESS)
|
||||
+ if (args->tpm2_nvindex != 0)
|
||||
{
|
||||
- fprintf (stderr, "Failed to evict SRK with handle 0x%x (TPM2_EvictControl: 0x%x).\n", args->tpm2_srk, rc);
|
||||
- err = GRUB_ERR_BAD_DEVICE;
|
||||
- goto exit2;
|
||||
+ if (TPM_HT_IS_PERSISTENT (args->tpm2_nvindex) == true)
|
||||
+ {
|
||||
+ err = protect_tpm2_evict (args->tpm2_nvindex);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ else if (TPM_HT_IS_NVINDEX (args->tpm2_nvindex) == true)
|
||||
+ {
|
||||
+ err = protect_tpm2_nv_undefine (args->tpm2_nvindex);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ fprintf (stderr, "Unsupported handle 0x%x\n", args->tpm2_nvindex);
|
||||
+ err = GRUB_ERR_BAD_ARGUMENT;
|
||||
+ goto exit;
|
||||
+ }
|
||||
}
|
||||
|
||||
err = GRUB_ERR_NONE;
|
||||
|
||||
- exit2:
|
||||
- grub_tpm2_flushcontext (args->tpm2_srk);
|
||||
-
|
||||
- exit1:
|
||||
+ exit:
|
||||
protect_tpm2_close_device ();
|
||||
|
||||
- return GRUB_ERR_NONE;
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
@@ -1045,9 +1231,36 @@ protect_tpm2_args_verify (protect_args_t *args)
|
||||
return GRUB_ERR_BAD_ARGUMENT;
|
||||
}
|
||||
|
||||
- if (args->tpm2_outfile == NULL)
|
||||
+ if (args->tpm2_outfile == NULL && args->tpm2_nvindex == 0)
|
||||
{
|
||||
- fprintf (stderr, N_("--tpm2-outfile must be specified.\n"));
|
||||
+ fprintf (stderr, N_("--tpm2-outfile or --tpm2-nvindex must be specified.\n"));
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ if (args->tpm2_nvindex != 0)
|
||||
+ {
|
||||
+ if (args->tpm2_tpm2key == true && TPM_HT_IS_PERSISTENT (args->tpm2_nvindex) == true)
|
||||
+ {
|
||||
+ fprintf (stderr, N_("Persistent handle does not support TPM 2.0 Key File format.\n"));
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ if (TPM_HT_IS_PERSISTENT (args->tpm2_nvindex) == false && TPM_HT_IS_NVINDEX (args->tpm2_nvindex) == false)
|
||||
+ {
|
||||
+ fprintf (stderr, N_("--tpm2-nvindex must be a persistent or NV index handle.\n"));
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ if (args->tpm2_nvindex == args->tpm2_srk)
|
||||
+ {
|
||||
+ fprintf (stderr, N_("--tpm2-nvindex and --tpm2-srk must be different.\n"));
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (args->tpm2_srk != 0 && TPM_HT_IS_PERSISTENT(args->tpm2_srk) == false)
|
||||
+ {
|
||||
+ fprintf (stderr, N_("--tpm2-srk must be a persistent handle, e.g. 0x81000000.\n"));
|
||||
return GRUB_ERR_BAD_ARGUMENT;
|
||||
}
|
||||
|
||||
@@ -1099,9 +1312,9 @@ protect_tpm2_args_verify (protect_args_t *args)
|
||||
return GRUB_ERR_BAD_ARGUMENT;
|
||||
}
|
||||
|
||||
- if (args->tpm2_srk == 0)
|
||||
+ if (args->tpm2_srk == 0 && args->tpm2_nvindex == 0)
|
||||
{
|
||||
- fprintf (stderr, N_("--tpm2-srk is not specified when --action is 'remove'.\n"));
|
||||
+ fprintf (stderr, N_("missing --tpm2-srk or --tpm2-nvindex for --action 'remove'.\n"));
|
||||
return GRUB_ERR_BAD_ARGUMENT;
|
||||
}
|
||||
|
||||
@@ -1274,7 +1487,7 @@ protect_argp_parser (int key, char *arg, struct argp_state *state)
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
- args->tpm2_evict = 1;
|
||||
+ args->tpm2_evict = true;
|
||||
args->args |= PROTECT_ARG_TPM2_EVICT;
|
||||
break;
|
||||
|
||||
@@ -1285,10 +1498,28 @@ protect_argp_parser (int key, char *arg, struct argp_state *state)
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
- args->tpm2_tpm2key = 1;
|
||||
+ args->tpm2_tpm2key = true;
|
||||
args->args |= PROTECT_ARG_TPM2_TPM2KEY;
|
||||
break;
|
||||
|
||||
+ case PROTECT_OPT_TPM2_NVINDEX:
|
||||
+ if (args->args & PROTECT_ARG_TPM2_NVINDEX)
|
||||
+ {
|
||||
+ fprintf (stderr, N_("--tpm2-nvindex can only be specified once.\n"));
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ err = grub_tpm2_protector_parse_tpm_handle (arg, &args->tpm2_nvindex);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ if (grub_errno != GRUB_ERR_NONE)
|
||||
+ grub_print_error ();
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ args->args |= PROTECT_ARG_TPM2_NVINDEX;
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
--
|
||||
2.43.0
|
||||
|
@@ -1,688 +0,0 @@
|
||||
From 964b7ef5695ac925e8cdcf3381d5cfb45dc5d140 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Tue, 25 Feb 2025 02:33:17 +0530
|
||||
Subject: [PATCH 8/9] appendedsig: The grub command's trusted and distrusted
|
||||
support
|
||||
|
||||
To support the following trusted and distrusted commands
|
||||
|
||||
1. trusted_list:
|
||||
It will show the list of trusted certificates and binary hashes
|
||||
2. distrusted_list:
|
||||
It will show the list of distrusted certificates and binary/certificate hashes
|
||||
3. trusted_certificate:
|
||||
It will add the trusted certificate to the trusted list
|
||||
4. trusted_signature:
|
||||
It will add the certificate/binary hash to the trusted list
|
||||
5. distrusted_certificate:
|
||||
It will remove the trusted certificate from trsuted list
|
||||
6. distrusted_signature:
|
||||
It will add the certificate/binary hash to the distrsuted list
|
||||
|
||||
Note:-
|
||||
The addition/deletion of trusted certificates and binary hashes
|
||||
are not allowed in grub command prompt while secure boot is enabled.
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
---
|
||||
grub-core/commands/appendedsig/appendedsig.c | 545 ++++++++++++-------
|
||||
1 file changed, 354 insertions(+), 191 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/appendedsig/appendedsig.c b/grub-core/commands/appendedsig/appendedsig.c
|
||||
index 3cbe51ec13..6ccfdb4c6e 100644
|
||||
--- a/grub-core/commands/appendedsig/appendedsig.c
|
||||
+++ b/grub-core/commands/appendedsig/appendedsig.c
|
||||
@@ -118,6 +118,36 @@ static enum
|
||||
check_sigs_forced = 2
|
||||
} check_sigs = check_sigs_no;
|
||||
|
||||
+enum
|
||||
+{
|
||||
+ OPTION_BINARY_HASH = 0,
|
||||
+ OPTION_CERT_HASH = 1
|
||||
+};
|
||||
+
|
||||
+static const struct grub_arg_option options[] =
|
||||
+{
|
||||
+ {"binary-hash", 'b', 0, N_("hash file of the binary."), 0, ARG_TYPE_NONE},
|
||||
+ {"cert-hash", 'c', 1, N_("hash file of the certificate."), 0, ARG_TYPE_NONE},
|
||||
+ {0, 0, 0, 0, 0, 0}
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+print_hex (const grub_uint8_t *data, const grub_size_t length)
|
||||
+{
|
||||
+ grub_size_t i, count = 0;
|
||||
+ for (i = 0; i < length-1; i++)
|
||||
+ {
|
||||
+ grub_printf ("%02x:", data[i]);
|
||||
+ count++;
|
||||
+ if (count == 16)
|
||||
+ {
|
||||
+ grub_printf ("\n\t ");
|
||||
+ count = 0;
|
||||
+ }
|
||||
+ }
|
||||
+ grub_printf ("%02x\n", data[i]);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* GUID can be used to determine the hashing function and
|
||||
* generate the hash using determined hashing function.
|
||||
@@ -346,78 +376,6 @@ grub_env_write_sec (struct grub_env_var *var __attribute__((unused)),
|
||||
return grub_strdup (grub_env_read_sec (NULL, NULL));
|
||||
}
|
||||
|
||||
-static grub_err_t
|
||||
-file_read_all (grub_file_t file, grub_uint8_t **buf, grub_size_t *len)
|
||||
-{
|
||||
- grub_off_t full_file_size;
|
||||
- grub_size_t file_size, total_read_size = 0;
|
||||
- grub_ssize_t read_size;
|
||||
-
|
||||
- full_file_size = grub_file_size (file);
|
||||
- if (full_file_size == GRUB_FILE_SIZE_UNKNOWN)
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
- N_("Cannot read a file of unknown size into a buffer"));
|
||||
-
|
||||
- if (full_file_size > GRUB_SIZE_MAX)
|
||||
- return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
- N_("File is too large to read: %" PRIuGRUB_UINT64_T
|
||||
- " bytes"), full_file_size);
|
||||
-
|
||||
- file_size = (grub_size_t) full_file_size;
|
||||
-
|
||||
- *buf = grub_malloc (file_size);
|
||||
- if (!*buf)
|
||||
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||||
- N_("Could not allocate file data buffer size %"
|
||||
- PRIuGRUB_SIZE), file_size);
|
||||
-
|
||||
- while (total_read_size < file_size)
|
||||
- {
|
||||
- read_size =
|
||||
- grub_file_read (file, *buf + total_read_size,
|
||||
- file_size - total_read_size);
|
||||
-
|
||||
- if (read_size < 0)
|
||||
- {
|
||||
- grub_free (*buf);
|
||||
- return grub_errno;
|
||||
- }
|
||||
- else if (read_size == 0)
|
||||
- {
|
||||
- grub_free (*buf);
|
||||
- return grub_error (GRUB_ERR_IO,
|
||||
- N_("Could not read full file size (%"
|
||||
- PRIuGRUB_SIZE "), only %" PRIuGRUB_SIZE
|
||||
- " bytes read"), file_size, total_read_size);
|
||||
- }
|
||||
-
|
||||
- total_read_size += read_size;
|
||||
- }
|
||||
- *len = file_size;
|
||||
- return GRUB_ERR_NONE;
|
||||
-}
|
||||
-
|
||||
-static grub_err_t
|
||||
-read_cert_from_file (grub_file_t f, struct x509_certificate *certificate)
|
||||
-{
|
||||
- grub_err_t err;
|
||||
- grub_uint8_t *buf;
|
||||
- grub_size_t file_size;
|
||||
-
|
||||
- err = file_read_all (f, &buf, &file_size);
|
||||
- if (err != GRUB_ERR_NONE)
|
||||
- return err;
|
||||
-
|
||||
- err = parse_x509_certificate (buf, file_size, certificate);
|
||||
- if (err != GRUB_ERR_NONE)
|
||||
- {
|
||||
- grub_free (buf);
|
||||
- return err;
|
||||
- }
|
||||
-
|
||||
- return GRUB_ERR_NONE;
|
||||
-}
|
||||
-
|
||||
static grub_err_t
|
||||
extract_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize,
|
||||
struct grub_appended_signature *sig)
|
||||
@@ -647,159 +605,351 @@ static grub_err_t
|
||||
grub_cmd_verify_signature (grub_command_t cmd __attribute__((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
- grub_file_t f;
|
||||
grub_err_t err = GRUB_ERR_NONE;
|
||||
- grub_uint8_t *data;
|
||||
- grub_size_t file_size;
|
||||
+ grub_file_t signed_file = NULL;
|
||||
+ grub_uint8_t *signed_data = NULL;
|
||||
+ grub_ssize_t signed_data_size = 0;
|
||||
|
||||
- if (argc < 1)
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
|
||||
+ if (argc != 1)
|
||||
+ {
|
||||
+ grub_printf (N_("a signed file is expected\n"
|
||||
+ "Example:\n\tverify_appended <SIGNED FILE>\n"));
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
|
||||
grub_dprintf ("appendedsig", "verifying %s\n", args[0]);
|
||||
|
||||
- f = grub_file_open (args[0], GRUB_FILE_TYPE_VERIFY_SIGNATURE);
|
||||
- if (!f)
|
||||
+ signed_file = grub_file_open (args[0], GRUB_FILE_TYPE_VERIFY_SIGNATURE);
|
||||
+ if (signed_file == NULL)
|
||||
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("unable to open a signed file"));
|
||||
+
|
||||
+ err = grub_read_file (signed_file, &signed_data, &signed_data_size);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
{
|
||||
- err = grub_errno;
|
||||
- goto cleanup;
|
||||
+ grub_file_close (signed_file);
|
||||
+ return err;
|
||||
}
|
||||
|
||||
- err = file_read_all (f, &data, &file_size);
|
||||
+ grub_file_close (signed_file);
|
||||
+ err = grub_verify_appended_signature (signed_data, signed_data_size);
|
||||
+ grub_free (signed_data);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_trusted_list (grub_command_t cmd __attribute__((unused)),
|
||||
+ int argc __attribute__((unused)), char **args __attribute__((unused)))
|
||||
+{
|
||||
+ struct x509_certificate *cert = NULL;
|
||||
+ grub_size_t i = 0, cert_num = 1;
|
||||
+
|
||||
+ for (cert = db.keys; cert; cert = cert->next)
|
||||
+ {
|
||||
+ grub_printf (N_("trusted certificate %" PRIuGRUB_SIZE ":\n"), cert_num);
|
||||
+ grub_printf (N_("\tserial: "));
|
||||
+
|
||||
+ for (i = 0; i < cert->serial_len - 1; i++)
|
||||
+ grub_printf ("%02x:", cert->serial[i]);
|
||||
+
|
||||
+ grub_printf ("%02x\n", cert->serial[cert->serial_len - 1]);
|
||||
+ grub_printf ("\tCN: %s\n\n", cert->subject);
|
||||
+ cert_num++;
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < db.signature_entries; i++)
|
||||
+ {
|
||||
+ grub_printf (N_("trusted binary hash %" PRIuGRUB_SIZE ":\n"), i+1);
|
||||
+ grub_printf (N_("\thash: "));
|
||||
+ print_hex (db.signatures[i], db.signature_size[i]);
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_distrusted_list (grub_command_t cmd __attribute__((unused)),
|
||||
+ int argc __attribute__((unused)),
|
||||
+ char **args __attribute__((unused)))
|
||||
+{
|
||||
+ struct x509_certificate *cert = NULL;
|
||||
+ grub_size_t i = 0, cert_num = 1;
|
||||
+
|
||||
+ for (cert = dbx.keys; cert; cert = cert->next)
|
||||
+ {
|
||||
+ grub_printf (N_("distrusted certificate %" PRIuGRUB_SIZE ":\n"), cert_num);
|
||||
+ grub_printf (N_("\tserial: "));
|
||||
+
|
||||
+ for (i = 0; i < cert->serial_len - 1; i++)
|
||||
+ grub_printf ("%02x:", cert->serial[i]);
|
||||
+
|
||||
+ grub_printf ("%02x\n", cert->serial[cert->serial_len - 1]);
|
||||
+ grub_printf ("\tCN: %s\n\n", cert->subject);
|
||||
+ cert_num++;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < dbx.signature_entries; i++)
|
||||
+ {
|
||||
+ grub_printf (N_("distrusted certificate/binary hash %" PRIuGRUB_SIZE ":\n"), i+1);
|
||||
+ grub_printf (N_("\thash: "));
|
||||
+ print_hex (dbx.signatures[i], dbx.signature_size[i]);
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_trusted_cert (grub_command_t cmd __attribute__((unused)),
|
||||
+ int argc, char **args)
|
||||
+{
|
||||
+ grub_err_t err = GRUB_ERR_NONE;
|
||||
+ grub_file_t cert_file = NULL;
|
||||
+ grub_uint8_t *cert_data = NULL;
|
||||
+ grub_ssize_t cert_data_size = 0;
|
||||
+
|
||||
+ if (argc != 1)
|
||||
+ {
|
||||
+ grub_printf (N_("a trusted X.509 certificate file is expected\n"
|
||||
+ "Example:\n\ttrusted_certificate <CERT FILE>\n"));
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ if (check_sigs == check_sigs_forced)
|
||||
+ {
|
||||
+ grub_printf ("Warning: since secure boot is enabled, "
|
||||
+ "adding of trusted X.509 certificate is not permitted!\n");
|
||||
+ return grub_errno;
|
||||
+ }
|
||||
+
|
||||
+ if (grub_strlen (args[0]) == 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_FILENAME,
|
||||
+ N_("missing trusted X.509 certificate file"));
|
||||
+
|
||||
+ cert_file = grub_file_open (args[0], GRUB_FILE_TYPE_CERTIFICATE_TRUST |
|
||||
+ GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
+ if (cert_file == NULL)
|
||||
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND,
|
||||
+ N_("unable to open the trusted X.509 certificate file"));
|
||||
+
|
||||
+ err = grub_read_file (cert_file, &cert_data, &cert_data_size);
|
||||
if (err != GRUB_ERR_NONE)
|
||||
- goto cleanup;
|
||||
+ {
|
||||
+ grub_file_close (cert_file);
|
||||
+ return err;
|
||||
+ }
|
||||
|
||||
- err = grub_verify_appended_signature (data, file_size);
|
||||
+ grub_file_close (cert_file);
|
||||
+ err = add_certificate (cert_data, cert_data_size, &db, 1);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ free_trusted_list ();
|
||||
+ free_distrusted_list ();
|
||||
+ grub_error (err, "adding of trusted certificate failed");
|
||||
+ }
|
||||
|
||||
- grub_free (data);
|
||||
+ grub_free (cert_data);
|
||||
|
||||
-cleanup:
|
||||
- if (f)
|
||||
- grub_file_close (f);
|
||||
return err;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-grub_cmd_distrust (grub_command_t cmd __attribute__((unused)),
|
||||
- int argc, char **args)
|
||||
+grub_cmd_trusted_hash (grub_command_t cmd __attribute__((unused)), int argc, char**args)
|
||||
{
|
||||
- unsigned long cert_num, i;
|
||||
- struct x509_certificate *cert, *prev;
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_file_t hash_file = NULL;
|
||||
+ grub_uint8_t *hash_data = NULL;
|
||||
+ grub_ssize_t hash_data_size = 0;
|
||||
|
||||
if (argc != 1)
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("One argument expected"));
|
||||
+ {
|
||||
+ grub_printf (N_("a trusted binary hash file is expected\n"
|
||||
+ "Example:\n\ttrusted_signature <BINARY HASH FILE>\n"));
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
|
||||
- grub_errno = GRUB_ERR_NONE;
|
||||
- cert_num = grub_strtoul (args[0], NULL, 10);
|
||||
- if (grub_errno != GRUB_ERR_NONE)
|
||||
- return grub_errno;
|
||||
+ if (check_sigs == check_sigs_forced)
|
||||
+ {
|
||||
+ grub_printf ("Warning: since secure boot is enabled, "
|
||||
+ "adding of trusted binary hash is not permitted!\n");
|
||||
+ return grub_errno;
|
||||
+ }
|
||||
|
||||
- if (cert_num < 1)
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
- N_("Certificate number too small - numbers start at 1"));
|
||||
+ if (grub_strlen (args[0]) == 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_FILENAME, N_("missing trusted binary hash file"));
|
||||
|
||||
- if (cert_num == 1)
|
||||
- {
|
||||
- cert = db.keys;
|
||||
- db.keys = cert->next;
|
||||
+ hash_file = grub_file_open (args[0], GRUB_FILE_TYPE_TO_HASH | GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
+ if (hash_file == NULL)
|
||||
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND,
|
||||
+ N_("unable to open the trusted binary hash file"));
|
||||
|
||||
- certificate_release (cert);
|
||||
- grub_free (cert);
|
||||
- return GRUB_ERR_NONE;
|
||||
+ rc = grub_read_file (hash_file, &hash_data, &hash_data_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_file_close (hash_file);
|
||||
+ return rc;
|
||||
}
|
||||
- i = 2;
|
||||
- prev = db.keys;
|
||||
- cert = db.keys->next;
|
||||
- while (cert)
|
||||
+
|
||||
+ grub_file_close (hash_file);
|
||||
+
|
||||
+ grub_dprintf ("appendedsig", "adding a trusted binary hash %s\n with size of %" PRIuGRUB_SIZE "\n",
|
||||
+ hash_data, hash_data_size);
|
||||
+
|
||||
+ /* only accept SHA256, SHA384 and SHA512 binary hash */
|
||||
+ if (hash_data_size != 32 && hash_data_size != 48 && hash_data_size != 64)
|
||||
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("unacceptable trusted binary hash type"));
|
||||
+
|
||||
+ rc = add_hash ((const grub_uint8_t **) &hash_data, hash_data_size, &db.signatures,
|
||||
+ &db.signature_size, &db.signature_entries);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
{
|
||||
- if (i == cert_num)
|
||||
- {
|
||||
- prev->next = cert->next;
|
||||
- certificate_release (cert);
|
||||
- grub_free (cert);
|
||||
- return GRUB_ERR_NONE;
|
||||
- }
|
||||
- i++;
|
||||
- prev = cert;
|
||||
- cert = cert->next;
|
||||
+ free_trusted_list ();
|
||||
+ free_distrusted_list ();
|
||||
+ grub_error (rc, "adding of trusted binary hash failed");
|
||||
}
|
||||
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
- N_("No certificate number %lu found - only %lu certificates in the store"),
|
||||
- cert_num, i - 1);
|
||||
+ grub_free (hash_data);
|
||||
+
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-grub_cmd_trust (grub_command_t cmd __attribute__((unused)),
|
||||
- int argc, char **args)
|
||||
+grub_cmd_distrusted_cert (grub_command_t cmd __attribute__((unused)), int argc, char **args)
|
||||
{
|
||||
- grub_file_t certf;
|
||||
- struct x509_certificate *cert = NULL;
|
||||
- grub_err_t err;
|
||||
+ grub_size_t cert_num = 0, i = 1;
|
||||
+ struct x509_certificate *current_cert = db.keys;
|
||||
+ struct x509_certificate *previous_cert = db.keys;
|
||||
|
||||
if (argc != 1)
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
|
||||
+ {
|
||||
+ grub_printf (N_("trusted certificate number is expected\n"
|
||||
+ "Example:\n\tdistrusted_certificate <CERT_NUMER>\n"));
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
|
||||
- certf = grub_file_open (args[0],
|
||||
- GRUB_FILE_TYPE_CERTIFICATE_TRUST
|
||||
- | GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
- if (!certf)
|
||||
- return grub_errno;
|
||||
+ if (check_sigs == check_sigs_forced)
|
||||
+ {
|
||||
+ grub_printf ("Warning: since secure boot is enabled, "
|
||||
+ "removing of trusted certificate is not permitted!\n");
|
||||
+ return grub_errno;
|
||||
+ }
|
||||
|
||||
+ cert_num = grub_strtoul (args[0], NULL, 10);
|
||||
+ if (cert_num < 1)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("trusted certificate number should to begin with 1"));
|
||||
|
||||
- cert = grub_zalloc (sizeof (struct x509_certificate));
|
||||
- if (!cert)
|
||||
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||||
- N_("Could not allocate memory for certificate"));
|
||||
+ if (cert_num > db.key_entries)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("trusted certificate number should not exceed %" PRIuGRUB_SIZE ""),
|
||||
+ db.key_entries);
|
||||
+ else if (cert_num < db.key_entries)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("there is no certificate on the trusted list. so, not permitted"));
|
||||
|
||||
- err = read_cert_from_file (certf, cert);
|
||||
- grub_file_close (certf);
|
||||
- if (err != GRUB_ERR_NONE)
|
||||
+ for (i = 1; i < db.key_entries; i++)
|
||||
{
|
||||
- grub_free (cert);
|
||||
- return err;
|
||||
+ if (cert_num == 1)
|
||||
+ {
|
||||
+ previous_cert = current_cert->next;
|
||||
+ break;
|
||||
+ }
|
||||
+ else if (cert_num == i)
|
||||
+ {
|
||||
+ previous_cert->next = current_cert->next;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ previous_cert = current_cert;
|
||||
+ current_cert = current_cert->next;
|
||||
}
|
||||
- grub_dprintf ("appendedsig", "Loaded certificate with CN: %s\n",
|
||||
- cert->subject);
|
||||
|
||||
- cert->next = db.keys;
|
||||
- db.keys = cert;
|
||||
+ certificate_release (current_cert);
|
||||
+ grub_free (current_cert);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-grub_cmd_list (grub_command_t cmd __attribute__((unused)),
|
||||
- int argc __attribute__((unused)),
|
||||
- char **args __attribute__((unused)))
|
||||
+grub_cmd_distrusted_hash (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
- struct x509_certificate *cert;
|
||||
- int cert_num = 1;
|
||||
- grub_size_t i;
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_file_t hash_file = NULL;
|
||||
+ grub_uint8_t *hash_data = NULL;
|
||||
+ grub_ssize_t hash_data_size = 0;
|
||||
|
||||
- for (cert = db.keys; cert; cert = cert->next)
|
||||
+ if (argc != 2)
|
||||
{
|
||||
- grub_printf (N_("Certificate %d:\n"), cert_num);
|
||||
+ grub_printf (N_("a distrusted certificate/binary hash file is expected\n"
|
||||
+ "Example:\n\tdistrusted_signature [option] <FILE>\n"
|
||||
+ "option:\n[-b|--binary-hash] FILE [BINARY HASH FILE]\n"
|
||||
+ "[-c|--cert-hash] FILE [CERTFICATE HASH FILE]\n"));
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
|
||||
- grub_printf (N_("\tSerial: "));
|
||||
- for (i = 0; i < cert->serial_len - 1; i++)
|
||||
- {
|
||||
- grub_printf ("%02x:", cert->serial[i]);
|
||||
- }
|
||||
- grub_printf ("%02x\n", cert->serial[cert->serial_len - 1]);
|
||||
+ if (check_sigs == check_sigs_forced)
|
||||
+ {
|
||||
+ grub_printf ("Warning: since secure boot is enabled, "
|
||||
+ "adding of distrusted certificate/binary hash is not permitted!\n");
|
||||
+ return grub_errno;
|
||||
+ }
|
||||
|
||||
- grub_printf ("\tCN: %s\n\n", cert->subject);
|
||||
- cert_num++;
|
||||
+ if (!ctxt->state[OPTION_BINARY_HASH].set && !ctxt->state[OPTION_CERT_HASH].set)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing options and use --help to konw"));
|
||||
+
|
||||
+ if (grub_strlen (args[1]) == 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_FILENAME,
|
||||
+ N_("missing distrusted certificate/binary hash file"));
|
||||
+
|
||||
+ hash_file = grub_file_open (args[1], GRUB_FILE_TYPE_TO_HASH | GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
+ if (hash_file == NULL)
|
||||
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND,
|
||||
+ N_("unable to open the distrusted certificate/binary hash file"));
|
||||
|
||||
+ rc = grub_read_file (hash_file, &hash_data, &hash_data_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_file_close (hash_file);
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
- return GRUB_ERR_NONE;
|
||||
+ grub_file_close (hash_file);
|
||||
+
|
||||
+ grub_dprintf ("appendedsig", "adding a distrusted certificate/binary hash %s\n"
|
||||
+ " with size of %" PRIuGRUB_SIZE "\n", hash_data, hash_data_size);
|
||||
+
|
||||
+ if (ctxt->state[OPTION_BINARY_HASH].set)
|
||||
+ {
|
||||
+ /* only accept SHA256, SHA384 and SHA512 binary hash */
|
||||
+ if (hash_data_size != 32 && hash_data_size != 48 && hash_data_size != 64)
|
||||
+ return grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
+ N_("unacceptable distrusted binary hash type"));
|
||||
+ }
|
||||
+ else if (ctxt->state[OPTION_CERT_HASH].set)
|
||||
+ {
|
||||
+ /* only accept SHA256, SHA384 and SHA512 certificate hash */
|
||||
+ if (hash_data_size != 32 && hash_data_size != 48 && hash_data_size != 64)
|
||||
+ return grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
+ N_("unacceptable distrusted certificate hash type"));
|
||||
+ }
|
||||
+
|
||||
+ rc = add_hash ((const grub_uint8_t **) &hash_data, hash_data_size, &dbx.signatures,
|
||||
+ &dbx.signature_size, &dbx.signature_entries);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ free_trusted_list ();
|
||||
+ free_distrusted_list ();
|
||||
+ grub_error (rc, "adding of distrusted binary/certificate hash failed");
|
||||
+ }
|
||||
+
|
||||
+ grub_free (hash_data);
|
||||
+
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-appendedsig_init (grub_file_t io __attribute__((unused)),
|
||||
- enum grub_file_type type,
|
||||
- void **context __attribute__((unused)),
|
||||
- enum grub_verify_flags *flags)
|
||||
+appendedsig_init (grub_file_t io __attribute__ ((unused)), enum grub_file_type type,
|
||||
+ void **context __attribute__ ((unused)), enum grub_verify_flags *flags)
|
||||
{
|
||||
if (check_sigs == check_sigs_no)
|
||||
{
|
||||
@@ -874,8 +1024,6 @@ static struct grub_fs pseudo_fs = {
|
||||
.fs_read = pseudo_read
|
||||
};
|
||||
|
||||
-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.
|
||||
@@ -1167,6 +1315,10 @@ load_static_keys (const struct grub_module_header *header, const grub_bool_t is_
|
||||
return rc;
|
||||
}
|
||||
|
||||
+static grub_extcmd_t cmd_distrusted_hash;
|
||||
+static grub_command_t cmd_verify, cmd_trusted_list, cmd_trusted_cert, cmd_trusted_hash,
|
||||
+ cmd_distrusted_list, cmd_distrusted_cert;
|
||||
+
|
||||
GRUB_MOD_INIT (appendedsig)
|
||||
{
|
||||
int rc;
|
||||
@@ -1229,22 +1381,31 @@ GRUB_MOD_INIT (appendedsig)
|
||||
|
||||
grub_pks_free_keystore ();
|
||||
}
|
||||
-
|
||||
- cmd_trust =
|
||||
- grub_register_command ("trust_certificate", grub_cmd_trust,
|
||||
- N_("X509_CERTIFICATE"),
|
||||
- N_("Add X509_CERTIFICATE to trusted certificates."));
|
||||
- cmd_list =
|
||||
- grub_register_command ("list_certificates", grub_cmd_list, 0,
|
||||
- N_("Show the list of trusted x509 certificates."));
|
||||
- cmd_verify =
|
||||
- grub_register_command ("verify_appended", grub_cmd_verify_signature,
|
||||
- N_("FILE"),
|
||||
- N_("Verify FILE against the trusted x509 certificates."));
|
||||
- cmd_distrust =
|
||||
- grub_register_command ("distrust_certificate", grub_cmd_distrust,
|
||||
- N_("CERT_NUMBER"),
|
||||
- N_("Remove CERT_NUMBER (as listed by list_certificates) from trusted certificates."));
|
||||
+ cmd_trusted_cert = grub_register_command ("trusted_certificate", grub_cmd_trusted_cert,
|
||||
+ N_("X509_CERTIFICATE"),
|
||||
+ N_("Add X509_CERTIFICATE to trusted list."));
|
||||
+ cmd_trusted_hash = grub_register_command ("trusted_signature", grub_cmd_trusted_hash,
|
||||
+ N_("BINARY HASH FILE"),
|
||||
+ N_("Add trusted BINARY HASH to trusted list."));
|
||||
+ cmd_distrusted_cert = grub_register_command ("distrusted_certificate", grub_cmd_distrusted_cert,
|
||||
+ N_("CERT_NUMBER"),
|
||||
+ N_("Remove CERT_NUMBER (as listed by list_trusted)"
|
||||
+ " from trusted list."));
|
||||
+ cmd_distrusted_hash = grub_register_extcmd ("distrusted_signature", grub_cmd_distrusted_hash, 0,
|
||||
+ N_("[-b|--binary-hash] FILE [BINARY HASH FILE]\n"
|
||||
+ "[-c|--cert-hash] FILE [CERTFICATE HASH FILE]"),
|
||||
+ N_("Add distrusted CERTFICATE/BINARY HASH "
|
||||
+ "to distrusted list."),
|
||||
+ options);
|
||||
+ cmd_trusted_list = grub_register_command ("trusted_list", grub_cmd_trusted_list, 0,
|
||||
+ N_("Show the list of trusted x509 certificates and"
|
||||
+ " trusted binary hashes."));
|
||||
+ cmd_distrusted_list = grub_register_command ("distrusted_list", grub_cmd_distrusted_list, 0,
|
||||
+ N_("Show the list of distrusted certificates and"
|
||||
+ " certificate/binary hashes"));
|
||||
+ cmd_verify = grub_register_command ("verify_appended", grub_cmd_verify_signature, N_("FILE"),
|
||||
+ N_("Verify FILE against the trusted x509 certificates/"
|
||||
+ "trusted binary hashes."));
|
||||
|
||||
grub_verifier_register (&grub_appendedsig_verifier);
|
||||
grub_dl_set_persistent (mod);
|
||||
@@ -1256,10 +1417,12 @@ GRUB_MOD_FINI (appendedsig)
|
||||
* grub_dl_set_persistent should prevent this from actually running, but
|
||||
* it does still run under emu.
|
||||
*/
|
||||
-
|
||||
grub_verifier_unregister (&grub_appendedsig_verifier);
|
||||
grub_unregister_command (cmd_verify);
|
||||
- grub_unregister_command (cmd_list);
|
||||
- grub_unregister_command (cmd_trust);
|
||||
- grub_unregister_command (cmd_distrust);
|
||||
+ grub_unregister_command (cmd_trusted_list);
|
||||
+ grub_unregister_command (cmd_distrusted_list);
|
||||
+ grub_unregister_command (cmd_trusted_cert);
|
||||
+ grub_unregister_command (cmd_distrusted_cert);
|
||||
+ grub_unregister_command (cmd_trusted_hash);
|
||||
+ grub_unregister_extcmd (cmd_distrusted_hash);
|
||||
}
|
||||
--
|
||||
2.48.1
|
||||
|
75
0008-blscfg-reading-bls-fragments-if-boot-present.patch
Normal file
75
0008-blscfg-reading-bls-fragments-if-boot-present.patch
Normal file
@@ -0,0 +1,75 @@
|
||||
From 2b0e6effc31ec166bbbe35a3cd2b4c73051f38bb Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 16 Jun 2023 15:54:50 +0800
|
||||
Subject: [PATCH 8/9] blscfg: reading bls fragments if boot present
|
||||
|
||||
The Boot Loader Specification (BLS) designates the EFI System Partition
|
||||
(ESP) as a primary location for $BOOT, where boot menu entries can be
|
||||
stored. The specification encourages boot loaders to retrieve menu
|
||||
entries from the ESP, even when XBOOTLDR is present.
|
||||
|
||||
This commit aligns with the BLS specification by introducing the
|
||||
capability to search for the ESP in addition to the default root
|
||||
partition or any specified location via blscfg's command line. The $boot
|
||||
environment variable is utilized as a reference to the ESP device for
|
||||
the blscfg command. Initialization of $boot in grub.cfg is demonstrated
|
||||
as follows:
|
||||
|
||||
insmod part_gpt
|
||||
insmod fat
|
||||
search --no-floppy --fs-uuid --set=boot F414-5A9F
|
||||
|
||||
If $boot is unset, no additional search for the BLS location will be
|
||||
performed.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/blscfg.c | 10 ++++++++++
|
||||
util/grub.d/10_linux.in | 3 ++-
|
||||
2 files changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
|
||||
index c872bcef0..cbe2a289e 100644
|
||||
--- a/grub-core/commands/blscfg.c
|
||||
+++ b/grub-core/commands/blscfg.c
|
||||
@@ -1186,6 +1186,7 @@ grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED,
|
||||
char *entry_id = NULL;
|
||||
bool show_default = true;
|
||||
bool show_non_default = true;
|
||||
+ const char *boot = NULL;
|
||||
|
||||
if (argc == 1) {
|
||||
if (grub_strcmp (args[0], "default") == 0) {
|
||||
@@ -1205,6 +1206,15 @@ grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED,
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
+ boot = grub_env_get("boot");
|
||||
+ path = (boot) ? grub_xasprintf("(%s)" GRUB_BLS_CONFIG_PATH, boot) : NULL;
|
||||
+ if (path)
|
||||
+ {
|
||||
+ bls_load_entries(path);
|
||||
+ grub_print_error();
|
||||
+ }
|
||||
+ grub_free(path);
|
||||
+
|
||||
return bls_create_entries(show_default, show_non_default, entry_id);
|
||||
}
|
||||
|
||||
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
|
||||
index 45eefb332..edf0fca55 100644
|
||||
--- a/util/grub.d/10_linux.in
|
||||
+++ b/util/grub.d/10_linux.in
|
||||
@@ -201,7 +201,8 @@ populate_menu()
|
||||
}
|
||||
|
||||
# Make BLS the default if GRUB_ENABLE_BLSCFG was not set and grubby is not installed.
|
||||
-if [ -z "${GRUB_ENABLE_BLSCFG}" ] && ! command -v new-kernel-pkg >/dev/null; then
|
||||
+# FIXME: The test should be aligned to openSUSE, grubby is not our default tool
|
||||
+if [ -z "${GRUB_ENABLE_BLSCFG}" ] && ! command -v new-kernel-pkg >/dev/null && false; then
|
||||
GRUB_ENABLE_BLSCFG="true"
|
||||
fi
|
||||
|
||||
--
|
||||
2.44.0
|
||||
|
@@ -1,117 +0,0 @@
|
||||
From ba5a201546cfb69d3079f18c89a79bda98e7bcd1 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 8 May 2025 19:02:14 +0200
|
||||
Subject: [PATCH 8/8] cryptocheck: Add --quiet option
|
||||
|
||||
The option can be used to suppress output if we only want to test the
|
||||
return value of the command.
|
||||
|
||||
Also, mention this option in the documentation.
|
||||
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
docs/grub.texi | 4 +++-
|
||||
grub-core/commands/search.c | 7 ++++++-
|
||||
grub-core/disk/diskfilter.c | 25 +++++++++++++++++++------
|
||||
3 files changed, 28 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index c4936db8c1..9646cf9282 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -4684,12 +4684,14 @@ Alias for @code{hashsum --hash crc32 arg @dots{}}. See command @command{hashsum}
|
||||
@node cryptocheck
|
||||
@subsection cryptocheck
|
||||
|
||||
-@deffn Command cryptocheck device
|
||||
+@deffn Command cryptocheck [ @option{--quiet} ] 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.
|
||||
+
|
||||
+The option @option{--quiet} can be given to suppress the output.
|
||||
@end deffn
|
||||
|
||||
@node cryptomount
|
||||
diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
|
||||
index 185c1e70f7..49b679e805 100644
|
||||
--- a/grub-core/commands/search.c
|
||||
+++ b/grub-core/commands/search.c
|
||||
@@ -67,6 +67,9 @@ is_unencrypted_disk (grub_disk_t disk)
|
||||
|
||||
if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID)
|
||||
{
|
||||
+ char opt[] = "--quiet";
|
||||
+ char *args[2];
|
||||
+
|
||||
cmd = grub_command_find ("cryptocheck");
|
||||
if (cmd == NULL) /* No diskfilter module loaded for some reason. */
|
||||
return true;
|
||||
@@ -77,7 +80,9 @@ is_unencrypted_disk (grub_disk_t disk)
|
||||
return true;
|
||||
|
||||
grub_snprintf (disk_str, disk_str_len, "(%s)", disk->name);
|
||||
- res = cmd->func (cmd, 1, &disk_str);
|
||||
+ args[0] = opt;
|
||||
+ args[1] = disk_str;
|
||||
+ res = cmd->func (cmd, 2, args);
|
||||
grub_free (disk_str);
|
||||
return (res != GRUB_ERR_NONE) ? true : false; /* GRUB_ERR_NONE for encrypted. */
|
||||
}
|
||||
diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c
|
||||
index 3f7c05e14e..b1d5d464f5 100644
|
||||
--- a/grub-core/disk/diskfilter.c
|
||||
+++ b/grub-core/disk/diskfilter.c
|
||||
@@ -1524,6 +1524,19 @@ grub_cmd_cryptocheck (grub_command_t cmd __attribute__ ((unused)),
|
||||
int check_pvs_res;
|
||||
int namelen;
|
||||
int pvs_cnt;
|
||||
+ int opt_quiet = 0;
|
||||
+
|
||||
+ if (argc == 2)
|
||||
+ {
|
||||
+ if (grub_strcmp (args[0], "--quiet") == 0)
|
||||
+ {
|
||||
+ opt_quiet = 1;
|
||||
+ argc--;
|
||||
+ args++;
|
||||
+ }
|
||||
+ else
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unrecognized option: %s"), args[0]);
|
||||
+ }
|
||||
|
||||
if (argc != 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("disk name expected"));
|
||||
@@ -1546,11 +1559,11 @@ grub_cmd_cryptocheck (grub_command_t cmd __attribute__ ((unused)),
|
||||
|
||||
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" : "");
|
||||
+ if (!opt_quiet)
|
||||
+ 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;
|
||||
}
|
||||
@@ -1578,7 +1591,7 @@ GRUB_MOD_INIT(diskfilter)
|
||||
{
|
||||
grub_disk_dev_register (&grub_diskfilter_dev);
|
||||
cmd = grub_register_command ("cryptocheck", grub_cmd_cryptocheck,
|
||||
- N_("DEVICE"),
|
||||
+ N_("[--quiet] DEVICE"),
|
||||
N_("Check if a logical volume resides on encrypted disks."));
|
||||
}
|
||||
|
||||
--
|
||||
2.49.0
|
||||
|
@@ -1,48 +0,0 @@
|
||||
From 312edf1f0ebaebba72e348ae88d95b29fa24c09c Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Wed, 23 Oct 2024 17:54:33 +0530
|
||||
Subject: [PATCH 8/8] grub-mkimage: Add SBAT metadata into ELF note for PowerPC
|
||||
targets
|
||||
|
||||
The SBAT metadata is read from CSV file and transformed into an ELF note
|
||||
with the -s option.
|
||||
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
util/mkimage.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/util/mkimage.c b/util/mkimage.c
|
||||
index be7f02c5c..d3948937b 100644
|
||||
--- a/util/mkimage.c
|
||||
+++ b/util/mkimage.c
|
||||
@@ -958,8 +958,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
total_module_size += dtb_size + sizeof (struct grub_module_header);
|
||||
}
|
||||
|
||||
- if (sbat_path != NULL && image_target->id != IMAGE_EFI)
|
||||
- grub_util_error (_(".sbat section can be embedded into EFI images only"));
|
||||
+ if (sbat_path != NULL && (image_target->id != IMAGE_EFI && image_target->id != IMAGE_PPC))
|
||||
+ grub_util_error (_("SBAT data can be added only to EFI or powerpc-ieee1275 images"));
|
||||
|
||||
if (disable_shim_lock)
|
||||
total_module_size += sizeof (struct grub_module_header);
|
||||
@@ -1836,6 +1836,13 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
{
|
||||
grub_uint64_t target_addr;
|
||||
char *sbat = NULL;
|
||||
+ if (sbat_path != NULL)
|
||||
+ {
|
||||
+ sbat_size = grub_util_get_image_size (sbat_path);
|
||||
+ sbat = xmalloc (sbat_size);
|
||||
+ grub_util_load_image (sbat_path, sbat);
|
||||
+ layout.sbat_size = sbat_size;
|
||||
+ }
|
||||
if (image_target->id == IMAGE_LOONGSON_ELF)
|
||||
{
|
||||
if (comp == GRUB_COMPRESSION_NONE)
|
||||
--
|
||||
2.47.1
|
||||
|
@@ -1,83 +0,0 @@
|
||||
From de9400db3f181e059f9ab1bb6a667ae2c29baf03 Mon Sep 17 00:00:00 2001
|
||||
From: B Horn <b@horn.uk>
|
||||
Date: Fri, 15 Nov 2024 13:12:09 +0000
|
||||
Subject: [PATCH 08/20] net: Fix OOB write in grub_net_search_config_file()
|
||||
|
||||
The function included a call to grub_strcpy() which copied data from an
|
||||
environment variable to a buffer allocated in grub_cmd_normal(). The
|
||||
grub_cmd_normal() didn't consider the length of the environment variable.
|
||||
So, the copy operation could exceed the allocation and lead to an OOB
|
||||
write. Fix the issue by replacing grub_strcpy() with grub_strlcpy() and
|
||||
pass the underlying buffers size to the grub_net_search_config_file().
|
||||
|
||||
Fixes: CVE-2025-0624
|
||||
|
||||
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/net/net.c | 7 ++++---
|
||||
grub-core/normal/main.c | 2 +-
|
||||
include/grub/net.h | 2 +-
|
||||
3 files changed, 6 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/grub-core/net/net.c b/grub-core/net/net.c
|
||||
index 22221dc6a0..df13c3aaaa 100644
|
||||
--- a/grub-core/net/net.c
|
||||
+++ b/grub-core/net/net.c
|
||||
@@ -1912,14 +1912,15 @@ grub_config_search_through (char *config, char *suffix,
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
-grub_net_search_config_file (char *config)
|
||||
+grub_net_search_config_file (char *config, grub_size_t config_buf_len)
|
||||
{
|
||||
- grub_size_t config_len;
|
||||
+ grub_size_t config_len, suffix_len;
|
||||
char *suffix;
|
||||
|
||||
config_len = grub_strlen (config);
|
||||
config[config_len] = '-';
|
||||
suffix = config + config_len + 1;
|
||||
+ suffix_len = config_buf_len - (config_len + 1);
|
||||
|
||||
struct grub_net_network_level_interface *inf;
|
||||
FOR_NET_NETWORK_LEVEL_INTERFACES (inf)
|
||||
@@ -1945,7 +1946,7 @@ grub_net_search_config_file (char *config)
|
||||
|
||||
if (client_uuid)
|
||||
{
|
||||
- grub_strcpy (suffix, client_uuid);
|
||||
+ grub_strlcpy (suffix, client_uuid, suffix_len);
|
||||
if (grub_config_search_through (config, suffix, 1, 0) == 0)
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
|
||||
index b08fd6977d..f2679c4378 100644
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -451,7 +451,7 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)),
|
||||
|
||||
if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0 &&
|
||||
!disable_net_search)
|
||||
- grub_net_search_config_file (config);
|
||||
+ grub_net_search_config_file (config, config_len);
|
||||
|
||||
grub_enter_normal_mode (config);
|
||||
grub_free (config);
|
||||
diff --git a/include/grub/net.h b/include/grub/net.h
|
||||
index dfb089a35c..abb637eaa2 100644
|
||||
--- a/include/grub/net.h
|
||||
+++ b/include/grub/net.h
|
||||
@@ -652,7 +652,7 @@ void
|
||||
grub_net_remove_dns_server (const struct grub_net_network_level_address *s);
|
||||
|
||||
grub_err_t
|
||||
-grub_net_search_config_file (char *config);
|
||||
+grub_net_search_config_file (char *config, grub_size_t config_buf_len);
|
||||
|
||||
extern char *grub_net_default_server;
|
||||
|
||||
--
|
||||
2.48.1
|
||||
|
252
0009-10_linux-Some-refinement-for-BLS.patch
Normal file
252
0009-10_linux-Some-refinement-for-BLS.patch
Normal file
@@ -0,0 +1,252 @@
|
||||
From abd8b83cdc6398c52c7d2b71b378938cf51872fd Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Wed, 13 Mar 2024 15:26:42 +0800
|
||||
Subject: [PATCH 9/9] 10_linux: Some refinement for BLS
|
||||
|
||||
Remove BLS_POPULATE_MENU as it is not being used currently and removing
|
||||
kernelopts assignment in the grub boot config itself to fully delegate
|
||||
the responsibility of generating kernel options to a functioning BLS
|
||||
generator.
|
||||
|
||||
Additionally, removing unused dead code, which is often blamed for
|
||||
causing errors in the dash shell script.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
util/grub.d/10_linux.in | 194 ----------------------------------------
|
||||
1 file changed, 194 deletions(-)
|
||||
|
||||
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
|
||||
index edf0fca55..666eae995 100644
|
||||
--- a/util/grub.d/10_linux.in
|
||||
+++ b/util/grub.d/10_linux.in
|
||||
@@ -93,11 +93,7 @@ fi
|
||||
|
||||
populate_header_warn()
|
||||
{
|
||||
-if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then
|
||||
- bls_parser="10_linux script"
|
||||
-else
|
||||
bls_parser="blscfg command"
|
||||
-fi
|
||||
cat <<EOF
|
||||
|
||||
# This section was generated by a script. Do not modify the generated file - all changes
|
||||
@@ -110,102 +106,6 @@ cat <<EOF
|
||||
EOF
|
||||
}
|
||||
|
||||
-read_config()
|
||||
-{
|
||||
- config_file=${1}
|
||||
- title=""
|
||||
- initrd=""
|
||||
- options=""
|
||||
- linux=""
|
||||
- grub_arg=""
|
||||
-
|
||||
- while read -r line
|
||||
- do
|
||||
- record=$(echo ${line} | cut -f 1 -d ' ')
|
||||
- value=$(echo ${line} | cut -s -f2- -d ' ')
|
||||
- case "${record}" in
|
||||
- "title")
|
||||
- title=${value}
|
||||
- ;;
|
||||
- "initrd")
|
||||
- initrd=${value}
|
||||
- ;;
|
||||
- "linux")
|
||||
- linux=${value}
|
||||
- ;;
|
||||
- "options")
|
||||
- options=${value}
|
||||
- ;;
|
||||
- "grub_arg")
|
||||
- grub_arg=${value}
|
||||
- ;;
|
||||
- esac
|
||||
- done < ${config_file}
|
||||
-}
|
||||
-
|
||||
-blsdir="/boot/loader/entries"
|
||||
-
|
||||
-get_sorted_bls()
|
||||
-{
|
||||
- if ! [ -d "${blsdir}" ] || [ -f /run/ostree-booted ] || [ -d /ostree/repo ]; then
|
||||
- return
|
||||
- fi
|
||||
-
|
||||
- local IFS=$'\n'
|
||||
-
|
||||
- files=($(for bls in ${blsdir}/*.conf; do
|
||||
- if ! [[ -e "${bls}" ]] ; then
|
||||
- continue
|
||||
- fi
|
||||
- bls="${bls%.conf}"
|
||||
- bls="${bls##*/}"
|
||||
- echo "${bls}"
|
||||
- done | ${kernel_sort} 2>/dev/null | tac)) || :
|
||||
-
|
||||
- echo "${files[@]}"
|
||||
-}
|
||||
-
|
||||
-update_bls_cmdline()
|
||||
-{
|
||||
- local cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
|
||||
- local -a files=($(get_sorted_bls))
|
||||
-
|
||||
- for bls in "${files[@]}"; do
|
||||
- local options="${cmdline}"
|
||||
- if [ -z "${bls##*debug*}" ]; then
|
||||
- options="${options} ${GRUB_CMDLINE_LINUX_DEBUG}"
|
||||
- fi
|
||||
- options="$(echo "${options}" | sed -e 's/\//\\\//g')"
|
||||
- sed -i -e "s/^options.*/options ${options}/" "${blsdir}/${bls}.conf"
|
||||
- done
|
||||
-}
|
||||
-
|
||||
-populate_menu()
|
||||
-{
|
||||
- local -a files=($(get_sorted_bls))
|
||||
-
|
||||
- gettext_printf "Generating boot entries from BLS files...\n" >&2
|
||||
-
|
||||
- for bls in "${files[@]}"; do
|
||||
- read_config "${blsdir}/${bls}.conf"
|
||||
-
|
||||
- menu="${menu}menuentry '${title}' ${grub_arg} --id=${bls} {\n"
|
||||
- menu="${menu}\t linux ${linux} ${options}\n"
|
||||
- if [ -n "${initrd}" ] ; then
|
||||
- menu="${menu}\t initrd ${boot_prefix}${initrd}\n"
|
||||
- fi
|
||||
- menu="${menu}}\n\n"
|
||||
- done
|
||||
- # The printf command seems to be more reliable across shells for special character (\n, \t) evaluation
|
||||
- printf "$menu"
|
||||
-}
|
||||
-
|
||||
-# Make BLS the default if GRUB_ENABLE_BLSCFG was not set and grubby is not installed.
|
||||
-# FIXME: The test should be aligned to openSUSE, grubby is not our default tool
|
||||
-if [ -z "${GRUB_ENABLE_BLSCFG}" ] && ! command -v new-kernel-pkg >/dev/null && false; then
|
||||
- GRUB_ENABLE_BLSCFG="true"
|
||||
-fi
|
||||
-
|
||||
if [ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]; then
|
||||
if [ x$dirname = x/ ]; then
|
||||
if [ -z "${prepare_root_cache}" ]; then
|
||||
@@ -225,111 +125,17 @@ if [ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]; then
|
||||
prepare_grub_to_access_device_with_variable boot ${boot_device}
|
||||
fi
|
||||
|
||||
- arch="$(uname -m)"
|
||||
- if [ "x${arch}" = "xppc64le" ] && [ -d /sys/firmware/opal ]; then
|
||||
-
|
||||
- BLS_POPULATE_MENU="true"
|
||||
- petitboot_path="/sys/firmware/devicetree/base/ibm,firmware-versions/petitboot"
|
||||
-
|
||||
- if test -e ${petitboot_path}; then
|
||||
- read -r -d '' petitboot_version < ${petitboot_path}
|
||||
- petitboot_version="$(echo ${petitboot_version//v})"
|
||||
-
|
||||
- if test -n ${petitboot_version}; then
|
||||
- major_version="$(echo ${petitboot_version} | cut -d . -f1)"
|
||||
- minor_version="$(echo ${petitboot_version} | cut -d . -f2)"
|
||||
-
|
||||
- re='^[0-9]+$'
|
||||
- if [[ $major_version =~ $re ]] && [[ $minor_version =~ $re ]] &&
|
||||
- ([[ ${major_version} -gt 1 ]] ||
|
||||
- [[ ${major_version} -eq 1 &&
|
||||
- ${minor_version} -ge 8 ]]); then
|
||||
- BLS_POPULATE_MENU="false"
|
||||
- fi
|
||||
- fi
|
||||
- fi
|
||||
- fi
|
||||
-
|
||||
populate_header_warn
|
||||
|
||||
- cat << EOF
|
||||
-# The kernelopts variable should be defined in the grubenv file. But to ensure that menu
|
||||
-# entries populated from BootLoaderSpec files that use this variable work correctly even
|
||||
-# without a grubenv file, define a fallback kernelopts variable if this has not been set.
|
||||
-#
|
||||
-# The kernelopts variable in the grubenv file can be modified using the grubby tool or by
|
||||
-# executing the grub2-mkconfig tool. For the latter, the values of the GRUB_CMDLINE_LINUX
|
||||
-# and GRUB_CMDLINE_LINUX_DEFAULT options from /etc/default/grub file are used to set both
|
||||
-# the kernelopts variable in the grubenv file and the fallback kernelopts variable.
|
||||
-if [ -z "\${kernelopts}" ]; then
|
||||
- set kernelopts="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
|
||||
-fi
|
||||
-EOF
|
||||
-
|
||||
- update_bls_cmdline
|
||||
-
|
||||
- if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then
|
||||
- populate_menu
|
||||
- else
|
||||
cat << EOF
|
||||
|
||||
insmod blscfg
|
||||
blscfg
|
||||
EOF
|
||||
- fi
|
||||
-
|
||||
- if [ "x${GRUB_GRUBENV_UPDATE}" = "xyes" ]; then
|
||||
- blsdir="/boot/loader/entries"
|
||||
- [ -d "${blsdir}" ] && GRUB_BLS_FS="$(${grub_probe} --target=fs ${blsdir})"
|
||||
- if [ "x${GRUB_BLS_FS}" = "xbtrfs" ] || [ "x${GRUB_BLS_FS}" = "xzfs" ]; then
|
||||
- blsdir=$(make_system_path_relative_to_its_root "${blsdir}")
|
||||
- if [ "x${blsdir}" != "x/loader/entries" ] && [ "x${blsdir}" != "x/boot/loader/entries" ]; then
|
||||
- ${grub_editenv} - set blsdir="${blsdir}"
|
||||
- fi
|
||||
- fi
|
||||
-
|
||||
- if [ -n "${GRUB_EARLY_INITRD_LINUX_CUSTOM}" ]; then
|
||||
- ${grub_editenv} - set early_initrd="${GRUB_EARLY_INITRD_LINUX_CUSTOM}"
|
||||
- fi
|
||||
-
|
||||
- if [ -n "${GRUB_DEFAULT_DTB}" ]; then
|
||||
- ${grub_editenv} - set devicetree="${GRUB_DEFAULT_DTB}"
|
||||
- fi
|
||||
-
|
||||
- if [ -n "${GRUB_SAVEDEFAULT}" ]; then
|
||||
- ${grub_editenv} - set save_default="${GRUB_SAVEDEFAULT}"
|
||||
- fi
|
||||
- fi
|
||||
|
||||
exit 0
|
||||
fi
|
||||
|
||||
-mktitle ()
|
||||
-{
|
||||
- local title_type
|
||||
- local version
|
||||
- local OS_NAME
|
||||
- local OS_VERS
|
||||
-
|
||||
- title_type=$1 && shift
|
||||
- version=$1 && shift
|
||||
-
|
||||
- OS_NAME="$(eval $(grep ^NAME= /etc/os-release) ; echo ${NAME})"
|
||||
- OS_VERS="$(eval $(grep ^VERSION= /etc/os-release) ; echo ${VERSION})"
|
||||
-
|
||||
- case $title_type in
|
||||
- recovery)
|
||||
- title=$(printf '%s (%s) %s (recovery mode)' \
|
||||
- "${OS_NAME}" "${version}" "${OS_VERS}")
|
||||
- ;;
|
||||
- *)
|
||||
- title=$(printf '%s (%s) %s' \
|
||||
- "${OS_NAME}" "${version}" "${OS_VERS}")
|
||||
- ;;
|
||||
- esac
|
||||
- echo -n ${title}
|
||||
-}
|
||||
-
|
||||
title_correction_code=
|
||||
|
||||
hotkey=1
|
||||
--
|
||||
2.45.2
|
||||
|
@@ -1,218 +0,0 @@
|
||||
From e57bcf83765291da62ad92f330cc1ffb535d4017 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Tue, 25 Feb 2025 02:47:03 +0530
|
||||
Subject: [PATCH 9/9] appendedsig: documentation
|
||||
|
||||
This explains how static and dynamic key appended signatures can be used to form part of
|
||||
a secure boot chain, and documents the commands and variables introduced.
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
---
|
||||
docs/grub.texi | 113 +++++++++++++++++++++++++++++++++----------------
|
||||
1 file changed, 76 insertions(+), 37 deletions(-)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index e89007920c..9aaea72826 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -4373,7 +4373,9 @@ you forget a command, you can run the command @command{help}
|
||||
* date:: Display or set current date and time
|
||||
* devicetree:: Load a device tree blob
|
||||
* distrust:: Remove a pubkey from trusted keys
|
||||
-* distrust_certificate:: Remove a certificate from the list of trusted certificates
|
||||
+* distrusted_certificate:: Remove a certificate from the trusted list
|
||||
+* distrusted_list:: List distrusted certificates and binary/certificate hashes
|
||||
+* distrusted_signature:: Add a binary hash to the distrusted list
|
||||
* drivemap:: Map a drive to another
|
||||
* echo:: Display a line of text
|
||||
* efitextmode:: Set/Get text output mode resolution
|
||||
@@ -4390,7 +4392,6 @@ you forget a command, you can run the command @command{help}
|
||||
* hexdump:: Show raw contents of a file or memory
|
||||
* insmod:: Insert a module
|
||||
* keystatus:: Check key modifier status
|
||||
-* list_certificates:: List trusted certificates
|
||||
* list_env:: List variables in environment block
|
||||
* list_trusted:: List trusted public keys
|
||||
* load_env:: Load variables from environment block
|
||||
@@ -4429,7 +4430,9 @@ you forget a command, you can run the command @command{help}
|
||||
* test:: Check file types and compare values
|
||||
* true:: Do nothing, successfully
|
||||
* trust:: Add public key to list of trusted keys
|
||||
-* trust_certificate:: Add an x509 certificate to the list of trusted certificates
|
||||
+* trusted_certificate:: Add an x509 certificate to the trusted list
|
||||
+* trusted_list:: List trusted certificates and binary hashes
|
||||
+* trusted_signature:: Add a binary hash to the trusted list.
|
||||
* unset:: Unset an environment variable
|
||||
@comment * vbeinfo:: List available video modes
|
||||
* verify_appended:: Verify appended digital signature
|
||||
@@ -4775,16 +4778,15 @@ These keys are used to validate signatures when environment variable
|
||||
GPG-style digital signatures}, for more information.
|
||||
@end deffn
|
||||
|
||||
+@node distrusted_certificate
|
||||
+@subsection distrusted_certificate
|
||||
|
||||
-@node distrust_certificate
|
||||
-@subsection distrust_certificate
|
||||
-
|
||||
-@deffn Command distrust_certificate cert_number
|
||||
+@deffn Command distrusted_certificate cert_number
|
||||
Remove the x509 certificate numbered @var{cert_number} from GRUB's keyring of
|
||||
trusted x509 certificates for verifying appended signatures.
|
||||
|
||||
@var{cert_number} is the certificate number as listed by
|
||||
-@command{list_certificates} (@pxref{list_certificates}).
|
||||
+@command{trusted_list} (@pxref{trusted_list}).
|
||||
|
||||
These certificates are used to validate appended signatures when environment
|
||||
variable @code{check_appended_signatures} is set to @code{enforce}
|
||||
@@ -4793,6 +4795,27 @@ variable @code{check_appended_signatures} is set to @code{enforce}
|
||||
information.
|
||||
@end deffn
|
||||
|
||||
+@node distrusted_list
|
||||
+@subsection distrusted_list
|
||||
+
|
||||
+@deffn Command distrusted_list
|
||||
+List all the distrusted x509 certificates and binary/certificate hashes.
|
||||
+The output is a numbered list of certificates and binary/certificate hashes,
|
||||
+showing the certificate's serial number and Common Name.
|
||||
+@end deffn
|
||||
+
|
||||
+@node distrusted_signature
|
||||
+@subsection distrusted_signature
|
||||
+
|
||||
+@deffn Command distrusted_signature
|
||||
+Read a binary hash from the file @var{binary hash file}
|
||||
+and add it to GRUB's internal distrusted list. These hash are used to
|
||||
+restrict validation of linux image integrity using trusted list if appended
|
||||
+signatures validation failed when the environment variable
|
||||
+@code{check_appended_signatures} is set to @code{enforce}.
|
||||
+
|
||||
+See @xref{Using appended signatures} for more information.
|
||||
+@end deffn
|
||||
|
||||
@node drivemap
|
||||
@subsection drivemap
|
||||
@@ -5069,22 +5092,6 @@ without any options, the @command{keystatus} command returns true if and
|
||||
only if checking key modifier status is supported.
|
||||
@end deffn
|
||||
|
||||
-
|
||||
-@node list_certificates
|
||||
-@subsection list_certificates
|
||||
-
|
||||
-@deffn Command list_certificates
|
||||
-List all x509 certificates trusted by GRUB for validating appended signatures.
|
||||
-The output is a numbered list of certificates, showing the certificate's serial
|
||||
-number and Common Name.
|
||||
-
|
||||
-The certificate number can be used as an argument to
|
||||
-@command{distrust_certificate} (@pxref{distrust_certificate}).
|
||||
-
|
||||
-See @xref{Using appended signatures} for more information.
|
||||
-@end deffn
|
||||
-
|
||||
-
|
||||
@node list_env
|
||||
@subsection list_env
|
||||
|
||||
@@ -5936,17 +5943,17 @@ information.
|
||||
@end deffn
|
||||
|
||||
|
||||
-@node trust_certificate
|
||||
-@subsection trust_certificate
|
||||
+@node trusted_certificate
|
||||
+@subsection trusted_certificate
|
||||
|
||||
-@deffn Command trust_certificate x509_certificate
|
||||
+@deffn Command trusted_certificate x509_certificate
|
||||
Read a DER-formatted x509 certificate from the file @var{x509_certificate}
|
||||
and add it to GRUB's internal list of trusted x509 certificates. These
|
||||
certificates are used to validate appended signatures when the environment
|
||||
variable @code{check_appended_signatures} is set to @code{enforce}.
|
||||
|
||||
Note that if @code{check_appended_signatures} is set to @code{enforce}
|
||||
-when @command{trust_certificate} is executed, then @var{x509_certificate}
|
||||
+when @command{trusted_certificate} is executed, then @var{x509_certificate}
|
||||
must itself bear an appended signature. (It is not sufficient that
|
||||
@var{x509_certificate} be signed by a trusted certificate according to the
|
||||
x509 rules: grub does not include support for validating signatures within x509
|
||||
@@ -5955,6 +5962,32 @@ certificates themselves.)
|
||||
See @xref{Using appended signatures} for more information.
|
||||
@end deffn
|
||||
|
||||
+@node trusted_list
|
||||
+@subsection trusted_list
|
||||
+
|
||||
+@deffn Command trusted_list
|
||||
+List all x509 certificates and binary hases trusted by GRUB for validating
|
||||
+appended signatures. The output is a numbered list of certificates and binary
|
||||
+hashes, showing the certificate's serial number and Common Name.
|
||||
+
|
||||
+The certificate number can be used as an argument to
|
||||
+@command{distrusted_certificate} (@pxref{distrusted_certificate}).
|
||||
+
|
||||
+See @xref{Using appended signatures} for more information.
|
||||
+@end deffn
|
||||
+
|
||||
+@node trusted_signature
|
||||
+@subsection trusted_signature
|
||||
+
|
||||
+@deffn Command trust_signature
|
||||
+Read a binary hash from the file @var{binary hash file}
|
||||
+and add it to GRUB's internal trusted list. These binary hash are used to
|
||||
+validate linux image integrity if appended signatures validation failed
|
||||
+when the environment variable @code{check_appended_signatures} is set
|
||||
+to @code{enforce}.
|
||||
+
|
||||
+See @xref{Using appended signatures} for more information.
|
||||
+@end deffn
|
||||
|
||||
@node unset
|
||||
@subsection unset
|
||||
@@ -5979,9 +6012,8 @@ only on PC BIOS platforms.
|
||||
|
||||
@deffn Command verify_appended file
|
||||
Verifies an appended signature on @var{file} against the trusted certificates
|
||||
-known to GRUB (See @pxref{list_certificates}, @pxref{trust_certificate}, and
|
||||
-@pxref{distrust_certificate}).
|
||||
-
|
||||
+known to GRUB (See @pxref{trusted_list}, @pxref{trusted_certificate}, and
|
||||
+@pxref{distrusted_certificate}).
|
||||
Exit code @code{$?} is set to 0 if the signature validates
|
||||
successfully. If validation fails, it is set to a non-zero value.
|
||||
See @xref{Using appended signatures}, for more information.
|
||||
@@ -6669,14 +6701,21 @@ To enable appended signature verification, load the appendedsig module and an
|
||||
x509 certificate for verification. Building the appendedsig module into the
|
||||
core grub image is recommended.
|
||||
|
||||
-Certificates can be managed at boot time using the @pxref{trust_certificate},
|
||||
-@pxref{distrust_certificate} and @pxref{list_certificates} commands.
|
||||
-Certificates can also be built in to the core image using the @code{--x509}
|
||||
-parameter to @command{grub-install} or @command{grub-mkimage}.
|
||||
+For static key, Certificates will be built in to the core image using
|
||||
+the @code{--x509} parameter to @command{grub-install} or @command{grub-mkimage}.
|
||||
+it can allow to list the trusted certificates and binary hashes at boot time using
|
||||
+@pxref{trusted_list} and list distrusted certificates and binary/certificate hashes
|
||||
+at boot time using @pxref{distrusted_list} commands.
|
||||
+
|
||||
+For dynamic key, loads the signature database (DB) and forbidden
|
||||
+signature database (DBX) from platform keystore (PKS) and it can allow to list
|
||||
+the trusted certificates and binary hashes at boot time using @pxref{trusted_list}
|
||||
+and list distrusted certificates and binary/certificate hashes at boot time using
|
||||
+@pxref{distrusted_list} commands.
|
||||
|
||||
-A file can be explictly verified using the @pxref{verify_appended} command.
|
||||
+A file can be explicitly verified using the @pxref{verify_appended} command.
|
||||
|
||||
-Only signatures made with the SHA-256 or SHA-512 hash algorithm are supported,
|
||||
+Only signatures made with the SHA-256, SHA-384 and SHA-512 hash algorithm are supported,
|
||||
and only RSA signatures are supported.
|
||||
|
||||
A file can be signed with the @command{sign-file} utility supplied with the
|
||||
--
|
||||
2.48.1
|
||||
|
@@ -1,36 +0,0 @@
|
||||
From c3093b6240302e52438469857fec616aa4b294a3 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
Date: Fri, 8 Mar 2024 22:47:20 +1100
|
||||
Subject: [PATCH 09/20] video/readers/jpeg: Do not permit duplicate SOF0
|
||||
markers in JPEG
|
||||
|
||||
Otherwise a subsequent header could change the height and width
|
||||
allowing future OOB writes.
|
||||
|
||||
Fixes: CVE-2024-45774
|
||||
|
||||
Reported-by: Nils Langius <nils@langius.de>
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/video/readers/jpeg.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
|
||||
index ae634fd419..631a893564 100644
|
||||
--- a/grub-core/video/readers/jpeg.c
|
||||
+++ b/grub-core/video/readers/jpeg.c
|
||||
@@ -339,6 +339,10 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data)
|
||||
if (grub_errno != GRUB_ERR_NONE)
|
||||
return grub_errno;
|
||||
|
||||
+ if (data->image_height != 0 || data->image_width != 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE,
|
||||
+ "jpeg: cannot have duplicate SOF0 markers");
|
||||
+
|
||||
if (grub_jpeg_get_byte (data) != 8)
|
||||
return grub_error (GRUB_ERR_BAD_FILE_TYPE,
|
||||
"jpeg: only 8-bit precision is supported");
|
||||
--
|
||||
2.48.1
|
||||
|
@@ -1,37 +0,0 @@
|
||||
From 5d6f17ba4e94fe00b80498e9ce1aac57e22adba7 Mon Sep 17 00:00:00 2001
|
||||
From: Lidong Chen <lidong.chen@oracle.com>
|
||||
Date: Fri, 22 Nov 2024 06:27:55 +0000
|
||||
Subject: [PATCH 10/20] commands/extcmd: Missing check for failed allocation
|
||||
|
||||
The grub_extcmd_dispatcher() calls grub_arg_list_alloc() to allocate
|
||||
a grub_arg_list struct but it does not verify the allocation was successful.
|
||||
In case of failed allocation the NULL state pointer can be accessed in
|
||||
parse_option() through grub_arg_parse() which may lead to a security issue.
|
||||
|
||||
Fixes: CVE-2024-45775
|
||||
|
||||
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/commands/extcmd.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/extcmd.c b/grub-core/commands/extcmd.c
|
||||
index 4ac111a991..95bd71235a 100644
|
||||
--- a/grub-core/commands/extcmd.c
|
||||
+++ b/grub-core/commands/extcmd.c
|
||||
@@ -49,6 +49,9 @@ grub_extcmd_dispatcher (struct grub_command *cmd, int argc, char **args,
|
||||
}
|
||||
|
||||
state = grub_arg_list_alloc (ext, argc, args);
|
||||
+ if (state == NULL)
|
||||
+ return grub_errno;
|
||||
+
|
||||
if (grub_arg_parse (ext, argc, args, state, &new_args, &new_argc))
|
||||
{
|
||||
context.state = state;
|
||||
--
|
||||
2.48.1
|
||||
|
@@ -1,34 +0,0 @@
|
||||
From a496d7fbb80826b341ec1a578704dd574b716d68 Mon Sep 17 00:00:00 2001
|
||||
From: B Horn <b@horn.uk>
|
||||
Date: Fri, 1 Nov 2024 19:24:29 +0000
|
||||
Subject: [PATCH 11/20] commands/pgp: Unregister the "check_signatures" hooks
|
||||
on module unload
|
||||
|
||||
If the hooks are not removed they can be called after the module has
|
||||
been unloaded leading to an use-after-free.
|
||||
|
||||
Fixes: CVE-2025-0622
|
||||
|
||||
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/commands/pgp.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c
|
||||
index 847a5046a5..fa3ef5c754 100644
|
||||
--- a/grub-core/commands/pgp.c
|
||||
+++ b/grub-core/commands/pgp.c
|
||||
@@ -982,6 +982,8 @@ GRUB_MOD_INIT(pgp)
|
||||
|
||||
GRUB_MOD_FINI(pgp)
|
||||
{
|
||||
+ grub_register_variable_hook ("check_signatures", NULL, NULL);
|
||||
+ grub_env_unset ("check_signatures");
|
||||
grub_verifier_unregister (&grub_pubkey_verifier);
|
||||
grub_unregister_extcmd (cmd);
|
||||
grub_unregister_extcmd (cmd_trust);
|
||||
--
|
||||
2.48.1
|
||||
|
@@ -1,40 +0,0 @@
|
||||
From cf9108c54b25bd485832bf8930c18abf2935b35e Mon Sep 17 00:00:00 2001
|
||||
From: B Horn <b@horn.uk>
|
||||
Date: Fri, 1 Nov 2024 23:46:55 +0000
|
||||
Subject: [PATCH 12/20] normal: Remove variables hooks on module unload
|
||||
|
||||
The normal module does not entirely cleanup after itself in
|
||||
its GRUB_MOD_FINI() leaving a few variables hooks in place.
|
||||
It is not possible to unload normal module now but fix the
|
||||
issues for completeness.
|
||||
|
||||
On the occasion replace 0s with NULLs for "pager" variable
|
||||
hooks unregister.
|
||||
|
||||
Fixes: CVE-2025-0622
|
||||
|
||||
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/normal/main.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
|
||||
index f2679c4378..c9eda889ca 100644
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -694,7 +694,9 @@ GRUB_MOD_FINI(normal)
|
||||
grub_xputs = grub_xputs_saved;
|
||||
|
||||
grub_set_history (0);
|
||||
- grub_register_variable_hook ("pager", 0, 0);
|
||||
+ grub_register_variable_hook ("pager", NULL, NULL);
|
||||
+ grub_register_variable_hook ("color_normal", NULL, NULL);
|
||||
+ grub_register_variable_hook ("color_highlight", NULL, NULL);
|
||||
grub_fs_autoload_hook = 0;
|
||||
grub_unregister_command (cmd_clear);
|
||||
}
|
||||
--
|
||||
2.48.1
|
||||
|
@@ -1,37 +0,0 @@
|
||||
From dff23721425f363f2d1b6ee41be44af69cdd4aab Mon Sep 17 00:00:00 2001
|
||||
From: B Horn <b@horn.uk>
|
||||
Date: Fri, 1 Nov 2024 23:52:06 +0000
|
||||
Subject: [PATCH 13/20] gettext: Remove variables hooks on module unload
|
||||
|
||||
The gettext module does not entirely cleanup after itself in
|
||||
its GRUB_MOD_FINI() leaving a few variables hooks in place.
|
||||
It is not possible to unload gettext module because normal
|
||||
module depends on it. Though fix the issues for completeness.
|
||||
|
||||
Fixes: CVE-2025-0622
|
||||
|
||||
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/gettext/gettext.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c
|
||||
index 7a1c14e4f3..e4f4f8ee66 100644
|
||||
--- a/grub-core/gettext/gettext.c
|
||||
+++ b/grub-core/gettext/gettext.c
|
||||
@@ -535,6 +535,10 @@ GRUB_MOD_INIT (gettext)
|
||||
|
||||
GRUB_MOD_FINI (gettext)
|
||||
{
|
||||
+ grub_register_variable_hook ("locale_dir", NULL, NULL);
|
||||
+ grub_register_variable_hook ("secondary_locale_dir", NULL, NULL);
|
||||
+ grub_register_variable_hook ("lang", NULL, NULL);
|
||||
+
|
||||
grub_gettext_delete_list (&main_context);
|
||||
grub_gettext_delete_list (&secondary_context);
|
||||
|
||||
--
|
||||
2.48.1
|
||||
|
@@ -1,39 +0,0 @@
|
||||
From 9126fb474968a1f4ea8e233c5746fa735a07b3d4 Mon Sep 17 00:00:00 2001
|
||||
From: Lidong Chen <lidong.chen@oracle.com>
|
||||
Date: Fri, 22 Nov 2024 06:27:56 +0000
|
||||
Subject: [PATCH 14/20] gettext: Integer overflow leads to heap OOB write or
|
||||
read
|
||||
|
||||
Calculation of ctx->grub_gettext_msg_list size in grub_mofile_open() may
|
||||
overflow leading to subsequent OOB write or read. This patch fixes the
|
||||
issue by replacing grub_zalloc() and explicit multiplication with
|
||||
grub_calloc() which does the same thing in safe manner.
|
||||
|
||||
Fixes: CVE-2024-45776
|
||||
|
||||
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/gettext/gettext.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c
|
||||
index e4f4f8ee66..63bb1ab73f 100644
|
||||
--- a/grub-core/gettext/gettext.c
|
||||
+++ b/grub-core/gettext/gettext.c
|
||||
@@ -323,8 +323,8 @@ grub_mofile_open (struct grub_gettext_context *ctx,
|
||||
for (ctx->grub_gettext_max_log = 0; ctx->grub_gettext_max >> ctx->grub_gettext_max_log;
|
||||
ctx->grub_gettext_max_log++);
|
||||
|
||||
- ctx->grub_gettext_msg_list = grub_zalloc (ctx->grub_gettext_max
|
||||
- * sizeof (ctx->grub_gettext_msg_list[0]));
|
||||
+ ctx->grub_gettext_msg_list = grub_calloc (ctx->grub_gettext_max,
|
||||
+ sizeof (ctx->grub_gettext_msg_list[0]));
|
||||
if (!ctx->grub_gettext_msg_list)
|
||||
{
|
||||
grub_file_close (fd);
|
||||
--
|
||||
2.48.1
|
||||
|
@@ -1,56 +0,0 @@
|
||||
From 1f8d74717d2bebd1206143c1acbf720be9097011 Mon Sep 17 00:00:00 2001
|
||||
From: Lidong Chen <lidong.chen@oracle.com>
|
||||
Date: Fri, 22 Nov 2024 06:27:57 +0000
|
||||
Subject: [PATCH 15/20] gettext: Integer overflow leads to heap OOB write
|
||||
|
||||
The size calculation of the translation buffer in
|
||||
grub_gettext_getstr_from_position() may overflow
|
||||
to 0 leading to heap OOB write. This patch fixes
|
||||
the issue by using grub_add() and checking for
|
||||
an overflow.
|
||||
|
||||
Fixes: CVE-2024-45777
|
||||
|
||||
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/gettext/gettext.c | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c
|
||||
index 63bb1ab73f..9ffc734284 100644
|
||||
--- a/grub-core/gettext/gettext.c
|
||||
+++ b/grub-core/gettext/gettext.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <grub/file.h>
|
||||
#include <grub/kernel.h>
|
||||
#include <grub/i18n.h>
|
||||
+#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -99,6 +100,7 @@ grub_gettext_getstr_from_position (struct grub_gettext_context *ctx,
|
||||
char *translation;
|
||||
struct string_descriptor desc;
|
||||
grub_err_t err;
|
||||
+ grub_size_t alloc_sz;
|
||||
|
||||
internal_position = (off + position * sizeof (desc));
|
||||
|
||||
@@ -109,7 +111,10 @@ grub_gettext_getstr_from_position (struct grub_gettext_context *ctx,
|
||||
length = grub_cpu_to_le32 (desc.length);
|
||||
offset = grub_cpu_to_le32 (desc.offset);
|
||||
|
||||
- translation = grub_malloc (length + 1);
|
||||
+ if (grub_add (length, 1, &alloc_sz))
|
||||
+ return NULL;
|
||||
+
|
||||
+ translation = grub_malloc (alloc_sz);
|
||||
if (!translation)
|
||||
return NULL;
|
||||
|
||||
--
|
||||
2.48.1
|
||||
|
@@ -1,72 +0,0 @@
|
||||
From fd945966dc04c01765dcf129d8884f0b22991e74 Mon Sep 17 00:00:00 2001
|
||||
From: Jonathan Bar Or <jonathanbaror@gmail.com>
|
||||
Date: Thu, 23 Jan 2025 19:17:05 +0100
|
||||
Subject: [PATCH 16/20] commands/read: Fix an integer overflow when supplying
|
||||
more than 2^31 characters
|
||||
|
||||
The grub_getline() function currently has a signed integer variable "i"
|
||||
that can be overflown when user supplies more than 2^31 characters.
|
||||
It results in a memory corruption of the allocated line buffer as well
|
||||
as supplying large negative values to grub_realloc().
|
||||
|
||||
Fixes: CVE-2025-0690
|
||||
|
||||
Reported-by: Jonathan Bar Or <jonathanbaror@gmail.com>
|
||||
Signed-off-by: Jonathan Bar Or <jonathanbaror@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/commands/read.c | 19 +++++++++++++++----
|
||||
1 file changed, 15 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/read.c b/grub-core/commands/read.c
|
||||
index 9bbc523f6b..b8597692e2 100644
|
||||
--- a/grub-core/commands/read.c
|
||||
+++ b/grub-core/commands/read.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <grub/types.h>
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/i18n.h>
|
||||
+#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -38,13 +39,14 @@ static const struct grub_arg_option options[] =
|
||||
static char *
|
||||
grub_getline (int silent)
|
||||
{
|
||||
- int i;
|
||||
+ grub_size_t i;
|
||||
char *line;
|
||||
char *tmp;
|
||||
int c;
|
||||
+ grub_size_t alloc_size;
|
||||
|
||||
i = 0;
|
||||
- line = grub_malloc (1 + i + sizeof('\0'));
|
||||
+ line = grub_malloc (1 + sizeof('\0'));
|
||||
if (! line)
|
||||
return NULL;
|
||||
|
||||
@@ -60,8 +62,17 @@ grub_getline (int silent)
|
||||
line[i] = (char) c;
|
||||
if (!silent)
|
||||
grub_printf ("%c", c);
|
||||
- i++;
|
||||
- tmp = grub_realloc (line, 1 + i + sizeof('\0'));
|
||||
+ if (grub_add (i, 1, &i))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ if (grub_add (i, 1 + sizeof('\0'), &alloc_size))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ tmp = grub_realloc (line, alloc_size);
|
||||
if (! tmp)
|
||||
{
|
||||
grub_free (line);
|
||||
--
|
||||
2.48.1
|
||||
|
@@ -1,37 +0,0 @@
|
||||
From 0f62a673fe00e83984810b7ec61b2d9a0bb8b9d4 Mon Sep 17 00:00:00 2001
|
||||
From: B Horn <b@horn.uk>
|
||||
Date: Thu, 18 Apr 2024 20:29:39 +0100
|
||||
Subject: [PATCH 17/20] commands/minicmd: Block the dump command in lockdown
|
||||
mode
|
||||
|
||||
The dump enables a user to read memory which should not be possible
|
||||
in lockdown mode.
|
||||
|
||||
Fixes: CVE-2025-1118
|
||||
|
||||
Reported-by: B Horn <b@horn.uk>
|
||||
Reported-by: Jonathan Bar Or <jonathanbaror@gmail.com>
|
||||
Signed-off-by: B Horn <b@horn.uk>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/commands/minicmd.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c
|
||||
index fa498931ed..903af33131 100644
|
||||
--- a/grub-core/commands/minicmd.c
|
||||
+++ b/grub-core/commands/minicmd.c
|
||||
@@ -203,8 +203,8 @@ GRUB_MOD_INIT(minicmd)
|
||||
grub_register_command ("help", grub_mini_cmd_help,
|
||||
0, N_("Show this message."));
|
||||
cmd_dump =
|
||||
- grub_register_command ("dump", grub_mini_cmd_dump,
|
||||
- N_("ADDR [SIZE]"), N_("Show memory contents."));
|
||||
+ grub_register_command_lockdown ("dump", grub_mini_cmd_dump,
|
||||
+ N_("ADDR [SIZE]"), N_("Show memory contents."));
|
||||
cmd_rmmod =
|
||||
grub_register_command ("rmmod", grub_mini_cmd_rmmod,
|
||||
N_("MODULE"), N_("Remove a module."));
|
||||
--
|
||||
2.48.1
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user