Re: PR31692, objdump fails .debug_info size check

The fuzzers found a hole.  bfd_section_size_insane doesn't check
!SEC_HAS_CONTENTS sections against file size for obvious reasons,
which allows fuzzed debug sections to be stupidly large.  Real debug
sections of course always have contents.

	PR 31692
	* objdump.c (load_specific_debug_section): Don't allow sections
	without contents.
This commit is contained in:
Alan Modra
2024-05-10 22:15:06 +09:30
parent a4f76c0765
commit ad658482c1

View File

@@ -4307,41 +4307,45 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
return false; return false;
} }
section->start = contents = xmalloc (alloced); ret = false;
/* Ensure any string section has a terminating NUL. */ if ((sec->flags & SEC_HAS_CONTENTS) != 0)
section->start[section->size] = 0;
if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
&& debug_displays [debug].relocate)
{ {
ret = bfd_simple_get_relocated_section_contents (abfd, section->start = contents = xmalloc (alloced);
sec, /* Ensure any string section has a terminating NUL. */
section->start, section->start[section->size] = 0;
syms) != NULL;
if (ret) if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
&& debug_displays [debug].relocate)
{ {
long reloc_size = bfd_get_reloc_upper_bound (abfd, sec); ret = bfd_simple_get_relocated_section_contents (abfd,
sec,
if (reloc_size > 0) section->start,
syms) != NULL;
if (ret)
{ {
long reloc_count; long reloc_size = bfd_get_reloc_upper_bound (abfd, sec);
arelent **relocs;
relocs = (arelent **) xmalloc (reloc_size); if (reloc_size > 0)
reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, syms);
if (reloc_count <= 0)
free (relocs);
else
{ {
section->reloc_info = relocs; long reloc_count;
section->num_relocs = reloc_count; arelent **relocs;
relocs = (arelent **) xmalloc (reloc_size);
reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, syms);
if (reloc_count <= 0)
free (relocs);
else
{
section->reloc_info = relocs;
section->num_relocs = reloc_count;
}
} }
} }
} }
else
ret = bfd_get_full_section_contents (abfd, sec, &contents);
} }
else
ret = bfd_get_full_section_contents (abfd, sec, &contents);
if (!ret) if (!ret)
{ {