]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
asan: use after free in _bfd_elf_mips_get_relocated_section_contents
authorAlan Modra <amodra@gmail.com>
Fri, 17 Dec 2021 04:31:20 +0000 (15:01 +1030)
committerAlan Modra <amodra@gmail.com>
Fri, 17 Dec 2021 05:31:34 +0000 (16:01 +1030)
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

index 4aaa3ea1fc3c02a971790f277e671449ef79dfd2..34005c6aee0d0548b5991d6b31f944d7bdf6ca5c 100644 (file)
@@ -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;
 }
 \f
 static bool