grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

xen: Fix parsing of XZ kernel.


From: Vladimir 'phcoder' Serbinenko
Subject: xen: Fix parsing of XZ kernel.
Date: Mon, 06 Feb 2017 23:51:52 +0000

In case of xz, the uncompressed size is appended to xz data which confuses
our xz decompressor. Trim it.

Daniel, Andrei, Alexander, do you agree that this should go into 2.02?
---
 grub-core/loader/i386/xen_file.c | 30 ++++++++++++++++++++++++------
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/grub-core/loader/i386/xen_file.c b/grub-core/loader/i386/xen_file.c
index 37f9ad8..eabaf8f 100644
--- a/grub-core/loader/i386/xen_file.c
+++ b/grub-core/loader/i386/xen_file.c
@@ -26,6 +26,8 @@ grub_xen_file (grub_file_t file)
   grub_elf_t elf;
   struct linux_kernel_header lh;
   grub_file_t off_file;
+  grub_uint32_t payload_offset, payload_length;
+  grub_uint8_t magic[6];
 
   elf = grub_elf_file (file, file->name);
   if (elf)
@@ -46,20 +48,36 @@ grub_xen_file (grub_file_t file)
       return NULL;
     }
 
-  if (lh.payload_length < 4)
+  payload_length = lh.payload_length;
+  payload_offset = (lh.setup_sects + 1) * 512
+    + lh.payload_offset;
+
+  if (payload_length < sizeof (magic))
     {
       grub_error (GRUB_ERR_BAD_OS, "payload too short");
       return NULL;
     }
 
   grub_dprintf ("xen", "found bzimage payload 0x%llx-0x%llx\n",
- (unsigned long long) (lh.setup_sects + 1) * 512
- + lh.payload_offset,
+ (unsigned long long) payload_offset,
  (unsigned long long) lh.payload_length);
 
-  off_file = grub_file_offset_open (file, (lh.setup_sects + 1) * 512
-    + lh.payload_offset,
-    lh.payload_length);
+  grub_file_seek (file, payload_offset);
+
+  if (grub_file_read (file, &magic, sizeof (magic)) != sizeof (magic))
+    {
+      if (!grub_errno)
+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
+    file->name);
+      goto fail;
+    }
+
+  /* Kernel suffixes xz payload with their uncompressed size.
+     Trim it.  */
+  if (grub_memcmp (magic, "\3757zXZ\0", 6) == 0)
+    payload_length -= 4;
+  off_file = grub_file_offset_open (file, payload_offset,
+    payload_length);
   if (!off_file)
     goto fail;
 
-- 
2.9.3


reply via email to

[Prev in Thread] Current Thread [Next in Thread]