From: Alan Modra Date: Mon, 1 Apr 2024 09:28:53 +0000 (+1030) Subject: asan: heap-buffer-overflow objdump.c:3299 in disassemble_bytes X-Git-Tag: gdb-15-branchpoint~551 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=159daa36fa;p=thirdparty%2Fbinutils-gdb.git 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. --- diff --git a/binutils/objdump.c b/binutils/objdump.c index 7beb221cb2f..8293387558f 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);