objdump: Add various sanity checks to guard against corrupted data.
authorMark Wielaard <mjw@redhat.com>
Thu, 4 Dec 2014 16:01:20 +0000 (17:01 +0100)
committerMark Wielaard <mjw@redhat.com>
Thu, 4 Dec 2014 16:01:20 +0000 (17:01 +0100)
Reported-by: Alexander Cherepanov <cherepan@mccme.ru>
Signed-off-by: Mark Wielaard <mjw@redhat.com>
src/ChangeLog
src/objdump.c

index 0819c1e..c149a9c 100644 (file)
@@ -1,3 +1,10 @@
+2014-12-04  Mark Wielaard  <mjw@redhat.com>
+
+       * objdump.c (show_relocs_x): Make sure destshdr exists.
+       (show_relocs_rel): Don't rely on shdr->sh_entsize, use gelf_fsize.
+       (show_relocs_rela): Likewise.
+       (show_relocs): Make sure destshdr, symshdr and symdata exists.
+
 2014-11-30  Mark Wielaard  <mjw@redhat.com>
 
        * readelf.c (handle_sysv_hash64): Fix overflow check.
index 5376447..87290cc 100644 (file)
@@ -389,7 +389,7 @@ show_relocs_x (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *symdata,
                                           ? xndx : sym->st_shndx),
                               &destshdr_mem);
 
-      if (shdr == NULL)
+      if (shdr == NULL || destshdr == NULL)
        printf ("<%s %ld>",
                gettext ("INVALID SECTION"),
                (long int) (sym->st_shndx == SHN_XINDEX
@@ -418,7 +418,8 @@ show_relocs_rel (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data,
                 Elf_Data *symdata, Elf_Data *xndxdata, size_t symstrndx,
                 size_t shstrndx)
 {
-  int nentries = shdr->sh_size / shdr->sh_entsize;
+  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
+  int nentries = shdr->sh_size / sh_entsize;
 
   for (int cnt = 0; cnt < nentries; ++cnt)
     {
@@ -438,7 +439,8 @@ show_relocs_rela (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data,
                  Elf_Data *symdata, Elf_Data *xndxdata, size_t symstrndx,
                  size_t shstrndx)
 {
-  int nentries = shdr->sh_size / shdr->sh_entsize;
+  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
+  int nentries = shdr->sh_size / sh_entsize;
 
   for (int cnt = 0; cnt < nentries; ++cnt)
     {
@@ -506,6 +508,8 @@ show_relocs (Ebl *ebl, const char *fname, uint32_t shstrndx)
          GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf,
                                                          shdr->sh_info),
                                              &destshdr_mem);
+         if (unlikely (destshdr == NULL))
+           continue;
 
          printf (gettext ("\nRELOCATION RECORDS FOR [%s]:\n"
                           "%-*s TYPE                 VALUE\n"),
@@ -522,6 +526,8 @@ show_relocs (Ebl *ebl, const char *fname, uint32_t shstrndx)
          GElf_Shdr symshdr_mem;
          GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
          Elf_Data *symdata = elf_getdata (symscn, NULL);
+         if (unlikely (symshdr == NULL || symdata == NULL))
+           continue;
 
          /* Search for the optional extended section index table.  */
          Elf_Data *xndxdata = NULL;