mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-26 05:47:26 +08:00
Fix seg-fault in strip when copying a file containing corrupt secondary relocs.
PR 25673 * elf.c (_bfd_elf_write_secondary_reloc_section): Fix illegal memory access when processing a corrupt secondary reloc section.
This commit is contained in:
@ -1,3 +1,9 @@
|
|||||||
|
2020-03-18 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
PR 25673
|
||||||
|
* elf.c (_bfd_elf_write_secondary_reloc_section): Fix illegal
|
||||||
|
memory access when processing a corrupt secondary reloc section.
|
||||||
|
|
||||||
2020-03-18 Christophe Lyon <christophe.lyon@linaro.org>
|
2020-03-18 Christophe Lyon <christophe.lyon@linaro.org>
|
||||||
|
|
||||||
* elf32-arm.c (arm_build_one_stub): Emit a fatal error message
|
* elf32-arm.c (arm_build_one_stub): Emit a fatal error message
|
||||||
|
109
bfd/elf.c
109
bfd/elf.c
@ -12637,6 +12637,10 @@ _bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec)
|
|||||||
bfd_vma addr_offset;
|
bfd_vma addr_offset;
|
||||||
asection * relsec;
|
asection * relsec;
|
||||||
bfd_vma (*r_info) (bfd_vma, bfd_vma);
|
bfd_vma (*r_info) (bfd_vma, bfd_vma);
|
||||||
|
bfd_boolean result = TRUE;
|
||||||
|
|
||||||
|
if (sec == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
#if BFD_DEFAULT_TARGET_SIZE > 32
|
#if BFD_DEFAULT_TARGET_SIZE > 32
|
||||||
if (bfd_arch_bits_per_address (abfd) != 32)
|
if (bfd_arch_bits_per_address (abfd) != 32)
|
||||||
@ -12645,9 +12649,6 @@ _bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec)
|
|||||||
#endif
|
#endif
|
||||||
r_info = elf32_r_info;
|
r_info = elf32_r_info;
|
||||||
|
|
||||||
if (sec == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* The address of an ELF reloc is section relative for an object
|
/* The address of an ELF reloc is section relative for an object
|
||||||
file, and absolute for an executable file or shared library.
|
file, and absolute for an executable file or shared library.
|
||||||
The address of a BFD reloc is always section relative. */
|
The address of a BFD reloc is always section relative. */
|
||||||
@ -12672,10 +12673,28 @@ _bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec)
|
|||||||
arelent * src_irel;
|
arelent * src_irel;
|
||||||
bfd_byte * dst_rela;
|
bfd_byte * dst_rela;
|
||||||
|
|
||||||
BFD_ASSERT (hdr->contents == NULL);
|
if (hdr->contents != NULL)
|
||||||
|
{
|
||||||
|
_bfd_error_handler
|
||||||
|
/* xgettext:c-format */
|
||||||
|
(_("%pB(%pA): error: secondary reloc section processed twice"),
|
||||||
|
abfd, relsec);
|
||||||
|
bfd_set_error (bfd_error_bad_value);
|
||||||
|
result = FALSE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
reloc_count = hdr->sh_size / hdr->sh_entsize;
|
reloc_count = hdr->sh_size / hdr->sh_entsize;
|
||||||
BFD_ASSERT (reloc_count > 0);
|
if (reloc_count <= 0)
|
||||||
|
{
|
||||||
|
_bfd_error_handler
|
||||||
|
/* xgettext:c-format */
|
||||||
|
(_("%pB(%pA): error: secondary reloc section is empty!"),
|
||||||
|
abfd, relsec);
|
||||||
|
bfd_set_error (bfd_error_bad_value);
|
||||||
|
result = FALSE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
hdr->contents = bfd_alloc (abfd, hdr->sh_size);
|
hdr->contents = bfd_alloc (abfd, hdr->sh_size);
|
||||||
if (hdr->contents == NULL)
|
if (hdr->contents == NULL)
|
||||||
@ -12689,7 +12708,16 @@ _bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec)
|
|||||||
last_sym_idx = 0;
|
last_sym_idx = 0;
|
||||||
dst_rela = hdr->contents;
|
dst_rela = hdr->contents;
|
||||||
src_irel = (arelent *) esd->sec_info;
|
src_irel = (arelent *) esd->sec_info;
|
||||||
BFD_ASSERT (src_irel != NULL);
|
if (src_irel == NULL)
|
||||||
|
{
|
||||||
|
_bfd_error_handler
|
||||||
|
/* xgettext:c-format */
|
||||||
|
(_("%pB(%pA): error: internal relocs missing for secondary reloc section"),
|
||||||
|
abfd, relsec);
|
||||||
|
bfd_set_error (bfd_error_bad_value);
|
||||||
|
result = FALSE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (idx = 0; idx < reloc_count; idx++, dst_rela += hdr->sh_entsize)
|
for (idx = 0; idx < reloc_count; idx++, dst_rela += hdr->sh_entsize)
|
||||||
{
|
{
|
||||||
@ -12699,49 +12727,72 @@ _bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec)
|
|||||||
int n;
|
int n;
|
||||||
|
|
||||||
ptr = src_irel + idx;
|
ptr = src_irel + idx;
|
||||||
|
if (ptr == NULL)
|
||||||
|
{
|
||||||
|
_bfd_error_handler
|
||||||
|
/* xgettext:c-format */
|
||||||
|
(_("%pB(%pA): error: reloc table entry %u is empty"),
|
||||||
|
abfd, relsec, idx);
|
||||||
|
bfd_set_error (bfd_error_bad_value);
|
||||||
|
result = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptr->sym_ptr_ptr == NULL)
|
||||||
|
{
|
||||||
|
/* FIXME: Is this an error ? */
|
||||||
|
n = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
sym = *ptr->sym_ptr_ptr;
|
sym = *ptr->sym_ptr_ptr;
|
||||||
|
|
||||||
if (sym == last_sym)
|
if (sym == last_sym)
|
||||||
n = last_sym_idx;
|
n = last_sym_idx;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
last_sym = sym;
|
|
||||||
n = _bfd_elf_symbol_from_bfd_symbol (abfd, & sym);
|
n = _bfd_elf_symbol_from_bfd_symbol (abfd, & sym);
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
{
|
{
|
||||||
#if DEBUG_SECONDARY_RELOCS
|
_bfd_error_handler
|
||||||
fprintf (stderr, "failed to find symbol %s whilst rewriting relocs\n",
|
/* xgettext:c-format */
|
||||||
sym->name);
|
(_("%pB(%pA): error: secondary reloc %u references a missing symbol"),
|
||||||
#endif
|
abfd, relsec, idx);
|
||||||
/* FIXME: Signal failure somehow. */
|
bfd_set_error (bfd_error_bad_value);
|
||||||
|
result = FALSE;
|
||||||
n = 0;
|
n = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
last_sym = sym;
|
||||||
last_sym_idx = n;
|
last_sym_idx = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*ptr->sym_ptr_ptr)->the_bfd != NULL
|
if (sym->the_bfd != NULL
|
||||||
&& (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
|
&& sym->the_bfd->xvec != abfd->xvec
|
||||||
&& ! _bfd_elf_validate_reloc (abfd, ptr))
|
&& ! _bfd_elf_validate_reloc (abfd, ptr))
|
||||||
{
|
{
|
||||||
#if DEBUG_SECONDARY_RELOCS
|
_bfd_error_handler
|
||||||
fprintf (stderr, "symbol %s is not in the output bfd\n",
|
/* xgettext:c-format */
|
||||||
sym->name);
|
(_("%pB(%pA): error: secondary reloc %u references a deleted symbol"),
|
||||||
#endif
|
abfd, relsec, idx);
|
||||||
/* FIXME: Signal failure somehow. */
|
bfd_set_error (bfd_error_bad_value);
|
||||||
|
result = FALSE;
|
||||||
n = 0;
|
n = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ptr->howto == NULL)
|
|
||||||
{
|
|
||||||
#if DEBUG_SECONDARY_RELOCS
|
|
||||||
fprintf (stderr, "reloc for symbol %s does not have a howto associated with it\n",
|
|
||||||
sym->name);
|
|
||||||
#endif
|
|
||||||
/* FIXME: Signal failure somehow. */
|
|
||||||
n = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
src_rela.r_offset = ptr->address + addr_offset;
|
src_rela.r_offset = ptr->address + addr_offset;
|
||||||
|
if (ptr->howto == NULL)
|
||||||
|
{
|
||||||
|
_bfd_error_handler
|
||||||
|
/* xgettext:c-format */
|
||||||
|
(_("%pB(%pA): error: secondary reloc %u is of an unknown type"),
|
||||||
|
abfd, relsec, idx);
|
||||||
|
bfd_set_error (bfd_error_bad_value);
|
||||||
|
result = FALSE;
|
||||||
|
src_rela.r_info = r_info (0, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
src_rela.r_info = r_info (n, ptr->howto->type);
|
src_rela.r_info = r_info (n, ptr->howto->type);
|
||||||
src_rela.r_addend = ptr->addend;
|
src_rela.r_addend = ptr->addend;
|
||||||
ebd->s->swap_reloca_out (abfd, &src_rela, dst_rela);
|
ebd->s->swap_reloca_out (abfd, &src_rela, dst_rela);
|
||||||
@ -12749,5 +12800,5 @@ _bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return result;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user