summaryrefslogtreecommitdiff
path: root/bfd/elfxx-mips.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2022-06-03 22:47:50 +0930
committerAlan Modra <amodra@gmail.com>2022-06-03 23:32:39 +0930
commit3dc8d5eadaecc37722ec6979acf320cf0b969be8 (patch)
treecddcc6d1f94276c029174e1b23e2a43291d420bb /bfd/elfxx-mips.c
parent7e6ba6a2a56e6195da36329bdeb1654e20aad198 (diff)
downloadbinutils-gdb-3dc8d5eadaecc37722ec6979acf320cf0b969be8.tar.gz
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.c55
1 files changed, 32 insertions, 23 deletions
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 97a406a8d1a..e0e23926f03 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;
}