diff options
author | Alan Modra <amodra@gmail.com> | 2024-04-01 19:58:53 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2024-04-01 21:21:51 +1030 |
commit | 159daa36fab5c2c0df88b6e9fd4cda4e560c3f9f (patch) | |
tree | 97e503ee4efcbb9e4f7081d575a156fba86f3f0e /binutils | |
parent | b67a17aa7c0c478a2f2c2f045854e9745abfe114 (diff) | |
download | gdb-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.c | 34 |
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); |