]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
* grub-core/loader/i386/linux.c (grub_linux_boot): Fix overflow and
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 31 May 2012 10:04:55 +0000 (12:04 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 31 May 2012 10:04:55 +0000 (12:04 +0200)
uninited variable. Allocate at least setup_sects.

ChangeLog
grub-core/loader/i386/linux.c

index 0623e6834fe139dae1a56fadc7b40e32f255c9d9..d3ecbbfd58d642d76e7e62a97c7c1fc6636c3c56 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
 
        Fix handling of EFI with big memory maps.
index 1d53be24700275273a4f23edbfd20592ce3844dd..ed924b77d0d4221196d032da265971a2f7227d42 100644 (file)
@@ -379,13 +379,16 @@ grub_linux_boot (void)
   char *tmp;
   struct grub_relocator32_state state;
   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 cl_offset;
 
   mmap_size = find_mmap_size ();
   /* Make sure that each size is aligned to a page boundary.  */
   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);
 
 #ifdef GRUB_MACHINE_EFI
@@ -403,27 +406,30 @@ grub_linux_boot (void)
                             grub_memory_type_t type)
     {
       /* We must put real mode code in the traditional space.  */
+      if (type != GRUB_MEMORY_AVAILABLE || addr > 0x90000)
+       return 0;
 
-      if (type == GRUB_MEMORY_AVAILABLE
-         && addr <= 0x90000)
-       {
-         if (addr < 0x10000)
-           {
-             size += addr - 0x10000;
-             addr = 0x10000;
-           }
+      if (addr + size < 0x10000)
+       return 0;
 
-         if (addr + size > 0x90000)
-           size = 0x90000 - addr;
+      if (addr < 0x10000)
+       {
+         size += addr - 0x10000;
+         addr = 0x10000;
+       }
 
-         if (real_size + efi_mmap_size > size)
-           return 0;
+      if (addr + size > 0x90000)
+       size = 0x90000 - addr;
 
-         real_mode_target = ((addr + size) - (real_size + efi_mmap_size));
-         return 1;
-       }
+      if (real_size + efi_mmap_size > size)
+       return 0;
 
-      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
   grub_efi_mmap_iterate (hook, 1);
@@ -432,6 +438,11 @@ grub_linux_boot (void)
 #else
   grub_mmap_iterate (hook);
 #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)
     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;
 
-  grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_target = %lx, real_size = %x\n",
-                (unsigned long) real_mode_mem, (unsigned long) real_mode_target,
-               (unsigned) real_size);
-
+  grub_dprintf ("linux", "real_mode_mem = %lx\n",
+                (unsigned long) real_mode_mem);
   params = real_mode_mem;
 
   *params = linux_params;