dcavalca / rpms / grub2

Forked from rpms/grub2 3 years ago
Clone

Blame SOURCES/0322-Fix-a-regression-caused-by-efi-fix-some-malformed-de.patch

b1bcb2
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
c4e390
From: Chris Coulson <chris.coulson@canonical.com>
c4e390
Date: Wed, 22 Jul 2020 17:06:04 +0100
b1bcb2
Subject: [PATCH] Fix a regression caused by "efi: fix some malformed device
b1bcb2
 path arithmetic errors"
c4e390
c4e390
This commit introduced a bogus check inside copy_file_path to
c4e390
determine whether the destination grub_efi_file_path_device_path_t
c4e390
was valid before anything was copied to it. Depending on the
c4e390
contents of the heap buffer, this check could fail which would
c4e390
result in copy_file_path returning early.
c4e390
c4e390
Without any error propagated to the caller, make_file_path would
c4e390
then try to advance the invalid device path node with
c4e390
GRUB_EFI_NEXT_DEVICE_PATH, which would also fail, returning a NULL
c4e390
pointer that would subsequently be dereferenced.
c4e390
c4e390
Remove the bogus check, and also propagate errors from copy_file_path.
c4e390
---
c4e390
 grub-core/loader/efi/chainloader.c | 26 ++++++++++++++------------
c4e390
 1 file changed, 14 insertions(+), 12 deletions(-)
c4e390
c4e390
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
c4e390
index b90dfd6c5a6..dbcdf333b62 100644
c4e390
--- a/grub-core/loader/efi/chainloader.c
c4e390
+++ b/grub-core/loader/efi/chainloader.c
c4e390
@@ -115,7 +115,7 @@ grub_chainloader_boot (void)
c4e390
   return grub_errno;
c4e390
 }
c4e390
 
c4e390
-static void
c4e390
+static grub_err_t
c4e390
 copy_file_path (grub_efi_file_path_device_path_t *fp,
c4e390
 		const char *str, grub_efi_uint16_t len)
c4e390
 {
c4e390
@@ -125,15 +125,9 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
c4e390
   fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE;
c4e390
   fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE;
c4e390
 
c4e390
-  if (!GRUB_EFI_DEVICE_PATH_VALID ((grub_efi_device_path_t *)fp))
c4e390
-    {
c4e390
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "EFI Device Path is invalid");
c4e390
-      return;
c4e390
-    }
c4e390
-
c4e390
   path_name = grub_calloc (len, GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name));
c4e390
   if (!path_name)
c4e390
-    return;
c4e390
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed to allocate path buffer");
c4e390
 
c4e390
   size = grub_utf8_to_utf16 (path_name, len * GRUB_MAX_UTF16_PER_UTF8,
c4e390
 			     (const grub_uint8_t *) str, len, 0);
c4e390
@@ -145,6 +139,8 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
c4e390
   /* File Path is NULL terminated */
c4e390
   fp->path_name[size++] = '\0';
c4e390
   fp->header.length = size * sizeof (grub_efi_char16_t) + sizeof (*fp);
c4e390
+  grub_free (path_name);
c4e390
+  return GRUB_ERR_NONE;
c4e390
 }
c4e390
 
c4e390
 static grub_efi_device_path_t *
c4e390
@@ -202,13 +198,19 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
c4e390
   /* Fill the file path for the directory.  */
c4e390
   d = (grub_efi_device_path_t *) ((char *) file_path
c4e390
 				  + ((char *) d - (char *) dp));
c4e390
-  copy_file_path ((grub_efi_file_path_device_path_t *) d,
c4e390
-		  dir_start, dir_end - dir_start);
c4e390
+  if (copy_file_path ((grub_efi_file_path_device_path_t *) d,
c4e390
+		      dir_start, dir_end - dir_start) != GRUB_ERR_NONE)
c4e390
+    {
c4e390
+    fail:
c4e390
+      grub_free (file_path);
c4e390
+      return 0;
c4e390
+    }
c4e390
 
c4e390
   /* Fill the file path for the file.  */
c4e390
   d = GRUB_EFI_NEXT_DEVICE_PATH (d);
c4e390
-  copy_file_path ((grub_efi_file_path_device_path_t *) d,
c4e390
-		  dir_end + 1, grub_strlen (dir_end + 1));
c4e390
+  if (copy_file_path ((grub_efi_file_path_device_path_t *) d,
c4e390
+		      dir_end + 1, grub_strlen (dir_end + 1)) != GRUB_ERR_NONE)
c4e390
+    goto fail;
c4e390
 
c4e390
   /* Fill the end of device path nodes.  */
c4e390
   d = GRUB_EFI_NEXT_DEVICE_PATH (d);