diff --git a/backport-0001-cryptodisk-Refactor-to-discard-have_it-global.patch b/backport-0001-cryptodisk-Refactor-to-discard-have_it-global.patch new file mode 100644 index 0000000000000000000000000000000000000000..7bff27086e9df72c042bf78f05830302cf078ff2 --- /dev/null +++ b/backport-0001-cryptodisk-Refactor-to-discard-have_it-global.patch @@ -0,0 +1,187 @@ +From 450a423b1074d0f0f4909038cb40b54ac95cd241 Mon Sep 17 00:00:00 2001 +From: Glenn Washburn +Date: Thu, 9 Dec 2021 11:14:51 -0600 +Subject: [PATCH 01/30] cryptodisk: Refactor to discard have_it global + +The global "have_it" was never used by the crypto-backends, but was used to +determine if a crypto-backend successfully mounted a cryptodisk with a given +UUID. This is not needed however, because grub_device_iterate() will return +1 if and only if grub_cryptodisk_scan_device() returns 1. And +grub_cryptodisk_scan_device() will now only return 1 if a search_uuid has +been specified and a cryptodisk was successfully setup by a crypto-backend or +a cryptodisk of the requested UUID is already open. + +To implement this grub_cryptodisk_scan_device_real() is modified to return +a cryptodisk or NULL on failure and having the appropriate grub_errno set to +indicated failure. Note that grub_cryptodisk_scan_device_real() will fail now +with a new errno GRUB_ERR_BAD_MODULE when none of the cryptodisk backend +modules succeed in identifying the source disk. + +With this change grub_device_iterate() will return 1 when a crypto device is +successfully decrypted or when the source device has already been successfully +opened. Prior to this change, trying to mount an already successfully opened +device would trigger an error with the message "no such cryptodisk found", +which is at best misleading. The mount should silently succeed in this case, +which is what happens with this patch. + +Signed-off-by: Glenn Washburn +Reviewed-by: Daniel Kiper +--- + grub-core/disk/cryptodisk.c | 56 +++++++++++++++++++++++-------------- + 1 file changed, 35 insertions(+), 21 deletions(-) + +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index 6883f48..66f5e8c 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -807,7 +807,7 @@ grub_util_cryptodisk_get_uuid (grub_disk_t disk) + + #endif + +-static int check_boot, have_it; ++static int check_boot; + static char *search_uuid; + + static void +@@ -819,7 +819,7 @@ cryptodisk_close (grub_cryptodisk_t dev) + grub_free (dev); + } + +-static grub_err_t ++static grub_cryptodisk_t + grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source) + { + grub_err_t err; +@@ -829,13 +829,13 @@ grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source) + dev = grub_cryptodisk_get_by_source_disk (source); + + if (dev) +- return GRUB_ERR_NONE; ++ return dev; + + FOR_CRYPTODISK_DEVS (cr) + { + dev = cr->scan (source, search_uuid, check_boot); + if (grub_errno) +- return grub_errno; ++ return NULL; + if (!dev) + continue; + +@@ -843,16 +843,16 @@ grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source) + if (err) + { + cryptodisk_close (dev); +- return err; ++ return NULL; + } + + grub_cryptodisk_insert (dev, name, source); + +- have_it = 1; +- +- return GRUB_ERR_NONE; ++ return dev; + } +- return GRUB_ERR_NONE; ++ ++ grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk module can handle this device"); ++ return NULL; + } + + #ifdef GRUB_UTIL +@@ -906,8 +906,10 @@ static int + grub_cryptodisk_scan_device (const char *name, + void *data __attribute__ ((unused))) + { +- grub_err_t err; ++ int ret = 0; + grub_disk_t source; ++ grub_cryptodisk_t dev; ++ grub_errno = GRUB_ERR_NONE; + + /* Try to open disk. */ + source = grub_disk_open (name); +@@ -917,13 +919,26 @@ grub_cryptodisk_scan_device (const char *name, + return 0; + } + +- err = grub_cryptodisk_scan_device_real (name, source); ++ dev = grub_cryptodisk_scan_device_real (name, source); ++ if (dev) ++ { ++ ret = (search_uuid != NULL && grub_strcasecmp (search_uuid, dev->uuid) == 0); ++ goto cleanup; ++ } + +- grub_disk_close (source); +- +- if (err) ++ /* ++ * Do not print error when err is GRUB_ERR_BAD_MODULE to avoid many unhelpful ++ * error messages. ++ */ ++ if (grub_errno == GRUB_ERR_BAD_MODULE) ++ grub_error_pop (); ++ ++ if (grub_errno != GRUB_ERR_NONE) + grub_print_error (); +- return have_it && search_uuid ? 1 : 0; ++ ++ cleanup: ++ grub_disk_close (source); ++ return ret; + } + + static grub_err_t +@@ -934,9 +949,9 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) + if (argc < 1 && !state[1].set && !state[2].set) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); + +- have_it = 0; + if (state[0].set) + { ++ int found_uuid; + grub_cryptodisk_t dev; + + dev = grub_cryptodisk_get_by_uuid (args[0]); +@@ -949,10 +964,10 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) + + check_boot = state[2].set; + search_uuid = args[0]; +- grub_device_iterate (&grub_cryptodisk_scan_device, NULL); ++ found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, NULL); + search_uuid = NULL; + +- if (!have_it) ++ if (!found_uuid) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found"); + return GRUB_ERR_NONE; + } +@@ -966,7 +981,6 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) + } + else + { +- grub_err_t err; + grub_disk_t disk; + grub_cryptodisk_t dev; + char *diskname; +@@ -1002,13 +1016,13 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) + return GRUB_ERR_NONE; + } + +- err = grub_cryptodisk_scan_device_real (diskname, disk); ++ dev = grub_cryptodisk_scan_device_real (diskname, disk); + + grub_disk_close (disk); + if (disklast) + *disklast = ')'; + +- return err; ++ return (dev == NULL) ? grub_errno : GRUB_ERR_NONE; + } + } + +-- +2.33.0 + diff --git a/backport-0002-cryptodisk-Return-failure-in-cryptomount-when-no-cry.patch b/backport-0002-cryptodisk-Return-failure-in-cryptomount-when-no-cry.patch new file mode 100644 index 0000000000000000000000000000000000000000..fd17a4b7d5a25b62b3557b960362a8491b811225 --- /dev/null +++ b/backport-0002-cryptodisk-Return-failure-in-cryptomount-when-no-cry.patch @@ -0,0 +1,32 @@ +From 542b8e8cb389ab411f8b5044fd3e8bcffc22d2f9 Mon Sep 17 00:00:00 2001 +From: Glenn Washburn +Date: Thu, 9 Dec 2021 11:14:52 -0600 +Subject: [PATCH 02/30] cryptodisk: Return failure in cryptomount when no + cryptodisk modules are loaded + +This displays an error notifying the user that they'll want to load +a backend module to make cryptomount useful. + +Signed-off-by: Glenn Washburn +Reviewed-by: Daniel Kiper +--- + grub-core/disk/cryptodisk.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index 66f5e8c..ea68794 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -949,6 +949,9 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) + if (argc < 1 && !state[1].set && !state[2].set) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); + ++ if (grub_cryptodisk_list == NULL) ++ return grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk modules loaded"); ++ + if (state[0].set) + { + int found_uuid; +-- +2.33.0 + diff --git a/backport-0003-cryptodisk-Improve-error-messaging-in-cryptomount-in.patch b/backport-0003-cryptodisk-Improve-error-messaging-in-cryptomount-in.patch new file mode 100644 index 0000000000000000000000000000000000000000..a86d6b2cedd8dbf9418bde7ee392ba8e6ad383db --- /dev/null +++ b/backport-0003-cryptodisk-Improve-error-messaging-in-cryptomount-in.patch @@ -0,0 +1,58 @@ +From 9f5be9d4e5a7192e498e5b8e9a3ed1f64c065e63 Mon Sep 17 00:00:00 2001 +From: Glenn Washburn +Date: Thu, 9 Dec 2021 11:14:53 -0600 +Subject: [PATCH 03/30] cryptodisk: Improve error messaging in cryptomount + invocations + +Update such that "cryptomount -u UUID" will not print two error messages +when an invalid passphrase is given and the most relevant error message +will be displayed. + +Signed-off-by: Glenn Washburn +Reviewed-by: Daniel Kiper +--- + grub-core/disk/cryptodisk.c | 21 +++++++++++++++++---- + 1 file changed, 17 insertions(+), 4 deletions(-) + +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index ea68794..770f51e 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -933,7 +933,10 @@ grub_cryptodisk_scan_device (const char *name, + if (grub_errno == GRUB_ERR_BAD_MODULE) + grub_error_pop (); + +- if (grub_errno != GRUB_ERR_NONE) ++ if (search_uuid != NULL) ++ /* Push error onto stack to save for cryptomount. */ ++ grub_error_push (); ++ else + grub_print_error (); + + cleanup: +@@ -970,9 +973,19 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) + found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, NULL); + search_uuid = NULL; + +- if (!found_uuid) +- return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found"); +- return GRUB_ERR_NONE; ++ if (found_uuid) ++ return GRUB_ERR_NONE; ++ else if (grub_errno == GRUB_ERR_NONE) ++ { ++ /* ++ * Try to pop the next error on the stack. If there is not one, then ++ * no device matched the given UUID. ++ */ ++ grub_error_pop (); ++ if (grub_errno == GRUB_ERR_NONE) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found"); ++ } ++ return grub_errno; + } + else if (state[1].set || (argc == 0 && state[2].set)) + { +-- +2.33.0 + diff --git a/backport-0004-cryptodisk-Improve-cryptomount-u-error-message.patch b/backport-0004-cryptodisk-Improve-cryptomount-u-error-message.patch new file mode 100644 index 0000000000000000000000000000000000000000..967b12ac951613e41134c1002f0854d946d2b19e --- /dev/null +++ b/backport-0004-cryptodisk-Improve-cryptomount-u-error-message.patch @@ -0,0 +1,31 @@ +From e499cd344a68a1e3491492f0b0ac17a4e9c21eaf Mon Sep 17 00:00:00 2001 +From: Glenn Washburn +Date: Thu, 9 Dec 2021 11:14:54 -0600 +Subject: [PATCH 04/30] cryptodisk: Improve cryptomount -u error message + +When a cryptmount is specified with a UUID, but no cryptodisk backends find +a disk with that UUID, return a more detailed message giving telling the +user that they might not have a needed cryptobackend module loaded. + +Signed-off-by: Glenn Washburn +Reviewed-by: Daniel Kiper +--- + grub-core/disk/cryptodisk.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index 770f51e..8dd0817 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -983,7 +983,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) + */ + grub_error_pop (); + if (grub_errno == GRUB_ERR_NONE) +- return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found"); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found, perhaps a needed disk or cryptodisk module is not loaded"); + } + return grub_errno; + } +-- +2.33.0 + diff --git a/backport-0005-cryptodisk-Add-infrastructure-to-pass-data-from-cryp.patch b/backport-0005-cryptodisk-Add-infrastructure-to-pass-data-from-cryp.patch new file mode 100644 index 0000000000000000000000000000000000000000..acb98334318e2bb10c51abf95aa89ea4ca79332e --- /dev/null +++ b/backport-0005-cryptodisk-Add-infrastructure-to-pass-data-from-cryp.patch @@ -0,0 +1,226 @@ +From 1fc707bb9d86981efbb54d71bc0016a11fa61c42 Mon Sep 17 00:00:00 2001 +From: Glenn Washburn +Date: Thu, 9 Dec 2021 11:14:55 -0600 +Subject: [PATCH 05/30] cryptodisk: Add infrastructure to pass data from + cryptomount to cryptodisk modules + +Previously, the cryptomount arguments were passed by global variable and +function call argument, neither of which are ideal. This change passes data +via a grub_cryptomount_args struct, which can be added to over time as +opposed to continually adding arguments to the cryptodisk scan and +recover_key. + +As an example, passing a password as a cryptomount argument is implemented. +However, the backends are not implemented, so testing this will return a not +implemented error. + +Also, add comments to cryptomount argument parsing to make it more obvious +which argument states are being handled. + +Signed-off-by: Glenn Washburn +Reviewed-by: Daniel Kiper +--- + grub-core/disk/cryptodisk.c | 31 +++++++++++++++++++++---------- + grub-core/disk/geli.c | 6 +++++- + grub-core/disk/luks.c | 7 ++++++- + include/grub/cryptodisk.h | 9 ++++++++- + 4 files changed, 40 insertions(+), 13 deletions(-) + +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index 8dd0817..f01b027 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -41,6 +41,7 @@ static const struct grub_arg_option options[] = + /* TRANSLATORS: It's still restricted to cryptodisks only. */ + {"all", 'a', 0, N_("Mount all."), 0, 0}, + {"boot", 'b', 0, N_("Mount all volumes with `boot' flag set."), 0, 0}, ++ {"password", 'p', 0, N_("Password to open volumes."), 0, ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} + }; + +@@ -820,7 +821,9 @@ cryptodisk_close (grub_cryptodisk_t dev) + } + + static grub_cryptodisk_t +-grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source) ++grub_cryptodisk_scan_device_real (const char *name, ++ grub_disk_t source, ++ grub_cryptomount_args_t cargs) + { + grub_err_t err; + grub_cryptodisk_t dev; +@@ -839,7 +842,7 @@ grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source) + if (!dev) + continue; + +- err = cr->recover_key (source, dev); ++ err = cr->recover_key (source, dev, cargs); + if (err) + { + cryptodisk_close (dev); +@@ -904,11 +907,12 @@ grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat) + + static int + grub_cryptodisk_scan_device (const char *name, +- void *data __attribute__ ((unused))) ++ void *data) + { + int ret = 0; + grub_disk_t source; + grub_cryptodisk_t dev; ++ grub_cryptomount_args_t cargs = data; + grub_errno = GRUB_ERR_NONE; + + /* Try to open disk. */ +@@ -919,7 +923,7 @@ grub_cryptodisk_scan_device (const char *name, + return 0; + } + +- dev = grub_cryptodisk_scan_device_real (name, source); ++ dev = grub_cryptodisk_scan_device_real (name, source, cargs); + if (dev) + { + ret = (search_uuid != NULL && grub_strcasecmp (search_uuid, dev->uuid) == 0); +@@ -948,6 +952,7 @@ static grub_err_t + grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) + { + struct grub_arg_list *state = ctxt->state; ++ struct grub_cryptomount_args cargs = {0}; + + if (argc < 1 && !state[1].set && !state[2].set) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); +@@ -955,7 +960,13 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) + if (grub_cryptodisk_list == NULL) + return grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk modules loaded"); + +- if (state[0].set) ++ if (state[3].set) /* password */ ++ { ++ cargs.key_data = (grub_uint8_t *) state[3].arg; ++ cargs.key_len = grub_strlen (state[3].arg); ++ } ++ ++ if (state[0].set) /* uuid */ + { + int found_uuid; + grub_cryptodisk_t dev; +@@ -970,7 +981,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) + + check_boot = state[2].set; + search_uuid = args[0]; +- found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, NULL); ++ found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, &cargs); + search_uuid = NULL; + + if (found_uuid) +@@ -987,11 +998,11 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) + } + return grub_errno; + } +- else if (state[1].set || (argc == 0 && state[2].set)) ++ else if (state[1].set || (argc == 0 && state[2].set)) /* -a|-b */ + { + search_uuid = NULL; + check_boot = state[2].set; +- grub_device_iterate (&grub_cryptodisk_scan_device, NULL); ++ grub_device_iterate (&grub_cryptodisk_scan_device, &cargs); + search_uuid = NULL; + return GRUB_ERR_NONE; + } +@@ -1032,7 +1043,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) + return GRUB_ERR_NONE; + } + +- dev = grub_cryptodisk_scan_device_real (diskname, disk); ++ dev = grub_cryptodisk_scan_device_real (diskname, disk, &cargs); + + grub_disk_close (disk); + if (disklast) +@@ -1171,7 +1182,7 @@ GRUB_MOD_INIT (cryptodisk) + { + grub_disk_dev_register (&grub_cryptodisk_dev); + cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0, +- N_("SOURCE|-u UUID|-a|-b"), ++ N_("[-p password] "), + N_("Mount a crypto device."), options); + grub_procfs_register ("luks_script", &luks_script); + } +diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c +index e9d2329..48d9be9 100644 +--- a/grub-core/disk/geli.c ++++ b/grub-core/disk/geli.c +@@ -398,7 +398,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, + } + + static grub_err_t +-recover_key (grub_disk_t source, grub_cryptodisk_t dev) ++recover_key (grub_disk_t source, grub_cryptodisk_t dev, grub_cryptomount_args_t cargs) + { + grub_size_t keysize; + grub_uint8_t digest[GRUB_CRYPTO_MAX_MDLEN]; +@@ -414,6 +414,10 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev) + grub_disk_addr_t sector; + grub_err_t err; + ++ /* Keyfiles are not implemented yet */ ++ if (cargs->key_data != NULL || cargs->key_len) ++ return GRUB_ERR_NOT_IMPLEMENTED_YET; ++ + if (dev->cipher->cipher->blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE) + return grub_error (GRUB_ERR_BUG, "cipher block is too long"); + +diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c +index 18b3a8b..86bf951 100644 +--- a/grub-core/disk/luks.c ++++ b/grub-core/disk/luks.c +@@ -309,7 +309,8 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, + + static grub_err_t + luks_recover_key (grub_disk_t source, +- grub_cryptodisk_t dev) ++ grub_cryptodisk_t dev, ++ grub_cryptomount_args_t cargs) + { + struct grub_luks_phdr header; + grub_size_t keysize; +@@ -322,6 +323,10 @@ luks_recover_key (grub_disk_t source, + grub_size_t max_stripes = 1; + char *tmp; + ++ /* Keyfiles are not implemented yet */ ++ if (cargs->key_data != NULL || cargs->key_len) ++ return GRUB_ERR_NOT_IMPLEMENTED_YET; ++ + err = grub_disk_read (source, 0, 0, sizeof (header), &header); + if (err) + return err; +diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h +index 32f564a..a41b426 100644 +--- a/include/grub/cryptodisk.h ++++ b/include/grub/cryptodisk.h +@@ -60,6 +60,13 @@ typedef gcry_err_code_t + (*grub_cryptodisk_rekey_func_t) (struct grub_cryptodisk *dev, + grub_uint64_t zoneno); + ++struct grub_cryptomount_args ++{ ++ grub_uint8_t *key_data; ++ grub_size_t key_len; ++}; ++typedef struct grub_cryptomount_args *grub_cryptomount_args_t; ++ + struct grub_cryptodisk + { + struct grub_cryptodisk *next; +@@ -108,7 +115,7 @@ struct grub_cryptodisk_dev + + grub_cryptodisk_t (*scan) (grub_disk_t disk, const char *check_uuid, + int boot_only); +- grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev); ++ grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev, grub_cryptomount_args_t cargs); + }; + typedef struct grub_cryptodisk_dev *grub_cryptodisk_dev_t; + +-- +2.33.0 + diff --git a/backport-0006-cryptodisk-Refactor-password-input-out-of-crypto-dev.patch b/backport-0006-cryptodisk-Refactor-password-input-out-of-crypto-dev.patch new file mode 100644 index 0000000000000000000000000000000000000000..60ba6eca40ae26651fa09598abe5a9bb55afefe8 --- /dev/null +++ b/backport-0006-cryptodisk-Refactor-password-input-out-of-crypto-dev.patch @@ -0,0 +1,270 @@ +From 964793a17bfecdb4bfa1e766e6880337c02dcd2c Mon Sep 17 00:00:00 2001 +From: Glenn Washburn +Date: Thu, 9 Dec 2021 11:14:56 -0600 +Subject: [PATCH 06/30] cryptodisk: Refactor password input out of crypto dev + modules into cryptodisk + +The crypto device modules should only be setting up the crypto devices and +not getting user input. This has the added benefit of simplifying the code +such that three essentially duplicate pieces of code are merged into one. + +Add documentation of passphrase option for cryptomount as it is now usable. + +Signed-off-by: Glenn Washburn +Reviewed-by: Daniel Kiper +--- + docs/grub.texi | 8 ++++-- + grub-core/disk/cryptodisk.c | 56 +++++++++++++++++++++++++++++-------- + grub-core/disk/geli.c | 26 ++++------------- + grub-core/disk/luks.c | 27 +++--------------- + include/grub/cryptodisk.h | 1 + + 5 files changed, 60 insertions(+), 58 deletions(-) + +diff --git a/docs/grub.texi b/docs/grub.texi +index 2b12b2c..44fd6dc 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -4253,9 +4253,11 @@ Alias for @code{hashsum --hash crc32 arg @dots{}}. See command @command{hashsum} + @node cryptomount + @subsection cryptomount + +-@deffn Command cryptomount device|@option{-u} uuid|@option{-a}|@option{-b} +-Setup access to encrypted device. If necessary, passphrase +-is requested interactively. Option @var{device} configures specific grub device ++@deffn Command cryptomount [@option{-p} password] device|@option{-u} uuid|@option{-a}|@option{-b} ++Setup access to encrypted device. If @option{-p} is not given, a passphrase ++is requested interactively. Otherwise, the given @var{password} will be used and ++no passphrase will be requested interactively. ++Option @var{device} configures specific grub device + (@pxref{Naming convention}); option @option{-u} @var{uuid} configures device + with specified @var{uuid}; option @option{-a} configures all detected encrypted + devices; option @option{-b} configures all geli containers that have boot flag set. +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index f01b027..3b2ded1 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -825,9 +825,11 @@ grub_cryptodisk_scan_device_real (const char *name, + grub_disk_t source, + grub_cryptomount_args_t cargs) + { +- grub_err_t err; ++ grub_err_t ret = GRUB_ERR_NONE; + grub_cryptodisk_t dev; + grub_cryptodisk_dev_t cr; ++ int askpass = 0; ++ char *part = NULL; + + dev = grub_cryptodisk_get_by_source_disk (source); + +@@ -841,21 +843,53 @@ grub_cryptodisk_scan_device_real (const char *name, + return NULL; + if (!dev) + continue; +- +- err = cr->recover_key (source, dev, cargs); +- if (err) +- { +- cryptodisk_close (dev); +- return NULL; +- } ++ ++ if (!cargs->key_len) ++ { ++ /* Get the passphrase from the user, if no key data. */ ++ askpass = 1; ++ if (source->partition != NULL) ++ part = grub_partition_get_name (source->partition); ++ grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, ++ source->partition != NULL ? "," : "", ++ part != NULL ? part : "", ++ dev->uuid); ++ grub_free (part); ++ ++ cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE); ++ if (cargs->key_data == NULL) ++ return NULL; ++ ++ if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE)) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied"); ++ goto error; ++ } ++ cargs->key_len = grub_strlen ((char *) cargs->key_data); ++ } ++ ++ ret = cr->recover_key (source, dev, cargs); ++ if (ret != GRUB_ERR_NONE) ++ goto error; + + grub_cryptodisk_insert (dev, name, source); + +- return dev; ++ goto cleanup; + } +- + grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk module can handle this device"); +- return NULL; ++ goto cleanup; ++ ++ error: ++ cryptodisk_close (dev); ++ dev = NULL; ++ ++ cleanup: ++ if (askpass) ++ { ++ cargs->key_len = 0; ++ grub_free (cargs->key_data); ++ } ++ return dev; + } + + #ifdef GRUB_UTIL +diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c +index 48d9be9..248c42a 100644 +--- a/grub-core/disk/geli.c ++++ b/grub-core/disk/geli.c +@@ -135,8 +135,6 @@ const char *algorithms[] = { + [0x16] = "aes" + }; + +-#define MAX_PASSPHRASE 256 +- + static gcry_err_code_t + geli_rekey (struct grub_cryptodisk *dev, grub_uint64_t zoneno) + { +@@ -406,17 +404,14 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev, grub_cryptomount_args_t + grub_uint8_t verify_key[GRUB_CRYPTO_MAX_MDLEN]; + grub_uint8_t zero[GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE]; + grub_uint8_t geli_cipher_key[64]; +- char passphrase[MAX_PASSPHRASE] = ""; + unsigned i; + gcry_err_code_t gcry_err; + struct grub_geli_phdr header; +- char *tmp; + grub_disk_addr_t sector; + grub_err_t err; + +- /* Keyfiles are not implemented yet */ +- if (cargs->key_data != NULL || cargs->key_len) +- return GRUB_ERR_NOT_IMPLEMENTED_YET; ++ if (cargs->key_data == NULL || cargs->key_len == 0) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "no key data"); + + if (dev->cipher->cipher->blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE) + return grub_error (GRUB_ERR_BUG, "cipher block is too long"); +@@ -438,23 +433,12 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev, grub_cryptomount_args_t + + grub_puts_ (N_("Attempting to decrypt master key...")); + +- /* Get the passphrase from the user. */ +- tmp = NULL; +- if (source->partition) +- tmp = grub_partition_get_name (source->partition); +- grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, +- source->partition ? "," : "", tmp ? : "", +- dev->uuid); +- grub_free (tmp); +- if (!grub_password_get (passphrase, MAX_PASSPHRASE)) +- return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); +- + /* Calculate the PBKDF2 of the user supplied passphrase. */ + if (grub_le_to_cpu32 (header.niter) != 0) + { + grub_uint8_t pbkdf_key[64]; +- gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase, +- grub_strlen (passphrase), ++ gcry_err = grub_crypto_pbkdf2 (dev->hash, cargs->key_data, ++ cargs->key_len, + header.salt, + sizeof (header.salt), + grub_le_to_cpu32 (header.niter), +@@ -477,7 +461,7 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev, grub_cryptomount_args_t + return grub_crypto_gcry_error (GPG_ERR_OUT_OF_MEMORY); + + grub_crypto_hmac_write (hnd, header.salt, sizeof (header.salt)); +- grub_crypto_hmac_write (hnd, passphrase, grub_strlen (passphrase)); ++ grub_crypto_hmac_write (hnd, cargs->key_data, cargs->key_len); + + gcry_err = grub_crypto_hmac_fini (hnd, geomkey); + if (gcry_err) +diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c +index 86bf951..8b39f52 100644 +--- a/grub-core/disk/luks.c ++++ b/grub-core/disk/luks.c +@@ -29,8 +29,6 @@ + + GRUB_MOD_LICENSE ("GPLv3+"); + +-#define MAX_PASSPHRASE 256 +- + #define LUKS_KEY_ENABLED 0x00AC71F3 + + /* On disk LUKS header */ +@@ -315,17 +313,14 @@ luks_recover_key (grub_disk_t source, + struct grub_luks_phdr header; + grub_size_t keysize; + grub_uint8_t *split_key = NULL; +- char passphrase[MAX_PASSPHRASE] = ""; + grub_uint8_t candidate_digest[sizeof (header.mkDigest)]; + unsigned i; + grub_size_t length; + grub_err_t err; + grub_size_t max_stripes = 1; +- char *tmp; + +- /* Keyfiles are not implemented yet */ +- if (cargs->key_data != NULL || cargs->key_len) +- return GRUB_ERR_NOT_IMPLEMENTED_YET; ++ if (cargs->key_data == NULL || cargs->key_len == 0) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "no key data"); + + err = grub_disk_read (source, 0, 0, sizeof (header), &header); + if (err) +@@ -345,20 +340,6 @@ luks_recover_key (grub_disk_t source, + if (!split_key) + return grub_errno; + +- /* Get the passphrase from the user. */ +- tmp = NULL; +- if (source->partition) +- tmp = grub_partition_get_name (source->partition); +- grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, +- source->partition ? "," : "", tmp ? : "", +- dev->uuid); +- grub_free (tmp); +- if (!grub_password_get (passphrase, MAX_PASSPHRASE)) +- { +- grub_free (split_key); +- return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); +- } +- + /* Try to recover master key from each active keyslot. */ + for (i = 0; i < ARRAY_SIZE (header.keyblock); i++) + { +@@ -373,8 +354,8 @@ luks_recover_key (grub_disk_t source, + grub_dprintf ("luks", "Trying keyslot %d\n", i); + + /* Calculate the PBKDF2 of the user supplied passphrase. */ +- gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase, +- grub_strlen (passphrase), ++ gcry_err = grub_crypto_pbkdf2 (dev->hash, cargs->key_data, ++ cargs->key_len, + header.keyblock[i].passwordSalt, + sizeof (header.keyblock[i].passwordSalt), + grub_be_to_cpu32 (header.keyblock[i]. +diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h +index a41b426..55d5c26 100644 +--- a/include/grub/cryptodisk.h ++++ b/include/grub/cryptodisk.h +@@ -53,6 +53,7 @@ typedef enum + #define GRUB_CRYPTODISK_GF_LOG_BYTES (GRUB_CRYPTODISK_GF_LOG_SIZE - 3) + #define GRUB_CRYPTODISK_GF_BYTES (1U << GRUB_CRYPTODISK_GF_LOG_BYTES) + #define GRUB_CRYPTODISK_MAX_KEYLEN 128 ++#define GRUB_CRYPTODISK_MAX_PASSPHRASE 256 + + struct grub_cryptodisk; + +-- +2.33.0 + diff --git a/backport-0007-cryptodisk-Move-global-variables-into-grub_cryptomou.patch b/backport-0007-cryptodisk-Move-global-variables-into-grub_cryptomou.patch new file mode 100644 index 0000000000000000000000000000000000000000..b50322263d0b1240ec6a2e8382e8dde5b7af6fbe --- /dev/null +++ b/backport-0007-cryptodisk-Move-global-variables-into-grub_cryptomou.patch @@ -0,0 +1,214 @@ +From 4fcf56249bd68eeb0ba2ad722dcfded0045de688 Mon Sep 17 00:00:00 2001 +From: Glenn Washburn +Date: Thu, 9 Dec 2021 11:14:57 -0600 +Subject: [PATCH 07/30] cryptodisk: Move global variables into + grub_cryptomount_args struct + +Note that cargs.search_uuid does not need to be initialized in various parts +of the cryptomount argument parsing, just once when cargs is declared with +a struct initializer. The previous code used a global variable which would +retain the value across cryptomount invocations. + +Signed-off-by: Glenn Washburn +Reviewed-by: Daniel Kiper +--- + grub-core/disk/cryptodisk.c | 24 +++++++++--------------- + grub-core/disk/geli.c | 9 ++++----- + grub-core/disk/luks.c | 9 ++++----- + include/grub/cryptodisk.h | 9 +++++++-- + 4 files changed, 24 insertions(+), 27 deletions(-) + +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index 3b2ded1..6613b27 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -808,9 +808,6 @@ grub_util_cryptodisk_get_uuid (grub_disk_t disk) + + #endif + +-static int check_boot; +-static char *search_uuid; +- + static void + cryptodisk_close (grub_cryptodisk_t dev) + { +@@ -838,7 +835,7 @@ grub_cryptodisk_scan_device_real (const char *name, + + FOR_CRYPTODISK_DEVS (cr) + { +- dev = cr->scan (source, search_uuid, check_boot); ++ dev = cr->scan (source, cargs); + if (grub_errno) + return NULL; + if (!dev) +@@ -901,6 +898,7 @@ grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat) + grub_cryptodisk_t dev; + grub_cryptodisk_dev_t cr; + grub_disk_t source; ++ struct grub_cryptomount_args cargs = {0}; + + /* Try to open disk. */ + source = grub_disk_open (sourcedev); +@@ -917,7 +915,7 @@ grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat) + + FOR_CRYPTODISK_DEVS (cr) + { +- dev = cr->scan (source, search_uuid, check_boot); ++ dev = cr->scan (source, &cargs); + if (grub_errno) + return grub_errno; + if (!dev) +@@ -960,7 +958,7 @@ grub_cryptodisk_scan_device (const char *name, + dev = grub_cryptodisk_scan_device_real (name, source, cargs); + if (dev) + { +- ret = (search_uuid != NULL && grub_strcasecmp (search_uuid, dev->uuid) == 0); ++ ret = (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, dev->uuid) == 0); + goto cleanup; + } + +@@ -971,7 +969,7 @@ grub_cryptodisk_scan_device (const char *name, + if (grub_errno == GRUB_ERR_BAD_MODULE) + grub_error_pop (); + +- if (search_uuid != NULL) ++ if (cargs->search_uuid != NULL) + /* Push error onto stack to save for cryptomount. */ + grub_error_push (); + else +@@ -1013,10 +1011,9 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) + return GRUB_ERR_NONE; + } + +- check_boot = state[2].set; +- search_uuid = args[0]; ++ cargs.check_boot = state[2].set; ++ cargs.search_uuid = args[0]; + found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, &cargs); +- search_uuid = NULL; + + if (found_uuid) + return GRUB_ERR_NONE; +@@ -1034,10 +1031,8 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) + } + else if (state[1].set || (argc == 0 && state[2].set)) /* -a|-b */ + { +- search_uuid = NULL; +- check_boot = state[2].set; ++ cargs.check_boot = state[2].set; + grub_device_iterate (&grub_cryptodisk_scan_device, &cargs); +- search_uuid = NULL; + return GRUB_ERR_NONE; + } + else +@@ -1048,8 +1043,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) + char *disklast = NULL; + grub_size_t len; + +- search_uuid = NULL; +- check_boot = state[2].set; ++ cargs.check_boot = state[2].set; + diskname = args[0]; + len = grub_strlen (diskname); + if (len && diskname[0] == '(' && diskname[len - 1] == ')') +diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c +index 248c42a..6e02451 100644 +--- a/grub-core/disk/geli.c ++++ b/grub-core/disk/geli.c +@@ -240,8 +240,7 @@ grub_util_get_geli_uuid (const char *dev) + #endif + + static grub_cryptodisk_t +-configure_ciphers (grub_disk_t disk, const char *check_uuid, +- int boot_only) ++configure_ciphers (grub_disk_t disk, grub_cryptomount_args_t cargs) + { + grub_cryptodisk_t newdev; + struct grub_geli_phdr header; +@@ -289,7 +288,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, + return NULL; + } + +- if (boot_only && !(grub_le_to_cpu32 (header.flags) & GRUB_GELI_FLAGS_BOOT)) ++ if (cargs->check_boot && !(grub_le_to_cpu32 (header.flags) & GRUB_GELI_FLAGS_BOOT)) + { + grub_dprintf ("geli", "not a boot volume\n"); + return NULL; +@@ -302,9 +301,9 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, + return NULL; + } + +- if (check_uuid && grub_strcasecmp (check_uuid, uuid) != 0) ++ if (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, uuid) != 0) + { +- grub_dprintf ("geli", "%s != %s\n", uuid, check_uuid); ++ grub_dprintf ("geli", "%s != %s\n", uuid, cargs->search_uuid); + return NULL; + } + +diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c +index 8b39f52..298606f 100644 +--- a/grub-core/disk/luks.c ++++ b/grub-core/disk/luks.c +@@ -63,8 +63,7 @@ gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, + grub_size_t blocknumbers); + + static grub_cryptodisk_t +-configure_ciphers (grub_disk_t disk, const char *check_uuid, +- int check_boot) ++configure_ciphers (grub_disk_t disk, grub_cryptomount_args_t cargs) + { + grub_cryptodisk_t newdev; + const char *iptr; +@@ -84,7 +83,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, + int benbi_log = 0; + grub_err_t err; + +- if (check_boot) ++ if (cargs->check_boot) + return NULL; + + /* Read the LUKS header. */ +@@ -110,9 +109,9 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, + } + *optr = 0; + +- if (check_uuid && grub_strcasecmp (check_uuid, uuid) != 0) ++ if (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, uuid) != 0) + { +- grub_dprintf ("luks", "%s != %s\n", uuid, check_uuid); ++ grub_dprintf ("luks", "%s != %s\n", uuid, cargs->search_uuid); + return NULL; + } + +diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h +index 55d5c26..33224a5 100644 +--- a/include/grub/cryptodisk.h ++++ b/include/grub/cryptodisk.h +@@ -63,7 +63,13 @@ typedef gcry_err_code_t + + struct grub_cryptomount_args + { ++ /* scan: Flag to indicate that only bootable volumes should be decrypted */ ++ grub_uint32_t check_boot : 1; ++ /* scan: Only volumes matching this UUID should be decrpyted */ ++ char *search_uuid; ++ /* recover_key: Key data used to decrypt voume */ + grub_uint8_t *key_data; ++ /* recover_key: Length of key_data */ + grub_size_t key_len; + }; + typedef struct grub_cryptomount_args *grub_cryptomount_args_t; +@@ -114,8 +120,7 @@ struct grub_cryptodisk_dev + struct grub_cryptodisk_dev *next; + struct grub_cryptodisk_dev **prev; + +- grub_cryptodisk_t (*scan) (grub_disk_t disk, const char *check_uuid, +- int boot_only); ++ grub_cryptodisk_t (*scan) (grub_disk_t disk, grub_cryptomount_args_t cargs); + grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev, grub_cryptomount_args_t cargs); + }; + typedef struct grub_cryptodisk_dev *grub_cryptodisk_dev_t; +-- +2.33.0 + diff --git a/backport-0008-cryptodisk-Improve-handling-of-partition-name-in-cry.patch b/backport-0008-cryptodisk-Improve-handling-of-partition-name-in-cry.patch new file mode 100644 index 0000000000000000000000000000000000000000..0a99535cbec4fc8e1323f917a35d88b4f8bae800 --- /dev/null +++ b/backport-0008-cryptodisk-Improve-handling-of-partition-name-in-cry.patch @@ -0,0 +1,39 @@ +From ea9aa4d566591710b3eae8f0ce286b1040424e5f Mon Sep 17 00:00:00 2001 +From: Glenn Washburn +Date: Thu, 9 Dec 2021 11:14:58 -0600 +Subject: [PATCH 08/30] cryptodisk: Improve handling of partition name in + cryptomount password prompt + +Call grub_partition_get_name() unconditionally to initialize the part +variable. Then part will only be NULL when grub_partition_get_name() errors. +Note that when source->partition is NULL, then grub_partition_get_name() +returns an allocated empty string. So no comma or partition will be printed, +as desired. + +Signed-off-by: Glenn Washburn +Reviewed-by: Daniel Kiper +--- + grub-core/disk/cryptodisk.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index 6613b27..9a69e24 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -845,11 +845,10 @@ grub_cryptodisk_scan_device_real (const char *name, + { + /* Get the passphrase from the user, if no key data. */ + askpass = 1; +- if (source->partition != NULL) +- part = grub_partition_get_name (source->partition); ++ part = grub_partition_get_name (source->partition); + grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, + source->partition != NULL ? "," : "", +- part != NULL ? part : "", ++ part != NULL ? part : N_("UNKNOWN"), + dev->uuid); + grub_free (part); + +-- +2.33.0 + diff --git a/backport-0009-cryptodisk-Fix-Coverity-use-after-free-bug.patch b/backport-0009-cryptodisk-Fix-Coverity-use-after-free-bug.patch new file mode 100644 index 0000000000000000000000000000000000000000..428440013a6c48d7871fc586a776f5deccd975f0 --- /dev/null +++ b/backport-0009-cryptodisk-Fix-Coverity-use-after-free-bug.patch @@ -0,0 +1,75 @@ +From 155b53904177961d3d44032c87c0eb4b288d2271 Mon Sep 17 00:00:00 2001 +From: Glenn Washburn +Date: Sat, 1 Jan 2022 15:48:25 -0600 +Subject: [PATCH 09/30] cryptodisk: Fix Coverity use after free bug + +The Coverity output is: + + *** CID 366905: Memory - illegal accesses (USE_AFTER_FREE) + /grub-core/disk/cryptodisk.c: 1064 in grub_cryptodisk_scan_device_real() + 1058 cleanup: + 1059 if (askpass) + 1060 { + 1061 cargs->key_len = 0; + 1062 grub_free (cargs->key_data); + 1063 } + >>> CID 366905: Memory - illegal accesses (USE_AFTER_FREE) + >>> Using freed pointer "dev". + 1064 return dev; + 1065 } + 1066 + 1067 #ifdef GRUB_UTIL + 1068 #include + 1069 grub_err_t + +Here the "dev" variable can point to a freed cryptodisk device if the +function grub_cryptodisk_insert() fails. This can happen only on a OOM +condition, but when this happens grub_cryptodisk_insert() calls grub_free on +the passed device. Since grub_cryptodisk_scan_device_real() assumes that +grub_cryptodisk_insert() is always successful, it will return the device, +though the device was freed. + +Change grub_cryptodisk_insert() to not free the passed device on failure. +Then on grub_cryptodisk_insert() failure, free the device pointer. This is +done by going to the label "error", which will call cryptodisk_close() to +free the device and set the device pointer to NULL, so that a pointer to +freed memory is not returned. + +Fixes: CID 366905 + +Signed-off-by: Glenn Washburn +Reviewed-by: Daniel Kiper +--- + grub-core/disk/cryptodisk.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index 9a69e24..b8a43a8 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -713,10 +713,7 @@ grub_cryptodisk_insert (grub_cryptodisk_t newdev, const char *name, + { + newdev->source = grub_strdup (name); + if (!newdev->source) +- { +- grub_free (newdev); +- return grub_errno; +- } ++ return grub_errno; + + newdev->id = last_cryptodisk_id++; + newdev->source_id = source->id; +@@ -868,7 +865,9 @@ grub_cryptodisk_scan_device_real (const char *name, + if (ret != GRUB_ERR_NONE) + goto error; + +- grub_cryptodisk_insert (dev, name, source); ++ ret = grub_cryptodisk_insert (dev, name, source); ++ if (ret != GRUB_ERR_NONE) ++ goto error; + + goto cleanup; + } +-- +2.33.0 + diff --git a/backport-0010-misc-Implement-grub_strlcpy.patch b/backport-0010-misc-Implement-grub_strlcpy.patch new file mode 100644 index 0000000000000000000000000000000000000000..1c71ea5a0a0dce9b46f2fdb72927cd774e661f32 --- /dev/null +++ b/backport-0010-misc-Implement-grub_strlcpy.patch @@ -0,0 +1,68 @@ +From e4218ee68f9508e6831315b0b1af57a53c23d41f Mon Sep 17 00:00:00 2001 +From: B Horn +Date: Sat, 15 Jun 2024 02:33:08 +0100 +Subject: [PATCH 10/30] misc: Implement grub_strlcpy() + +grub_strlcpy() acts the same way as strlcpy() does on most *NIX, +returning the length of src and ensuring dest is always NUL +terminated except when size is 0. + +Signed-off-by: B Horn +Reviewed-by: Daniel Kiper +--- + include/grub/misc.h | 39 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 39 insertions(+) + +diff --git a/include/grub/misc.h b/include/grub/misc.h +index 08ea894..c801243 100644 +--- a/include/grub/misc.h ++++ b/include/grub/misc.h +@@ -64,6 +64,45 @@ grub_stpcpy (char *dest, const char *src) + return d - 1; + } + ++static inline grub_size_t ++grub_strlcpy (char *dest, const char *src, grub_size_t size) ++{ ++ char *d = dest; ++ grub_size_t res = 0; ++ /* ++ * We do not subtract one from size here to avoid dealing with underflowing ++ * the value, which is why to_copy is always checked to be greater than one ++ * throughout this function. ++ */ ++ grub_size_t to_copy = size; ++ ++ /* Copy size - 1 bytes to dest. */ ++ if (to_copy > 1) ++ while ((*d++ = *src++) != '\0' && ++res && --to_copy > 1) ++ ; ++ ++ /* ++ * NUL terminate if size != 0. The previous step may have copied a NUL byte ++ * if it reached the end of the string, but we know dest[size - 1] must always ++ * be a NUL byte. ++ */ ++ if (size != 0) ++ dest[size - 1] = '\0'; ++ ++ /* If there is still space in dest, but are here, we reached the end of src. */ ++ if (to_copy > 1) ++ return res; ++ ++ /* ++ * If we haven't reached the end of the string, iterate through to determine ++ * the strings total length. ++ */ ++ while (*src++ != '\0' && ++res) ++ ; ++ ++ return res; ++} ++ + /* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */ + static inline void * + grub_memcpy (void *dest, const void *src, grub_size_t n) +-- +2.33.0 + diff --git a/backport-0011-fs-ufs-Fix-a-heap-OOB-write.patch b/backport-0011-fs-ufs-Fix-a-heap-OOB-write.patch new file mode 100644 index 0000000000000000000000000000000000000000..497c8035fa56ce63a4b3236069c1a770147caa66 --- /dev/null +++ b/backport-0011-fs-ufs-Fix-a-heap-OOB-write.patch @@ -0,0 +1,34 @@ +From 149f679d27cd7f2905728c7ab526ade8048aadc5 Mon Sep 17 00:00:00 2001 +From: B Horn +Date: Sun, 12 May 2024 02:03:33 +0100 +Subject: [PATCH 11/30] fs/ufs: Fix a heap OOB write + +grub_strcpy() was used to copy a symlink name from the filesystem +image to a heap allocated buffer. This led to a OOB write to adjacent +heap allocations. Fix by using grub_strlcpy(). + +Fixes: CVE-2024-45781 + +Reported-by: B Horn +Signed-off-by: B Horn +Reviewed-by: Daniel Kiper +--- + grub-core/fs/ufs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c +index fca46ba..ea02a68 100644 +--- a/grub-core/fs/ufs.c ++++ b/grub-core/fs/ufs.c +@@ -463,7 +463,7 @@ grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino) + /* Check against zero is paylindromic, no need to swap. */ + if (data->inode.nblocks == 0 + && INODE_SIZE (data) <= sizeof (data->inode.symlink)) +- grub_strcpy (symlink, (char *) data->inode.symlink); ++ grub_strlcpy (symlink, (char *) data->inode.symlink, sz); + else + { + if (grub_ufs_read_file (data, 0, 0, 0, sz, symlink) < 0) +-- +2.33.0 + diff --git a/backport-0012-fs-hfs-Fix-stack-OOB-write-with-grub_strcpy.patch b/backport-0012-fs-hfs-Fix-stack-OOB-write-with-grub_strcpy.patch new file mode 100644 index 0000000000000000000000000000000000000000..248093e936b9a3b325ccefc7b4bf6c0bb19d5d7f --- /dev/null +++ b/backport-0012-fs-hfs-Fix-stack-OOB-write-with-grub_strcpy.patch @@ -0,0 +1,34 @@ +From 9ae93fc5aed1863f43db59ed7c114aed32f57fe3 Mon Sep 17 00:00:00 2001 +From: B Horn +Date: Sun, 12 May 2024 02:48:33 +0100 +Subject: [PATCH 12/30] fs/hfs: Fix stack OOB write with grub_strcpy() + +Replaced with grub_strlcpy(). + +Fixes: CVE-2024-45782 +Fixes: CVE-2024-56737 +Fixes: https://savannah.gnu.org/bugs/?66599 + +Reported-by: B Horn +Signed-off-by: B Horn +Reviewed-by: Daniel Kiper +--- + grub-core/fs/hfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c +index 9a5b7bb..fe4cb45 100644 +--- a/grub-core/fs/hfs.c ++++ b/grub-core/fs/hfs.c +@@ -379,7 +379,7 @@ grub_hfs_mount (grub_disk_t disk) + volume name. */ + key.parent_dir = grub_cpu_to_be32_compile_time (1); + key.strlen = data->sblock.volname[0]; +- grub_strcpy ((char *) key.str, (char *) (data->sblock.volname + 1)); ++ grub_strlcpy ((char *) key.str, (char *) (data->sblock.volname + 1), sizeof (key.str)); + + if (grub_hfs_find_node (data, (char *) &key, data->cat_root, + 0, (char *) &dir, sizeof (dir)) == 0) +-- +2.33.0 + diff --git a/backport-0013-fs-tar-Integer-overflow-leads-to-heap-OOB-write.patch b/backport-0013-fs-tar-Integer-overflow-leads-to-heap-OOB-write.patch new file mode 100644 index 0000000000000000000000000000000000000000..c3866be1039b46f15e2778809ef9048fc2a457a6 --- /dev/null +++ b/backport-0013-fs-tar-Integer-overflow-leads-to-heap-OOB-write.patch @@ -0,0 +1,92 @@ +From 8b286566bed5bd1871bab2620e645e448e0f38fb Mon Sep 17 00:00:00 2001 +From: Lidong Chen +Date: Fri, 22 Nov 2024 06:27:58 +0000 +Subject: [PATCH 13/30] fs/tar: Integer overflow leads to heap OOB write + +Both namesize and linksize are derived from hd.size, a 12-digit octal +number parsed by read_number(). Later direct arithmetic calculation like +"namesize + 1" and "linksize + 1" may exceed the maximum value of +grub_size_t leading to heap OOB write. This patch fixes the issue by +using grub_add() and checking for an overflow. + +Fixes: CVE-2024-45780 + +Reported-by: Nils Langius +Signed-off-by: Lidong Chen +Reviewed-by: Daniel Kiper +Reviewed-by: Alec Brown +--- + grub-core/fs/tar.c | 23 ++++++++++++++++++----- + 1 file changed, 18 insertions(+), 5 deletions(-) + +diff --git a/grub-core/fs/tar.c b/grub-core/fs/tar.c +index c551ed6..a9e39b0 100644 +--- a/grub-core/fs/tar.c ++++ b/grub-core/fs/tar.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -76,6 +77,7 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name, + { + struct head hd; + int reread = 0, have_longname = 0, have_longlink = 0; ++ grub_size_t sz; + + data->hofs = data->next_hofs; + +@@ -97,7 +99,11 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name, + { + grub_err_t err; + grub_size_t namesize = read_number (hd.size, sizeof (hd.size)); +- *name = grub_malloc (namesize + 1); ++ ++ if (grub_add (namesize, 1, &sz)) ++ return grub_error (GRUB_ERR_BAD_FS, N_("name size overflow")); ++ ++ *name = grub_malloc (sz); + if (*name == NULL) + return grub_errno; + err = grub_disk_read (data->disk, 0, +@@ -117,15 +123,19 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name, + { + grub_err_t err; + grub_size_t linksize = read_number (hd.size, sizeof (hd.size)); +- if (data->linkname_alloc < linksize + 1) ++ ++ if (grub_add (linksize, 1, &sz)) ++ return grub_error (GRUB_ERR_BAD_FS, N_("link size overflow")); ++ ++ if (data->linkname_alloc < sz) + { + char *n; +- n = grub_calloc (2, linksize + 1); ++ n = grub_calloc (2, sz); + if (!n) + return grub_errno; + grub_free (data->linkname); + data->linkname = n; +- data->linkname_alloc = 2 * (linksize + 1); ++ data->linkname_alloc = 2 * (sz); + } + + err = grub_disk_read (data->disk, 0, +@@ -148,7 +158,10 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name, + while (extra_size < sizeof (hd.prefix) + && hd.prefix[extra_size]) + extra_size++; +- *name = grub_malloc (sizeof (hd.name) + extra_size + 2); ++ ++ if (grub_add (sizeof (hd.name) + 2, extra_size, &sz)) ++ return grub_error (GRUB_ERR_BAD_FS, N_("long name size overflow")); ++ *name = grub_malloc (sz); + if (*name == NULL) + return grub_errno; + if (hd.prefix[0]) +-- +2.33.0 + diff --git a/backport-0014-fs-hfsplus-Set-a-grub_errno-if-mount-fails.patch b/backport-0014-fs-hfsplus-Set-a-grub_errno-if-mount-fails.patch new file mode 100644 index 0000000000000000000000000000000000000000..6aa918d9daa7c47df1a8f5046c4e41c8235a5e37 --- /dev/null +++ b/backport-0014-fs-hfsplus-Set-a-grub_errno-if-mount-fails.patch @@ -0,0 +1,38 @@ +From dd4d930245cd2112b3d66001db76f8ea3af81da5 Mon Sep 17 00:00:00 2001 +From: B Horn +Date: Sun, 12 May 2024 06:22:51 +0100 +Subject: [PATCH 14/30] fs/hfsplus: Set a grub_errno if mount fails + +It was possible for mount to fail but not set grub_errno. This led to +a possible double decrement of the module reference count if the NULL +page was mapped. + +Fixing in general as a similar bug was fixed in commit 61b13c187 +(fs/hfsplus: Set grub_errno to prevent NULL pointer access) and there +are likely more variants around. + +Fixes: CVE-2024-45783 + +Reported-by: B Horn +Signed-off-by: B Horn +Reviewed-by: Daniel Kiper +--- + grub-core/fs/hfsplus.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c +index 361e5be..97efe0b 100644 +--- a/grub-core/fs/hfsplus.c ++++ b/grub-core/fs/hfsplus.c +@@ -392,7 +392,7 @@ grub_hfsplus_mount (grub_disk_t disk) + + fail: + +- if (grub_errno == GRUB_ERR_OUT_OF_RANGE) ++ if (grub_errno == GRUB_ERR_OUT_OF_RANGE || grub_errno == GRUB_ERR_NONE) + grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem"); + + grub_free (data); +-- +2.33.0 + diff --git a/backport-0015-disk-cryptodisk-Require-authentication-after-TPM-unl.patch b/backport-0015-disk-cryptodisk-Require-authentication-after-TPM-unl.patch new file mode 100644 index 0000000000000000000000000000000000000000..f787a960b313e81679b3e80e75c4488dd8b0ad04 --- /dev/null +++ b/backport-0015-disk-cryptodisk-Require-authentication-after-TPM-unl.patch @@ -0,0 +1,313 @@ +From 97f2cb18dccf7022701baf6b622d0c7a48928a05 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Thu, 29 Aug 2024 13:27:30 +0800 +Subject: [PATCH 06/30] disk/cryptodisk: Require authentication after TPM + unlock for CLI access + +The GRUB may use TPM to verify the integrity of boot components and the +result can determine whether a previously sealed key can be released. If +everything checks out, showing nothing has been tampered with, the key +is released and GRUB unlocks the encrypted root partition for the next +stage of booting. + +However, the liberal Command Line Interface (CLI) can be misused by +anyone in this case to access files in the encrypted partition one way +or another. Despite efforts to keep the CLI secure by preventing utility +command output from leaking file content, many techniques in the wild +could still be used to exploit the CLI, enabling attacks or learning +methods to attack. It's nearly impossible to account for all scenarios +where a hack could be applied. + +Therefore, to mitigate potential misuse of the CLI after the root device +has been successfully unlocked via TPM, the user should be required to +authenticate using the LUKS password. This added layer of security +ensures that only authorized users can access the CLI reducing the risk +of exploitation or unauthorized access to the encrypted partition. + +Fixes: CVE-2024-49504 + +Signed-off-by: Michael Chang +Reviewed-by: Daniel Kiper +--- + grub-core/disk/cryptodisk.c | 86 +++++++++++++++++++++++++++++++++++ + grub-core/kern/main.c | 13 ++++++ + grub-core/normal/auth.c | 30 ++++++++++++ + grub-core/normal/main.c | 4 ++ + grub-core/normal/menu_entry.c | 4 ++ + include/grub/auth.h | 1 + + include/grub/cryptodisk.h | 3 ++ + include/grub/misc.h | 9 ++++ + 8 files changed, 150 insertions(+) + +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index b8a43a8..a8f235c 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -869,6 +869,9 @@ grub_cryptodisk_scan_device_real (const char *name, + if (ret != GRUB_ERR_NONE) + goto error; + ++#ifndef GRUB_UTIL ++ grub_cli_set_auth_needed (); ++#endif + goto cleanup; + } + grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk module can handle this device"); +@@ -1196,6 +1199,89 @@ luks_script_get (grub_size_t *sz) + return ret; + } + ++#ifdef GRUB_MACHINE_EFI ++grub_err_t ++grub_cryptodisk_challenge_password (void) ++{ ++ grub_cryptodisk_t cr_dev; ++ ++ for (cr_dev = cryptodisk_list; cr_dev != NULL; cr_dev = cr_dev->next) ++ { ++ grub_cryptodisk_dev_t cr; ++ grub_disk_t source = NULL; ++ grub_err_t ret = GRUB_ERR_NONE; ++ grub_cryptodisk_t dev = NULL; ++ char *part = NULL; ++ struct grub_cryptomount_args cargs = {0}; ++ ++ cargs.check_boot = 0; ++ cargs.search_uuid = cr_dev->uuid; ++ ++ source = grub_disk_open (cr_dev->source); ++ ++ if (source == NULL) ++ { ++ ret = grub_errno; ++ goto error_out; ++ } ++ ++ FOR_CRYPTODISK_DEVS (cr) ++ { ++ dev = cr->scan (source, &cargs); ++ if (grub_errno) ++ { ++ ret = grub_errno; ++ goto error_out; ++ } ++ if (dev == NULL) ++ continue; ++ break; ++ } ++ ++ if (dev == NULL) ++ { ++ ret = grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk module can handle this device"); ++ goto error_out; ++ } ++ ++ part = grub_partition_get_name (source->partition); ++ grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, ++ source->partition != NULL ? "," : "", ++ part != NULL ? part : N_("UNKNOWN"), cr_dev->uuid); ++ grub_free (part); ++ ++ cargs.key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE); ++ if (cargs.key_data == NULL) ++ { ++ ret = grub_errno; ++ goto error_out; ++ } ++ ++ if (!grub_password_get ((char *) cargs.key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE)) ++ { ++ ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied"); ++ goto error_out; ++ } ++ cargs.key_len = grub_strlen ((char *) cargs.key_data); ++ ret = cr->recover_key (source, dev, &cargs); ++ ++ error_out: ++ grub_disk_close (source); ++ if (dev != NULL) ++ cryptodisk_close (dev); ++ if (cargs.key_data) ++ { ++ grub_memset (cargs.key_data, 0, cargs.key_len); ++ grub_free (cargs.key_data); ++ } ++ ++ return ret; ++ } ++ ++ return GRUB_ERR_NONE; ++} ++#endif /* GRUB_MACHINE_EFI */ ++ + struct grub_procfs_entry luks_script = + { + .name = "luks_script", +diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c +index 0285e95..438a15c 100644 +--- a/grub-core/kern/main.c ++++ b/grub-core/kern/main.c +@@ -35,6 +35,8 @@ + #include + #endif + ++static bool cli_need_auth = false; ++ + grub_addr_t + grub_modules_get_end (void) + { +@@ -245,6 +247,17 @@ grub_load_normal_mode (void) + grub_command_execute ("normal", 0, 0); + } + ++bool ++grub_is_cli_need_auth (void) ++{ ++ return cli_need_auth; ++} ++ ++void grub_cli_set_auth_needed (void) ++{ ++ cli_need_auth = true; ++} ++ + static void + reclaim_module_space (void) + { +diff --git a/grub-core/normal/auth.c b/grub-core/normal/auth.c +index c35ce97..29d8a75 100644 +--- a/grub-core/normal/auth.c ++++ b/grub-core/normal/auth.c +@@ -25,6 +25,10 @@ + #include + #include + ++#ifdef GRUB_MACHINE_EFI ++#include ++#endif ++ + 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); + } + ++grub_err_t ++grub_auth_check_cli_access (void) ++{ ++ if (grub_is_cli_need_auth () == true) ++ { ++#ifdef GRUB_MACHINE_EFI ++ static bool authenticated = false; ++ ++ if (authenticated == false) ++ { ++ grub_err_t ret; ++ ++ ret = grub_cryptodisk_challenge_password (); ++ if (ret == GRUB_ERR_NONE) ++ authenticated = true; ++ return ret; ++ } ++ return GRUB_ERR_NONE; ++#else ++ return GRUB_ACCESS_DENIED; ++#endif ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ + 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 7a2dd3b..6d706db 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -502,9 +502,13 @@ grub_cmdline_run (int nested, int force_auth) + } + while (err && force_auth); + ++ if (err == GRUB_ERR_NONE) ++ err = grub_auth_check_cli_access (); ++ + if (err) + { + grub_print_error (); ++ grub_wait_after_message (); + grub_errno = GRUB_ERR_NONE; + return; + } +diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c +index de64a36..572dd12 100644 +--- a/grub-core/normal/menu_entry.c ++++ b/grub-core/normal/menu_entry.c +@@ -1252,9 +1252,13 @@ grub_menu_entry_run (grub_menu_entry_t entry) + + err = grub_auth_check_authentication (NULL); + ++ if (err == GRUB_ERR_NONE) ++ err = grub_auth_check_cli_access (); ++ + if (err) + { + grub_print_error (); ++ grub_wait_after_message (); + grub_errno = GRUB_ERR_NONE; + return; + } +diff --git a/include/grub/auth.h b/include/grub/auth.h +index 7473344..21d5190 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); + 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 33224a5..412bd12 100644 +--- a/include/grub/cryptodisk.h ++++ b/include/grub/cryptodisk.h +@@ -169,4 +169,7 @@ grub_util_get_geli_uuid (const char *dev); + grub_cryptodisk_t grub_cryptodisk_get_by_uuid (const char *uuid); + 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); ++#endif + #endif +diff --git a/include/grub/misc.h b/include/grub/misc.h +index c801243..b121388 100644 +--- a/include/grub/misc.h ++++ b/include/grub/misc.h +@@ -423,6 +423,13 @@ grub_puts (const char *s) + return 1; /* Cannot fail. */ + } + ++#ifndef __cplusplus ++#ifndef GRUB_POSIX_BOOL_DEFINED ++typedef enum { false = 0, true = 1 } bool; ++#define GRUB_POSIX_BOOL_DEFINED 1 ++#endif ++#endif ++ + int EXPORT_FUNC(grub_puts_) (const char *s); + int EXPORT_FUNC(grub_debug_enabled) (const char *condition); + void EXPORT_FUNC(grub_real_dprintf) (const char *file, +@@ -443,6 +450,8 @@ void EXPORT_FUNC(grub_exit) (int rc) __attribute__ ((noreturn)); + grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, + grub_uint64_t d, + grub_uint64_t *r); ++extern bool EXPORT_FUNC(grub_is_cli_need_auth) (void); ++extern void EXPORT_FUNC(grub_cli_set_auth_needed) (void); + + /* Must match softdiv group in gentpl.py. */ + #if !defined(GRUB_MACHINE_EMU) && (defined(__arm__) || defined(__ia64__) || \ +-- +2.33.0 + diff --git a/backport-0016-net-Fix-OOB-write-in-grub_net_search_config_file.patch b/backport-0016-net-Fix-OOB-write-in-grub_net_search_config_file.patch new file mode 100644 index 0000000000000000000000000000000000000000..9edd5a1cccf8618f50fe62fa0f529d034df55aae --- /dev/null +++ b/backport-0016-net-Fix-OOB-write-in-grub_net_search_config_file.patch @@ -0,0 +1,84 @@ +From f21928173f423e66b0fcea9f34e87938d9aa2b0e Mon Sep 17 00:00:00 2001 +From: B Horn +Date: Fri, 15 Nov 2024 13:12:09 +0000 +Subject: [PATCH 16/30] net: Fix OOB write in grub_net_search_config_file() + +The function included a call to grub_strcpy() which copied data from an +environment variable to a buffer allocated in grub_cmd_normal(). The +grub_cmd_normal() didn't consider the length of the environment variable. +So, the copy operation could exceed the allocation and lead to an OOB +write. Fix the issue by replacing grub_strcpy() with grub_strlcpy() and +pass the underlying buffers size to the grub_net_search_config_file(). + +Fixes: CVE-2025-0624 + +Reported-by: B Horn +Signed-off-by: B Horn +Reviewed-by: Daniel Kiper +--- + grub-core/net/net.c | 7 ++++--- + grub-core/normal/main.c | 2 +- + include/grub/net.h | 2 +- + 3 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/grub-core/net/net.c b/grub-core/net/net.c +index d19583e..b8c113f 100644 +--- a/grub-core/net/net.c ++++ b/grub-core/net/net.c +@@ -1906,9 +1906,9 @@ grub_net_restore_hw (void) + } + + grub_err_t +-grub_net_search_configfile (char *config) ++grub_net_search_configfile (char *config, grub_size_t config_buf_len) + { +- grub_size_t config_len; ++ grub_size_t config_len, suffix_len; + char *suffix; + + auto int search_through (grub_size_t num_tries, grub_size_t slice_size); +@@ -1945,6 +1945,7 @@ grub_net_search_configfile (char *config) + config_len = grub_strlen (config); + config[config_len] = '-'; + suffix = config + config_len + 1; ++ suffix_len = config_buf_len - (config_len + 1); + + struct grub_net_network_level_interface *inf; + FOR_NET_NETWORK_LEVEL_INTERFACES (inf) +@@ -1970,7 +1971,7 @@ grub_net_search_configfile (char *config) + + if (client_uuid) + { +- grub_strcpy (suffix, client_uuid); ++ grub_strlcpy (suffix, client_uuid, suffix_len); + if (search_through (1, 0) == 0) return GRUB_ERR_NONE; + } + +diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c +index 6d706db..b6198bd 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -359,7 +359,7 @@ grub_try_normal (const char *variable) + return GRUB_ERR_FILE_NOT_FOUND; + + grub_snprintf (config, config_len, "%s/grub.cfg", prefix); +- err = grub_net_search_configfile (config); ++ err = grub_net_search_configfile (config, config_len); + } + + if (err != GRUB_ERR_NONE) +diff --git a/include/grub/net.h b/include/grub/net.h +index 5a01747..388b301 100644 +--- a/include/grub/net.h ++++ b/include/grub/net.h +@@ -666,6 +666,6 @@ extern char *grub_net_default_server; + #define VLANTAG_IDENTIFIER 0x8100 + + grub_err_t +-grub_net_search_configfile (char *config); ++grub_net_search_configfile (char *config, grub_size_t config_buf_len); + + #endif /* ! GRUB_NET_HEADER */ +-- +2.33.0 + diff --git a/backport-0017-video-readers-jpeg-Do-not-permit-duplicate-SOF0-mark.patch b/backport-0017-video-readers-jpeg-Do-not-permit-duplicate-SOF0-mark.patch new file mode 100644 index 0000000000000000000000000000000000000000..3b04206345a14803a34da7d5d8b6dfba22278473 --- /dev/null +++ b/backport-0017-video-readers-jpeg-Do-not-permit-duplicate-SOF0-mark.patch @@ -0,0 +1,36 @@ +From 997cf622ebc5394e4d07c9b2fba9485fbb1489b6 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Fri, 8 Mar 2024 22:47:20 +1100 +Subject: [PATCH 17/30] video/readers/jpeg: Do not permit duplicate SOF0 + markers in JPEG + +Otherwise a subsequent header could change the height and width +allowing future OOB writes. + +Fixes: CVE-2024-45774 + +Reported-by: Nils Langius +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/video/readers/jpeg.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c +index 62b6aa7..657e239 100644 +--- a/grub-core/video/readers/jpeg.c ++++ b/grub-core/video/readers/jpeg.c +@@ -333,6 +333,10 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data) + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + ++ if (data->image_height != 0 || data->image_width != 0) ++ return grub_error (GRUB_ERR_BAD_FILE_TYPE, ++ "jpeg: cannot have duplicate SOF0 markers"); ++ + if (grub_jpeg_get_byte (data) != 8) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: only 8-bit precision is supported"); +-- +2.33.0 + diff --git a/backport-0018-fs-ext2-Fix-out-of-bounds-read-for-inline-extents.patch b/backport-0018-fs-ext2-Fix-out-of-bounds-read-for-inline-extents.patch new file mode 100644 index 0000000000000000000000000000000000000000..6f83dd2b049d5b9ce742f8e97dbd3e9dd21efbf1 --- /dev/null +++ b/backport-0018-fs-ext2-Fix-out-of-bounds-read-for-inline-extents.patch @@ -0,0 +1,49 @@ +From 5b8d7595ea33530cef3c9f39bdb0bc0b851f42d9 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Fri, 31 May 2024 15:14:23 +0800 +Subject: [PATCH 18/30] fs/ext2: Fix out-of-bounds read for inline extents + +When inline extents are used, i.e. the extent tree depth equals zero, +a maximum of four entries can fit into the inode's data block. If the +extent header states a number of entries greater than four the current +ext2 implementation causes an out-of-bounds read. Fix this issue by +capping the number of extents to four when reading inline extents. + +Reported-by: Daniel Axtens +Signed-off-by: Michael Chang +Reviewed-by: Daniel Kiper +--- + grub-core/fs/ext2.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c +index 848bf93..a15baea 100644 +--- a/grub-core/fs/ext2.c ++++ b/grub-core/fs/ext2.c +@@ -473,6 +473,8 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + struct grub_ext4_extent *ext; + int i; + grub_disk_addr_t ret; ++ grub_uint16_t nent; ++ const grub_uint16_t max_inline_ext = sizeof (inode->blocks) / sizeof (*ext) - 1; /* Minus 1 extent header. */ + + leaf = grub_ext4_find_leaf (data, (struct grub_ext4_extent_header *) inode->blocks.dir_blocks, fileblock); + if (! leaf) +@@ -482,7 +484,13 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + } + + ext = (struct grub_ext4_extent *) (leaf + 1); +- for (i = 0; i < grub_le_to_cpu16 (leaf->entries); i++) ++ ++ nent = grub_le_to_cpu16 (leaf->entries); ++ ++ if (leaf->depth == 0) ++ nent = grub_min (nent, max_inline_ext); ++ ++ for (i = 0; i < nent; i++) + { + if (fileblock < grub_le_to_cpu32 (ext[i].block)) + break; +-- +2.33.0 + diff --git a/backport-0019-fs-ext2-Rework-out-of-bounds-read-for-inline-and-ext.patch b/backport-0019-fs-ext2-Rework-out-of-bounds-read-for-inline-and-ext.patch new file mode 100644 index 0000000000000000000000000000000000000000..566794f3c198b763929fac6521461cb22675e222 --- /dev/null +++ b/backport-0019-fs-ext2-Rework-out-of-bounds-read-for-inline-and-ext.patch @@ -0,0 +1,66 @@ +From aaac041941a6a2a6538daddc22d16d21cc8fa221 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Fri, 21 Feb 2025 09:06:12 +0800 +Subject: [PATCH 19/30] fs/ext2: Rework out-of-bounds read for inline and + external exten + +Previously, the number of extent entries was not properly capped based +on the actual available space. This could lead to insufficient reads for +external extents, since the computation was based solely on the inline +extent layout. + +In this patch, when processing the extent header, we determine whether +the header is stored inline (i.e., at inode->blocks.dir_blocks) or in an +external extent block. We then clamp the number of entries accordingly +(using max_inline_ext for inline extents and max_external_ext for +external extent blocks). + +This change ensures that only the valid number of extent entries is +processed, preventing out-of-bound reads and potential filesystem +corruption. + +Fixes: 7e2f750f0a (fs/ext2: Fix out-of-bounds read for inline extents) + +Signed-off-by: Michael Chang +--- + grub-core/fs/ext2.c | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c +index a15baea..169f606 100644 +--- a/grub-core/fs/ext2.c ++++ b/grub-core/fs/ext2.c +@@ -474,7 +474,10 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + int i; + grub_disk_addr_t ret; + grub_uint16_t nent; ++ /* maximum number of extent entries in the inode's inline extent area */ + const grub_uint16_t max_inline_ext = sizeof (inode->blocks) / sizeof (*ext) - 1; /* Minus 1 extent header. */ ++ /* maximum number of extent entries in the external extent block */ ++ const grub_uint16_t max_external_ext = EXT2_BLOCK_SIZE(data) / sizeof (*ext) - 1; /* Minus 1 extent header. */ + + leaf = grub_ext4_find_leaf (data, (struct grub_ext4_extent_header *) inode->blocks.dir_blocks, fileblock); + if (! leaf) +@@ -487,8 +490,18 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + + nent = grub_le_to_cpu16 (leaf->entries); + +- if (leaf->depth == 0) ++ /* ++ * Determine the effective number of extent entries (nent) to process: ++ * If the extent header (leaf) is stored inline in the inode’s block ++ * area (i.e. at inode->blocks.dir_blocks), then only max_inline_ext ++ * entries can fit. ++ * Otherwise, if the header was read from an external extent block, use ++ * the larger limit, max_external_ext, based on the full block size. ++ */ ++ if (leaf == (struct grub_ext4_extent_header *) inode->blocks.dir_blocks) + nent = grub_min (nent, max_inline_ext); ++ else ++ nent = grub_min (nent, max_external_ext); + + for (i = 0; i < nent; i++) + { +-- +2.33.0 + diff --git a/backport-0020-commands-extcmd-Missing-check-for-failed-allocation.patch b/backport-0020-commands-extcmd-Missing-check-for-failed-allocation.patch new file mode 100644 index 0000000000000000000000000000000000000000..2750352e789ad54e71c46f517ef04a0d646875d0 --- /dev/null +++ b/backport-0020-commands-extcmd-Missing-check-for-failed-allocation.patch @@ -0,0 +1,37 @@ +From 74f67febe5baeeda199ea5576a7603a283575b47 Mon Sep 17 00:00:00 2001 +From: Lidong Chen +Date: Fri, 22 Nov 2024 06:27:55 +0000 +Subject: [PATCH 20/30] commands/extcmd: Missing check for failed allocation + +The grub_extcmd_dispatcher() calls grub_arg_list_alloc() to allocate +a grub_arg_list struct but it does not verify the allocation was successful. +In case of failed allocation the NULL state pointer can be accessed in +parse_option() through grub_arg_parse() which may lead to a security issue. + +Fixes: CVE-2024-45775 + +Reported-by: Nils Langius +Signed-off-by: Lidong Chen +Reviewed-by: Daniel Kiper +Reviewed-by: Alec Brown +--- + grub-core/commands/extcmd.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/grub-core/commands/extcmd.c b/grub-core/commands/extcmd.c +index 90a5ca2..c236be1 100644 +--- a/grub-core/commands/extcmd.c ++++ b/grub-core/commands/extcmd.c +@@ -49,6 +49,9 @@ grub_extcmd_dispatcher (struct grub_command *cmd, int argc, char **args, + } + + state = grub_arg_list_alloc (ext, argc, args); ++ if (state == NULL) ++ return grub_errno; ++ + if (grub_arg_parse (ext, argc, args, state, &new_args, &new_argc)) + { + context.state = state; +-- +2.33.0 + diff --git a/backport-0021-commands-pgp-Unregister-the-check_signatures-hooks-o.patch b/backport-0021-commands-pgp-Unregister-the-check_signatures-hooks-o.patch new file mode 100644 index 0000000000000000000000000000000000000000..053c0bccf95978935899e80c665535a8f8154325 --- /dev/null +++ b/backport-0021-commands-pgp-Unregister-the-check_signatures-hooks-o.patch @@ -0,0 +1,34 @@ +From b2b257bb8e00542b258706c830c2b8d4b0f884b1 Mon Sep 17 00:00:00 2001 +From: B Horn +Date: Fri, 1 Nov 2024 19:24:29 +0000 +Subject: [PATCH 21/30] commands/pgp: Unregister the "check_signatures" hooks + on module unload + +If the hooks are not removed they can be called after the module has +been unloaded leading to an use-after-free. + +Fixes: CVE-2025-0622 + +Reported-by: B Horn +Signed-off-by: B Horn +Reviewed-by: Daniel Kiper +--- + grub-core/commands/pgp.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c +index bbf6871..827c167 100644 +--- a/grub-core/commands/pgp.c ++++ b/grub-core/commands/pgp.c +@@ -1010,6 +1010,8 @@ GRUB_MOD_INIT(pgp) + + GRUB_MOD_FINI(pgp) + { ++ grub_register_variable_hook ("check_signatures", NULL, NULL); ++ grub_env_unset ("check_signatures"); + grub_verifier_unregister (&grub_pubkey_verifier); + grub_unregister_extcmd (cmd); + grub_unregister_extcmd (cmd_trust); +-- +2.33.0 + diff --git a/backport-0022-normal-Remove-variables-hooks-on-module-unload.patch b/backport-0022-normal-Remove-variables-hooks-on-module-unload.patch new file mode 100644 index 0000000000000000000000000000000000000000..d54951e2956b1f1ad47e26d2926af1854d13ff27 --- /dev/null +++ b/backport-0022-normal-Remove-variables-hooks-on-module-unload.patch @@ -0,0 +1,40 @@ +From 5f045216e3d6f5ceec5107fbd07696bd40c99784 Mon Sep 17 00:00:00 2001 +From: B Horn +Date: Fri, 1 Nov 2024 23:46:55 +0000 +Subject: [PATCH 22/30] normal: Remove variables hooks on module unload + +The normal module does not entirely cleanup after itself in +its GRUB_MOD_FINI() leaving a few variables hooks in place. +It is not possible to unload normal module now but fix the +issues for completeness. + +On the occasion replace 0s with NULLs for "pager" variable +hooks unregister. + +Fixes: CVE-2025-0622 + +Reported-by: B Horn +Signed-off-by: B Horn +Reviewed-by: Daniel Kiper +--- + grub-core/normal/main.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c +index b6198bd..d3a7f9a 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -635,7 +635,9 @@ GRUB_MOD_FINI(normal) + grub_xputs = grub_xputs_saved; + + grub_set_history (0); +- grub_register_variable_hook ("pager", 0, 0); ++ grub_register_variable_hook ("pager", NULL, NULL); ++ grub_register_variable_hook ("color_normal", NULL, NULL); ++ grub_register_variable_hook ("color_highlight", NULL, NULL); + grub_fs_autoload_hook = 0; + grub_unregister_command (cmd_clear); + } +-- +2.33.0 + diff --git a/backport-0023-gettext-Remove-variables-hooks-on-module-unload.patch b/backport-0023-gettext-Remove-variables-hooks-on-module-unload.patch new file mode 100644 index 0000000000000000000000000000000000000000..6f3456195a7316e2d23e3fd0f8c0ea9a08ff8b6d --- /dev/null +++ b/backport-0023-gettext-Remove-variables-hooks-on-module-unload.patch @@ -0,0 +1,37 @@ +From 53f38279511636a6623a790fa251871daa3a09ea Mon Sep 17 00:00:00 2001 +From: B Horn +Date: Fri, 1 Nov 2024 23:52:06 +0000 +Subject: [PATCH 23/30] gettext: Remove variables hooks on module unload + +The gettext module does not entirely cleanup after itself in +its GRUB_MOD_FINI() leaving a few variables hooks in place. +It is not possible to unload gettext module because normal +module depends on it. Though fix the issues for completeness. + +Fixes: CVE-2025-0622 + +Reported-by: B Horn +Signed-off-by: B Horn +Reviewed-by: Daniel Kiper +--- + grub-core/gettext/gettext.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c +index 84d520c..1344c7c 100644 +--- a/grub-core/gettext/gettext.c ++++ b/grub-core/gettext/gettext.c +@@ -520,6 +520,10 @@ GRUB_MOD_INIT (gettext) + + GRUB_MOD_FINI (gettext) + { ++ grub_register_variable_hook ("locale_dir", NULL, NULL); ++ grub_register_variable_hook ("secondary_locale_dir", NULL, NULL); ++ grub_register_variable_hook ("lang", NULL, NULL); ++ + grub_gettext_delete_list (&main_context); + grub_gettext_delete_list (&secondary_context); + +-- +2.33.0 + diff --git a/backport-0024-gettext-Integer-overflow-leads-to-heap-OOB-write-or-.patch b/backport-0024-gettext-Integer-overflow-leads-to-heap-OOB-write-or-.patch new file mode 100644 index 0000000000000000000000000000000000000000..8e7a42b31321fb63a0d1002b15c6e00b53d9f683 --- /dev/null +++ b/backport-0024-gettext-Integer-overflow-leads-to-heap-OOB-write-or-.patch @@ -0,0 +1,39 @@ +From 8289e9d160b560e64af480945d9ed63e19a750e0 Mon Sep 17 00:00:00 2001 +From: Lidong Chen +Date: Fri, 22 Nov 2024 06:27:56 +0000 +Subject: [PATCH 24/30] gettext: Integer overflow leads to heap OOB write or + read + +Calculation of ctx->grub_gettext_msg_list size in grub_mofile_open() may +overflow leading to subsequent OOB write or read. This patch fixes the +issue by replacing grub_zalloc() and explicit multiplication with +grub_calloc() which does the same thing in safe manner. + +Fixes: CVE-2024-45776 + +Reported-by: Nils Langius +Signed-off-by: Lidong Chen +Reviewed-by: Daniel Kiper +Reviewed-by: Alec Brown +--- + grub-core/gettext/gettext.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c +index 1344c7c..cb304eb 100644 +--- a/grub-core/gettext/gettext.c ++++ b/grub-core/gettext/gettext.c +@@ -323,8 +323,8 @@ grub_mofile_open (struct grub_gettext_context *ctx, + for (ctx->grub_gettext_max_log = 0; ctx->grub_gettext_max >> ctx->grub_gettext_max_log; + ctx->grub_gettext_max_log++); + +- ctx->grub_gettext_msg_list = grub_zalloc (ctx->grub_gettext_max +- * sizeof (ctx->grub_gettext_msg_list[0])); ++ ctx->grub_gettext_msg_list = grub_calloc (ctx->grub_gettext_max, ++ sizeof (ctx->grub_gettext_msg_list[0])); + if (!ctx->grub_gettext_msg_list) + { + grub_file_close (fd); +-- +2.33.0 + diff --git a/backport-0025-gettext-Integer-overflow-leads-to-heap-OOB-write.patch b/backport-0025-gettext-Integer-overflow-leads-to-heap-OOB-write.patch new file mode 100644 index 0000000000000000000000000000000000000000..f61becbeb1bfc11ea1adbe987431c508f456ad66 --- /dev/null +++ b/backport-0025-gettext-Integer-overflow-leads-to-heap-OOB-write.patch @@ -0,0 +1,56 @@ +From c3c4962ebca5dd2ae8d3a67fd7ff93dd4487a8e2 Mon Sep 17 00:00:00 2001 +From: Lidong Chen +Date: Fri, 22 Nov 2024 06:27:57 +0000 +Subject: [PATCH 25/30] gettext: Integer overflow leads to heap OOB write + +The size calculation of the translation buffer in +grub_gettext_getstr_from_position() may overflow +to 0 leading to heap OOB write. This patch fixes +the issue by using grub_add() and checking for +an overflow. + +Fixes: CVE-2024-45777 + +Reported-by: Nils Langius +Signed-off-by: Lidong Chen +Reviewed-by: Daniel Kiper +Reviewed-by: Alec Brown +--- + grub-core/gettext/gettext.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c +index cb304eb..9654bb3 100644 +--- a/grub-core/gettext/gettext.c ++++ b/grub-core/gettext/gettext.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -99,6 +100,7 @@ grub_gettext_getstr_from_position (struct grub_gettext_context *ctx, + char *translation; + struct string_descriptor desc; + grub_err_t err; ++ grub_size_t alloc_sz; + + internal_position = (off + position * sizeof (desc)); + +@@ -109,7 +111,10 @@ grub_gettext_getstr_from_position (struct grub_gettext_context *ctx, + length = grub_cpu_to_le32 (desc.length); + offset = grub_cpu_to_le32 (desc.offset); + +- translation = grub_malloc (length + 1); ++ if (grub_add (length, 1, &alloc_sz)) ++ return NULL; ++ ++ translation = grub_malloc (alloc_sz); + if (!translation) + return NULL; + +-- +2.33.0 + diff --git a/backport-0026-commands-read-Fix-an-integer-overflow-when-supplying.patch b/backport-0026-commands-read-Fix-an-integer-overflow-when-supplying.patch new file mode 100644 index 0000000000000000000000000000000000000000..036f8c78ddf17677ec34dc62ad0ef55bf2846b04 --- /dev/null +++ b/backport-0026-commands-read-Fix-an-integer-overflow-when-supplying.patch @@ -0,0 +1,71 @@ +From d2abdef4c240aa6040705c33377fac55c5763ffe Mon Sep 17 00:00:00 2001 +From: Jonathan Bar Or +Date: Thu, 23 Jan 2025 19:17:05 +0100 +Subject: [PATCH 26/30] commands/read: Fix an integer overflow when supplying + more than 2^31 characters + +The grub_getline() function currently has a signed integer variable "i" +that can be overflown when user supplies more than 2^31 characters. +It results in a memory corruption of the allocated line buffer as well +as supplying large negative values to grub_realloc(). + +Fixes: CVE-2025-0690 + +Reported-by: Jonathan Bar Or +Signed-off-by: Jonathan Bar Or +Reviewed-by: Daniel Kiper +--- + grub-core/commands/read.c | 19 +++++++++++++++---- + 1 file changed, 15 insertions(+), 4 deletions(-) + +diff --git a/grub-core/commands/read.c b/grub-core/commands/read.c +index fe3e88b..ebdee7f 100644 +--- a/grub-core/commands/read.c ++++ b/grub-core/commands/read.c +@@ -25,19 +25,21 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + + static char * + grub_getline (void) + { +- int i; ++ grub_size_t i; + char *line; + char *tmp; + char c; ++ grub_size_t alloc_size; + + i = 0; +- line = grub_malloc (1 + i + sizeof('\0')); ++ line = grub_malloc (1 + sizeof('\0')); + if (! line) + return NULL; + +@@ -50,8 +52,17 @@ grub_getline (void) + line[i] = c; + if (grub_isprint (c)) + grub_printf ("%c", c); +- i++; +- tmp = grub_realloc (line, 1 + i + sizeof('\0')); ++ if (grub_add (i, 1, &i)) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ return NULL; ++ } ++ if (grub_add (i, 1 + sizeof('\0'), &alloc_size)) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ return NULL; ++ } ++ tmp = grub_realloc (line, alloc_size); + if (! tmp) + { + grub_free (line); +-- +2.33.0 + diff --git a/backport-0027-commands-minicmd-Block-the-dump-command-in-lockdown-.patch b/backport-0027-commands-minicmd-Block-the-dump-command-in-lockdown-.patch new file mode 100644 index 0000000000000000000000000000000000000000..a0febb607f37f6e2bcb080c563072c58171dea9a --- /dev/null +++ b/backport-0027-commands-minicmd-Block-the-dump-command-in-lockdown-.patch @@ -0,0 +1,37 @@ +From 9c9be3def811edc55d467f5ff4cccbb70230aba2 Mon Sep 17 00:00:00 2001 +From: B Horn +Date: Thu, 18 Apr 2024 20:29:39 +0100 +Subject: [PATCH 27/30] commands/minicmd: Block the dump command in lockdown + mode + +The dump enables a user to read memory which should not be possible +in lockdown mode. + +Fixes: CVE-2025-1118 + +Reported-by: B Horn +Reported-by: Jonathan Bar Or +Signed-off-by: B Horn +Reviewed-by: Daniel Kiper +--- + grub-core/commands/minicmd.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c +index 2bd3ac7..0898923 100644 +--- a/grub-core/commands/minicmd.c ++++ b/grub-core/commands/minicmd.c +@@ -215,8 +215,8 @@ GRUB_MOD_INIT(minicmd) + grub_register_command ("help", grub_mini_cmd_help, + 0, N_("Show this message.")); + cmd_dump = +- grub_register_command ("dump", grub_mini_cmd_dump, +- N_("ADDR [SIZE]"), N_("Show memory contents.")); ++ grub_register_command_lockdown ("dump", grub_mini_cmd_dump, ++ N_("ADDR [SIZE]"), N_("Show memory contents.")); + cmd_rmmod = + grub_register_command ("rmmod", grub_mini_cmd_rmmod, + N_("MODULE"), N_("Remove a module.")); +-- +2.33.0 + diff --git a/backport-0028-fs-bfs-Disable-under-lockdown.patch b/backport-0028-fs-bfs-Disable-under-lockdown.patch new file mode 100644 index 0000000000000000000000000000000000000000..91c55f1f25ba829029beb63a9deb7c27158c493c --- /dev/null +++ b/backport-0028-fs-bfs-Disable-under-lockdown.patch @@ -0,0 +1,53 @@ +From 3fb3783b092783379c0eb42349601cab43b934d3 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Sat, 23 Mar 2024 15:59:43 +1100 +Subject: [PATCH 28/30] fs/bfs: Disable under lockdown + +The BFS is not fuzz-clean. Don't allow it to be loaded under lockdown. +This will also disable the AFS. + +Fixes: CVE-2024-45778 +Fixes: CVE-2024-45779 + +Reported-by: Nils Langius +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/fs/bfs.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c +index 47dbe20..8d704e2 100644 +--- a/grub-core/fs/bfs.c ++++ b/grub-core/fs/bfs.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -1104,7 +1105,10 @@ GRUB_MOD_INIT (bfs) + { + COMPILE_TIME_ASSERT (1 << LOG_EXTENT_SIZE == + sizeof (struct grub_bfs_extent)); +- grub_fs_register (&grub_bfs_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_fs_register (&grub_bfs_fs); ++ } + } + + #ifdef MODE_AFS +@@ -1113,5 +1117,6 @@ GRUB_MOD_FINI (afs) + GRUB_MOD_FINI (bfs) + #endif + { +- grub_fs_unregister (&grub_bfs_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_bfs_fs); + } +-- +2.33.0 + diff --git a/backport-0029-fs-Disable-many-filesystems-under-lockdown.patch b/backport-0029-fs-Disable-many-filesystems-under-lockdown.patch new file mode 100644 index 0000000000000000000000000000000000000000..91208f93c2d9e915ee1bf02e108016ebc7d947f9 --- /dev/null +++ b/backport-0029-fs-Disable-many-filesystems-under-lockdown.patch @@ -0,0 +1,372 @@ +From ddf6d15756e2296fce47ff6fb9248cbaf3c5780d Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Sat, 23 Mar 2024 16:20:45 +1100 +Subject: [PATCH 29/30] fs: Disable many filesystems under lockdown + +The idea is to permit the following: btrfs, cpio, exfat, ext, f2fs, fat, +hfsplus, iso9660, squash4, tar, xfs and zfs. + +The JFS, ReiserFS, romfs, UDF and UFS security vulnerabilities were +reported by Jonathan Bar Or . + +Fixes: CVE-2025-0677 +Fixes: CVE-2025-0684 +Fixes: CVE-2025-0685 +Fixes: CVE-2025-0686 +Fixes: CVE-2025-0689 + +Suggested-by: Daniel Axtens +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/fs/affs.c | 9 +++++++-- + grub-core/fs/cbfs.c | 9 +++++++-- + grub-core/fs/jfs.c | 9 +++++++-- + grub-core/fs/minix.c | 9 +++++++-- + grub-core/fs/nilfs2.c | 9 +++++++-- + grub-core/fs/ntfs.c | 9 +++++++-- + grub-core/fs/reiserfs.c | 9 +++++++-- + grub-core/fs/romfs.c | 9 +++++++-- + grub-core/fs/sfs.c | 9 +++++++-- + grub-core/fs/udf.c | 9 +++++++-- + grub-core/fs/ufs.c | 9 +++++++-- + 11 files changed, 77 insertions(+), 22 deletions(-) + +diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c +index 230e26a..7fbd136 100644 +--- a/grub-core/fs/affs.c ++++ b/grub-core/fs/affs.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -699,11 +700,15 @@ static struct grub_fs grub_affs_fs = + + GRUB_MOD_INIT(affs) + { +- grub_fs_register (&grub_affs_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_fs_register (&grub_affs_fs); ++ } + my_mod = mod; + } + + GRUB_MOD_FINI(affs) + { +- grub_fs_unregister (&grub_affs_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_affs_fs); + } +diff --git a/grub-core/fs/cbfs.c b/grub-core/fs/cbfs.c +index 857bea9..09952ec 100644 +--- a/grub-core/fs/cbfs.c ++++ b/grub-core/fs/cbfs.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -390,12 +391,16 @@ GRUB_MOD_INIT (cbfs) + #if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN) + init_cbfsdisk (); + #endif +- grub_fs_register (&grub_cbfs_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_fs_register (&grub_cbfs_fs); ++ } + } + + GRUB_MOD_FINI (cbfs) + { +- grub_fs_unregister (&grub_cbfs_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_cbfs_fs); + #if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN) + fini_cbfsdisk (); + #endif +diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c +index 6f7c439..c0bbab8 100644 +--- a/grub-core/fs/jfs.c ++++ b/grub-core/fs/jfs.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -963,11 +964,15 @@ static struct grub_fs grub_jfs_fs = + + GRUB_MOD_INIT(jfs) + { +- grub_fs_register (&grub_jfs_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_fs_register (&grub_jfs_fs); ++ } + my_mod = mod; + } + + GRUB_MOD_FINI(jfs) + { +- grub_fs_unregister (&grub_jfs_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_jfs_fs); + } +diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c +index 3cd18c8..7588835 100644 +--- a/grub-core/fs/minix.c ++++ b/grub-core/fs/minix.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -732,7 +733,10 @@ GRUB_MOD_INIT(minix) + #endif + #endif + { +- grub_fs_register (&grub_minix_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_fs_register (&grub_minix_fs); ++ } + my_mod = mod; + } + +@@ -754,5 +758,6 @@ GRUB_MOD_FINI(minix) + #endif + #endif + { +- grub_fs_unregister (&grub_minix_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_minix_fs); + } +diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c +index aaba002..056b897 100644 +--- a/grub-core/fs/nilfs2.c ++++ b/grub-core/fs/nilfs2.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -1231,11 +1232,15 @@ GRUB_MOD_INIT (nilfs2) + grub_nilfs2_dat_entry)); + COMPILE_TIME_ASSERT (1 << LOG_INODE_SIZE + == sizeof (struct grub_nilfs2_inode)); +- grub_fs_register (&grub_nilfs2_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_fs_register (&grub_nilfs2_fs); ++ } + my_mod = mod; + } + + GRUB_MOD_FINI (nilfs2) + { +- grub_fs_unregister (&grub_nilfs2_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_nilfs2_fs); + } +diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c +index deb058a..5b342da 100644 +--- a/grub-core/fs/ntfs.c ++++ b/grub-core/fs/ntfs.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -1316,11 +1317,15 @@ static struct grub_fs grub_ntfs_fs = + + GRUB_MOD_INIT (ntfs) + { +- grub_fs_register (&grub_ntfs_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_fs_register (&grub_ntfs_fs); ++ } + my_mod = mod; + } + + GRUB_MOD_FINI (ntfs) + { +- grub_fs_unregister (&grub_ntfs_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_ntfs_fs); + } +diff --git a/grub-core/fs/reiserfs.c b/grub-core/fs/reiserfs.c +index af6a226..76cb231 100644 +--- a/grub-core/fs/reiserfs.c ++++ b/grub-core/fs/reiserfs.c +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -1417,11 +1418,15 @@ static struct grub_fs grub_reiserfs_fs = + + GRUB_MOD_INIT(reiserfs) + { +- grub_fs_register (&grub_reiserfs_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_fs_register (&grub_reiserfs_fs); ++ } + my_mod = mod; + } + + GRUB_MOD_FINI(reiserfs) + { +- grub_fs_unregister (&grub_reiserfs_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_reiserfs_fs); + } +diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c +index d97b8fb..d174449 100644 +--- a/grub-core/fs/romfs.c ++++ b/grub-core/fs/romfs.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -475,10 +476,14 @@ static struct grub_fs grub_romfs_fs = + + GRUB_MOD_INIT(romfs) + { +- grub_fs_register (&grub_romfs_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_fs_register (&grub_romfs_fs); ++ } + } + + GRUB_MOD_FINI(romfs) + { +- grub_fs_unregister (&grub_romfs_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_romfs_fs); + } +diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c +index 983e880..f64bdd2 100644 +--- a/grub-core/fs/sfs.c ++++ b/grub-core/fs/sfs.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + + GRUB_MOD_LICENSE ("GPLv3+"); +@@ -779,11 +780,15 @@ static struct grub_fs grub_sfs_fs = + + GRUB_MOD_INIT(sfs) + { +- grub_fs_register (&grub_sfs_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_fs_register (&grub_sfs_fs); ++ } + my_mod = mod; + } + + GRUB_MOD_FINI(sfs) + { +- grub_fs_unregister (&grub_sfs_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_sfs_fs); + } +diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c +index 2ac5c1d..f89c6b0 100644 +--- a/grub-core/fs/udf.c ++++ b/grub-core/fs/udf.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -1382,11 +1383,15 @@ static struct grub_fs grub_udf_fs = { + + GRUB_MOD_INIT (udf) + { +- grub_fs_register (&grub_udf_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_fs_register (&grub_udf_fs); ++ } + my_mod = mod; + } + + GRUB_MOD_FINI (udf) + { +- grub_fs_unregister (&grub_udf_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_udf_fs); + } +diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c +index ea02a68..e110c2f 100644 +--- a/grub-core/fs/ufs.c ++++ b/grub-core/fs/ufs.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -899,7 +900,10 @@ GRUB_MOD_INIT(ufs1) + #endif + #endif + { +- grub_fs_register (&grub_ufs_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_fs_register (&grub_ufs_fs); ++ } + my_mod = mod; + } + +@@ -913,6 +917,7 @@ GRUB_MOD_FINI(ufs1) + #endif + #endif + { +- grub_fs_unregister (&grub_ufs_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_ufs_fs); + } + +-- +2.33.0 + diff --git a/backport-0030-fs-Prevent-overflows-when-allocating-memory-for-arra.patch b/backport-0030-fs-Prevent-overflows-when-allocating-memory-for-arra.patch new file mode 100644 index 0000000000000000000000000000000000000000..2d7db54b3c9a23aab6628691034ac313fc2945c4 --- /dev/null +++ b/backport-0030-fs-Prevent-overflows-when-allocating-memory-for-arra.patch @@ -0,0 +1,85 @@ +From 071a0b83c7b085c78546f131794750df71709c12 Mon Sep 17 00:00:00 2001 +From: Lidong Chen +Date: Tue, 21 Jan 2025 19:02:37 +0000 +Subject: [PATCH 30/30] fs: Prevent overflows when allocating memory for arrays + +Use grub_calloc() when allocating memory for arrays to ensure proper +overflow checks are in place. + +The HFS+ and squash4 security vulnerabilities were reported by +Jonathan Bar Or . + +Fixes: CVE-2025-0678 +Fixes: CVE-2025-1125 + +Signed-off-by: Lidong Chen +Reviewed-by: Daniel Kiper +--- + grub-core/fs/btrfs.c | 4 ++-- + grub-core/fs/hfspluscomp.c | 9 +++++++-- + grub-core/fs/squash4.c | 8 ++++---- + 3 files changed, 13 insertions(+), 8 deletions(-) + +diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c +index cf3647a..6c2ee1b 100644 +--- a/grub-core/fs/btrfs.c ++++ b/grub-core/fs/btrfs.c +@@ -1323,8 +1323,8 @@ grub_btrfs_mount (grub_device_t dev) + } + + data->n_devices_allocated = 16; +- data->devices_attached = grub_malloc (sizeof (data->devices_attached[0]) +- * data->n_devices_allocated); ++ data->devices_attached = grub_calloc (data->n_devices_allocated, ++ sizeof (data->devices_attached[0])); + if (!data->devices_attached) + { + grub_free (data); +diff --git a/grub-core/fs/hfspluscomp.c b/grub-core/fs/hfspluscomp.c +index d76f3f1..4965ef1 100644 +--- a/grub-core/fs/hfspluscomp.c ++++ b/grub-core/fs/hfspluscomp.c +@@ -244,14 +244,19 @@ hfsplus_open_compressed_real (struct grub_hfsplus_file *node) + return 0; + } + node->compress_index_size = grub_le_to_cpu32 (index_size); +- node->compress_index = grub_malloc (node->compress_index_size +- * sizeof (node->compress_index[0])); ++ node->compress_index = grub_calloc (node->compress_index_size, ++ sizeof (node->compress_index[0])); + if (!node->compress_index) + { + node->compressed = 0; + grub_free (attr_node); + return grub_errno; + } ++ ++ /* ++ * The node->compress_index_size * sizeof (node->compress_index[0]) is safe here ++ * due to relevant checks done in grub_calloc() above. ++ */ + if (grub_hfsplus_read_file (node, 0, 0, + 0x104 + sizeof (index_size), + node->compress_index_size +diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c +index 8295b88..9f8555f 100644 +--- a/grub-core/fs/squash4.c ++++ b/grub-core/fs/squash4.c +@@ -816,10 +816,10 @@ direct_read (struct grub_squash_data *data, + break; + } + total_blocks = ((total_size + data->blksz - 1) >> data->log2_blksz); +- ino->block_sizes = grub_malloc (total_blocks +- * sizeof (ino->block_sizes[0])); +- ino->cumulated_block_sizes = grub_malloc (total_blocks +- * sizeof (ino->cumulated_block_sizes[0])); ++ ino->block_sizes = grub_calloc (total_blocks, ++ sizeof (ino->block_sizes[0])); ++ ino->cumulated_block_sizes = grub_calloc (total_blocks, ++ sizeof (ino->cumulated_block_sizes[0])); + if (!ino->block_sizes || !ino->cumulated_block_sizes) + { + grub_free (ino->block_sizes); +-- +2.33.0 + diff --git a/grub.patches b/grub.patches index 3b8ceb9de81524015c5703bb871b474294a4aa86..0412bd415e898634beb0f628a2e2acd91f317b5f 100644 --- a/grub.patches +++ b/grub.patches @@ -464,4 +464,33 @@ Patch0463: backport-commands-acpi-Fix-calculation-of-ACPI-tables-address.patch Patch0464: backport-CVE-2024-1048-grub-set-bootflag-Conservative-partial-fix.patch Patch0465: backport-CVE-2024-1048-grub-set-bootflag-More-complete-fix.patch Patch0466: backport-CVE-2024-1048-grub-set-bootflag-Exit-calmly-when-not.patch - +Patch0467: backport-0001-cryptodisk-Refactor-to-discard-have_it-global.patch +Patch0468: backport-0002-cryptodisk-Return-failure-in-cryptomount-when-no-cry.patch +Patch0469: backport-0003-cryptodisk-Improve-error-messaging-in-cryptomount-in.patch +Patch0470: backport-0004-cryptodisk-Improve-cryptomount-u-error-message.patch +Patch0471: backport-0005-cryptodisk-Add-infrastructure-to-pass-data-from-cryp.patch +Patch0472: backport-0006-cryptodisk-Refactor-password-input-out-of-crypto-dev.patch +Patch0473: backport-0007-cryptodisk-Move-global-variables-into-grub_cryptomou.patch +Patch0474: backport-0008-cryptodisk-Improve-handling-of-partition-name-in-cry.patch +Patch0475: backport-0009-cryptodisk-Fix-Coverity-use-after-free-bug.patch +Patch0476: backport-0010-misc-Implement-grub_strlcpy.patch +Patch0477: backport-0011-fs-ufs-Fix-a-heap-OOB-write.patch +Patch0478: backport-0012-fs-hfs-Fix-stack-OOB-write-with-grub_strcpy.patch +Patch0479: backport-0013-fs-tar-Integer-overflow-leads-to-heap-OOB-write.patch +Patch0480: backport-0014-fs-hfsplus-Set-a-grub_errno-if-mount-fails.patch +Patch0481: backport-0015-disk-cryptodisk-Require-authentication-after-TPM-unl.patch +Patch0482: backport-0016-net-Fix-OOB-write-in-grub_net_search_config_file.patch +Patch0483: backport-0017-video-readers-jpeg-Do-not-permit-duplicate-SOF0-mark.patch +Patch0484: backport-0018-fs-ext2-Fix-out-of-bounds-read-for-inline-extents.patch +Patch0485: backport-0019-fs-ext2-Rework-out-of-bounds-read-for-inline-and-ext.patch +Patch0486: backport-0020-commands-extcmd-Missing-check-for-failed-allocation.patch +Patch0487: backport-0021-commands-pgp-Unregister-the-check_signatures-hooks-o.patch +Patch0488: backport-0022-normal-Remove-variables-hooks-on-module-unload.patch +Patch0489: backport-0023-gettext-Remove-variables-hooks-on-module-unload.patch +Patch0490: backport-0024-gettext-Integer-overflow-leads-to-heap-OOB-write-or-.patch +Patch0491: backport-0025-gettext-Integer-overflow-leads-to-heap-OOB-write.patch +Patch0492: backport-0026-commands-read-Fix-an-integer-overflow-when-supplying.patch +Patch0493: backport-0027-commands-minicmd-Block-the-dump-command-in-lockdown-.patch +Patch0494: backport-0028-fs-bfs-Disable-under-lockdown.patch +Patch0495: backport-0029-fs-Disable-many-filesystems-under-lockdown.patch +Patch0496: backport-0030-fs-Prevent-overflows-when-allocating-memory-for-arra.patch diff --git a/grub2.spec b/grub2.spec index ba094ce1f03cf9165369a94ac0ab2f91f3ae1fef..30de1e03204cdc76741bbda1057dad3ef77a3b7c 100644 --- a/grub2.spec +++ b/grub2.spec @@ -8,7 +8,7 @@ Name: grub2 Epoch: 1 Version: 2.04 -Release: 39 +Release: 40 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -442,6 +442,15 @@ rm -r /boot/grub2.tmp/ || : %{_datadir}/man/man* %changelog +* Sat Feb 22 2025 zhangqiumiao - 1:2.04-40 +- Type:CVE +- CVE:CVE-2024-45781,CVE-2024-45782,CVE-2024-56737,CVE-2024-45780,CVE-2024-45783,CVE-2024-49504,CVE-2025-0624,CVE-20 +24-45774,CVE-2024-45775,CVE-2025-0622,CVE-2025-0622,CVE-2025-0622,CVE-2024-45776,CVE-2024-45777,CVE-2025-0690,CVE-20 +25-1118,CVE-2024-45778,CVE-2024-45779,CVE-2025-0677,CVE-2025-0684,CVE-2025-0685,CVE-2025-0686,CVE-2025-0689,CVE-2025 +-0678,CVE-2025-1125 +- SUG:NA +- DESC:fix the vulnerabilities announced on February 18th, 2025 + * Tue Jun 25 2024 zhangqiumiao - 1:2.04-39 - Type:bugfix - CVE:NA