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