1*4882a593SmuzhiyunFrom fb55bc37dd510911df4eaf649da939f5fafdc7ce Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: Daniel Kiper <daniel.kiper@oracle.com>
3*4882a593SmuzhiyunDate: Wed, 29 Jul 2020 13:38:31 +0200
4*4882a593SmuzhiyunSubject: [PATCH] efi/chainloader: Propagate errors from copy_file_path()
5*4882a593SmuzhiyunMIME-Version: 1.0
6*4882a593SmuzhiyunContent-Type: text/plain; charset=UTF-8
7*4882a593SmuzhiyunContent-Transfer-Encoding: 8bit
8*4882a593Smuzhiyun
9*4882a593SmuzhiyunWithout any error propagated to the caller, make_file_path()
10*4882a593Smuzhiyunwould then try to advance the invalid device path node with
11*4882a593SmuzhiyunGRUB_EFI_NEXT_DEVICE_PATH(), which would fail, returning a NULL
12*4882a593Smuzhiyunpointer that would subsequently be dereferenced. Hence, propagate
13*4882a593Smuzhiyunerrors from copy_file_path().
14*4882a593Smuzhiyun
15*4882a593SmuzhiyunSigned-off-by: Chris Coulson <chris.coulson@canonical.com>
16*4882a593SmuzhiyunReviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
17*4882a593SmuzhiyunSigned-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
18*4882a593Smuzhiyun---
19*4882a593Smuzhiyun grub-core/loader/efi/chainloader.c | 19 +++++++++++++------
20*4882a593Smuzhiyun 1 file changed, 13 insertions(+), 6 deletions(-)
21*4882a593Smuzhiyun
22*4882a593Smuzhiyundiff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
23*4882a593Smuzhiyunindex a8d7b9155..7b31c3fb9 100644
24*4882a593Smuzhiyun--- a/grub-core/loader/efi/chainloader.c
25*4882a593Smuzhiyun+++ b/grub-core/loader/efi/chainloader.c
26*4882a593Smuzhiyun@@ -106,7 +106,7 @@ grub_chainloader_boot (void)
27*4882a593Smuzhiyun   return grub_errno;
28*4882a593Smuzhiyun }
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun-static void
31*4882a593Smuzhiyun+static grub_err_t
32*4882a593Smuzhiyun copy_file_path (grub_efi_file_path_device_path_t *fp,
33*4882a593Smuzhiyun 		const char *str, grub_efi_uint16_t len)
34*4882a593Smuzhiyun {
35*4882a593Smuzhiyun@@ -118,7 +118,7 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun   path_name = grub_calloc (len, GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name));
38*4882a593Smuzhiyun   if (!path_name)
39*4882a593Smuzhiyun-    return;
40*4882a593Smuzhiyun+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed to allocate path buffer");
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun   size = grub_utf8_to_utf16 (path_name, len * GRUB_MAX_UTF16_PER_UTF8,
43*4882a593Smuzhiyun 			     (const grub_uint8_t *) str, len, 0);
44*4882a593Smuzhiyun@@ -131,6 +131,7 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
45*4882a593Smuzhiyun   fp->path_name[size++] = '\0';
46*4882a593Smuzhiyun   fp->header.length = size * sizeof (grub_efi_char16_t) + sizeof (*fp);
47*4882a593Smuzhiyun   grub_free (path_name);
48*4882a593Smuzhiyun+  return GRUB_ERR_NONE;
49*4882a593Smuzhiyun }
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun static grub_efi_device_path_t *
52*4882a593Smuzhiyun@@ -189,13 +190,19 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
53*4882a593Smuzhiyun   d = (grub_efi_device_path_t *) ((char *) file_path
54*4882a593Smuzhiyun 				  + ((char *) d - (char *) dp));
55*4882a593Smuzhiyun   grub_efi_print_device_path (d);
56*4882a593Smuzhiyun-  copy_file_path ((grub_efi_file_path_device_path_t *) d,
57*4882a593Smuzhiyun-		  dir_start, dir_end - dir_start);
58*4882a593Smuzhiyun+  if (copy_file_path ((grub_efi_file_path_device_path_t *) d,
59*4882a593Smuzhiyun+		      dir_start, dir_end - dir_start) != GRUB_ERR_NONE)
60*4882a593Smuzhiyun+    {
61*4882a593Smuzhiyun+ fail:
62*4882a593Smuzhiyun+      grub_free (file_path);
63*4882a593Smuzhiyun+      return 0;
64*4882a593Smuzhiyun+    }
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun   /* Fill the file path for the file.  */
67*4882a593Smuzhiyun   d = GRUB_EFI_NEXT_DEVICE_PATH (d);
68*4882a593Smuzhiyun-  copy_file_path ((grub_efi_file_path_device_path_t *) d,
69*4882a593Smuzhiyun-		  dir_end + 1, grub_strlen (dir_end + 1));
70*4882a593Smuzhiyun+  if (copy_file_path ((grub_efi_file_path_device_path_t *) d,
71*4882a593Smuzhiyun+		      dir_end + 1, grub_strlen (dir_end + 1)) != GRUB_ERR_NONE)
72*4882a593Smuzhiyun+    goto fail;
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun   /* Fill the end of device path nodes.  */
75*4882a593Smuzhiyun   d = GRUB_EFI_NEXT_DEVICE_PATH (d);
76*4882a593Smuzhiyun--
77*4882a593Smuzhiyun2.26.2
78*4882a593Smuzhiyun
79