Correct readelf e_shstrndx range check
authorAlan Modra <amodra@gmail.com>
Wed, 22 Aug 2018 00:34:58 +0000 (10:04 +0930)
committerAlan Modra <amodra@gmail.com>
Wed, 22 Aug 2018 06:07:00 +0000 (15:37 +0930)
Fixes a bogus out of range error:
  Number of section headers:         0 (210016)
  Section header string table index: 1 <corrupt: out of range>

Caused due to e_shnum remaining as zero rather than being updated to
the value from section_header[0].sh_info at the point where we range
check e_shstrndx.

* readelf.c (process_file_header): Assign updated values from
section_header[0] fields to e_phnum, e_shnum and e_shstrndx
during printing of header.  Correct e_shstrndx range check.
Remove unnecessary casts and use %u rather than %ld for
unsigned int header fields.  Don't print a random %lx when
reporting an unknown EI_VERSION.

binutils/ChangeLog
binutils/readelf.c

index 97e35405c6387ee78b2442e36c6e5d353ee73047..69ca9aa3adf1950c00ebd48598f6754c3efe4031 100644 (file)
@@ -1,3 +1,12 @@
+2018-08-22  Alan Modra  <amodra@gmail.com>
+
+       * readelf.c (process_file_header): Assign updated values from
+       section_header[0] fields to e_phnum, e_shnum and e_shstrndx
+       during printing of header.  Correct e_shstrndx range check.
+       Remove unnecessary casts and use %u rather than %ld for
+       unsigned int header fields.  Don't print a random %lx when
+       reporting an unknown EI_VERSION.
+
 2018-08-21  Nick Clifton  <nickc@redhat.com>
 
        * MAINTAINERS: Note that Arnold Metselaar has retired as the z80
index 52aebd379137def6011cd2a56e4c4d96bbf5357f..a936ff375876408d70005ea6fb69060895bd8120 100644 (file)
@@ -4765,12 +4765,12 @@ process_file_header (Filedata * filedata)
              get_elf_class (header->e_ident[EI_CLASS]));
       printf (_("  Data:                              %s\n"),
              get_data_encoding (header->e_ident[EI_DATA]));
-      printf (_("  Version:                           %d %s\n"),
+      printf (_("  Version:                           %d%s\n"),
              header->e_ident[EI_VERSION],
              (header->e_ident[EI_VERSION] == EV_CURRENT
-              ? "(current)"
+              ? _(" (current)")
               : (header->e_ident[EI_VERSION] != EV_NONE
-                 ? _("<unknown: %lx>")
+                 ? _(" <unknown>")
                  : "")));
       printf (_("  OS/ABI:                            %s\n"),
              get_osabi_name (filedata, header->e_ident[EI_OSABI]));
@@ -4781,45 +4781,57 @@ process_file_header (Filedata * filedata)
       printf (_("  Machine:                           %s\n"),
              get_machine_name (header->e_machine));
       printf (_("  Version:                           0x%lx\n"),
-             (unsigned long) header->e_version);
+             header->e_version);
 
       printf (_("  Entry point address:               "));
-      print_vma ((bfd_vma) header->e_entry, PREFIX_HEX);
+      print_vma (header->e_entry, PREFIX_HEX);
       printf (_("\n  Start of program headers:          "));
-      print_vma ((bfd_vma) header->e_phoff, DEC);
+      print_vma (header->e_phoff, DEC);
       printf (_(" (bytes into file)\n  Start of section headers:          "));
-      print_vma ((bfd_vma) header->e_shoff, DEC);
+      print_vma (header->e_shoff, DEC);
       printf (_(" (bytes into file)\n"));
 
       printf (_("  Flags:                             0x%lx%s\n"),
-             (unsigned long) header->e_flags,
+             header->e_flags,
              get_machine_flags (filedata, header->e_flags, header->e_machine));
-      printf (_("  Size of this header:               %ld (bytes)\n"),
-             (long) header->e_ehsize);
-      printf (_("  Size of program headers:           %ld (bytes)\n"),
-             (long) header->e_phentsize);
-      printf (_("  Number of program headers:         %ld"),
-             (long) header->e_phnum);
+      printf (_("  Size of this header:               %u (bytes)\n"),
+             header->e_ehsize);
+      printf (_("  Size of program headers:           %u (bytes)\n"),
+             header->e_phentsize);
+      printf (_("  Number of program headers:         %u"),
+             header->e_phnum);
       if (filedata->section_headers != NULL
          && header->e_phnum == PN_XNUM
          && filedata->section_headers[0].sh_info != 0)
-       printf (" (%ld)", (long) filedata->section_headers[0].sh_info);
+       {
+         header->e_phnum = filedata->section_headers[0].sh_info;
+         printf (" (%u)", header->e_phnum);
+       }
       putc ('\n', stdout);
-      printf (_("  Size of section headers:           %ld (bytes)\n"),
-             (long) header->e_shentsize);
-      printf (_("  Number of section headers:         %ld"),
-             (long) header->e_shnum);
+      printf (_("  Size of section headers:           %u (bytes)\n"),
+             header->e_shentsize);
+      printf (_("  Number of section headers:         %u"),
+             header->e_shnum);
       if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
-       printf (" (%ld)", (long) filedata->section_headers[0].sh_size);
+       {
+         header->e_shnum = filedata->section_headers[0].sh_size;
+         printf (" (%u)", header->e_shnum);
+       }
       putc ('\n', stdout);
-      printf (_("  Section header string table index: %ld"),
-             (long) header->e_shstrndx);
+      printf (_("  Section header string table index: %u"),
+             header->e_shstrndx);
       if (filedata->section_headers != NULL
          && header->e_shstrndx == (SHN_XINDEX & 0xffff))
-       printf (" (%u)", filedata->section_headers[0].sh_link);
-      else if (header->e_shstrndx != SHN_UNDEF
-              && header->e_shstrndx >= header->e_shnum)
-       printf (_(" <corrupt: out of range>"));
+       {
+         header->e_shstrndx = filedata->section_headers[0].sh_link;
+         printf (" (%u)", header->e_shstrndx);
+       }
+      if (header->e_shstrndx != SHN_UNDEF
+         && header->e_shstrndx >= header->e_shnum)
+       {
+         header->e_shstrndx = SHN_UNDEF;
+         printf (_(" <corrupt: out of range>"));
+       }
       putc ('\n', stdout);
     }