grub-devel
[Top][All Lists]
Advanced

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

[PATCH] loader/i386/linux: Calculate the setup_header length


From: Daniel Kiper
Subject: [PATCH] loader/i386/linux: Calculate the setup_header length
Date: Fri, 29 Mar 2019 16:09:54 +0100

From: Andrew Jeddeloh <address@hidden>

Previously the setup_header length was just assumed to be the size of the
linux_kernel_params struct. The linux x86 32-bit boot protocol says that
the size of the linux_i386_kernel_header is 0x202 + the byte value at 0x201
in the linux_i386_kernel_header. Calculate the size of the header, rather
than assume it is the size of the linux_kernel_params struct.

Additionally, add some required members to the linux_kernel_params
struct and align the content of linux_i386_kernel_header struct with
it. New members naming was taken directly from Linux kernel source.

linux_kernel_params and linux_i386_kernel_header structs require more
cleanup. However, this is not urgent, so, let's do this after release.
Just in case...

Signed-off-by: Andrew Jeddeloh <address@hidden>
Signed-off-by: Daniel Kiper <address@hidden>
---
 grub-core/loader/i386/linux.c | 16 +++++++++++++++-
 include/grub/i386/linux.h     | 14 ++++++++++++--
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index b6015913b..73e15a90f 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -767,7 +767,21 @@ grub_cmd_linux (grub_command_t cmd __attribute__ 
((unused)),
   linux_params.kernel_alignment = (1 << align);
   linux_params.ps_mouse = linux_params.padding10 =  0;
 
-  len = sizeof (linux_params) - sizeof (lh);
+  /*
+   * The Linux 32-bit boot protocol defines the setup header size
+   * to be 0x202 + the byte value at 0x201.
+   */
+  len = 0x202 + *((char *) &linux_params.jump + 1);
+
+  /* Verify the struct is big enough so we do not write past the end. */
+  if (len > (char *) &linux_params.edd_mbr_sig_buffer - (char *) 
&linux_params) {
+    grub_error (GRUB_ERR_BAD_OS, "Linux setup header too big");
+    goto fail;
+  }
+
+  /* We've already read lh so there is no need to read it second time. */
+  len -= sizeof(lh);
+
   if (grub_file_read (file, (char *) &linux_params + sizeof (lh), len) != len)
     {
       if (!grub_errno)
diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h
index a96059311..ce30e7fb0 100644
--- a/include/grub/i386/linux.h
+++ b/include/grub/i386/linux.h
@@ -46,6 +46,9 @@
 #define VIDEO_CAPABILITY_SKIP_QUIRKS   (1 << 0)
 #define VIDEO_CAPABILITY_64BIT_BASE    (1 << 1)        /* Frame buffer base is 
64-bit. */
 
+/* Maximum number of MBR signatures to store. */
+#define EDD_MBR_SIG_MAX                        16
+
 #ifdef __x86_64__
 
 #define GRUB_LINUX_EFI_SIGNATURE       \
@@ -142,6 +145,7 @@ struct linux_i386_kernel_header
   grub_uint64_t setup_data;
   grub_uint64_t pref_address;
   grub_uint32_t init_size;
+  grub_uint32_t handover_offset;
 } GRUB_PACKED;
 
 /* Boot parameters for Linux based on 2.6.12. This is used by the setup
@@ -273,6 +277,7 @@ struct linux_kernel_params
 
   grub_uint8_t padding9[0x1f1 - 0x1e9];
 
+  /* Linux setup header copy - BEGIN. */
   grub_uint8_t setup_sects;            /* The size of the setup in sectors */
   grub_uint16_t root_flags;            /* If the root is mounted readonly */
   grub_uint16_t syssize;               /* obsolete */
@@ -311,9 +316,14 @@ struct linux_kernel_params
   grub_uint32_t payload_offset;
   grub_uint32_t payload_length;
   grub_uint64_t setup_data;
-  grub_uint8_t pad2[120];              /* 258 */
+  grub_uint64_t pref_address;
+  grub_uint32_t init_size;
+  grub_uint32_t handover_offset;
+  /* Linux setup header copy - END. */
+
+  grub_uint8_t _pad7[40];
+  grub_uint32_t edd_mbr_sig_buffer[EDD_MBR_SIG_MAX];   /* 290 */
   struct grub_e820_mmap e820_map[(0x400 - 0x2d0) / 20];        /* 2d0 */
-
 } GRUB_PACKED;
 #endif /* ! ASM_FILE */
 
-- 
2.11.0




reply via email to

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