]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
* grub-core/kern/x86_64/dl.c (grub_arch_dl_relocate_symbols): Add
authorVladimir Serbinenko <phcoder@gmail.com>
Fri, 22 Nov 2013 12:01:14 +0000 (13:01 +0100)
committerVladimir Serbinenko <phcoder@gmail.com>
Fri, 22 Nov 2013 12:01:14 +0000 (13:01 +0100)
range-checking for 32-bit quantities.

ChangeLog
grub-core/kern/x86_64/dl.c

index 6faadecdb3d07013de51085b41dfe8a9eb3f4400..f610f49458e8e028ebe05bd47d3252dc5d900e97 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2013-11-22  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       * grub-core/kern/x86_64/dl.c (grub_arch_dl_relocate_symbols): Add
+       range-checking for 32-bit quantities.
+
 2013-11-22  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * configure.ac: Compile with -fPIC when compiling with clang on
index 65f09ef53ddec288679832c58ae72ba22cef5c58..17c12154444b55ed73281919b1fef89b3ed0cab3 100644 (file)
@@ -100,14 +100,32 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
                    break;
 
                  case R_X86_64_PC32:
-                   *addr32 += rel->r_addend + sym->st_value -
-                             (Elf64_Xword) seg->addr - rel->r_offset;
+                   {
+                     grub_int64_t value;
+                     value = ((grub_int32_t) *addr32) + rel->r_addend + sym->st_value -
+                       (Elf64_Xword) seg->addr - rel->r_offset;
+                     if (value != (grub_int32_t) value)
+                       return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range");
+                     *addr32 = value;
+                   }
                    break;
 
                   case R_X86_64_32:
+                   {
+                     grub_uint64_t value = *addr32 + rel->r_addend + sym->st_value;
+                     if (value != (grub_uint32_t) value)
+                       return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range");
+                     *addr32 = value;
+                   }
+                   break;
                   case R_X86_64_32S:
-                    *addr32 += rel->r_addend + sym->st_value;
-                    break;
+                   {
+                     grub_int64_t value = ((grub_int32_t) *addr32) + rel->r_addend + sym->st_value;
+                     if (value != (grub_int32_t) value)
+                       return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range");
+                     *addr32 = value;
+                   }
+                   break;
 
                  default:
                    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,