PR28306, segfault in _bfd_mips_elf_reloc_unshuffle
Maciej W. Rozycki
macro@orcam.me.uk
Thu Sep 9 09:51:48 GMT 2021
On Wed, 8 Sep 2021, Alan Modra wrote:
> Protect the _bfd_mips_elf_reloc_unshuffle call in mips16_gprel_reloc
> by checking the reloc offset. The other changes catch potential
> buffer overflows when processing relocations near the end of a
> section.
>
> OK to apply?
Thank you for working on this issue. Overall it looks good to me, but
see one question below.
> diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c
> index dc607e776d1..2ab0bae976a 100644
> --- a/bfd/elfn32-mips.c
> +++ b/bfd/elfn32-mips.c
> @@ -877,7 +877,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
> /* No relocation. */
> HOWTO (R_MIPS_NONE, /* type */
> 0, /* rightshift */
> - 0, /* size (0 = byte, 1 = short, 2 = long) */
> + 3, /* size (0 = byte, 1 = short, 2 = long) */
> 0, /* bitsize */
> false, /* pc_relative */
> 0, /* bitpos */
This might well be a separate change, applied right away as obvious.
> diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
> index e4827fd17de..aef5ede3ef0 100644
> --- a/bfd/elfxx-mips.c
> +++ b/bfd/elfxx-mips.c
[...]
> @@ -2595,9 +2598,19 @@ _bfd_mips_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
> bfd_reloc_status_type status;
> bool relocatable;
>
> + /* ld -r or gas. */
> relocatable = (output_bfd != NULL);
>
> - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
> + /* We only use bfd_reloc_offset_in_range for final linking because
> + mips object files may use relocations that seem to access beyond
> + section limits. gas/testsuite/gas/mips/dla-reloc.s is an example
> + that puts R_MIPS_SUB, a 64-bit relocation, on the last
> + instruction in the section. If final linking that object file
> + the R_MIPS_SUB won't be processed here since it applies to the
> + addend for the next reloc rather than the section contents. */
> + if (!relocatable
> + && !bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
> + input_section, reloc_entry->address))
> return bfd_reloc_outofrange;
Would a correct check be feasible here? For a composed relocation only
the final entry is applied to output, so could we instead check if there
is a follow-up relocation?
Maciej
More information about the Binutils
mailing list