grub-devel.gnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC] efi/chainloader: build image path as single File Path
@ 2017-02-24  6:54 Andrei Borzenkov
  2017-02-24  8:43 ` [PATCH] efi: strip off final NULL from File Path in grub_efi_get_filename Andrei Borzenkov
  0 siblings, 1 reply; 4+ messages in thread
From: Andrei Borzenkov @ 2017-02-24  6:54 UTC (permalink / raw)
  To: grub-devel; +Cc: mchang

According to EFI 9.3.6.4 File Path Media Device Path, Path Name is

A NULL-terminated Path string including directory and file
names.

EFI chainloader is using two File Path nodes for image name - directory and
file. It appears that at least some firmware implementations interpret NULL
terminated directory path as end of full pathname, thus truncating it.

OTOH leaving path names non-NULL terminated caused other errors (see
commit ce95549cc54b5d6f494608a7c390dba3aab4fba7)

Use single File Path node containing both directory and file name to avoid it.

See also https://bugzilla.opensuse.org/show_bug.cgi?id=1026344

---

Anyone remembers why we build complete path using two nodes? As far as I can
tell no other bootloader does it. I am really uneasy to do it now, but we have
known bugs both with and without ce95549cc54b5d6f494608a7c390dba3aab4fba7 and
this looks like the most straightforward fix.

 grub-core/loader/efi/chainloader.c | 16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index adc8563..329dd57 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -158,29 +158,23 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
       d = GRUB_EFI_NEXT_DEVICE_PATH (d);
     }
 
-  /* File Path is NULL terminated. Allocate space for 2 extra characters */
-  /* FIXME why we split path in two components? */
+  /* File Path is NULL terminated. Allocate space for extra character */
   file_path = grub_malloc (size
-			   + ((grub_strlen (dir_start) + 2)
+			   + ((grub_strlen (dir_start) + 1)
 			      * GRUB_MAX_UTF16_PER_UTF8
 			      * sizeof (grub_efi_char16_t))
-			   + sizeof (grub_efi_file_path_device_path_t) * 2);
+			   + sizeof (grub_efi_file_path_device_path_t));
   if (! file_path)
     return 0;
 
   grub_memcpy (file_path, dp, size);
 
-  /* Fill the file path for the directory.  */
+  /* Fill the complete file path.  */
   d = (grub_efi_device_path_t *) ((char *) file_path
 				  + ((char *) d - (char *) dp));
   grub_efi_print_device_path (d);
   copy_file_path ((grub_efi_file_path_device_path_t *) d,
-		  dir_start, dir_end - dir_start);
-
-  /* Fill the file path for the file.  */
-  d = GRUB_EFI_NEXT_DEVICE_PATH (d);
-  copy_file_path ((grub_efi_file_path_device_path_t *) d,
-		  dir_end + 1, grub_strlen (dir_end + 1));
+		  dir_start, grub_strlen (dir_start));
 
   /* Fill the end of device path nodes.  */
   d = GRUB_EFI_NEXT_DEVICE_PATH (d);
-- 
tg: (2fb8cd2..) u/use-single-file-path-in-efi-chainloader (depends on: master)


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH] efi: strip off final NULL from File Path in grub_efi_get_filename
  2017-02-24  6:54 [PATCH RFC] efi/chainloader: build image path as single File Path Andrei Borzenkov
@ 2017-02-24  8:43 ` Andrei Borzenkov
  2017-02-24 23:21   ` Vladimir 'phcoder' Serbinenko
  0 siblings, 1 reply; 4+ messages in thread
From: Andrei Borzenkov @ 2017-02-24  8:43 UTC (permalink / raw)
  To: grub-devel; +Cc: mchang

UEFI 2.6 9.3.6.4 File Path Media Device Path says that Path Name is
"A NULL-terminated Path string including directory and file names".

Strip final NULL from Path Name in each File Path node when constructing
full path. To be on safe side, strip all of them.

Fixes failure chainloading grub from grub, when loaded grub truncates
image path and does not find its grub.cfg.

https://bugzilla.opensuse.org/show_bug.cgi?id=1026344

This was triggered by commit ce95549cc54b5d6f494608a7c390dba3aab4fba7;
before it we built Path Name without trailing NULL, and apparently all
other bootloaders use single File Path node, thus not exposing this bug.

---
@Vladimir, @Daniel - this fixes regression in rc1 and is real fix for
the mentioned problem (previous patch only fixed the case of grub - grub
chainloading, this patch should properly parse image path also when called
from other EFI application).

 grub-core/kern/efi/efi.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
index caf9bcc..d467785 100644
--- a/grub-core/kern/efi/efi.c
+++ b/grub-core/kern/efi/efi.c
@@ -366,6 +366,9 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
 	  len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
 		 / sizeof (grub_efi_char16_t));
 	  fp = (grub_efi_file_path_device_path_t *) dp;
+	  /* According to EFI spec Path Name is NULL terminated */
+	  while (len > 0 && fp->path_name[len - 1] == 0)
+	    len--;
 
 	  p = (char *) grub_utf16_to_utf8 ((unsigned char *) p, fp->path_name, len);
 	}
-- 
tg: (2fb8cd2..) u/efi-strip-final-NULL-from-file-path (depends on: master)


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] efi: strip off final NULL from File Path in grub_efi_get_filename
  2017-02-24  8:43 ` [PATCH] efi: strip off final NULL from File Path in grub_efi_get_filename Andrei Borzenkov
@ 2017-02-24 23:21   ` Vladimir 'phcoder' Serbinenko
  2017-02-25  5:44     ` Andrei Borzenkov
  0 siblings, 1 reply; 4+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2017-02-24 23:21 UTC (permalink / raw)
  To: The development of GNU GRUB; +Cc: mchang

[-- Attachment #1: Type: text/plain, Size: 2231 bytes --]

On Fri, Feb 24, 2017, 09:47 Andrei Borzenkov <arvidjaar@gmail.com> wrote:

> UEFI 2.6 9.3.6.4 File Path Media Device Path says that Path Name is
> "A NULL-terminated Path string including directory and file names".
>
> Strip final NULL from Path Name in each File Path node when constructing
> full path. To be on safe side, strip all of them.
>
> Fixes failure chainloading grub from grub, when loaded grub truncates
> image path and does not find its grub.cfg.
>
> https://bugzilla.opensuse.org/show_bug.cgi?id=1026344
>
> This was triggered by commit ce95549cc54b5d6f494608a7c390dba3aab4fba7;
> before it we built Path Name without trailing NULL, and apparently all
> other bootloaders use single File Path node, thus not exposing this bug.
>
> ---
> @Vladimir, @Daniel - this fixes regression in rc1 and is real fix for
> the mentioned problem (previous patch only fixed the case of grub - grub
> chainloading, this patch should properly parse image path also when called
> from other EFI application).
>
I'm OK with this patch. Especially that it's unlikely to break anything. Is
the other patch still needed? If other loaders do it with a single path
element we should probably too, to avoid this kind of bugs. Question is
mostly whether it's rc1 material.

>
>  grub-core/kern/efi/efi.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
> index caf9bcc..d467785 100644
> --- a/grub-core/kern/efi/efi.c
> +++ b/grub-core/kern/efi/efi.c
> @@ -366,6 +366,9 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
>           len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
>                  / sizeof (grub_efi_char16_t));
>           fp = (grub_efi_file_path_device_path_t *) dp;
> +         /* According to EFI spec Path Name is NULL terminated */
> +         while (len > 0 && fp->path_name[len - 1] == 0)
> +           len--;
>
>           p = (char *) grub_utf16_to_utf8 ((unsigned char *) p,
> fp->path_name, len);
>         }
> --
> tg: (2fb8cd2..) u/efi-strip-final-NULL-from-file-path (depends on: master)
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
>

[-- Attachment #2: Type: text/html, Size: 3953 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] efi: strip off final NULL from File Path in grub_efi_get_filename
  2017-02-24 23:21   ` Vladimir 'phcoder' Serbinenko
@ 2017-02-25  5:44     ` Andrei Borzenkov
  0 siblings, 0 replies; 4+ messages in thread
From: Andrei Borzenkov @ 2017-02-25  5:44 UTC (permalink / raw)
  To: The development of GNU GRUB; +Cc: mchang

25.02.2017 02:21, Vladimir 'phcoder' Serbinenko пишет:
> On Fri, Feb 24, 2017, 09:47 Andrei Borzenkov <arvidjaar@gmail.com> wrote:
> 
>> UEFI 2.6 9.3.6.4 File Path Media Device Path says that Path Name is
>> "A NULL-terminated Path string including directory and file names".
>>
>> Strip final NULL from Path Name in each File Path node when constructing
>> full path. To be on safe side, strip all of them.
>>
>> Fixes failure chainloading grub from grub, when loaded grub truncates
>> image path and does not find its grub.cfg.
>>
>> https://bugzilla.opensuse.org/show_bug.cgi?id=1026344
>>
>> This was triggered by commit ce95549cc54b5d6f494608a7c390dba3aab4fba7;
>> before it we built Path Name without trailing NULL, and apparently all
>> other bootloaders use single File Path node, thus not exposing this bug.
>>
>> ---
>> @Vladimir, @Daniel - this fixes regression in rc1 and is real fix for
>> the mentioned problem (previous patch only fixed the case of grub - grub
>> chainloading, this patch should properly parse image path also when called
>> from other EFI application).
>>
> I'm OK with this patch. Especially that it's unlikely to break anything. Is

Committed.

> the other patch still needed? If other loaders do it with a single path
> element we should probably too, to avoid this kind of bugs. Question is
> mostly whether it's rc1 material.
> 

It is not needed. I would still consider it long term - it makes code
less confusing and avoids probably less-utilized code paths elsewhere.

It also demonstrates that we desperately need EFI boot tests. Much
thanks to SUSE for setting up comprehensive test suite!



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-02-25  5:44 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-02-24  6:54 [PATCH RFC] efi/chainloader: build image path as single File Path Andrei Borzenkov
2017-02-24  8:43 ` [PATCH] efi: strip off final NULL from File Path in grub_efi_get_filename Andrei Borzenkov
2017-02-24 23:21   ` Vladimir 'phcoder' Serbinenko
2017-02-25  5:44     ` Andrei Borzenkov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).