Sync from SUSE:SLFO:Main grub2 revision 22210e8b4d1d1dbd09b665cf3004c663
This commit is contained in:
@@ -43,11 +43,9 @@ Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
grub-core/script/execute.c | 7 ----
|
||||
4 files changed, 154 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
|
||||
index c9eda889ca..091450e53c 100644
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -365,21 +365,6 @@ grub_normal_execute (const char *config, int nested, int batch)
|
||||
@@ -365,21 +365,6 @@
|
||||
{
|
||||
menu = read_config_file (config);
|
||||
|
||||
@@ -69,16 +67,15 @@ index c9eda889ca..091450e53c 100644
|
||||
/* Ignore any error. */
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
@@ -393,7 +378,50 @@ grub_normal_execute (const char *config, int nested, int batch)
|
||||
@@ -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;
|
||||
+
|
||||
@@ -121,21 +118,19 @@ index c9eda889ca..091450e53c 100644
|
||||
grub_boot_time ("Entering menu");
|
||||
grub_show_menu (menu, nested, 0);
|
||||
if (nested)
|
||||
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
|
||||
index dfdf0c7268..897da6abac 100644
|
||||
--- a/grub-core/normal/menu.c
|
||||
+++ b/grub-core/normal/menu.c
|
||||
@@ -33,6 +33,9 @@
|
||||
@@ -32,6 +32,9 @@
|
||||
#include <grub/script_sh.h>
|
||||
#include <grub/gfxterm.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/crypttab.h>
|
||||
+#ifdef GRUB_MACHINE_IEEE1275
|
||||
+#include <grub/ieee1275/ieee1275.h>
|
||||
+#endif
|
||||
|
||||
/* Time to delay after displaying an error message about a default/fallback
|
||||
entry failing to boot. */
|
||||
@@ -318,8 +321,31 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
|
||||
@@ -317,8 +320,31 @@
|
||||
grub_env_set ("default", ptr + 1);
|
||||
else
|
||||
grub_env_unset ("default");
|
||||
@@ -167,7 +162,7 @@ index dfdf0c7268..897da6abac 100644
|
||||
|
||||
if (errs_before != grub_err_printed_errors)
|
||||
grub_wait_after_message ();
|
||||
@@ -327,8 +353,23 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
|
||||
@@ -326,8 +352,23 @@
|
||||
errs_before = grub_err_printed_errors;
|
||||
|
||||
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
|
||||
@@ -193,8 +188,6 @@ index dfdf0c7268..897da6abac 100644
|
||||
|
||||
if (errs_before != grub_err_printed_errors)
|
||||
grub_wait_after_message ();
|
||||
diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c
|
||||
index 06682a396d..bbd05e5638 100644
|
||||
--- a/grub-core/normal/menu_entry.c
|
||||
+++ b/grub-core/normal/menu_entry.c
|
||||
@@ -29,6 +29,9 @@
|
||||
@@ -207,7 +200,7 @@ index 06682a396d..bbd05e5638 100644
|
||||
|
||||
enum update_mode
|
||||
{
|
||||
@@ -78,6 +81,9 @@ struct screen
|
||||
@@ -78,6 +81,9 @@
|
||||
int completion_shown;
|
||||
|
||||
int submenu;
|
||||
@@ -217,7 +210,7 @@ index 06682a396d..bbd05e5638 100644
|
||||
|
||||
struct per_term_screen *terms;
|
||||
unsigned nterms;
|
||||
@@ -578,6 +584,9 @@ destroy_screen (struct screen *screen)
|
||||
@@ -578,6 +584,9 @@
|
||||
grub_free (screen->killed_text);
|
||||
grub_free (screen->lines);
|
||||
grub_free (screen->terms);
|
||||
@@ -227,7 +220,7 @@ index 06682a396d..bbd05e5638 100644
|
||||
grub_free (screen);
|
||||
}
|
||||
|
||||
@@ -599,6 +608,11 @@ make_screen (grub_menu_entry_t entry)
|
||||
@@ -599,6 +608,11 @@
|
||||
screen->lines = grub_malloc (sizeof (struct line));
|
||||
if (! screen->lines)
|
||||
goto fail;
|
||||
@@ -239,7 +232,7 @@ index 06682a396d..bbd05e5638 100644
|
||||
|
||||
/* Initialize the first line which must be always present. */
|
||||
if (! init_line (screen, screen->lines))
|
||||
@@ -1215,14 +1229,64 @@ run (struct screen *screen)
|
||||
@@ -1215,14 +1229,64 @@
|
||||
script[size] = '\0';
|
||||
}
|
||||
grub_script_execute_new_scope (script, 0, dummy);
|
||||
@@ -307,8 +300,6 @@ index 06682a396d..bbd05e5638 100644
|
||||
|
||||
if (screen->submenu)
|
||||
{
|
||||
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
|
||||
index dab8fd2aeb..14ff09094f 100644
|
||||
--- a/grub-core/script/execute.c
|
||||
+++ b/grub-core/script/execute.c
|
||||
@@ -28,9 +28,6 @@
|
||||
@@ -321,7 +312,7 @@ index dab8fd2aeb..14ff09094f 100644
|
||||
|
||||
/* 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_script_execute_sourcecode (const char *source)
|
||||
@@ -886,10 +883,6 @@
|
||||
grub_err_t ret = 0;
|
||||
struct grub_script *parsed_script;
|
||||
|
||||
@@ -332,6 +323,3 @@ index dab8fd2aeb..14ff09094f 100644
|
||||
while (source)
|
||||
{
|
||||
char *line;
|
||||
--
|
||||
2.49.0
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
From 27b3e919b9b51a4fedeb3a5aef19c87f0cd7b687 Mon Sep 17 00:00:00 2001
|
||||
From 7b6cdb8ff71e43f95de9cefc19a7949e924c2be9 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 17 Nov 2023 12:32:59 +0800
|
||||
Subject: [PATCH] Improve TPM key protection on boot interruptions
|
||||
Subject: [PATCH 1/2] 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,19 +25,21 @@ 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 | 8 +++++++-
|
||||
grub-core/disk/cryptodisk.c | 10 ++++++++-
|
||||
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, 59 insertions(+), 22 deletions(-)
|
||||
7 files changed, 61 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/crypttab.c b/grub-core/commands/crypttab.c
|
||||
index c2217ca98..9397bede9 100644
|
||||
index c2217ca980..9397bede9e 100644
|
||||
--- a/grub-core/commands/crypttab.c
|
||||
+++ b/grub-core/commands/crypttab.c
|
||||
@@ -9,17 +9,20 @@
|
||||
@@ -125,7 +127,7 @@ index c2217ca98..9397bede9 100644
|
||||
|
||||
static grub_command_t cmd;
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index aa0d43562..babc94868 100644
|
||||
index cb87d337ac..5fd68f4549 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,
|
||||
@@ -138,17 +140,15 @@ index aa0d43562..babc94868 100644
|
||||
|
||||
dev = grub_cryptodisk_get_by_source_disk (source);
|
||||
|
||||
@@ -1183,6 +1186,9 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
ret = grub_cryptodisk_insert (dev, name, source);
|
||||
if (ret != GRUB_ERR_NONE)
|
||||
@@ -1185,6 +1188,7 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
goto error;
|
||||
+#ifndef GRUB_UTIL
|
||||
#ifndef GRUB_UTIL
|
||||
grub_cli_set_auth_needed ();
|
||||
+ is_tpmkey = 1;
|
||||
+#endif
|
||||
#endif
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
@@ -1244,7 +1250,7 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
@@ -1247,7 +1251,7 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
|
||||
#ifndef GRUB_UTIL
|
||||
if (cargs->key_data && dev)
|
||||
@@ -157,8 +157,19 @@ index aa0d43562..babc94868 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 9ee8f3790..e5e792958 100644
|
||||
index 9ee8f37907..e5e7929581 100644
|
||||
--- a/grub-core/loader/linux.c
|
||||
+++ b/grub-core/loader/linux.c
|
||||
@@ -226,13 +226,13 @@ grub_initrd_init (int argc, char *argv[],
|
||||
@@ -187,10 +198,10 @@ index 9ee8f3790..e5e792958 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 a3f711d1d..1b426af69 100644
|
||||
index 320adbe337..343cdbae2c 100644
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -479,7 +479,7 @@ grub_cmdline_run (int nested, int force_auth)
|
||||
@@ -599,7 +599,7 @@ grub_cmdline_run (int nested, int force_auth)
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -200,7 +211,7 @@ index a3f711d1d..1b426af69 100644
|
||||
|
||||
while (1)
|
||||
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
|
||||
index 14b0ab1ec..1df2638d7 100644
|
||||
index f243c5e0bd..897da6abac 100644
|
||||
--- a/grub-core/normal/menu.c
|
||||
+++ b/grub-core/normal/menu.c
|
||||
@@ -32,6 +32,7 @@
|
||||
@@ -208,10 +219,10 @@ index 14b0ab1ec..1df2638d7 100644
|
||||
#include <grub/gfxterm.h>
|
||||
#include <grub/dl.h>
|
||||
+#include <grub/crypttab.h>
|
||||
|
||||
/* 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)
|
||||
#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)
|
||||
if (grub_key_is_interrupt (key))
|
||||
{
|
||||
timeout = -1;
|
||||
@@ -219,7 +230,7 @@ index 14b0ab1ec..1df2638d7 100644
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -790,6 +792,11 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot, int *notify_boot)
|
||||
@@ -851,6 +853,11 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot, int *notify_boot)
|
||||
clear_timeout ();
|
||||
}
|
||||
|
||||
@@ -232,10 +243,10 @@ index 14b0ab1ec..1df2638d7 100644
|
||||
{
|
||||
case GRUB_TERM_KEY_HOME:
|
||||
diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c
|
||||
index 384ab9ce3..e5ba91ea4 100644
|
||||
index 38c958e657..bbd05e5638 100644
|
||||
--- a/grub-core/normal/menu_entry.c
|
||||
+++ b/grub-core/normal/menu_entry.c
|
||||
@@ -1263,7 +1263,7 @@ grub_menu_entry_run (grub_menu_entry_t entry)
|
||||
@@ -1331,7 +1331,7 @@ grub_menu_entry_run (grub_menu_entry_t entry)
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -245,7 +256,7 @@ index 384ab9ce3..e5ba91ea4 100644
|
||||
screen = make_screen (entry);
|
||||
if (! screen)
|
||||
diff --git a/include/grub/crypttab.h b/include/grub/crypttab.h
|
||||
index 113c53cfc..f86404686 100644
|
||||
index 113c53cfce..f86404686f 100644
|
||||
--- a/include/grub/crypttab.h
|
||||
+++ b/include/grub/crypttab.h
|
||||
@@ -4,21 +4,25 @@
|
||||
@@ -282,5 +293,5 @@ index 113c53cfc..f86404686 100644
|
||||
+grub_cryptokey_tpmkey_discard (void);
|
||||
#endif /* ! GRUB_CRYPTTAB_HEADER */
|
||||
--
|
||||
2.35.3
|
||||
2.49.0
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
From 219b06c69d38a10349183002efb82bfec3b7ff5b Mon Sep 17 00:00:00 2001
|
||||
From e56c40ade88270bec8b50680fe34bb358919057b Mon Sep 17 00:00:00 2001
|
||||
From: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Date: Wed, 21 Aug 2024 14:13:05 +0530
|
||||
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.
|
||||
@@ -8,16 +8,19 @@ 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 | 65 ++++++++++++++++++++++++++++++++-
|
||||
include/grub/util/install.h | 3 ++
|
||||
include/grub/util/ofpath.h | 4 ++
|
||||
4 files changed, 74 insertions(+), 4 deletions(-)
|
||||
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 @@
|
||||
@@ -209,7 +209,7 @@ find_obppath (const char *sysfs_path_orig)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +29,7 @@ Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
xrealpath (const char *in)
|
||||
{
|
||||
char *out;
|
||||
@@ -224,7 +224,7 @@
|
||||
@@ -224,7 +224,7 @@ xrealpath (const char *in)
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -35,7 +38,7 @@ Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
block_device_get_sysfs_path_and_link(const char *devicenode)
|
||||
{
|
||||
char *rpath;
|
||||
@@ -613,7 +613,7 @@
|
||||
@@ -613,7 +613,7 @@ of_path_get_nvme_nsid (const char* devname)
|
||||
return nsid;
|
||||
}
|
||||
|
||||
@@ -44,6 +47,8 @@ Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
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 @@
|
||||
@@ -55,54 +60,103 @@ Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
|
||||
static char *
|
||||
get_ofpathname (const char *dev)
|
||||
@@ -203,6 +205,56 @@
|
||||
@@ -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;
|
||||
+ char *sysfs_path, *nvme_ns, *ptr, *non_splitter_path;
|
||||
+ unsigned int nsid;
|
||||
+ char *multipath_boot;
|
||||
+ struct dirent *ep;
|
||||
+ DIR *dp;
|
||||
+ 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;
|
||||
+
|
||||
+ /*
|
||||
+ * Extracting the namespace from install_device.
|
||||
+ * ex. install_device : /dev/nvme1n1
|
||||
+ */
|
||||
+ 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);
|
||||
+ strcat (sysfs_path, "/subsystem");
|
||||
+ 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);
|
||||
+ while ((ep = readdir (dp)) != NULL)
|
||||
+ if (is_splitter == 0 && is_FC == 0)
|
||||
+ {
|
||||
+ char *path;
|
||||
+ if (grub_strstr (ep->d_name, "nvme"))
|
||||
+ 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)
|
||||
+ {
|
||||
+ path = xasprintf ("%s%s%x ", get_ofpathname (ep->d_name), "/namespace@", nsid);
|
||||
+ if ((strlen (multipath_boot) + strlen (path)) > BOOTDEV_BUFFER)
|
||||
+ char *path;
|
||||
+ if (grub_strstr (ep->d_name, "nvme"))
|
||||
+ {
|
||||
+ grub_util_warn (_("Maximum five entries are allowed in the bootlist"));
|
||||
+ 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);
|
||||
+ break;
|
||||
+ }
|
||||
+ strncpy (ptr, path, strlen (path));
|
||||
+ ptr += strlen (path);
|
||||
+ free (path);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *--ptr = '\0';
|
||||
+ closedir (dp);
|
||||
+
|
||||
@@ -112,7 +166,7 @@ Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
void
|
||||
grub_install_register_ieee1275 (int is_prep, const char *install_device,
|
||||
int partno, const char *relpath)
|
||||
@@ -242,8 +294,19 @@
|
||||
@@ -242,8 +343,19 @@ grub_install_register_ieee1275 (int is_prep, const char *install_device,
|
||||
}
|
||||
*ptr = '\0';
|
||||
}
|
||||
@@ -133,21 +187,25 @@ Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
|
||||
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
|
||||
@@ -241,6 +241,9 @@
|
||||
const char *efi_distributor,
|
||||
const char *force_disk);
|
||||
@@ -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_register_ieee1275 (int is_prep, const char *install_device,
|
||||
int partno, const char *relpath);
|
||||
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 @@
|
||||
@@ -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);
|
||||
@@ -157,3 +215,6 @@ Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
+unsigned int of_path_get_nvme_nsid (const char* devname);
|
||||
|
||||
#endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */
|
||||
--
|
||||
2.49.0
|
||||
|
||||
|
@@ -0,0 +1,33 @@
|
||||
From 4f45e963ea913000fd8e3fe20f9afb3722073cea Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Thu, 8 May 2025 19:02:07 +0200
|
||||
Subject: [PATCH 1/8] kern/rescue_reader: Block the rescue mode until the CLI
|
||||
authentication
|
||||
|
||||
This further mitigates potential misuse of the CLI after the
|
||||
root device has been successfully unlocked via TPM.
|
||||
|
||||
Fixes: CVE-2025-4382
|
||||
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/kern/rescue_reader.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/kern/rescue_reader.c b/grub-core/kern/rescue_reader.c
|
||||
index 4259857ba9..a71ada8fb7 100644
|
||||
--- a/grub-core/kern/rescue_reader.c
|
||||
+++ b/grub-core/kern/rescue_reader.c
|
||||
@@ -79,7 +79,7 @@ void __attribute__ ((noreturn))
|
||||
grub_rescue_run (void)
|
||||
{
|
||||
/* Stall if the CLI has been disabled */
|
||||
- if (grub_is_cli_disabled ())
|
||||
+ if (grub_is_cli_disabled () || grub_is_cli_need_auth ())
|
||||
{
|
||||
grub_printf ("Rescue mode has been disabled...\n");
|
||||
|
||||
--
|
||||
2.49.0
|
||||
|
@@ -38,19 +38,19 @@ Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
include/grub/misc.h | 2 +
|
||||
8 files changed, 140 insertions(+)
|
||||
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index babc94868d..21bf22ead1 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1188,6 +1188,7 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
@@ -1183,6 +1183,9 @@
|
||||
ret = grub_cryptodisk_insert (dev, name, source);
|
||||
if (ret != GRUB_ERR_NONE)
|
||||
goto error;
|
||||
#ifndef GRUB_UTIL
|
||||
is_tpmkey = 1;
|
||||
+#ifndef GRUB_UTIL
|
||||
+ grub_cli_set_auth_needed ();
|
||||
#endif
|
||||
+#endif
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -1706,6 +1707,89 @@ luks_script_get (grub_size_t *sz)
|
||||
}
|
||||
@@ -1700,6 +1703,89 @@
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -140,8 +140,6 @@ index babc94868d..21bf22ead1 100644
|
||||
struct grub_procfs_entry luks_script =
|
||||
{
|
||||
.name = "luks_script",
|
||||
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
|
||||
index 07b6940d2e..ef3b3756de 100644
|
||||
--- a/grub-core/kern/main.c
|
||||
+++ b/grub-core/kern/main.c
|
||||
@@ -37,6 +37,7 @@
|
||||
@@ -152,7 +150,7 @@ index 07b6940d2e..ef3b3756de 100644
|
||||
|
||||
grub_addr_t
|
||||
grub_modules_get_end (void)
|
||||
@@ -246,6 +247,17 @@ grub_is_cli_disabled (void)
|
||||
@@ -246,6 +247,17 @@
|
||||
return cli_disabled;
|
||||
}
|
||||
|
||||
@@ -170,8 +168,6 @@ index 07b6940d2e..ef3b3756de 100644
|
||||
static void
|
||||
check_is_cli_disabled (void)
|
||||
{
|
||||
diff --git a/grub-core/normal/auth.c b/grub-core/normal/auth.c
|
||||
index d940201866..2931ba604a 100644
|
||||
--- a/grub-core/normal/auth.c
|
||||
+++ b/grub-core/normal/auth.c
|
||||
@@ -25,6 +25,10 @@
|
||||
@@ -185,11 +181,10 @@ index d940201866..2931ba604a 100644
|
||||
struct grub_auth_user
|
||||
{
|
||||
struct grub_auth_user *next;
|
||||
@@ -200,6 +204,32 @@ grub_username_get (char buf[], unsigned buf_size)
|
||||
return (key != GRUB_TERM_ESC);
|
||||
@@ -201,6 +205,32 @@
|
||||
}
|
||||
|
||||
+grub_err_t
|
||||
grub_err_t
|
||||
+grub_auth_check_cli_access (void)
|
||||
+{
|
||||
+ if (grub_is_cli_need_auth () == true)
|
||||
@@ -211,18 +206,17 @@ index d940201866..2931ba604a 100644
|
||||
+ return GRUB_ACCESS_DENIED;
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
grub_err_t
|
||||
+grub_err_t
|
||||
grub_auth_check_authentication (const char *userlist)
|
||||
{
|
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
|
||||
index 8e58ced679..b08fd6977d 100644
|
||||
char login[1024];
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -560,9 +560,13 @@ grub_cmdline_run (int nested, int force_auth)
|
||||
@@ -560,9 +560,13 @@
|
||||
}
|
||||
while (err && force_auth);
|
||||
|
||||
@@ -236,11 +230,9 @@ index 8e58ced679..b08fd6977d 100644
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return;
|
||||
}
|
||||
diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c
|
||||
index e5ba91ea4d..06682a396d 100644
|
||||
--- a/grub-core/normal/menu_entry.c
|
||||
+++ b/grub-core/normal/menu_entry.c
|
||||
@@ -1256,9 +1256,13 @@ grub_menu_entry_run (grub_menu_entry_t entry)
|
||||
@@ -1256,9 +1256,13 @@
|
||||
|
||||
err = grub_auth_check_authentication (NULL);
|
||||
|
||||
@@ -254,22 +246,18 @@ index e5ba91ea4d..06682a396d 100644
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return;
|
||||
}
|
||||
diff --git a/include/grub/auth.h b/include/grub/auth.h
|
||||
index 7473344517..21d5190f04 100644
|
||||
--- a/include/grub/auth.h
|
||||
+++ b/include/grub/auth.h
|
||||
@@ -33,5 +33,6 @@ grub_err_t grub_auth_unregister_authentication (const char *user);
|
||||
@@ -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 */
|
||||
diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h
|
||||
index 0b41e249e8..b3291519b1 100644
|
||||
--- a/include/grub/cryptodisk.h
|
||||
+++ b/include/grub/cryptodisk.h
|
||||
@@ -203,4 +203,7 @@ grub_util_get_geli_uuid (const char *dev);
|
||||
@@ -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);
|
||||
|
||||
@@ -277,11 +265,9 @@ index 0b41e249e8..b3291519b1 100644
|
||||
+grub_err_t grub_cryptodisk_challenge_password (void);
|
||||
+#endif
|
||||
#endif
|
||||
diff --git a/include/grub/misc.h b/include/grub/misc.h
|
||||
index 1578f36c3c..6e94d18f5a 100644
|
||||
--- a/include/grub/misc.h
|
||||
+++ b/include/grub/misc.h
|
||||
@@ -392,6 +392,8 @@ grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
|
||||
@@ -392,6 +392,8 @@
|
||||
grub_uint64_t *r);
|
||||
|
||||
extern bool EXPORT_FUNC(grub_is_cli_disabled) (void);
|
||||
@@ -290,6 +276,3 @@ index 1578f36c3c..6e94d18f5a 100644
|
||||
|
||||
/* Must match softdiv group in gentpl.py. */
|
||||
#if !defined(GRUB_MACHINE_EMU) && (defined(__arm__) || defined(__ia64__) || \
|
||||
--
|
||||
2.47.1
|
||||
|
||||
|
134
0002-commands-search-Introduce-the-cryptodisk-only-argume.patch
Normal file
134
0002-commands-search-Introduce-the-cryptodisk-only-argume.patch
Normal file
@@ -0,0 +1,134 @@
|
||||
From 9ad07efefe389568c2cedc77a4a6b48cb830dc0a Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Thu, 8 May 2025 19:02:08 +0200
|
||||
Subject: [PATCH 2/8] commands/search: Introduce the --cryptodisk-only argument
|
||||
|
||||
This allows users to restrict the "search" command's scope to
|
||||
encrypted disks only.
|
||||
|
||||
Typically, this command is used to "rebase" $root and $prefix
|
||||
before loading additional configuration files via "source" or
|
||||
"configfile". Unfortunately, this leads to security problems,
|
||||
like CVE-2023-4001, when an unexpected, attacker-controlled
|
||||
device is chosen by the "search" command.
|
||||
|
||||
The --cryptodisk-only argument allows users to ensure that the
|
||||
file system picked is encrypted.
|
||||
|
||||
This feature supports the CLI authentication, blocking bypass
|
||||
attempts.
|
||||
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/commands/search.c | 20 ++++++++++++++++++++
|
||||
grub-core/commands/search_wrap.c | 7 ++++++-
|
||||
grub-core/normal/main.c | 3 ++-
|
||||
include/grub/search.h | 7 ++++---
|
||||
4 files changed, 32 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
|
||||
index 263f1501cd..f6bfef9585 100644
|
||||
--- a/grub-core/commands/search.c
|
||||
+++ b/grub-core/commands/search.c
|
||||
@@ -86,6 +86,26 @@ iterate_device (const char *name, void *data)
|
||||
grub_device_close (dev);
|
||||
}
|
||||
|
||||
+ /* Limit to encrypted disks when requested. */
|
||||
+ if (ctx->flags & SEARCH_FLAGS_CRYPTODISK_ONLY)
|
||||
+ {
|
||||
+ grub_device_t dev;
|
||||
+
|
||||
+ dev = grub_device_open (name);
|
||||
+ if (dev == NULL)
|
||||
+ {
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (dev->disk == NULL || dev->disk->dev->id != GRUB_DISK_DEVICE_CRYPTODISK_ID)
|
||||
+ {
|
||||
+ grub_device_close (dev);
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ grub_device_close (dev);
|
||||
+ }
|
||||
+
|
||||
#ifdef DO_SEARCH_FS_UUID
|
||||
#define compare_fn grub_strcasecmp
|
||||
#else
|
||||
diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c
|
||||
index 318581f3b1..5f536006cf 100644
|
||||
--- a/grub-core/commands/search_wrap.c
|
||||
+++ b/grub-core/commands/search_wrap.c
|
||||
@@ -41,6 +41,7 @@ static const struct grub_arg_option options[] =
|
||||
ARG_TYPE_STRING},
|
||||
{"no-floppy", 'n', 0, N_("Do not probe any floppy drive."), 0, 0},
|
||||
{"efidisk-only", 0, 0, N_("Only probe EFI disks."), 0, 0},
|
||||
+ {"cryptodisk-only", 0, 0, N_("Only probe encrypted disks."), 0, 0},
|
||||
{"hint", 'h', GRUB_ARG_OPTION_REPEATABLE,
|
||||
N_("First try the device HINT. If HINT ends in comma, "
|
||||
"also try subpartitions"), N_("HINT"), ARG_TYPE_STRING},
|
||||
@@ -75,6 +76,7 @@ enum options
|
||||
SEARCH_SET,
|
||||
SEARCH_NO_FLOPPY,
|
||||
SEARCH_EFIDISK_ONLY,
|
||||
+ SEARCH_CRYPTODISK_ONLY,
|
||||
SEARCH_HINT,
|
||||
SEARCH_HINT_IEEE1275,
|
||||
SEARCH_HINT_BIOS,
|
||||
@@ -189,6 +191,9 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
if (state[SEARCH_EFIDISK_ONLY].set)
|
||||
flags |= SEARCH_FLAGS_EFIDISK_ONLY;
|
||||
|
||||
+ if (state[SEARCH_CRYPTODISK_ONLY].set)
|
||||
+ flags |= SEARCH_FLAGS_CRYPTODISK_ONLY;
|
||||
+
|
||||
if (state[SEARCH_LABEL].set)
|
||||
grub_search_label (id, var, flags, hints, nhints);
|
||||
else if (state[SEARCH_FS_UUID].set)
|
||||
@@ -210,7 +215,7 @@ GRUB_MOD_INIT(search)
|
||||
cmd =
|
||||
grub_register_extcmd ("search", grub_cmd_search,
|
||||
GRUB_COMMAND_FLAG_EXTRACTOR | GRUB_COMMAND_ACCEPT_DASH,
|
||||
- N_("[-f|-l|-u|-s|-n] [--hint HINT [--hint HINT] ...]"
|
||||
+ N_("[-f|-l|-u|-s|-n] [--cryptodisk-only] [--hint HINT [--hint HINT] ...]"
|
||||
" NAME"),
|
||||
N_("Search devices by file, filesystem label"
|
||||
" or filesystem UUID."
|
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
|
||||
index d1cbaa1806..320adbe337 100644
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -647,7 +647,8 @@ static const char *features[] = {
|
||||
"feature_chainloader_bpb", "feature_ntldr", "feature_platform_search_hint",
|
||||
"feature_default_font_path", "feature_all_video_module",
|
||||
"feature_menuentry_id", "feature_menuentry_options", "feature_200_final",
|
||||
- "feature_nativedisk_cmd", "feature_timeout_style"
|
||||
+ "feature_nativedisk_cmd", "feature_timeout_style",
|
||||
+ "feature_search_cryptodisk_only"
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT(normal)
|
||||
diff --git a/include/grub/search.h b/include/grub/search.h
|
||||
index ffd2411ca1..3eabaf0ccd 100644
|
||||
--- a/include/grub/search.h
|
||||
+++ b/include/grub/search.h
|
||||
@@ -21,9 +21,10 @@
|
||||
|
||||
enum search_flags
|
||||
{
|
||||
- SEARCH_FLAGS_NONE = 0,
|
||||
- SEARCH_FLAGS_NO_FLOPPY = 1,
|
||||
- SEARCH_FLAGS_EFIDISK_ONLY = 2
|
||||
+ SEARCH_FLAGS_NONE = 0,
|
||||
+ SEARCH_FLAGS_NO_FLOPPY = 1,
|
||||
+ SEARCH_FLAGS_EFIDISK_ONLY = 2,
|
||||
+ SEARCH_FLAGS_CRYPTODISK_ONLY = 4
|
||||
};
|
||||
|
||||
void grub_search_fs_file (const char *key, const char *var,
|
||||
--
|
||||
2.49.0
|
||||
|
136
0003-disk-diskfilter-Introduce-the-cryptocheck-command.patch
Normal file
136
0003-disk-diskfilter-Introduce-the-cryptocheck-command.patch
Normal file
@@ -0,0 +1,136 @@
|
||||
From 781d736bd5d0004c705d73b0348b154d8ab838cf Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Thu, 8 May 2025 19:02:09 +0200
|
||||
Subject: [PATCH 3/8] disk/diskfilter: Introduce the "cryptocheck" command
|
||||
|
||||
This command examines a given diskfilter device, e.g., an LVM disk,
|
||||
and checks if underlying disks, physical volumes, are cryptodisks,
|
||||
e.g., LUKS disks, this layout is called "LVM-on-LUKS".
|
||||
|
||||
The return value is 0 when all underlying disks (of a given device)
|
||||
are cryptodisks (1 if at least one disk is unencrypted or in an
|
||||
unknown state).
|
||||
|
||||
Users are encouraged to include the relevant check before loading
|
||||
anything from an LVM disk that is supposed to be encrypted.
|
||||
|
||||
This further supports the CLI authentication, blocking bypass
|
||||
attempts when booting from an encrypted LVM disk.
|
||||
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/disk/diskfilter.c | 75 +++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 75 insertions(+)
|
||||
|
||||
diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c
|
||||
index c45bef1caf..3f7c05e14e 100644
|
||||
--- a/grub-core/disk/diskfilter.c
|
||||
+++ b/grub-core/disk/diskfilter.c
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <grub/dl.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/mm.h>
|
||||
+#include <grub/command.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/diskfilter.h>
|
||||
@@ -1487,6 +1488,73 @@ grub_diskfilter_get_pv_from_disk (grub_disk_t disk,
|
||||
}
|
||||
#endif
|
||||
|
||||
+static int
|
||||
+grub_diskfilter_check_pvs_encrypted (grub_disk_t disk, int *pvs_cnt)
|
||||
+{
|
||||
+ struct grub_diskfilter_lv *lv = disk->data;
|
||||
+ struct grub_diskfilter_pv *pv;
|
||||
+
|
||||
+ *pvs_cnt = 0;
|
||||
+
|
||||
+ if (lv->vg->pvs)
|
||||
+ for (pv = lv->vg->pvs; pv; pv = pv->next)
|
||||
+ {
|
||||
+ (*pvs_cnt)++;
|
||||
+
|
||||
+ if (pv->disk == NULL)
|
||||
+ {
|
||||
+ /* Can be a partially activated VG, bail out. */
|
||||
+ return GRUB_ERR_TEST_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ if (pv->disk->dev->id != GRUB_DISK_DEVICE_CRYPTODISK_ID)
|
||||
+ {
|
||||
+ /* All backing devices must be cryptodisks, stop. */
|
||||
+ return GRUB_ERR_TEST_FAILURE;
|
||||
+ }
|
||||
+ }
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_cryptocheck (grub_command_t cmd __attribute__ ((unused)),
|
||||
+ int argc, char **args)
|
||||
+{
|
||||
+ grub_disk_t disk;
|
||||
+ int check_pvs_res;
|
||||
+ int namelen;
|
||||
+ int pvs_cnt;
|
||||
+
|
||||
+ if (argc != 1)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("disk name expected"));
|
||||
+
|
||||
+ namelen = grub_strlen (args[0]);
|
||||
+ if (namelen > 2 && (args[0][0] == '(') && (args[0][namelen - 1] == ')'))
|
||||
+ args[0][namelen - 1] = 0;
|
||||
+ else
|
||||
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("invalid disk: %s"),
|
||||
+ args[0]);
|
||||
+
|
||||
+ if (!is_valid_diskfilter_name (&args[0][1]))
|
||||
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("unrecognized disk: %s"),
|
||||
+ &args[0][1]);
|
||||
+
|
||||
+ disk = grub_disk_open (&args[0][1]);
|
||||
+ if (disk == NULL)
|
||||
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("no such disk: %s"),
|
||||
+ &args[0][1]);
|
||||
+
|
||||
+ check_pvs_res = grub_diskfilter_check_pvs_encrypted (disk, &pvs_cnt);
|
||||
+ grub_disk_close (disk);
|
||||
+
|
||||
+ grub_printf("%s is %sencrypted (%d pv%s examined)\n", &args[0][1],
|
||||
+ (check_pvs_res == GRUB_ERR_NONE) ? "" : "un",
|
||||
+ pvs_cnt,
|
||||
+ (pvs_cnt > 1) ? "s" : "");
|
||||
+
|
||||
+ return check_pvs_res;
|
||||
+}
|
||||
+
|
||||
static struct grub_disk_dev grub_diskfilter_dev =
|
||||
{
|
||||
.name = "diskfilter",
|
||||
@@ -1503,14 +1571,21 @@ static struct grub_disk_dev grub_diskfilter_dev =
|
||||
.next = 0
|
||||
};
|
||||
|
||||
+static grub_command_t cmd;
|
||||
+
|
||||
|
||||
GRUB_MOD_INIT(diskfilter)
|
||||
{
|
||||
grub_disk_dev_register (&grub_diskfilter_dev);
|
||||
+ cmd = grub_register_command ("cryptocheck", grub_cmd_cryptocheck,
|
||||
+ N_("DEVICE"),
|
||||
+ N_("Check if a logical volume resides on encrypted disks."));
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(diskfilter)
|
||||
{
|
||||
grub_disk_dev_unregister (&grub_diskfilter_dev);
|
||||
+ if (cmd != NULL)
|
||||
+ grub_unregister_command (cmd);
|
||||
free_array ();
|
||||
}
|
||||
--
|
||||
2.49.0
|
||||
|
@@ -1,7 +1,7 @@
|
||||
From 6547d22fc9e20720d1a896be82b2d50d842f86b0 Mon Sep 17 00:00:00 2001
|
||||
From 977f8c63d9d85fd101e989310ac0ba011f252df1 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 20 Nov 2023 09:25:53 +0800
|
||||
Subject: [PATCH 4/4] Key revocation on out of bound file access
|
||||
Subject: [PATCH 2/2] 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,15 +14,23 @@ 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.
|
||||
|
||||
Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/crypttab.c | 36 +++++++++++++++++++++++++++++++++++
|
||||
include/grub/file.h | 1 +
|
||||
2 files changed, 37 insertions(+)
|
||||
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>
|
||||
---
|
||||
grub-core/commands/crypttab.c | 76 +++++++++++++++++++++++++++++++++++
|
||||
grub-core/disk/diskfilter.c | 1 +
|
||||
include/grub/file.h | 1 +
|
||||
3 files changed, 78 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/crypttab.c b/grub-core/commands/crypttab.c
|
||||
index 9397bede9e..f104154e23 100644
|
||||
--- a/grub-core/commands/crypttab.c
|
||||
+++ b/grub-core/commands/crypttab.c
|
||||
@@ -6,6 +6,7 @@
|
||||
@@ -6,11 +6,47 @@
|
||||
#include <grub/mm.h>
|
||||
#include <grub/list.h>
|
||||
#include <grub/crypttab.h>
|
||||
@@ -30,7 +38,47 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -89,6 +90,41 @@
|
||||
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)
|
||||
grub_cryptokey_discard();
|
||||
}
|
||||
|
||||
@@ -59,8 +107,11 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
+ case GRUB_FILE_TYPE_LINUX_INITRD:
|
||||
+ case GRUB_FILE_TYPE_LOADENV:
|
||||
+ case GRUB_FILE_TYPE_THEME:
|
||||
+ if (!disk || !grub_disk_is_crypto (disk))
|
||||
+ grub_cryptokey_discard ();
|
||||
+ if (!disk || is_unencrypted_disk (disk))
|
||||
+ {
|
||||
+ grub_cryptokey_discard ();
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
@@ -72,7 +123,7 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
static grub_err_t
|
||||
grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **argv)
|
||||
@@ -121,6 +157,8 @@
|
||||
@@ -121,6 +195,8 @@ GRUB_MOD_INIT(crypttab)
|
||||
{
|
||||
cmd = grub_register_command ("crypttab_entry", grub_cmd_crypttab_entry,
|
||||
N_("VOLUME-NAME ENCRYPTED-DEVICE KEY-FILE") , N_("No description"));
|
||||
@@ -81,9 +132,23 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
diff --git a/include/grub/file.h b/include/grub/file.h
|
||||
index c463e4f992..804d512231 100644
|
||||
--- a/include/grub/file.h
|
||||
+++ b/include/grub/file.h
|
||||
@@ -185,6 +185,7 @@
|
||||
@@ -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
|
||||
{
|
||||
@@ -91,78 +156,6 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
GRUB_FILE_FILTER_VERIFY,
|
||||
GRUB_FILE_FILTER_GZIO,
|
||||
GRUB_FILE_FILTER_XZIO,
|
||||
--- a/grub-core/disk/diskfilter.c
|
||||
+++ b/grub-core/disk/diskfilter.c
|
||||
@@ -558,6 +558,39 @@
|
||||
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 @@
|
||||
|
||||
disk->total_sectors = lv->size;
|
||||
disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE;
|
||||
+ disk->is_crypto_diskfilter = grub_diskfilter_has_cryptodisk (lv);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
--- a/include/grub/disk.h
|
||||
+++ b/include/grub/disk.h
|
||||
@@ -147,6 +147,8 @@
|
||||
|
||||
/* Device-specific data. */
|
||||
void *data;
|
||||
+
|
||||
+ int is_crypto_diskfilter;
|
||||
};
|
||||
typedef struct grub_disk *grub_disk_t;
|
||||
|
||||
@@ -317,4 +319,12 @@
|
||||
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 */
|
||||
--
|
||||
2.49.0
|
||||
|
||||
|
70
0004-commands-search-Add-the-diskfilter-support.patch
Normal file
70
0004-commands-search-Add-the-diskfilter-support.patch
Normal file
@@ -0,0 +1,70 @@
|
||||
From 13ae8a054a4a0b871ce3fd8ddaaff7a4f2ba2478 Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Thu, 8 May 2025 19:02:10 +0200
|
||||
Subject: [PATCH 4/8] commands/search: Add the diskfilter support
|
||||
|
||||
When the --cryptodisk-only argument is given, also check the target
|
||||
device using the "cryptocheck" command, if available.
|
||||
|
||||
This extends the checks to common layouts like LVM-on-LUKS, so the
|
||||
--cryptodisk-only argument transparently handles such setups.
|
||||
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/commands/search.c | 32 +++++++++++++++++++++++++++++++-
|
||||
1 file changed, 31 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
|
||||
index f6bfef9585..185c1e70f7 100644
|
||||
--- a/grub-core/commands/search.c
|
||||
+++ b/grub-core/commands/search.c
|
||||
@@ -54,6 +54,36 @@ struct search_ctx
|
||||
int is_cache;
|
||||
};
|
||||
|
||||
+static bool
|
||||
+is_unencrypted_disk (grub_disk_t disk)
|
||||
+{
|
||||
+ grub_command_t cmd;
|
||||
+ char *disk_str;
|
||||
+ int disk_str_len;
|
||||
+ int res;
|
||||
+
|
||||
+ if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
|
||||
+ return false; /* This is (crypto) disk. */
|
||||
+
|
||||
+ if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID)
|
||||
+ {
|
||||
+ cmd = grub_command_find ("cryptocheck");
|
||||
+ if (cmd == NULL) /* No diskfilter module loaded for some reason. */
|
||||
+ return true;
|
||||
+
|
||||
+ disk_str_len = grub_strlen (disk->name) + 2 + 1;
|
||||
+ disk_str = grub_malloc (disk_str_len);
|
||||
+ if (disk_str == NULL) /* Something is wrong, better report as unencrypted. */
|
||||
+ return true;
|
||||
+
|
||||
+ grub_snprintf (disk_str, disk_str_len, "(%s)", disk->name);
|
||||
+ res = cmd->func (cmd, 1, &disk_str);
|
||||
+ grub_free (disk_str);
|
||||
+ return (res != GRUB_ERR_NONE) ? true : false; /* GRUB_ERR_NONE for encrypted. */
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
/* Helper for FUNC_NAME. */
|
||||
static int
|
||||
iterate_device (const char *name, void *data)
|
||||
@@ -97,7 +127,7 @@ iterate_device (const char *name, void *data)
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return 0;
|
||||
}
|
||||
- if (dev->disk == NULL || dev->disk->dev->id != GRUB_DISK_DEVICE_CRYPTODISK_ID)
|
||||
+ if (dev->disk == NULL || is_unencrypted_disk (dev->disk) == true)
|
||||
{
|
||||
grub_device_close (dev);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
--
|
||||
2.49.0
|
||||
|
71
0005-docs-Document-available-crypto-disks-checks.patch
Normal file
71
0005-docs-Document-available-crypto-disks-checks.patch
Normal file
@@ -0,0 +1,71 @@
|
||||
From 45fffe05e9c33582258a88b4a722a5a561dbfa6e Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Thu, 8 May 2025 19:02:11 +0200
|
||||
Subject: [PATCH 5/8] docs: Document available crypto disks checks
|
||||
|
||||
Document the --cryptodisk-only argument. Also, document the
|
||||
"cryptocheck" command invoked when that argument is processed.
|
||||
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
docs/grub.texi | 22 +++++++++++++++++++++-
|
||||
1 file changed, 21 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index 9aaea72826..1c078c5c5b 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -4368,6 +4368,7 @@ you forget a command, you can run the command @command{help}
|
||||
* configfile:: Load a configuration file
|
||||
* cpuid:: Check for CPU features
|
||||
* crc:: Compute or check CRC32 checksums
|
||||
+* cryptocheck:: Check if a device is encrypted
|
||||
* cryptomount:: Mount a crypto device
|
||||
* cutmem:: Remove memory regions
|
||||
* date:: Display or set current date and time
|
||||
@@ -4680,6 +4681,16 @@ Alias for @code{hashsum --hash crc32 arg @dots{}}. See command @command{hashsum}
|
||||
(@pxref{hashsum}) for full description.
|
||||
@end deffn
|
||||
|
||||
+@node cryptocheck
|
||||
+@subsection cryptocheck
|
||||
+
|
||||
+@deffn Command cryptocheck device
|
||||
+Check if a given diskfilter device is backed by encrypted devices
|
||||
+(@pxref{cryptomount} for additional information).
|
||||
+
|
||||
+The command examines all backing devices, physical volumes, of a specified
|
||||
+logical volume, like LVM2, and fails when at least one of them is unencrypted.
|
||||
+@end deffn
|
||||
|
||||
@node cryptomount
|
||||
@subsection cryptomount
|
||||
@@ -5531,7 +5542,8 @@ unbootable. @xref{Using GPG-style digital signatures}, for more information.
|
||||
|
||||
@deffn Command search @
|
||||
[@option{--file}|@option{--label}|@option{--fs-uuid}] @
|
||||
- [@option{--set} [var]] [@option{--no-floppy}|@option{--efidisk-only}] name
|
||||
+ [@option{--set} [var]] [@option{--no-floppy}|@option{--efidisk-only}|@option{--cryptodisk-only}] @
|
||||
+ name
|
||||
Search devices by file (@option{-f}, @option{--file}), filesystem label
|
||||
(@option{-l}, @option{--label}), or filesystem UUID (@option{-u},
|
||||
@option{--fs-uuid}).
|
||||
@@ -5546,6 +5558,14 @@ devices, which can be slow.
|
||||
The (@option{--efidisk-only}) option prevents searching any other devices then
|
||||
EFI disks. This is typically used when chainloading to local EFI partition.
|
||||
|
||||
+The (@option{--cryptodisk-only}) option prevents searching any devices other
|
||||
+than encrypted disks. This is typically used when booting from an encrypted
|
||||
+file system to ensure that no code gets executed from an unencrypted device
|
||||
+having the same filesystem UUID or label.
|
||||
+
|
||||
+This option implicitly invokes the command @command{cryptocheck}, if it is
|
||||
+available (@pxref{cryptocheck} for additional information).
|
||||
+
|
||||
The @samp{search.file}, @samp{search.fs_label}, and @samp{search.fs_uuid}
|
||||
commands are aliases for @samp{search --file}, @samp{search --label}, and
|
||||
@samp{search --fs-uuid} respectively.
|
||||
--
|
||||
2.49.0
|
||||
|
150
0006-disk-cryptodisk-Add-the-erase-secrets-function.patch
Normal file
150
0006-disk-cryptodisk-Add-the-erase-secrets-function.patch
Normal file
@@ -0,0 +1,150 @@
|
||||
From 0a11bc48ea60f7611df2c5b640cecc325c7c4fd9 Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Thu, 8 May 2025 19:02:12 +0200
|
||||
Subject: [PATCH 6/8] disk/cryptodisk: Add the "erase secrets" function
|
||||
|
||||
This commit adds the grub_cryptodisk_erasesecrets() function to wipe
|
||||
master keys from all cryptodisks. This function is EFI-only.
|
||||
|
||||
Since there is no easy way to "force unmount" a given encrypted disk,
|
||||
this function renders all mounted cryptodisks unusable. An attempt to
|
||||
read them will return garbage.
|
||||
|
||||
This is why this function must be used in "no way back" conditions.
|
||||
|
||||
Currently, it is used when unloading the cryptodisk module and when
|
||||
performing the "exit" command (it is often used to switch to the next
|
||||
EFI application). This function is not called when performing the
|
||||
"chainloader" command, because the callee may return to GRUB. For this
|
||||
reason, users are encouraged to use "exit" instead of "chainloader" to
|
||||
execute third-party boot applications.
|
||||
|
||||
This function does not guarantee that all secrets are wiped from RAM.
|
||||
Console output, chunks from disk read requests and other may remain.
|
||||
|
||||
This function does not clear the IV prefix and rekey key for geli disks.
|
||||
|
||||
Also, this commit adds the relevant documentation improvements.
|
||||
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
docs/grub.texi | 6 ++++++
|
||||
grub-core/commands/minicmd.c | 11 +++++++++++
|
||||
grub-core/disk/cryptodisk.c | 28 ++++++++++++++++++++++++++++
|
||||
include/grub/cryptodisk.h | 1 +
|
||||
4 files changed, 46 insertions(+)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index 1c078c5c5b..c4936db8c1 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -4727,6 +4727,11 @@ namespace in addition to the cryptodisk namespace.
|
||||
|
||||
Support for plain encryption mode (plain dm-crypt) is provided via separate
|
||||
@command{@pxref{plainmount}} command.
|
||||
+
|
||||
+On the EFI platform, GRUB tries to erase master keys from memory when the cryptodisk
|
||||
+module is unloaded or the command @command{exit} is executed. All secrets remain in
|
||||
+memory when the command @command{chainloader} is issued, because execution can
|
||||
+return to GRUB on the EFI platform.
|
||||
@end deffn
|
||||
|
||||
@node cutmem
|
||||
@@ -6981,6 +6986,7 @@ USB support provides benefits similar to ATA (for USB disks) or AT (for USB
|
||||
keyboards). In addition it allows USBserial.
|
||||
|
||||
Chainloading refers to the ability to load another bootloader through the same protocol
|
||||
+and on some platforms, like EFI, allow that bootloader to return to the GRUB.
|
||||
|
||||
Hints allow faster disk discovery by already knowing in advance which is the disk in
|
||||
question. On some platforms hints are correct unless you move the disk between boots.
|
||||
diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c
|
||||
index 903af33131..bd9cb681ec 100644
|
||||
--- a/grub-core/commands/minicmd.c
|
||||
+++ b/grub-core/commands/minicmd.c
|
||||
@@ -29,6 +29,10 @@
|
||||
#include <grub/command.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+#include <grub/cryptodisk.h>
|
||||
+#endif
|
||||
+
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
/* cat FILE */
|
||||
@@ -187,6 +191,13 @@ grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char *argv[] __attribute__ ((unused)))
|
||||
{
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+ /*
|
||||
+ * The "exit" command is often used to launch the next boot application.
|
||||
+ * So, erase the secrets.
|
||||
+ */
|
||||
+ grub_cryptodisk_erasesecrets ();
|
||||
+#endif
|
||||
grub_exit ();
|
||||
/* Not reached. */
|
||||
}
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index 33eb6568ca..f9ae750f85 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1784,6 +1784,31 @@ grub_cryptodisk_challenge_password (void)
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
+
|
||||
+void
|
||||
+grub_cryptodisk_erasesecrets (void)
|
||||
+{
|
||||
+ grub_cryptodisk_t i;
|
||||
+ grub_uint8_t *buf;
|
||||
+
|
||||
+ buf = grub_zalloc (GRUB_CRYPTODISK_MAX_KEYLEN);
|
||||
+ if (buf == NULL)
|
||||
+ grub_fatal ("grub_cryptodisk_erasesecrets: cannot allocate memory");
|
||||
+
|
||||
+ for (i = cryptodisk_list; i != NULL; i = i->next)
|
||||
+ if (grub_cryptodisk_setkey (i, buf, i->keysize))
|
||||
+ grub_fatal ("grub_cryptodisk_erasesecrets: cannot erase secrets for %s", i->source);
|
||||
+ else
|
||||
+ grub_printf ("Erased crypto secrets for %s\n", i->source);
|
||||
+ /*
|
||||
+ * Unfortunately, there is no way to "force unmount" a given disk, it may
|
||||
+ * have mounted "child" disks as well, e.g., an LVM volume. So, this
|
||||
+ * function MUST be called when there is no way back, e.g., when exiting.
|
||||
+ * Otherwise, subsequent read calls for a cryptodisk will return garbage.
|
||||
+ */
|
||||
+
|
||||
+ grub_free (buf);
|
||||
+}
|
||||
#endif /* GRUB_MACHINE_EFI */
|
||||
|
||||
struct grub_procfs_entry luks_script =
|
||||
@@ -1808,6 +1833,9 @@ GRUB_MOD_INIT (cryptodisk)
|
||||
|
||||
GRUB_MOD_FINI (cryptodisk)
|
||||
{
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+ grub_cryptodisk_erasesecrets ();
|
||||
+#endif
|
||||
grub_disk_dev_unregister (&grub_cryptodisk_dev);
|
||||
cryptodisk_cleanup ();
|
||||
grub_unregister_extcmd (cmd);
|
||||
diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h
|
||||
index b3291519b1..08abfb7b6c 100644
|
||||
--- a/include/grub/cryptodisk.h
|
||||
+++ b/include/grub/cryptodisk.h
|
||||
@@ -205,5 +205,6 @@ grub_cryptodisk_t grub_cryptodisk_get_by_source_disk (grub_disk_t disk);
|
||||
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
grub_err_t grub_cryptodisk_challenge_password (void);
|
||||
+void grub_cryptodisk_erasesecrets (void);
|
||||
#endif
|
||||
#endif
|
||||
--
|
||||
2.49.0
|
||||
|
32
0007-disk-cryptodisk-Wipe-the-passphrase-from-memory.patch
Normal file
32
0007-disk-cryptodisk-Wipe-the-passphrase-from-memory.patch
Normal file
@@ -0,0 +1,32 @@
|
||||
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
|
||||
|
117
0008-cryptocheck-Add-quiet-option.patch
Normal file
117
0008-cryptocheck-Add-quiet-option.patch
Normal file
@@ -0,0 +1,117 @@
|
||||
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
|
||||
|
81
grub2-bls-boot-assessment.patch
Normal file
81
grub2-bls-boot-assessment.patch
Normal file
@@ -0,0 +1,81 @@
|
||||
Implement Automatic Boot Assessment for grub2-bls.
|
||||
|
||||
https://systemd.io/AUTOMATIC_BOOT_ASSESSMENT/
|
||||
|
||||
The entries are ordered first by the boot tries left, keeping
|
||||
the one without available tries (e.g. <entry>+0-3.conf)
|
||||
after the one without a boot counter or with a positive boot counter.
|
||||
|
||||
After removing the boot counter from the release string, keep the ordering
|
||||
as it worked previously.
|
||||
|
||||
Index: grub-2.12/grub-core/commands/blscfg.c
|
||||
===================================================================
|
||||
--- grub-2.12.orig/grub-core/commands/blscfg.c
|
||||
+++ grub-2.12/grub-core/commands/blscfg.c
|
||||
@@ -323,9 +323,37 @@ finish:
|
||||
/* NULL string pointer returned if nothing found */
|
||||
static void
|
||||
split_package_string (char *package_string, char **name,
|
||||
- char **version, char **release)
|
||||
+ char **version, char **release, int *tries_left)
|
||||
{
|
||||
- char *package_version, *package_release;
|
||||
+ char *package_version, *package_release, *tries_left_str, *tmp;
|
||||
+
|
||||
+ *tries_left = -1;
|
||||
+ /* Search for the start of the tries left, as per boot assessment */
|
||||
+ tries_left_str = grub_strrchr(package_string, '+');
|
||||
+ if (tries_left_str != NULL)
|
||||
+ {
|
||||
+ /* If there the number of tries available is after the number of tries left (e.g. +1-2)
|
||||
+ stop the string at the '-' delimiter, so that strtol
|
||||
+ does the parsing of the first part and skip the second */
|
||||
+ tmp = grub_strrchr(tries_left_str, '-');
|
||||
+ if (tmp != NULL)
|
||||
+ {
|
||||
+ *tmp = '\0';
|
||||
+ }
|
||||
+ tmp = tries_left_str;
|
||||
+ *tries_left = grub_strtol(++tmp, (const char **)&tmp, 10);
|
||||
+
|
||||
+ /* Conversion failed */
|
||||
+ if (tmp == tries_left_str)
|
||||
+ {
|
||||
+ /* Reset the counter */
|
||||
+ *tries_left = -1;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ *tries_left_str = '\0';
|
||||
+ }
|
||||
+ }
|
||||
|
||||
/* Release */
|
||||
package_release = grub_strrchr (package_string, '-');
|
||||
@@ -372,9 +401,23 @@ split_cmp(char *nvr0, char *nvr1, int ha
|
||||
int ret = 0;
|
||||
char *name0, *version0, *release0;
|
||||
char *name1, *version1, *release1;
|
||||
+ int tries_left0;
|
||||
+ int tries_left1;
|
||||
+
|
||||
+ split_package_string(nvr0, has_name ? &name0 : NULL, &version0, &release0, &tries_left0);
|
||||
+ split_package_string(nvr1, has_name ? &name1 : NULL, &version1, &release1, &tries_left1);
|
||||
|
||||
- split_package_string(nvr0, has_name ? &name0 : NULL, &version0, &release0);
|
||||
- split_package_string(nvr1, has_name ? &name1 : NULL, &version1, &release1);
|
||||
+ /* Check for systemd Automatic Boot Assessment
|
||||
+ 0 has no tries left, while 1 doesn't have a boot count / still has tries left */
|
||||
+ if (tries_left0 == 0 && tries_left1 != 0)
|
||||
+ {
|
||||
+ return -1;
|
||||
+ }
|
||||
+ /* viceversa, b has no tries left */
|
||||
+ else if (tries_left0 != 0 && tries_left1 == 0)
|
||||
+ {
|
||||
+ return 1;
|
||||
+ }
|
||||
|
||||
if (has_name)
|
||||
{
|
564
grub2-bls-boot-counting.patch
Normal file
564
grub2-bls-boot-counting.patch
Normal file
@@ -0,0 +1,564 @@
|
||||
Add a new bls_bumpcunter grub command that implement boot counting for bls entries.
|
||||
|
||||
Boot counting, explained in systemd Automatic Boot Assessment, keep track of the
|
||||
avaiable tries for each entry and the number of attempted boot. The bls_bumpcunter
|
||||
command parse the entry id, check if there is a boot count enabled and update
|
||||
its value accordingly. Then, EFI_SIMPLE_FILE_SYSTEM_PROTOCOL is used to rename
|
||||
the entry on the EFI partition.
|
||||
|
||||
https://systemd.io/AUTOMATIC_BOOT_ASSESSMENT/
|
||||
|
||||
Index: grub-2.12/include/grub/efi/filesystem.h
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ grub-2.12/include/grub/efi/filesystem.h
|
||||
@@ -0,0 +1,155 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ *
|
||||
+ * GRUB is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation, either version 3 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * GRUB is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#ifndef GRUB_EFI_TPM_HEADER
|
||||
+#define GRUB_EFI_TPM_HEADER 1
|
||||
+
|
||||
+#include <grub/efi/api.h>
|
||||
+#include <grub/env.h>
|
||||
+
|
||||
+struct grub_efi_file_io_token {
|
||||
+ grub_efi_event_t Event;
|
||||
+ grub_efi_status_t Status;
|
||||
+ grub_efi_uint64_t BufferSize;
|
||||
+ void *Buffer;
|
||||
+};
|
||||
+
|
||||
+typedef struct grub_efi_file_io_token grub_efi_file_io_token_t;
|
||||
+
|
||||
+
|
||||
+struct grub_efi_file_protocol
|
||||
+{
|
||||
+ grub_efi_uint64_t Revision;
|
||||
+
|
||||
+ grub_efi_status_t
|
||||
+ (__grub_efi_api *Open) (struct grub_efi_file_protocol *this,
|
||||
+ struct grub_efi_file_protocol **new_handle,
|
||||
+ grub_efi_char16_t *filename,
|
||||
+ grub_efi_uint64_t open_mode,
|
||||
+ grub_efi_uint64_t attributes);
|
||||
+
|
||||
+ grub_efi_status_t
|
||||
+ (__grub_efi_api *Close) (struct grub_efi_file_protocol *this);
|
||||
+
|
||||
+ grub_efi_status_t
|
||||
+ (__grub_efi_api *Delete) (struct grub_efi_file_protocol *this);
|
||||
+
|
||||
+ grub_efi_status_t
|
||||
+ (__grub_efi_api *Read) (struct grub_efi_file_protocol *this,
|
||||
+ grub_efi_uint64_t *buffer_size,
|
||||
+ void *buffer);
|
||||
+
|
||||
+ grub_efi_status_t
|
||||
+ (__grub_efi_api *Write) (struct grub_efi_file_protocol *this,
|
||||
+ grub_efi_uint64_t *buffer_size,
|
||||
+ void *buffer);
|
||||
+
|
||||
+ grub_efi_status_t
|
||||
+ (__grub_efi_api *GetPosition) (struct grub_efi_file_protocol *this,
|
||||
+ grub_efi_uint64_t *position);
|
||||
+
|
||||
+ grub_efi_status_t
|
||||
+ (__grub_efi_api *SetPosition) (struct grub_efi_file_protocol *this,
|
||||
+ grub_efi_uint64_t position);
|
||||
+
|
||||
+ grub_efi_status_t
|
||||
+ (__grub_efi_api *GetInfo) (struct grub_efi_file_protocol *this,
|
||||
+ grub_guid_t *information_type,
|
||||
+ grub_efi_uint64_t *buffer_size,
|
||||
+ void *buffer);
|
||||
+
|
||||
+ grub_efi_status_t
|
||||
+ (__grub_efi_api *SetInfo) (struct grub_efi_file_protocol *this,
|
||||
+ grub_guid_t *information_type,
|
||||
+ grub_efi_uint64_t buffer_size,
|
||||
+ void *buffer);
|
||||
+
|
||||
+ grub_efi_status_t
|
||||
+ (__grub_efi_api *Flush) (struct grub_efi_file_protocol *this);
|
||||
+
|
||||
+ grub_efi_status_t
|
||||
+ (__grub_efi_api *OpenEx) (struct grub_efi_file_protocol *this,
|
||||
+ struct grub_efi_file_protocol **new_handle,
|
||||
+ grub_efi_char16_t *filename,
|
||||
+ grub_efi_uint64_t open_mode,
|
||||
+ grub_efi_uint64_t attributes,
|
||||
+ grub_efi_file_io_token_t *token);
|
||||
+
|
||||
+ grub_efi_status_t
|
||||
+ (__grub_efi_api *ReadEx) (struct grub_efi_file_protocol *this,
|
||||
+ grub_efi_file_io_token_t *token);
|
||||
+
|
||||
+ grub_efi_status_t
|
||||
+ (__grub_efi_api *WriteEx) (struct grub_efi_file_protocol *this,
|
||||
+ grub_efi_file_io_token_t *token);
|
||||
+
|
||||
+ grub_efi_status_t
|
||||
+ (__grub_efi_api *FlushEx) (struct grub_efi_file_protocol *this,
|
||||
+ grub_efi_file_io_token_t *token);
|
||||
+};
|
||||
+
|
||||
+typedef struct grub_efi_file_protocol grub_efi_file_protocol_t;
|
||||
+
|
||||
+/*******************************************************
|
||||
+ Open Modes
|
||||
+ ******************************************************/
|
||||
+#define GRUB_EFI_FILE_MODE_READ 0x0000000000000001
|
||||
+#define GRUB_EFI_FILE_MODE_WRITE 0x0000000000000002
|
||||
+#define GRUB_EFI_FILE_MODE_CREATE 0x8000000000000000
|
||||
+
|
||||
+/*******************************************************
|
||||
+ File Attributes
|
||||
+ ******************************************************/
|
||||
+#define GRUB_EFI_FILE_READ_ONLY 0x0000000000000001
|
||||
+#define GRUB_EFI_FILE_HIDDEN 0x0000000000000002
|
||||
+#define GRUB_EFI_FILE_SYSTEM 0x0000000000000004
|
||||
+#define GRUB_EFI_FILE_RESERVED 0x0000000000000008
|
||||
+#define GRUB_EFI_FILE_DIRECTORY 0x0000000000000010
|
||||
+#define GRUB_EFI_FILE_ARCHIVE 0x0000000000000020
|
||||
+#define GRUB_EFI_FILE_VALID_ATTR 0x0000000000000037
|
||||
+
|
||||
+struct grub_efi_file_info {
|
||||
+ grub_efi_uint64_t Size;
|
||||
+ grub_efi_uint64_t FileSize;
|
||||
+ grub_efi_uint64_t PhysicalSize;
|
||||
+ grub_efi_time_t CreateTime;
|
||||
+ grub_efi_time_t LastAccessTime;
|
||||
+ grub_efi_time_t ModificationTime;
|
||||
+ grub_efi_uint64_t Attribute;
|
||||
+ grub_efi_char16_t FileName[];
|
||||
+};
|
||||
+
|
||||
+typedef struct grub_efi_file_info grub_efi_file_info_t;
|
||||
+
|
||||
+#define GRUB_EFI_FILE_INFO_ID \
|
||||
+ {0x09576e92,0x6d3f,0x11d2, \
|
||||
+ {0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b} \
|
||||
+ }
|
||||
+
|
||||
+struct grub_efi_simple_file_system_protocol
|
||||
+{
|
||||
+ grub_efi_uint64_t Revision;
|
||||
+
|
||||
+ grub_efi_status_t
|
||||
+ (__grub_efi_api *OpenVolume) (struct grub_efi_simple_file_system_protocol *this,
|
||||
+ struct grub_efi_file_protocol **root);
|
||||
+};
|
||||
+
|
||||
+typedef struct grub_efi_simple_file_system_protocol grub_efi_simple_file_system_protocol_t;
|
||||
+
|
||||
+
|
||||
+#endif
|
||||
Index: grub-2.12/grub-core/commands/blscfg.c
|
||||
===================================================================
|
||||
--- grub-2.12.orig/grub-core/commands/blscfg.c
|
||||
+++ grub-2.12/grub-core/commands/blscfg.c
|
||||
@@ -791,6 +791,8 @@ static void create_entry (struct bls_ent
|
||||
int i, index;
|
||||
bool add_dt_prefix = false;
|
||||
|
||||
+ char *bumpcounter = NULL;
|
||||
+
|
||||
grub_dprintf("blscfg", "%s got here\n", __func__);
|
||||
clinux = bls_get_val (entry, "linux", NULL);
|
||||
if (!clinux)
|
||||
@@ -949,6 +951,19 @@ static void create_entry (struct bls_ent
|
||||
grub_free(prefix);
|
||||
}
|
||||
|
||||
+ /* "bls_bumpcounter " + id + "\n" */
|
||||
+ int bumpcounter_size = sizeof("bls_bumpcounter ") + grub_strlen(id) + 1;
|
||||
+ bumpcounter = grub_malloc(bumpcounter_size);
|
||||
+ if (!bumpcounter)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||
+ goto finish;
|
||||
+ }
|
||||
+ char *tmp = bumpcounter;
|
||||
+ tmp = grub_stpcpy(tmp, "bls_bumpcounter ");
|
||||
+ tmp = grub_stpcpy(tmp, id);
|
||||
+ tmp = grub_stpcpy(tmp, "\n");
|
||||
+
|
||||
grub_dprintf ("blscfg2", "devicetree %s for id:\"%s\"\n", dt, id);
|
||||
|
||||
const char *sdval = grub_env_get("save_default");
|
||||
@@ -961,7 +976,7 @@ static void create_entry (struct bls_ent
|
||||
"insmod gzio\n"
|
||||
"linux %s%s%s%s\n"
|
||||
#endif
|
||||
- "%s%s",
|
||||
+ "%s%s%s",
|
||||
savedefault ? "savedefault\n" : "",
|
||||
#ifdef GRUB_MACHINE_EMU
|
||||
separate_boot ? GRUB_BOOT_DEVICE : "",
|
||||
@@ -969,7 +984,8 @@ static void create_entry (struct bls_ent
|
||||
bootdev,
|
||||
#endif
|
||||
clinux, options ? " " : "", options ? options : "",
|
||||
- initrd ? initrd : "", dt ? dt : "");
|
||||
+ bumpcounter ? bumpcounter : "", initrd ? initrd : "",
|
||||
+ dt ? dt : "");
|
||||
|
||||
grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey, NULL, src, 0, 0, &index, entry);
|
||||
grub_dprintf ("blscfg", "Added entry %d id:\"%s\"\n", index, id);
|
||||
@@ -987,6 +1003,7 @@ finish:
|
||||
grub_free (argv);
|
||||
grub_free (src);
|
||||
grub_free (bootdev);
|
||||
+ grub_free (bumpcounter);
|
||||
}
|
||||
|
||||
struct find_entry_info {
|
||||
Index: grub-2.12/grub-core/commands/blsbumpcounter.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ grub-2.12/grub-core/commands/blsbumpcounter.c
|
||||
@@ -0,0 +1,54 @@
|
||||
+/*-*- Mode: C; c-basic-offset: 2; indent-tabs-mode: t -*-*/
|
||||
+
|
||||
+/* blsbumpcounter.c - implementation of boot counting for the Automatic Boot Assessment */
|
||||
+
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ *
|
||||
+ * 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/extcmd.h>
|
||||
+#include <grub/dl.h>
|
||||
+
|
||||
+#include <stddef.h>
|
||||
+
|
||||
+GRUB_MOD_LICENSE ("GPLv3+");
|
||||
+
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_bumpcounters (grub_extcmd_context_t ctxt UNUSED,
|
||||
+ int argc UNUSED, char **args UNUSED)
|
||||
+{
|
||||
+ /* placeholder, as blsbumpcounter only work on EFI platforms */
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static grub_extcmd_t cmd;
|
||||
+
|
||||
+GRUB_MOD_INIT(blsbumpcounter)
|
||||
+{
|
||||
+ cmd = grub_register_extcmd ("bls_bumpcounter",
|
||||
+ grub_cmd_bumpcounters,
|
||||
+ 0,
|
||||
+ NULL,
|
||||
+ N_("Bump the boot entry counting (only works on EFI)."),
|
||||
+ NULL);
|
||||
+}
|
||||
+
|
||||
+GRUB_MOD_FINI(blsbumpcounter)
|
||||
+{
|
||||
+ grub_unregister_extcmd (cmd);
|
||||
+}
|
||||
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
|
||||
@@ -858,6 +858,13 @@ module = {
|
||||
};
|
||||
|
||||
module = {
|
||||
+ name = blsbumpcounter;
|
||||
+ common = commands/blsbumpcounter.c;
|
||||
+ efi = commands/efi/blsbumpcounter.c;
|
||||
+};
|
||||
+
|
||||
+
|
||||
+module = {
|
||||
name = boot;
|
||||
common = commands/boot.c;
|
||||
i386_pc = lib/i386/pc/biosnum.c;
|
||||
Index: grub-2.12/grub-core/commands/efi/blsbumpcounter.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ grub-2.12/grub-core/commands/efi/blsbumpcounter.c
|
||||
@@ -0,0 +1,252 @@
|
||||
+/*-*- Mode: C; c-basic-offset: 2; indent-tabs-mode: t -*-*/
|
||||
+
|
||||
+/* bls.c - implementation of the boot loader spec */
|
||||
+
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ *
|
||||
+ * 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/extcmd.h>
|
||||
+#include <grub/fs.h>
|
||||
+#include <grub/env.h>
|
||||
+#include <grub/lib/envblk.h>
|
||||
+#include <grub/efi/api.h>
|
||||
+#include <grub/efi/efi.h>
|
||||
+#include <grub/efi/filesystem.h>
|
||||
+
|
||||
+#include <stddef.h>
|
||||
+
|
||||
+GRUB_MOD_LICENSE ("GPLv3+");
|
||||
+
|
||||
+#define GRUB_BLS_CONFIG_PATH "\\loader\\entries\\"
|
||||
+
|
||||
+#define GRUB_EFI_LOADER_GUID \
|
||||
+ { 0x4a67b082, 0x0a4c, 0x41cf, { 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f } }
|
||||
+
|
||||
+static grub_guid_t grub_simple_file_system_guid = GRUB_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
|
||||
+static grub_guid_t grub_efi_loader_guid = GRUB_EFI_LOADER_GUID;
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_bumpcounters (grub_extcmd_context_t ctxt UNUSED,
|
||||
+ int argc UNUSED, char **args UNUSED)
|
||||
+{
|
||||
+ grub_efi_file_info_t *file_info = NULL;
|
||||
+ grub_efi_file_protocol_t *handle = NULL;
|
||||
+ grub_efi_file_protocol_t *root = NULL;
|
||||
+ grub_efi_simple_file_system_protocol_t *volume = NULL;
|
||||
+ char* id = NULL;
|
||||
+
|
||||
+ grub_dprintf("bls_bumpcounter", "starting bumpcounter\n");
|
||||
+ /* There should be exactly two arguments, the entry that is getting booted and the disk where
|
||||
+ it can be found */
|
||||
+ if (argc != 1) {
|
||||
+ grub_dprintf("bls_bumpcounter", "one argument should be passed\n");
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
+ id = args[0];
|
||||
+
|
||||
+ /* Look for the start of the count
|
||||
+ If no '+' symbol has been found, the boot counting isn't enabled for the selected entry */
|
||||
+ if (grub_strrchr(id, '+') == NULL) {
|
||||
+ grub_dprintf("bls_bumpcounter", "boot counting is not in effect for id %s\n", id);
|
||||
+ return GRUB_ERR_NONE;
|
||||
+ }
|
||||
+
|
||||
+ grub_efi_loaded_image_t *image = NULL;
|
||||
+ grub_dprintf("bls_bumpcounter", "Using loaded EFI image device\n");
|
||||
+ image = grub_efi_get_loaded_image (grub_efi_image_handle);
|
||||
+
|
||||
+ if (!image) {
|
||||
+ grub_dprintf("bls_bumpcounter", "grub_efi_get_loaded_image failed\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ grub_efi_status_t err;
|
||||
+ grub_efi_boot_services_t *bs;
|
||||
+ bs = grub_efi_system_table->boot_services;
|
||||
+ err = bs->handle_protocol (image->device_handle,
|
||||
+ (void *) &grub_simple_file_system_guid, (void *) &volume);
|
||||
+ if (err != GRUB_EFI_SUCCESS) {
|
||||
+ grub_dprintf("bls_bumpcounter", "Cannot get handle to EFI_SIMPLE_FILE_SYSTEM_PROTOCOL: %lu\n", (unsigned long)err);
|
||||
+ return GRUB_ERR_BAD_DEVICE;
|
||||
+ }
|
||||
+ volume->OpenVolume(volume, &root);
|
||||
+ if (err != GRUB_EFI_SUCCESS) {
|
||||
+ grub_dprintf("bls_bumpcounter", "Cannot open the volume: %lu\n", (unsigned long)err);
|
||||
+ return GRUB_ERR_BAD_DEVICE;
|
||||
+ }
|
||||
+
|
||||
+ char *blsdir = (char *)grub_env_get ("blsdir");
|
||||
+ char *tmp = NULL;
|
||||
+ if (blsdir) {
|
||||
+ tmp = blsdir;
|
||||
+ while (*tmp) {
|
||||
+ if (*tmp == '/') {
|
||||
+ /* Replace linux path delimiter (/) with EFI compatible (\) */
|
||||
+ *tmp = '\\';
|
||||
+ }
|
||||
+ tmp++;
|
||||
+ }
|
||||
+ } else {
|
||||
+ blsdir = (char *)GRUB_BLS_CONFIG_PATH;
|
||||
+ }
|
||||
+
|
||||
+ unsigned long int len = grub_strlen(blsdir) + grub_strlen(id) + sizeof(".conf") + 1;
|
||||
+ grub_efi_char16_t* old_path = grub_malloc(len * sizeof(grub_efi_char16_t));
|
||||
+ if (!old_path)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||
+ goto finish;
|
||||
+ }
|
||||
+ grub_efi_char16_t* tmp_path = old_path;
|
||||
+ tmp = blsdir;
|
||||
+ while (*tmp) {
|
||||
+ *tmp_path++ = (grub_efi_char16_t)*tmp++;
|
||||
+ }
|
||||
+ tmp = id;
|
||||
+ while (*tmp) {
|
||||
+ *tmp_path++ = (grub_efi_char16_t)*tmp++;
|
||||
+ }
|
||||
+ static const char* ext = ".conf";
|
||||
+ tmp = (char *)ext;
|
||||
+ while (*tmp) {
|
||||
+ *tmp_path++ = (grub_efi_char16_t)*tmp++;
|
||||
+ }
|
||||
+ *tmp_path = (grub_efi_char16_t)'\0';
|
||||
+
|
||||
+ err = root->Open(root, &handle, old_path, GRUB_EFI_FILE_MODE_READ|GRUB_EFI_FILE_MODE_WRITE, 0);
|
||||
+ grub_free(old_path);
|
||||
+ if (err != GRUB_EFI_SUCCESS) {
|
||||
+ grub_dprintf("bls_bumpcounter", "Cannot open the entry %s%s.conf : %lu\n", blsdir, id, (unsigned long)err);
|
||||
+ goto finish;
|
||||
+ }
|
||||
+
|
||||
+ /* Just like get_file_info works in systemd:src/boot/efi/util.c, get the file_info */
|
||||
+ grub_efi_uint64_t size = offsetof(grub_efi_file_info_t, FileName) + 256U * sizeof(grub_efi_char16_t);
|
||||
+ file_info = grub_malloc(size);
|
||||
+ if (!file_info)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||
+ goto finish;
|
||||
+ }
|
||||
+ grub_guid_t grub_efi_file_info_guid = GRUB_EFI_FILE_INFO_ID;
|
||||
+ err = handle->GetInfo(handle, &grub_efi_file_info_guid, &size, file_info);
|
||||
+ if (err == GRUB_EFI_BUFFER_TOO_SMALL) {
|
||||
+ grub_free(file_info);
|
||||
+ file_info = grub_malloc(size);
|
||||
+ if (!file_info) {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||
+ goto finish;
|
||||
+ }
|
||||
+ err = handle->GetInfo(handle, &grub_efi_file_info_guid, &size, file_info);
|
||||
+ }
|
||||
+
|
||||
+ if (err != GRUB_EFI_SUCCESS) {
|
||||
+ grub_dprintf("bls_bumpcounter", "Cannot get the file_info of the entry: %lu\n", (unsigned long)err);
|
||||
+ goto finish;
|
||||
+ }
|
||||
+
|
||||
+ /* Calculate the new filename with the bumped counter
|
||||
+ Look for the start of the count */
|
||||
+ tmp = grub_strrchr(id, '+');
|
||||
+ *tmp = '\0';
|
||||
+ int tries = -1;
|
||||
+ int tries_left = grub_strtol(++tmp, (const char**) &tmp, 10);
|
||||
+ /* The parsing succeeded */
|
||||
+ if (tmp != NULL) {
|
||||
+ if (tries_left > 0) {
|
||||
+ tries_left--;
|
||||
+ }
|
||||
+ if (*tmp == '-') {
|
||||
+ tmp++;
|
||||
+ tries = grub_strtol(tmp, (const char**) &tmp, 10);
|
||||
+ if (tmp != NULL) {
|
||||
+ tries++;
|
||||
+ } else {
|
||||
+ tries = -1;
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ goto finish;
|
||||
+ }
|
||||
+
|
||||
+ char *new_path;
|
||||
+ if (tries == -1) {
|
||||
+ /* This is the first try, rename accordingly */
|
||||
+ new_path = grub_xasprintf ("%s+%d-1.conf", id, tries_left);
|
||||
+ } else {
|
||||
+ new_path = grub_xasprintf ("%s+%d-%d.conf", id, tries_left, tries);
|
||||
+ }
|
||||
+ grub_dprintf("bls_bumpcounter", "renaming entry to %s\n", new_path);
|
||||
+
|
||||
+ /* Copy the new filename into the file_info struct */
|
||||
+ char* src = new_path;
|
||||
+ grub_efi_char16_t *dst = file_info->FileName;
|
||||
+ while (*src) {
|
||||
+ *dst++ = (grub_efi_char16_t) *src++;
|
||||
+ }
|
||||
+ *dst = (grub_efi_char16_t) '\0';
|
||||
+
|
||||
+ handle->SetInfo(handle, &grub_efi_file_info_guid, size, file_info);
|
||||
+
|
||||
+ if (err != GRUB_EFI_SUCCESS) {
|
||||
+ grub_dprintf("bls_bumpcounter", "Cannot rename file: %lu\n", (unsigned long)err);
|
||||
+ goto finish;
|
||||
+ }
|
||||
+
|
||||
+ handle->Flush(handle);
|
||||
+ grub_dprintf("bls_bumpcounter", "entry renamed\n");
|
||||
+ handle->Close(handle);
|
||||
+
|
||||
+ char* loader_boot_count_path = grub_xasprintf("%s%s", blsdir, new_path);
|
||||
+ grub_free(new_path);
|
||||
+ grub_efi_set_variable_to_string("LoaderBootCountPath", &grub_efi_loader_guid, loader_boot_count_path,
|
||||
+ GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
+ GRUB_EFI_VARIABLE_RUNTIME_ACCESS);
|
||||
+ grub_free(loader_boot_count_path);
|
||||
+
|
||||
+ if (err != GRUB_EFI_SUCCESS) {
|
||||
+ goto finish;
|
||||
+ }
|
||||
+
|
||||
+ grub_free(file_info);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+finish:
|
||||
+ grub_free(file_info);
|
||||
+
|
||||
+ return GRUB_ERR_BAD_DEVICE;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static grub_extcmd_t cmd;
|
||||
+
|
||||
+GRUB_MOD_INIT(blsbumpcounter)
|
||||
+{
|
||||
+ grub_dprintf("bls_bumpcounter", "%s got here\n", __func__);
|
||||
+ cmd = grub_register_extcmd ("bls_bumpcounter",
|
||||
+ grub_cmd_bumpcounters,
|
||||
+ 0,
|
||||
+ NULL,
|
||||
+ N_("Bump the boot entry counting."),
|
||||
+ NULL);
|
||||
+}
|
||||
+
|
||||
+GRUB_MOD_FINI(blsbumpcounter)
|
||||
+{
|
||||
+ grub_unregister_extcmd (cmd);
|
||||
+}
|
31
grub2-bls-boot-show-snapshot.patch
Normal file
31
grub2-bls-boot-show-snapshot.patch
Normal file
@@ -0,0 +1,31 @@
|
||||
Index: grub-2.12/grub-core/commands/blscfg.c
|
||||
===================================================================
|
||||
--- grub-2.12.orig/grub-core/commands/blscfg.c
|
||||
+++ grub-2.12/grub-core/commands/blscfg.c
|
||||
@@ -810,6 +810,7 @@ static void create_entry (struct bls_ent
|
||||
const char **argv = NULL;
|
||||
|
||||
char *title = NULL;
|
||||
+ char *version = NULL;
|
||||
char *clinux = NULL;
|
||||
char *options = NULL;
|
||||
char **initrds = NULL;
|
||||
@@ -853,7 +854,9 @@ static void create_entry (struct bls_ent
|
||||
if (dotconf)
|
||||
dotconf[0] = '\0';
|
||||
|
||||
- title = bls_get_val (entry, "title", NULL);
|
||||
+ title = grub_strdup(bls_get_val (entry, "title", NULL));
|
||||
+ version = bls_get_val (entry, "version", NULL);
|
||||
+ title = version ? grub_xasprintf("%s (%s)", title, version) : title;
|
||||
options = expand_val (bls_get_val (entry, "options", NULL));
|
||||
|
||||
if (!options)
|
||||
@@ -1040,6 +1043,7 @@ finish:
|
||||
grub_free (devicetree);
|
||||
grub_free (initrds);
|
||||
grub_free (options);
|
||||
+ grub_free (title);
|
||||
grub_free (classes);
|
||||
grub_free (args);
|
||||
grub_free (argv);
|
20
grub2-blscfg-fix-hang.patch
Normal file
20
grub2-blscfg-fix-hang.patch
Normal file
@@ -0,0 +1,20 @@
|
||||
Grub2 was hanging due to a infinite loop on incorrect entries.
|
||||
|
||||
Entries that contained the string ".conf" but did not end with it
|
||||
were causing the loop to never exit. Move dotconf pointer up
|
||||
if it doesn't trigger the loop exit condition so that
|
||||
grub_strstr can return a NULL pointer at some point.
|
||||
|
||||
Index: grub-2.12/grub-core/commands/blscfg.c
|
||||
===================================================================
|
||||
--- grub-2.12.orig/grub-core/commands/blscfg.c
|
||||
+++ grub-2.12/grub-core/commands/blscfg.c
|
||||
@@ -850,7 +850,7 @@ static void create_entry (struct bls_ent
|
||||
do
|
||||
{
|
||||
dotconf = grub_strstr(dotconf, ".conf");
|
||||
- } while (dotconf != NULL && dotconf[5] != '\0');
|
||||
+ } while (dotconf != NULL && dotconf[5] != '\0' && *(++dotconf));
|
||||
if (dotconf)
|
||||
dotconf[0] = '\0';
|
||||
|
101
grub2-blscfg-set-efivars.patch
Normal file
101
grub2-blscfg-set-efivars.patch
Normal file
@@ -0,0 +1,101 @@
|
||||
Set the EFI variables LoaderEntries and LoaderEntrySelected to
|
||||
follow systemd-boot implementation and make bootctl work.
|
||||
|
||||
Index: grub-2.12/grub-core/commands/blscfg.c
|
||||
===================================================================
|
||||
--- grub-2.12.orig/grub-core/commands/blscfg.c
|
||||
+++ grub-2.12/grub-core/commands/blscfg.c
|
||||
@@ -47,6 +47,14 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
#define GRUB_BOOT_DEVICE "($root)"
|
||||
#endif
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+#include <grub/efi/efi.h>
|
||||
+#define GRUB_EFI_LOADER_GUID \
|
||||
+ { 0x4a67b082, 0x0a4c, 0x41cf, { 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f } }
|
||||
+
|
||||
+static grub_guid_t grub_efi_loader_guid = GRUB_EFI_LOADER_GUID;
|
||||
+#endif
|
||||
+
|
||||
struct keyval
|
||||
{
|
||||
const char *key;
|
||||
@@ -1223,6 +1231,12 @@ bls_create_entries (bool show_default, b
|
||||
const char *def_entry = NULL;
|
||||
struct bls_entry *entry = NULL;
|
||||
int idx = 0;
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+ int size = 0;
|
||||
+ grub_efi_char16_t *efi_entries = NULL;
|
||||
+ grub_efi_char16_t *p = NULL;
|
||||
+ char* tmp = NULL;
|
||||
+#endif
|
||||
|
||||
def_entry = grub_env_get("default");
|
||||
|
||||
@@ -1238,10 +1252,38 @@ bls_create_entries (bool show_default, b
|
||||
(entry_id && grub_strcmp(entry_id, entry->filename) == 0)) {
|
||||
create_entry(entry);
|
||||
entry->visible = 1;
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+ size += grub_strlen(entry->filename) + 1;
|
||||
+#endif
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+ efi_entries = grub_malloc(size * sizeof(grub_efi_char16_t));
|
||||
+ if (efi_entries == NULL) {
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||||
+ "couldn't find space for LoaderEntries efi variable");
|
||||
+ }
|
||||
+ p = efi_entries;
|
||||
+ FOR_BLS_ENTRIES(entry) {
|
||||
+ if (entry->visible) {
|
||||
+ tmp = entry->filename;
|
||||
+ while (*tmp) {
|
||||
+ *p++ = (grub_efi_char16_t) *tmp++;
|
||||
+ }
|
||||
+ *p++ = (grub_efi_char16_t) '\0';
|
||||
+ }
|
||||
+ }
|
||||
+ if (efi_entries + size + 1 == p) {
|
||||
+ return grub_error(GRUB_ERR_BAD_NUMBER, "efi entries value is not correct");
|
||||
+ }
|
||||
+ grub_efi_set_variable_with_attributes("LoaderEntries", &grub_efi_loader_guid,
|
||||
+ efi_entries, size * sizeof(grub_efi_char16_t),
|
||||
+ GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
+ GRUB_EFI_VARIABLE_RUNTIME_ACCESS);
|
||||
+#endif
|
||||
+
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
Index: grub-2.12/grub-core/commands/efi/blsbumpcounter.c
|
||||
===================================================================
|
||||
--- grub-2.12.orig/grub-core/commands/efi/blsbumpcounter.c
|
||||
+++ grub-2.12/grub-core/commands/efi/blsbumpcounter.c
|
||||
@@ -60,8 +60,14 @@ grub_cmd_bumpcounters (grub_extcmd_conte
|
||||
|
||||
/* Look for the start of the count
|
||||
If no '+' symbol has been found, the boot counting isn't enabled for the selected entry */
|
||||
+ char* new_path = grub_xasprintf ("%s.conf", id);
|
||||
+ grub_efi_set_variable_to_string("LoaderEntrySelected", &grub_efi_loader_guid, new_path,
|
||||
+ GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
+ GRUB_EFI_VARIABLE_RUNTIME_ACCESS);
|
||||
+ grub_free(new_path);
|
||||
if (grub_strrchr(id, '+') == NULL) {
|
||||
grub_dprintf("bls_bumpcounter", "boot counting is not in effect for id %s\n", id);
|
||||
+
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
@@ -183,7 +189,6 @@ grub_cmd_bumpcounters (grub_extcmd_conte
|
||||
goto finish;
|
||||
}
|
||||
|
||||
- char *new_path;
|
||||
if (tries == -1) {
|
||||
/* This is the first try, rename accordingly */
|
||||
new_path = grub_xasprintf ("%s+%d-1.conf", id, tries_left);
|
@@ -61,7 +61,7 @@ snapshot_submenu () {
|
||||
if [ -z "$kernel_ver" -a -L ${snapshot}/boot/image ]; then
|
||||
kernel_ver=`readlink ${snapshot}/boot/image | sed -e 's/^image-//' -e 's/-default$//'`
|
||||
fi
|
||||
eval `cat ${snapshot}/etc/os-release`
|
||||
[ ! -f "${snapshot}/etc/os-release" ] || source "${snapshot}/etc/os-release"
|
||||
# bsc#934252 - Replace SLES 12.1 with SLES12-SP1 for the list of snapshots
|
||||
if test "${NAME}" = "SLES" -o "${NAME}" = "SLED"; then
|
||||
VERSION=`echo ${VERSION} | sed -e 's!^\([0-9]\{1,\}\)\.\([0-9]\{1,\}\)$!\1-SP\2!'`
|
||||
|
@@ -1,3 +1,49 @@
|
||||
-------------------------------------------------------------------
|
||||
Tue May 20 07:00:09 UTC 2025 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Fix product name missing in snapshot list (bsc#1243162)
|
||||
* grub2-snapper-plugin.sh
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue May 20 03:30:52 UTC 2025 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Fix incorrect nvme disks and boot order in bootlist output (bsc#1237174)
|
||||
* 0001-ieee1275-support-added-for-multiple-nvme-bootpaths.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon May 5 12:00:12 UTC 2025 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Fix CVE-2025-4382: TPM auto-decryption data exposure (bsc#1242971)
|
||||
* 0001-kern-rescue_reader-Block-the-rescue-mode-until-the-C.patch
|
||||
* 0002-commands-search-Introduce-the-cryptodisk-only-argume.patch
|
||||
* 0003-disk-diskfilter-Introduce-the-cryptocheck-command.patch
|
||||
* 0004-commands-search-Add-the-diskfilter-support.patch
|
||||
* 0005-docs-Document-available-crypto-disks-checks.patch
|
||||
* 0006-disk-cryptodisk-Add-the-erase-secrets-function.patch
|
||||
* 0007-disk-cryptodisk-Wipe-the-passphrase-from-memory.patch
|
||||
* 0008-cryptocheck-Add-quiet-option.patch
|
||||
- patch rebased
|
||||
* 0001-Improve-TPM-key-protection-on-boot-interruptions.patch
|
||||
* 0004-Key-revocation-on-out-of-bound-file-access.patch
|
||||
- patch refrehed
|
||||
* 0001-Fix-PowerPC-CAS-reboot-to-evaluate-menu-context.patch
|
||||
* 0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Apr 25 17:44:31 UTC 2025 - Andreas Stieger <andreas.stieger@gmx.de>
|
||||
|
||||
- grub2-common: use fuse3
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Apr 23 09:50:10 UTC 2025 - Danilo Spinella <danilo.spinella@suse.com>
|
||||
|
||||
- Add support for boot assessment, needed by health-checker
|
||||
* grub2-bls-boot-counting.patch
|
||||
* grub2-bls-boot-assessment.patch
|
||||
* grub2-bls-boot-show-snapshot.patch
|
||||
* grub2-blscfg-fix-hang.patch
|
||||
* grub2-blscfg-set-efivars.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Apr 23 09:25:57 UTC 2025 - Michael Chang <mchang@suse.com>
|
||||
|
||||
|
23
grub2.spec
23
grub2.spec
@@ -34,9 +34,9 @@ BuildRequires: device-mapper-devel
|
||||
BuildRequires: fdupes
|
||||
BuildRequires: flex
|
||||
BuildRequires: freetype2-devel
|
||||
BuildRequires: fuse-devel
|
||||
BuildRequires: gcc
|
||||
BuildRequires: glibc-devel
|
||||
BuildRequires: pkgconfig(fuse3)
|
||||
%if 0%{?suse_version} >= 1140
|
||||
BuildRequires: dejavu-fonts
|
||||
BuildRequires: gnu-unifont
|
||||
@@ -375,8 +375,6 @@ Patch188: grub2-mkconfig-riscv64.patch
|
||||
Patch189: arm64-Use-proper-memory-type-for-kernel-allocation.patch
|
||||
Patch190: 0001-luks2-Use-grub-tpm2-token-for-TPM2-protected-volume-.patch
|
||||
Patch191: Fix-the-size-calculation-for-the-synthesized-initrd.patch
|
||||
Patch192: 0001-Improve-TPM-key-protection-on-boot-interruptions.patch
|
||||
Patch195: 0004-Key-revocation-on-out-of-bound-file-access.patch
|
||||
# Workaround for 2.12 tarball
|
||||
Patch196: fix_no_extra_deps_in_release_tarball.patch
|
||||
Patch197: 0001-fs-xfs-always-verify-the-total-number-of-entries-is-.patch
|
||||
@@ -466,6 +464,21 @@ Patch292: 0007-util-grub-protect-Support-NV-index-mode.patch
|
||||
Patch293: grub2-string-initializer.patch
|
||||
Patch294: 0001-Fix-PowerPC-CAS-reboot-to-evaluate-menu-context.patch
|
||||
Patch295: 0001-blscfg-read-fragments-in-order.patch
|
||||
Patch296: grub2-bls-boot-counting.patch
|
||||
Patch297: grub2-bls-boot-assessment.patch
|
||||
Patch298: grub2-bls-boot-show-snapshot.patch
|
||||
Patch299: grub2-blscfg-fix-hang.patch
|
||||
Patch300: grub2-blscfg-set-efivars.patch
|
||||
Patch301: 0001-kern-rescue_reader-Block-the-rescue-mode-until-the-C.patch
|
||||
Patch302: 0002-commands-search-Introduce-the-cryptodisk-only-argume.patch
|
||||
Patch303: 0003-disk-diskfilter-Introduce-the-cryptocheck-command.patch
|
||||
Patch304: 0004-commands-search-Add-the-diskfilter-support.patch
|
||||
Patch305: 0005-docs-Document-available-crypto-disks-checks.patch
|
||||
Patch306: 0006-disk-cryptodisk-Add-the-erase-secrets-function.patch
|
||||
Patch307: 0007-disk-cryptodisk-Wipe-the-passphrase-from-memory.patch
|
||||
Patch308: 0008-cryptocheck-Add-quiet-option.patch
|
||||
Patch309: 0001-Improve-TPM-key-protection-on-boot-interruptions.patch
|
||||
Patch310: 0004-Key-revocation-on-out-of-bound-file-access.patch
|
||||
|
||||
%if 0%{?suse_version} < 1600
|
||||
Requires: gettext-runtime
|
||||
@@ -853,7 +866,7 @@ CD_MODULES="all_video boot cat configfile echo true \
|
||||
PXE_MODULES="tftp http"
|
||||
CRYPTO_MODULES="luks luks2 gcry_rijndael gcry_sha1 gcry_sha256 gcry_sha512 crypttab"
|
||||
%ifarch %{efi}
|
||||
CD_MODULES="${CD_MODULES} chain efifwsetup efinet read tpm tss2 tpm2_key_protector memdisk tar squash4 xzio blscfg"
|
||||
CD_MODULES="${CD_MODULES} chain efifwsetup efinet read tpm tss2 tpm2_key_protector memdisk tar squash4 xzio blscfg blsbumpcounter"
|
||||
PXE_MODULES="${PXE_MODULES} efinet"
|
||||
%else
|
||||
CD_MODULES="${CD_MODULES} net ofnet"
|
||||
@@ -959,7 +972,7 @@ mksquashfs ./boot memdisk.sqsh -keep-as-directory -comp xz -quiet -no-progress
|
||||
%{?sbat_generation:--sbat sbat.csv} \
|
||||
-d grub-core \
|
||||
all_video boot font gfxmenu gfxterm gzio halt jpeg minicmd normal part_gpt png reboot video \
|
||||
fat tpm tss2 tpm2_key_protector memdisk tar squash4 xzio blscfg linux bli regexp loadenv test echo true sleep
|
||||
fat tpm tss2 tpm2_key_protector memdisk tar squash4 xzio blscfg blsbumpcounter linux bli regexp loadenv test echo true sleep
|
||||
%endif
|
||||
|
||||
%ifarch x86_64 aarch64
|
||||
|
Reference in New Issue
Block a user