Correct readelf e_shstrndx range check

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.
This commit is contained in:
Alan Modra 2018-08-22 10:04:58 +09:30
parent ac1e2e51c0
commit e8a648884d
2 changed files with 47 additions and 26 deletions

View 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

View 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);
}