diff options
author | Alan Modra <amodra@gmail.com> | 2022-06-03 22:47:50 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2022-06-03 23:32:39 +0930 |
commit | 3dc8d5eadaecc37722ec6979acf320cf0b969be8 (patch) | |
tree | cddcc6d1f94276c029174e1b23e2a43291d420bb /bfd/elfxx-mips.c | |
parent | 7e6ba6a2a56e6195da36329bdeb1654e20aad198 (diff) | |
download | gdb-3dc8d5eadaecc37722ec6979acf320cf0b969be8.zip gdb-3dc8d5eadaecc37722ec6979acf320cf0b969be8.tar.gz gdb-3dc8d5eadaecc37722ec6979acf320cf0b969be8.tar.bz2 |
asan: heap buffer overflow in _bfd_mips_elf_section_from_shdr
* elfxx-mips.c (_bfd_mips_elf_section_from_shdr): Sanity check
intopt.size and remaining bytes in section for reginfo.
Diffstat (limited to 'bfd/elfxx-mips.c')
-rw-r--r-- | bfd/elfxx-mips.c | 55 |
1 files changed, 32 insertions, 23 deletions
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 97a406a..e0e2392 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -7542,34 +7542,43 @@ _bfd_mips_elf_section_from_shdr (bfd *abfd, &intopt); if (intopt.size < sizeof (Elf_External_Options)) { + bad_opt: _bfd_error_handler /* xgettext:c-format */ - (_("%pB: warning: bad `%s' option size %u smaller than" - " its header"), - abfd, MIPS_ELF_OPTIONS_SECTION_NAME (abfd), intopt.size); + (_("%pB: warning: truncated `%s' option"), + abfd, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)); break; } - if (ABI_64_P (abfd) && intopt.kind == ODK_REGINFO) - { - Elf64_Internal_RegInfo intreg; - - bfd_mips_elf64_swap_reginfo_in - (abfd, - ((Elf64_External_RegInfo *) - (l + sizeof (Elf_External_Options))), - &intreg); - elf_gp (abfd) = intreg.ri_gp_value; - } - else if (intopt.kind == ODK_REGINFO) + if (intopt.kind == ODK_REGINFO) { - Elf32_RegInfo intreg; - - bfd_mips_elf32_swap_reginfo_in - (abfd, - ((Elf32_External_RegInfo *) - (l + sizeof (Elf_External_Options))), - &intreg); - elf_gp (abfd) = intreg.ri_gp_value; + if (ABI_64_P (abfd)) + { + Elf64_Internal_RegInfo intreg; + size_t needed = (sizeof (Elf_External_Options) + + sizeof (Elf64_External_RegInfo)); + if (intopt.size < needed || (size_t) (lend - l) < needed) + goto bad_opt; + bfd_mips_elf64_swap_reginfo_in + (abfd, + ((Elf64_External_RegInfo *) + (l + sizeof (Elf_External_Options))), + &intreg); + elf_gp (abfd) = intreg.ri_gp_value; + } + else + { + Elf32_RegInfo intreg; + size_t needed = (sizeof (Elf_External_Options) + + sizeof (Elf32_External_RegInfo)); + if (intopt.size < needed || (size_t) (lend - l) < needed) + goto bad_opt; + bfd_mips_elf32_swap_reginfo_in + (abfd, + ((Elf32_External_RegInfo *) + (l + sizeof (Elf_External_Options))), + &intreg); + elf_gp (abfd) = intreg.ri_gp_value; + } } l += intopt.size; } |