Sync from SUSE:SLFO:Main grub2 revision 22210e8b4d1d1dbd09b665cf3004c663

This commit is contained in:
2025-05-28 11:32:43 +02:00
parent 51ed351d80
commit c60ef609ce
21 changed files with 1852 additions and 217 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View 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

View 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

View File

@@ -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

View 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

View 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

View 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

View 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

View 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

View 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)
{

View 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);
+}

View 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);

View 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';

View 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);

View File

@@ -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!'`

View File

@@ -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>

View File

@@ -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