PR29846, segmentation fault in objdump.c compare_symbols
authorAlan Modra <amodra@gmail.com>
Sun, 4 Dec 2022 11:45:40 +0000 (22:15 +1030)
committerAlan Modra <amodra@gmail.com>
Sun, 4 Dec 2022 12:02:20 +0000 (22:32 +1030)
Fixes a fuzzed object file problem where plt relocs were manipulated
in such a way that two synthetic symbols were generated at the same
plt location.  Won't occur in real object files.

PR 29846
PR 20337
* objdump.c (compare_symbols): Test symbol flags to exclude
section and synthetic symbols before attempting to check flavour.

binutils/objdump.c

index e8481b2d928bdd51bef903f283a91e8ea9448a39..d95c8b68bf06f0c60b6332789b676db439023781 100644 (file)
@@ -1222,20 +1222,17 @@ compare_symbols (const void *ap, const void *bp)
        return 1;
     }
 
-  if (bfd_get_flavour (bfd_asymbol_bfd (a)) == bfd_target_elf_flavour
+  /* Sort larger size ELF symbols before smaller.  See PR20337.  */
+  bfd_vma asz = 0;
+  if ((a->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0
+      && bfd_get_flavour (bfd_asymbol_bfd (a)) == bfd_target_elf_flavour)
+    asz = ((elf_symbol_type *) a)->internal_elf_sym.st_size;
+  bfd_vma bsz = 0;
+  if ((b->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0
       && bfd_get_flavour (bfd_asymbol_bfd (b)) == bfd_target_elf_flavour)
-    {
-      bfd_vma asz, bsz;
-
-      asz = 0;
-      if ((a->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0)
-       asz = ((elf_symbol_type *) a)->internal_elf_sym.st_size;
-      bsz = 0;
-      if ((b->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0)
-       bsz = ((elf_symbol_type *) b)->internal_elf_sym.st_size;
-      if (asz != bsz)
-       return asz > bsz ? -1 : 1;
-    }
+    bsz = ((elf_symbol_type *) b)->internal_elf_sym.st_size;
+  if (asz != bsz)
+    return asz > bsz ? -1 : 1;
 
   /* Symbols that start with '.' might be section names, so sort them
      after symbols that don't start with '.'.  */