loader/i386/linux: Calculate the setup_header length

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
end of the linux_i386_kernel_header is at 0x202 + the byte value at 0x201 in
the linux_i386_kernel_header. So, calculate the size of the header using the
end of the linux_i386_kernel_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 <andrew.jeddeloh@coreos.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Vladimir Serbinenko <phcoder@google.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
This commit is contained in:
Andrew Jeddeloh 2019-03-29 16:09:54 +01:00 committed by Vincent Batts
parent 28031a0791
commit f9b054242e
2 changed files with 32 additions and 4 deletions

View file

@ -787,9 +787,28 @@ 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 end
* to be at 0x202 + the byte value at 0x201.
*/
len = 0x202 + *((char *) &linux_params.jump + 1);
grub_memcpy ((char *) &linux_params + sizeof (lh), kernel + kernel_offset, len);
/* 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)
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
argv[0]);
goto fail;
}
kernel_offset += len;
linux_params.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE;