]> xenbits.xensource.com Git - people/andrewcoop/xen.git/commitdiff
Revert "libelf: treat phdr and shdr similarly"
authorJan Beulich <jbeulich@suse.com>
Thu, 8 Dec 2016 15:41:12 +0000 (16:41 +0100)
committerJan Beulich <jbeulich@suse.com>
Thu, 8 Dec 2016 15:41:12 +0000 (16:41 +0100)
This reverts commit a01b6d464f05dadf28bfd38612283bd1848f1350
as needing further adjustment (namely to properly avoid a
divide by zero issue spotted by Coverity and reported by
Andrew).

xen/common/libelf/libelf-loader.c
xen/common/libelf/libelf-tools.c

index 544cfc5b556c60008e9f244545d36e1d301a0feb..a72cd8a274fe7d64b546c4b0af0a464a4b2faef5 100644 (file)
@@ -52,45 +52,24 @@ elf_errorstatus elf_init(struct elf_binary *elf, const char *image_input, size_t
     elf->class = elf_uval_3264(elf, elf->ehdr, e32.e_ident[EI_CLASS]);
     elf->data = elf_uval_3264(elf, elf->ehdr, e32.e_ident[EI_DATA]);
 
-    /* Sanity check phdr if present. */
-    count = elf_phdr_count(elf);
-    if ( count )
+    /* Sanity check phdr. */
+    offset = elf_uval(elf, elf->ehdr, e_phoff) +
+        elf_uval(elf, elf->ehdr, e_phentsize) * elf_phdr_count(elf);
+    if ( offset > elf->size )
     {
-        if ( elf_uval(elf, elf->ehdr, e_phentsize) <
-             elf_size(elf, ELF_HANDLE_DECL(elf_phdr)) )
-        {
-            elf_err(elf, "ELF: phdr too small (%" PRIu64 ")\n",
-                    elf_uval(elf, elf->ehdr, e_phentsize));
-            return -1;
-        }
-        offset = elf_uval(elf, elf->ehdr, e_phoff) +
-            elf_uval(elf, elf->ehdr, e_phentsize) * count;
-        if ( offset > elf->size )
-        {
-            elf_err(elf, "ELF: phdr overflow (off %" PRIx64 " > size %lx)\n",
-                    offset, (unsigned long)elf->size);
-            return -1;
-        }
+        elf_err(elf, "ELF: phdr overflow (off %" PRIx64 " > size %lx)\n",
+                offset, (unsigned long)elf->size);
+        return -1;
     }
 
-    /* Sanity check shdr if present. */
-    count = elf_shdr_count(elf);
-    if ( count )
+    /* Sanity check shdr. */
+    offset = elf_uval(elf, elf->ehdr, e_shoff) +
+        elf_uval(elf, elf->ehdr, e_shentsize) * elf_shdr_count(elf);
+    if ( offset > elf->size )
     {
-        if ( elf_uval(elf, elf->ehdr, e_shentsize) < elf_size(elf, shdr) )
-        {
-            elf_err(elf, "ELF: shdr too small (%" PRIu64 ")\n",
-                    elf_uval(elf, elf->ehdr, e_shentsize));
-            return -1;
-        }
-        offset = elf_uval(elf, elf->ehdr, e_shoff) +
-            elf_uval(elf, elf->ehdr, e_shentsize) * count;
-        if ( offset > elf->size )
-        {
-            elf_err(elf, "ELF: shdr overflow (off %" PRIx64 " > size %lx)\n",
-                    offset, (unsigned long)elf->size);
-            return -1;
-        }
+        elf_err(elf, "ELF: shdr overflow (off %" PRIx64 " > size %lx)\n",
+                offset, (unsigned long)elf->size);
+        return -1;
     }
 
     /* Find section string table. */
@@ -100,6 +79,7 @@ elf_errorstatus elf_init(struct elf_binary *elf, const char *image_input, size_t
         elf->sec_strtab = elf_section_start(elf, shdr);
 
     /* Find symbol table and symbol string table. */
+    count = elf_shdr_count(elf);
     for ( i = 1; i < count; i++ )
     {
         shdr = elf_shdr_by_index(elf, i);
index bf661e7090f0d8de707e64c78ee72e312f3f9145..a9edb6a8dcb348b1de77966dd96e6c2dcc82d4ef 100644 (file)
@@ -130,11 +130,8 @@ uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr)
 unsigned elf_shdr_count(struct elf_binary *elf)
 {
     unsigned count = elf_uval(elf, elf->ehdr, e_shnum);
-    uint64_t max;
+    uint64_t max = elf->size / sizeof(Elf32_Shdr);
 
-    if ( !count )
-        return 0;
-    max = elf->size / elf_uval(elf, elf->ehdr, e_shentsize);
     if ( max > UINT_MAX )
         max = UINT_MAX;
     if ( count > max )
@@ -147,20 +144,7 @@ unsigned elf_shdr_count(struct elf_binary *elf)
 
 unsigned elf_phdr_count(struct elf_binary *elf)
 {
-    unsigned count = elf_uval(elf, elf->ehdr, e_phnum);
-    uint64_t max;
-
-    if ( !count )
-        return 0;
-    max = elf->size / elf_uval(elf, elf->ehdr, e_phentsize);
-    if ( max > UINT_MAX )
-        max = UINT_MAX;
-    if ( count > max )
-    {
-        elf_mark_broken(elf, "far too many program headers");
-        count = max;
-    }
-    return count;
+    return elf_uval(elf, elf->ehdr, e_phnum);
 }
 
 ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_name(struct elf_binary *elf, const char *name)