* grub-core/loader/i386/linux.c (grub_linux_boot): Fix overflow and
uninited variable. Allocate at least setup_sects.
This commit is contained in:
parent
a4e5ca80d9
commit
f19cb95e1d
2 changed files with 36 additions and 22 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2012-05-31 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/loader/i386/linux.c (grub_linux_boot): Fix overflow and
|
||||||
|
uninited variable. Allocate at least setup_sects.
|
||||||
|
|
||||||
2012-05-30 Vladimir Serbinenko <phcoder@gmail.com>
|
2012-05-30 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
Fix handling of EFI with big memory maps.
|
Fix handling of EFI with big memory maps.
|
||||||
|
|
|
@ -379,13 +379,16 @@ grub_linux_boot (void)
|
||||||
char *tmp;
|
char *tmp;
|
||||||
struct grub_relocator32_state state;
|
struct grub_relocator32_state state;
|
||||||
void *real_mode_mem;
|
void *real_mode_mem;
|
||||||
grub_addr_t real_mode_target;
|
grub_addr_t real_mode_target = 0;
|
||||||
grub_size_t real_size, mmap_size;
|
grub_size_t real_size, mmap_size;
|
||||||
grub_size_t cl_offset;
|
grub_size_t cl_offset;
|
||||||
|
|
||||||
mmap_size = find_mmap_size ();
|
mmap_size = find_mmap_size ();
|
||||||
/* Make sure that each size is aligned to a page boundary. */
|
/* Make sure that each size is aligned to a page boundary. */
|
||||||
cl_offset = ALIGN_UP (mmap_size + sizeof (*params), 4096);
|
cl_offset = ALIGN_UP (mmap_size + sizeof (*params), 4096);
|
||||||
|
if (cl_offset < ((grub_size_t) params->setup_sects << GRUB_DISK_SECTOR_BITS))
|
||||||
|
cl_offset = ALIGN_UP ((grub_size_t) (params->setup_sects
|
||||||
|
<< GRUB_DISK_SECTOR_BITS), 4096);
|
||||||
real_size = ALIGN_UP (cl_offset + maximal_cmdline_size, 4096);
|
real_size = ALIGN_UP (cl_offset + maximal_cmdline_size, 4096);
|
||||||
|
|
||||||
#ifdef GRUB_MACHINE_EFI
|
#ifdef GRUB_MACHINE_EFI
|
||||||
|
@ -403,27 +406,30 @@ grub_linux_boot (void)
|
||||||
grub_memory_type_t type)
|
grub_memory_type_t type)
|
||||||
{
|
{
|
||||||
/* We must put real mode code in the traditional space. */
|
/* We must put real mode code in the traditional space. */
|
||||||
|
if (type != GRUB_MEMORY_AVAILABLE || addr > 0x90000)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (type == GRUB_MEMORY_AVAILABLE
|
if (addr + size < 0x10000)
|
||||||
&& addr <= 0x90000)
|
return 0;
|
||||||
|
|
||||||
|
if (addr < 0x10000)
|
||||||
{
|
{
|
||||||
if (addr < 0x10000)
|
size += addr - 0x10000;
|
||||||
{
|
addr = 0x10000;
|
||||||
size += addr - 0x10000;
|
|
||||||
addr = 0x10000;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addr + size > 0x90000)
|
|
||||||
size = 0x90000 - addr;
|
|
||||||
|
|
||||||
if (real_size + efi_mmap_size > size)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
real_mode_target = ((addr + size) - (real_size + efi_mmap_size));
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
if (addr + size > 0x90000)
|
||||||
|
size = 0x90000 - addr;
|
||||||
|
|
||||||
|
if (real_size + efi_mmap_size > size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
grub_dprintf ("linux", "addr = %lx, size = %x, need_size = %x\n",
|
||||||
|
(unsigned long) addr,
|
||||||
|
(unsigned) size,
|
||||||
|
(unsigned) (real_size + efi_mmap_size));
|
||||||
|
real_mode_target = ((addr + size) - (real_size + efi_mmap_size));
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
#ifdef GRUB_MACHINE_EFI
|
#ifdef GRUB_MACHINE_EFI
|
||||||
grub_efi_mmap_iterate (hook, 1);
|
grub_efi_mmap_iterate (hook, 1);
|
||||||
|
@ -432,6 +438,11 @@ grub_linux_boot (void)
|
||||||
#else
|
#else
|
||||||
grub_mmap_iterate (hook);
|
grub_mmap_iterate (hook);
|
||||||
#endif
|
#endif
|
||||||
|
grub_dprintf ("linux", "real_mode_target = %lx, real_size = %x, efi_mmap_size = %x\n",
|
||||||
|
(unsigned long) real_mode_target,
|
||||||
|
(unsigned) real_size,
|
||||||
|
(unsigned) efi_mmap_size);
|
||||||
|
|
||||||
if (! real_mode_target)
|
if (! real_mode_target)
|
||||||
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages");
|
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages");
|
||||||
|
|
||||||
|
@ -446,10 +457,8 @@ grub_linux_boot (void)
|
||||||
}
|
}
|
||||||
efi_mmap_buf = (grub_uint8_t *) real_mode_mem + real_size;
|
efi_mmap_buf = (grub_uint8_t *) real_mode_mem + real_size;
|
||||||
|
|
||||||
grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_target = %lx, real_size = %x\n",
|
grub_dprintf ("linux", "real_mode_mem = %lx\n",
|
||||||
(unsigned long) real_mode_mem, (unsigned long) real_mode_target,
|
(unsigned long) real_mode_mem);
|
||||||
(unsigned) real_size);
|
|
||||||
|
|
||||||
params = real_mode_mem;
|
params = real_mode_mem;
|
||||||
|
|
||||||
*params = linux_params;
|
*params = linux_params;
|
||||||
|
|
Loading…
Reference in a new issue