grub-devel
[Top][All Lists]
Advanced

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

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


From: Daniel Kiper
Subject: Re: [PATCH] loader/i386/linux: calculate the size of the setup header
Date: Thu, 10 May 2018 19:11:33 +0200
User-agent: Mutt/1.3.28i

On Wed, May 09, 2018 at 10:46:47AM -0700, Andrew Jeddeloh wrote:
> 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

There is no doubt. We want this patch.

> 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:

OK but earlier you have told that linux_kernel_params.e820_map[] is
overwritten. Is it still valid?

>  - 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.

It is but math is wrong. Please look below.

>  - If older versions have a smaller setup header section, less will be read.

Exactly.

> [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)

s/the size of the jump at 0x200/byte value at offset 0x201/

s/We've already read sizeof(lh)//

And please use /* ... */ for comments instead of //

> +  len = *((char *)&linux_params.jump + 1) + 0x202 - sizeof(lh);

len = *((char *)&linux_params.jump + 1) + 0x202;

> +  // Verify the struct is big enough so we do not write past the end
> +  if (len + sizeof(lh) > sizeof(linux_params)) {

if (len > &linux_params.e820_map - &linux_params)

> +    grub_error (GRUB_ERR_BAD_OS, "boot params setup header too big
> for linux_params struct");

s/boot params/Linux/

> +    goto fail;
> +  }

/* We've already read lh so there is not need to read it second time. */
len -= sizeof (lh);

> +
>    if (grub_file_read (file, (char *) &linux_params + sizeof (lh), len) != 
> len)
>      {
>        if (!grub_errno)

I hope that helps.

Daniel



reply via email to

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