PR23945, NULL pointer dereference in readelf.c:slurp_hppa_unwind_table
authorAlan Modra <amodra@gmail.com>
Sat, 1 Dec 2018 10:45:03 +0000 (21:15 +1030)
committerAlan Modra <amodra@gmail.com>
Sat, 1 Dec 2018 11:40:28 +0000 (22:10 +1030)
PR 23945
* readelf.c (slurp_ia64_unwind_table): Don't call elf_ia64_reloc_type
needlessly.
(slurp_hppa_unwind_table): Use same range checks and error messages
as slurp_ia64_unwind_table.

binutils/ChangeLog
binutils/readelf.c

index ea86649..ccaa9c9 100644 (file)
@@ -1,3 +1,11 @@
+2018-12-01  Alan Modra  <amodra@gmail.com>
+
+       PR 23945
+       * readelf.c (slurp_ia64_unwind_table): Don't call elf_ia64_reloc_type
+       needlessly.
+       (slurp_hppa_unwind_table): Use same range checks and error messages
+       as slurp_ia64_unwind_table.
+
 2018-11-29  Nick Clifton  <nickc@redhat.com>
 
        PR 23931
index afb039f..9eb5931 100644 (file)
@@ -7597,14 +7597,14 @@ slurp_ia64_unwind_table (Filedata *                  filedata,
 
       for (rp = rela; rp < rela + nrelas; ++rp)
        {
-         relname = elf_ia64_reloc_type (get_reloc_type (filedata, rp->r_info));
+         unsigned int r_type = get_reloc_type (filedata, rp->r_info);
+         relname = elf_ia64_reloc_type (r_type);
          sym = aux->symtab + get_reloc_symindex (rp->r_info);
 
          /* PR 17531: file: 9fa67536.  */
          if (relname == NULL)
            {
-             warn (_("Skipping unknown relocation type: %u\n"),
-                   get_reloc_type (filedata, rp->r_info));
+             warn (_("Skipping unknown relocation type: %u\n"), r_type);
              continue;
            }
 
@@ -8053,17 +8053,29 @@ slurp_hppa_unwind_table (Filedata *                  filedata,
 
       for (rp = rela; rp < rela + nrelas; ++rp)
        {
-         relname = elf_hppa_reloc_type (get_reloc_type (filedata, rp->r_info));
+         unsigned int r_type = get_reloc_type (filedata, rp->r_info);
+         relname = elf_hppa_reloc_type (r_type);
          sym = aux->symtab + get_reloc_symindex (rp->r_info);
 
+         if (relname == NULL)
+           {
+             warn (_("Skipping unknown relocation type: %u\n"), r_type);
+             continue;
+           }
+
          /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64.  */
          if (! const_strneq (relname, "R_PARISC_SEGREL"))
            {
-             warn (_("Skipping unexpected relocation type %s\n"), relname);
+             warn (_("Skipping unexpected relocation type: %s\n"), relname);
              continue;
            }
 
          i = rp->r_offset / unw_ent_size;
+         if (i >= aux->table_len)
+           {
+             warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
+             continue;
+           }
 
          switch ((rp->r_offset % unw_ent_size) / 4)
            {