From d2d9f6012b8fb9173db0317e316c89f74f716319 Mon Sep 17 00:00:00 2001 From: Nicolas Frayer Date: Jan 18 2024 14:22:34 +0000 Subject: grub-core/commands: add flag to only search root dev Resolves: #2223437 Resolves: #2224951 Resolves: #2258096 Resolves: CVE-2023-4001 Signed-off-by: Nicolas Frayer --- diff --git a/0348-add-flag-to-only-search-root-dev.patch b/0348-add-flag-to-only-search-root-dev.patch new file mode 100644 index 0000000..8ae8875 --- /dev/null +++ b/0348-add-flag-to-only-search-root-dev.patch @@ -0,0 +1,160 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Marta Lewandowska +Date: Mon, 9 Oct 2023 08:53:18 +0200 +Subject: [PATCH] add flag to only search root dev + +fixes bz#2223437 + +Signed-off-by: Marta Lewandowska +--- + grub-core/commands/search.c | 36 ++++++++++++++++++++++++++++++++++++ + grub-core/commands/search_wrap.c | 5 +++++ + grub-core/kern/misc.c | 30 ++++++++++++++++++++++++++++++ + include/grub/misc.h | 1 + + include/grub/search.h | 3 ++- + 5 files changed, 74 insertions(+), 1 deletion(-) + +diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c +index 57d26ced8a8e..819231751c38 100644 +--- a/grub-core/commands/search.c ++++ b/grub-core/commands/search.c +@@ -85,6 +85,42 @@ iterate_device (const char *name, void *data) + grub_device_close (dev); + } + ++ /* Skip it if it's not the root device when requested. */ ++ if (ctx->flags & SEARCH_FLAGS_ROOTDEV_ONLY) ++ { ++ const char *root_dev; ++ root_dev = grub_env_get ("root"); ++ if (root_dev != NULL && *root_dev != '\0') ++ { ++ char *root_disk = grub_malloc (grub_strlen(root_dev) + 1); ++ char *name_disk = grub_malloc (grub_strlen(name) + 1); ++ char *rem_1 = grub_malloc(grub_strlen(root_dev) + 1); ++ char *rem_2 = grub_malloc(grub_strlen(name) + 1); ++ ++ if (root_disk != NULL && name_disk != NULL && ++ rem_1 != NULL && rem_2 != NULL) ++ { ++ /* get just the disk name; partitions will be different. */ ++ grub_str_sep (root_dev, root_disk, ',', rem_1); ++ grub_str_sep (name, name_disk, ',', rem_2); ++ if (root_disk != NULL && *root_disk != '\0' && ++ name_disk != NULL && *name_disk != '\0') ++ if (grub_strcmp(root_disk, name_disk) != 0) ++ { ++ grub_free (root_disk); ++ grub_free (name_disk); ++ grub_free (rem_1); ++ grub_free (rem_2); ++ return 0; ++ } ++ } ++ grub_free (root_disk); ++ grub_free (name_disk); ++ grub_free (rem_1); ++ grub_free (rem_2); ++ } ++ } ++ + #ifdef DO_SEARCH_FS_UUID + #define compare_fn grub_strcasecmp + #else +diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c +index 0b62acf85359..06b5f51eefb5 100644 +--- a/grub-core/commands/search_wrap.c ++++ b/grub-core/commands/search_wrap.c +@@ -41,6 +41,7 @@ static const struct grub_arg_option options[] = + ARG_TYPE_STRING}, + {"no-floppy", 'n', 0, N_("Do not probe any floppy drive."), 0, 0}, + {"efidisk-only", 0, 0, N_("Only probe EFI disks."), 0, 0}, ++ {"root-dev-only", 'r', 0, N_("Only probe root device."), 0, 0}, + {"hint", 'h', GRUB_ARG_OPTION_REPEATABLE, + N_("First try the device HINT. If HINT ends in comma, " + "also try subpartitions"), N_("HINT"), ARG_TYPE_STRING}, +@@ -75,6 +76,7 @@ enum options + SEARCH_SET, + SEARCH_NO_FLOPPY, + SEARCH_EFIDISK_ONLY, ++ SEARCH_ROOTDEV_ONLY, + SEARCH_HINT, + SEARCH_HINT_IEEE1275, + SEARCH_HINT_BIOS, +@@ -189,6 +191,9 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args) + if (state[SEARCH_EFIDISK_ONLY].set) + flags |= SEARCH_FLAGS_EFIDISK_ONLY; + ++ if (state[SEARCH_ROOTDEV_ONLY].set) ++ flags |= SEARCH_FLAGS_ROOTDEV_ONLY; ++ + if (state[SEARCH_LABEL].set) + grub_search_label (id, var, flags, hints, nhints); + else if (state[SEARCH_FS_UUID].set) +diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c +index cb454614022f..c0ac7fee6cc2 100644 +--- a/grub-core/kern/misc.c ++++ b/grub-core/kern/misc.c +@@ -619,6 +619,36 @@ grub_reverse (char *str) + } + } + ++/* Separate string into two parts, broken up by delimiter delim. */ ++void ++grub_str_sep (const char *s, char *p, char delim, char *r) ++{ ++ char* t = grub_strndup(s, grub_strlen(s)); ++ ++ if (t != NULL && *t != '\0') ++ { ++ char* tmp = t; ++ ++ while (((*p = *t) != '\0') && ((*p = *t) != delim)) ++ { ++ p++; ++ t++; ++ } ++ *p = '\0'; ++ ++ if (*t != '\0') ++ { ++ t++; ++ while ((*r++ = *t++) != '\0') ++ ; ++ *r = '\0'; ++ } ++ grub_free (tmp); ++ } ++ else ++ grub_free (t); ++} ++ + /* Divide N by D, return the quotient, and store the remainder in *R. */ + grub_uint64_t + grub_divmod64 (grub_uint64_t n, grub_uint64_t d, grub_uint64_t *r) +diff --git a/include/grub/misc.h b/include/grub/misc.h +index faae0ae8606c..981526644d29 100644 +--- a/include/grub/misc.h ++++ b/include/grub/misc.h +@@ -314,6 +314,7 @@ void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n); + grub_size_t EXPORT_FUNC(grub_strlen) (const char *s) WARN_UNUSED_RESULT; + int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2))); + int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2))); ++void EXPORT_FUNC(grub_str_sep) (const char *s, char *p, char delim, char *r); + + /* Replace all `ch' characters of `input' with `with' and copy the + result into `output'; return EOS address of `output'. */ +diff --git a/include/grub/search.h b/include/grub/search.h +index 4190aeb2cbf5..321d1400e451 100644 +--- a/include/grub/search.h ++++ b/include/grub/search.h +@@ -22,7 +22,8 @@ + enum search_flags + { + SEARCH_FLAGS_NO_FLOPPY = 1, +- SEARCH_FLAGS_EFIDISK_ONLY = 2 ++ SEARCH_FLAGS_EFIDISK_ONLY = 2, ++ SEARCH_FLAGS_ROOTDEV_ONLY = 4 + }; + + void grub_search_fs_file (const char *key, const char *var, diff --git a/grub.patches b/grub.patches index e791a0b..caf506f 100644 --- a/grub.patches +++ b/grub.patches @@ -345,3 +345,4 @@ Patch0344: 0344-fs-xfs-Incorrect-short-form-directory-data-boundary-.patch Patch0345: 0345-fs-xfs-Add-large-extent-counters-incompat-feature-su.patch Patch0346: 0346-chainloader-remove-device-path-debug-message.patch Patch0347: 0347-normal-Remove-grub_env_set-prefix-in-grub_try_normal.patch +Patch0348: 0348-add-flag-to-only-search-root-dev.patch diff --git a/grub2.spec b/grub2.spec index ee8599e..2929175 100644 --- a/grub2.spec +++ b/grub2.spec @@ -17,7 +17,7 @@ Name: grub2 Epoch: 1 Version: 2.06 -Release: 115%{?dist} +Release: 116%{?dist} Summary: Bootloader with support for Linux, Multiboot and more License: GPL-3.0-or-later URL: http://www.gnu.org/software/grub/ @@ -368,7 +368,7 @@ BOOT_UUID=$(grub2-probe --target=fs_uuid ${GRUB_HOME}) GRUB_DIR=$(grub2-mkrelpath ${GRUB_HOME}) cat << EOF > ${EFI_HOME}/grub.cfg.stb -search --no-floppy --fs-uuid --set=dev ${BOOT_UUID} +search --no-floppy --root-dev-only --fs-uuid --set=dev ${BOOT_UUID} set prefix=(\$dev)${GRUB_DIR} export \$prefix configfile \$prefix/grub.cfg @@ -554,6 +554,13 @@ mv ${EFI_HOME}/grub.cfg.stb ${EFI_HOME}/grub.cfg %endif %changelog +* Wed Jan 17 2024 Nicolas Frayer - 2.06-116 +- grub-core/commands: add flag to only search root dev +- Resolves: #2223437 +- Resolves: #2224951 +- Resolves: #2258096 +- Resolves: CVE-2023-4001 + * Wed Jan 17 2024 Nicolas Frayer - 2.06-115 - xfs: some bios systems can't boot with one of the xfs upstream patches - Resolves: #2254370