aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2024-04-01 19:58:53 +1030
committerAlan Modra <amodra@gmail.com>2024-04-01 21:21:51 +1030
commit159daa36fab5c2c0df88b6e9fd4cda4e560c3f9f (patch)
tree97e503ee4efcbb9e4f7081d575a156fba86f3f0e /binutils
parentb67a17aa7c0c478a2f2c2f045854e9745abfe114 (diff)
downloadgdb-159daa36fab5c2c0df88b6e9fd4cda4e560c3f9f.zip
gdb-159daa36fab5c2c0df88b6e9fd4cda4e560c3f9f.tar.gz
gdb-159daa36fab5c2c0df88b6e9fd4cda4e560c3f9f.tar.bz2
asan: heap-buffer-overflow objdump.c:3299 in disassemble_bytes
Fix yet another crash, this one with a fuzzed function symbol size. The patch also corrects objdump behaviour when both --disassemble=sym and --stop-address=value are given. Previously --disassemble=sym overrode --stop-address, now we take the lower of the stop-address value and the end of function. * objdump.c (disassemble_section): Sanity check ELF st_size.
Diffstat (limited to 'binutils')
-rw-r--r--binutils/objdump.c34
1 files changed, 15 insertions, 19 deletions
diff --git a/binutils/objdump.c b/binutils/objdump.c
index 7beb221..8293387 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -3923,30 +3923,26 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
(*rel_pp)->address - rel_offset < sym_offset)
++rel_pp;
+ loop_until = next_sym;
if (sym->flags & BSF_FUNCTION)
{
- if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
- && ((elf_symbol_type *) sym)->internal_elf_sym.st_size > 0)
- {
- /* Sym is a function symbol with a size associated
- with it. Turn on automatic disassembly for the
- next VALUE bytes. */
- stop_offset = addr_offset
- + ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
- loop_until = stop_offset_reached;
- }
- else
+ loop_until = function_sym;
+
+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
{
- /* Otherwise we need to tell the loop heuristic to
- loop until the next function symbol is encountered. */
- loop_until = function_sym;
+ bfd_size_type fsize =
+ ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
+ if (addr_offset + fsize > addr_offset
+ && addr_offset + fsize <= stop_offset)
+ {
+ /* Sym is a function symbol with a valid
+ size associated with it. Disassemble
+ to the end of the function. */
+ stop_offset = addr_offset + fsize;
+ loop_until = stop_offset_reached;
+ }
}
}
- else
- {
- /* Otherwise loop until the next symbol is encountered. */
- loop_until = next_sym;
- }
}
free (alloc);