All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Kiper via Grub-devel <grub-devel@gnu.org>
To: grub-devel@gnu.org
Cc: Daniel Kiper <daniel.kiper@oracle.com>,
	dfirblog@gmail.com, eworm@archlinux.org, glin@suse.com,
	mbenatto@redhat.com, mchang@suse.com, meissner@suse.com,
	tpowa@archlinux.org
Subject: [SECURITY PATCH 6/8] disk/cryptodisk: Add the "erase secrets" function
Date: Thu,  8 May 2025 19:02:12 +0200	[thread overview]
Message-ID: <20250508170214.26577-7-daniel.kiper@oracle.com> (raw)
In-Reply-To: <20250508170214.26577-1-daniel.kiper@oracle.com>

From: Maxim Suhanov <dfirblog@gmail.com>

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 48438c2b6..cc4acb27e 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -6788,6 +6788,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
@@ -9406,6 +9411,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 8c5ee3e60..ff4ff021c 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 7a785a49c..544a30d61 100644
--- a/grub-core/disk/cryptodisk.c
+++ b/grub-core/disk/cryptodisk.c
@@ -1856,6 +1856,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 =
@@ -1880,6 +1905,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 5bb15751d..81e631778 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.11.0


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

  parent reply	other threads:[~2025-05-08 17:04 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-08 17:02 [SECURITY PATCH 00/08] GRUB2 vulnerabilities - 2025/05/08 Daniel Kiper via Grub-devel
2025-05-08 17:02 ` [SECURITY PATCH 1/8] kern/rescue_reader: Block the rescue mode until the CLI authentication Daniel Kiper via Grub-devel
2025-05-08 17:02 ` [SECURITY PATCH 2/8] commands/search: Introduce the --cryptodisk-only argument Daniel Kiper via Grub-devel
2025-05-09 12:47   ` Vladimir 'phcoder' Serbinenko
2025-05-08 17:02 ` [SECURITY PATCH 3/8] disk/diskfilter: Introduce the "cryptocheck" command Daniel Kiper via Grub-devel
2025-05-09 12:44   ` Vladimir 'phcoder' Serbinenko
2025-05-08 17:02 ` [SECURITY PATCH 4/8] commands/search: Add the diskfilter support Daniel Kiper via Grub-devel
2025-05-09 12:41   ` Vladimir 'phcoder' Serbinenko
2025-05-08 17:02 ` [SECURITY PATCH 5/8] docs: Document available crypto disks checks Daniel Kiper via Grub-devel
2025-05-08 17:02 ` Daniel Kiper via Grub-devel [this message]
2025-05-09 12:37   ` [SECURITY PATCH 6/8] disk/cryptodisk: Add the "erase secrets" function Vladimir 'phcoder' Serbinenko
2025-05-08 17:02 ` [SECURITY PATCH 7/8] disk/cryptodisk: Wipe the passphrase from memory Daniel Kiper via Grub-devel
2025-05-09 12:34   ` Vladimir 'phcoder' Serbinenko
2025-05-08 17:02 ` [SECURITY PATCH 8/8] cryptocheck: Add --quiet option Daniel Kiper via Grub-devel
2025-05-09 12:33   ` Vladimir 'phcoder' Serbinenko
2025-05-09  7:47 ` [SECURITY PATCH 00/08] GRUB2 vulnerabilities - 2025/05/08 Christian Hesse
2025-05-09 11:06   ` Daniel Kiper via Grub-devel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250508170214.26577-7-daniel.kiper@oracle.com \
    --to=grub-devel@gnu.org \
    --cc=daniel.kiper@oracle.com \
    --cc=dfirblog@gmail.com \
    --cc=eworm@archlinux.org \
    --cc=glin@suse.com \
    --cc=mbenatto@redhat.com \
    --cc=mchang@suse.com \
    --cc=meissner@suse.com \
    --cc=tpowa@archlinux.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.