Le jeu. 8 mai 2025, 20:04, Daniel Kiper via Grub-devel <grub-devel@gnu.org>
a écrit :

> From: Maxim Suhanov <dfirb...@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.
>
That is wrong. We need to unmount it and any further attempt to read from
given disk should return "no such disk".

>
> 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 <dfirb...@gmail.com>
> Reviewed-by: Daniel Kiper <daniel.ki...@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
>
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to