cmd/search: Rework of CVE-2023-4001 fix

Related: #2224951
Resolved: #2263369
Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
This commit is contained in:
Nicolas Frayer 2024-04-19 17:57:13 +02:00
parent a25b6d7a50
commit 6dd575bf56
3 changed files with 190 additions and 4 deletions

View file

@ -0,0 +1,180 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nicolas Frayer <nfrayer@redhat.com>
Date: Thu, 16 May 2024 10:58:32 +0200
Subject: [PATCH] cmd/search: Rework of CVE-2023-4001 fix
The initial fix implemented a new flag that forces the grub cfg
stub to be located on the same disk as grub. This created several
issues such as RAID machines not being able to boot as their
partition names under grub were different from the partition where
grub is located. It also simply means that any machines with the
/boot partition located on a disk other than the one containing grub
won't boot.
This commit denies booting if the grub cfg stub is located on a USB
drive with a duplicated UUID (UUID being the same as the partition
containing the actual grub cfg stub)
Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
---
grub-core/commands/search.c | 134 +++++++++++++++++++++++++++++++++++++++++---
1 file changed, 126 insertions(+), 8 deletions(-)
diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
index 4735feefcde5..5956b39dca72 100644
--- a/grub-core/commands/search.c
+++ b/grub-core/commands/search.c
@@ -30,6 +30,8 @@
#include <grub/i18n.h>
#include <grub/disk.h>
#include <grub/partition.h>
+#include <grub/efi/api.h>
+#include <grub/time.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -54,6 +56,100 @@ struct search_ctx
int is_cache;
};
+static int
+is_device_usb (const char *name)
+{
+ int ret = 0;
+
+ grub_device_t dev = grub_device_open(name);
+
+ if (dev)
+ {
+ struct grub_efidisk_data
+ {
+ grub_efi_handle_t handle;
+ grub_efi_device_path_t *device_path;
+ grub_efi_device_path_t *last_device_path;
+ grub_efi_block_io_t *block_io;
+ struct grub_efidisk_data *next;
+ };
+
+ if (dev->disk && dev->disk->data)
+ {
+ struct grub_efidisk_data *dp = dev->disk->data;
+
+ if ( GRUB_EFI_DEVICE_PATH_TYPE (dp->last_device_path) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE &&
+ GRUB_EFI_DEVICE_PATH_SUBTYPE (dp->last_device_path) == GRUB_EFI_USB_DEVICE_PATH_SUBTYPE)
+ {
+ ret = 1;
+ }
+ }
+ grub_device_close(dev);
+ }
+
+ return ret;
+}
+
+static int
+get_device_uuid(const char *name, char** quid)
+{
+ int ret = 0;
+
+ grub_device_t dev_part = grub_device_open(name);
+
+ if (dev_part)
+ {
+ grub_fs_t fs;
+
+ fs = grub_fs_probe (dev_part);
+
+#ifdef DO_SEARCH_FS_UUID
+#define read_fn fs_uuid
+#else
+#define read_fn fs_label
+#endif
+ if (fs && fs->read_fn)
+ {
+ fs->read_fn (dev_part, quid);
+
+ if (grub_errno == GRUB_ERR_NONE && *quid)
+ {
+ ret = 1;
+ }
+
+ }
+ grub_device_close (dev_part);
+ }
+
+ return ret;
+}
+struct uuid_context {
+ char* name;
+ char* uuid;
+};
+
+static int
+check_for_duplicate (const char *name, void *data)
+{
+ int ret = 0;
+ struct uuid_context * uuid_ctx = (struct uuid_context *)data;
+ char *quid = 0;
+
+ get_device_uuid(name, &quid);
+
+ if (quid == NULL)
+ return 0;
+
+ if (!grub_strcasecmp(quid, uuid_ctx->uuid) && grub_strcasecmp(name, uuid_ctx->name))
+ {
+ ret = 1;
+ }
+
+ grub_free(quid);
+
+ return ret;
+}
+
/* Helper for FUNC_NAME. */
static int
iterate_device (const char *name, void *data)
@@ -106,14 +202,36 @@ iterate_device (const char *name, void *data)
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_device_t dev, dev_part;
+
+ if (is_device_usb(name) && !is_device_usb(root_dev))
+ {
+ char *quid_name = NULL;
+ int longlist = 0;
+ struct uuid_context uuid_ctx;
+ int ret = 0;
+
+ get_device_uuid(name, &quid_name);
+ if (!grub_strcmp(quid_name, ctx->key))
+ {
+ uuid_ctx.name = name;
+ uuid_ctx.uuid = quid_name;
+
+ ret = grub_device_iterate (check_for_duplicate, &uuid_ctx);
+
+ if (ret)
+ {
+ grub_printf("Duplicated media UUID found, rebooting ...\n");
+ grub_sleep(10);
+ grub_reboot();
+ }
+ }
+
+ if (quid_name) grub_free (quid_name);
+
+ }
+ }
}
grub_free (root_disk);
grub_free (name_disk);

View file

@ -357,3 +357,4 @@ Patch0356: 0356-fs-ntfs-Fix-an-OOB-read-when-parsing-bitmaps-for-ind.patch
Patch0357: 0357-fs-ntfs-Fix-an-OOB-read-when-parsing-a-volume-label.patch
Patch0358: 0358-fs-ntfs-Make-code-more-readable.patch
Patch0359: 0359-fs-xfs-Handle-non-continuous-data-blocks-in-director.patch
Patch0360: 0360-cmd-search-Rework-of-CVE-2023-4001-fix.patch

View file

@ -17,7 +17,7 @@
Name: grub2
Epoch: 1
Version: 2.06
Release: 120%{?dist}
Release: 121%{?dist}
Summary: Bootloader with support for Linux, Multiboot and more
License: GPLv3+
URL: http://www.gnu.org/software/grub/
@ -357,9 +357,11 @@ fi
if test ! -f ${EFI_HOME}/grub.cfg; then
# there's no config in ESP, create one
grub2-mkconfig -o ${EFI_HOME}/grub.cfg
cp -a ${EFI_HOME}/grub.cfg ${EFI_HOME}/grub.cfg.rpmsave
cp -a ${EFI_HOME}/grub.cfg ${GRUB_HOME}/
fi
if ((grep -q "configfile" ${EFI_HOME}/grub.cfg || grep -q "source" ${EFI_HOME}/grub.cfg) && ! grep -q "# It is automatically generated by grub2-mkconfig using templates" ${EFI_HOME}/grub.cfg); then
if (((grep -q "configfile" ${EFI_HOME}/grub.cfg && grep -q "root-dev-only" ${EFI_HOME}/grub.cfg) || grep -q "source" ${EFI_HOME}/grub.cfg) && ! grep -q "# It is automatically generated by grub2-mkconfig using templates" ${EFI_HOME}/grub.cfg); then
exit 0 #Already unified
fi
@ -379,8 +381,6 @@ if test -f ${EFI_HOME}/grubenv; then
mv --force ${EFI_HOME}/grubenv ${GRUB_HOME}/grubenv
fi
cp -a ${EFI_HOME}/grub.cfg ${EFI_HOME}/grub.cfg.rpmsave
cp -a ${EFI_HOME}/grub.cfg ${GRUB_HOME}/
mv ${EFI_HOME}/grub.cfg.stb ${EFI_HOME}/grub.cfg
%files common -f grub.lang
@ -554,6 +554,11 @@ mv ${EFI_HOME}/grub.cfg.stb ${EFI_HOME}/grub.cfg
%endif
%changelog
* Fri Apr 12 2024 Nicolas Frayer <nfrayer@redhat.com> - 2.06-121
- cmd/search: Rework of CVE-2023-4001 fix
- Related: #2224951
- Resolved: #2263369
* Fri Apr 12 2024 Nicolas Frayer <nfrayer@redhat.com> - 2.06-120
- fs/xfs: Handle non-continuous data blocks in directory extents
- Related: #2254370