From 7ebf6ed02bde3a488bb588316e47b4df68796076 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 17 Dec 2021 15:01:20 +1030 Subject: [PATCH] asan: use after free in _bfd_elf_mips_get_relocated_section_contents Leaving entries on mips_hi16_list from a previous pass over relocs leads to confusing bugs. * elfxx-mips.c (_bfd_elf_mips_get_relocated_section_contents): Free mips_hi16_list entries on error exit. --- bfd/elfxx-mips.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 4aaa3ea1fc3..34005c6aee0 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -13242,7 +13242,26 @@ _bfd_elf_mips_get_relocated_section_contents reloc_vector = (arelent **) bfd_malloc (reloc_size); if (reloc_vector == NULL) - return NULL; + { + struct mips_hi16 **hip, *hi; + error_return: + /* If we are going to return an error, remove entries on + mips_hi16_list that point into this section's data. Data + will typically be freed on return from this function. */ + hip = &mips_hi16_list; + while ((hi = *hip) != NULL) + { + if (hi->input_section == input_section) + { + *hip = hi->next; + free (hi); + } + else + hip = &hi->next; + } + data = NULL; + goto out; + } reloc_count = bfd_canonicalize_reloc (input_bfd, input_section, @@ -13432,12 +13451,9 @@ _bfd_elf_mips_get_relocated_section_contents } } + out: free (reloc_vector); return data; - - error_return: - free (reloc_vector); - return NULL; } static bool