grub-devel
[Top][All Lists]
Advanced

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

[PATCH] loader/i386/linux: calculate the size of the setup header


From: Andrew Jeddeloh
Subject: [PATCH] loader/i386/linux: calculate the size of the setup header
Date: Wed, 9 May 2018 10:46:47 -0700

This patch is prompted from a question I asked a while ago about why
the disk read is necessary. See the thread here [1].

This changes the disk read to use the length of the setup header as
calculated by the x86 32 bit linux boot protocol [1]. I'm not 100%
sure its patch that's wanted however. The idea was that grub should
only read the amount specified by the boot protocol and not more, but
it turns out the size of the linux_kernel_params struct is already
sized such that grub reads the exact amount anyway (at least with the
recent kernels I've tested with). This introduces two changes:
 - if a new version of linux makes the setup headers section larger,
this will fail instead of only readiing the old fields. I'm not sure
if this behavior is desired.
 - If older versions have a smaller setup header section, less will be read.

[1] http://lists.gnu.org/archive/html/grub-devel/2018-04/msg00073.html
[2] 
https://raw.githubusercontent.com/torvalds/linux/master/Documentation/x86/boot.txt


Previously the length was just assumed to be the size of the
linux_params struct. The linux x86 32 bit boot protocol says the size of
the setup header is 0x202 + the byte at 0x201 in the boot params.
Calculate the size of the header, rather than assume it is the size of
the linux_params struct.

Signed-off-by: Andrew Jeddeloh <address@hidden>
---
 grub-core/loader/i386/linux.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index 44301e126..9b4d33785 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -805,7 +805,16 @@ 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 size of
+  // the jump at 0x200. We've already read sizeof(lh)
+  len = *((char *)&linux_params.jump + 1) + 0x202 - sizeof(lh);
+
+  // Verify the struct is big enough so we do not write past the end
+  if (len + sizeof(lh) > sizeof(linux_params)) {
+    grub_error (GRUB_ERR_BAD_OS, "boot params setup header too big
for linux_params struct");
+    goto fail;
+  }
+
   if (grub_file_read (file, (char *) &linux_params + sizeof (lh), len) != len)
     {
       if (!grub_errno)
-- 
2.14.1



reply via email to

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