aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2025-05-20 15:22:13 +0930
committerAlan Modra <amodra@gmail.com>2025-05-20 15:33:36 +0930
commit50095e94928f244b8ad0cb93201b05499e25ad6e (patch)
treec2390e2c2d2870aa8e1b6af864da4e9ca0a3e937
parenta5c34789033f845f65ddbf723db4f571abc750fe (diff)
downloadbinutils-50095e94928f244b8ad0cb93201b05499e25ad6e.zip
binutils-50095e94928f244b8ad0cb93201b05499e25ad6e.tar.gz
binutils-50095e94928f244b8ad0cb93201b05499e25ad6e.tar.bz2
ubsan: undefined shift in loongarch_elf_add_sub_reloc_uleb128
An oss-fuzz testcase found: runtime error: shift exponent 140 is too large for 32-bit type 'int' OK, that's just a completely silly uleb, but we ought to be able to handle 64 bits here. * elfxx-loongarch.c (loongarch_elf_add_sub_reloc_uleb128): Formatting. Don't left shift int. Avoid shifts larger than bits in a bfd_vma.
-rw-r--r--bfd/elfxx-loongarch.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c
index 9498022..182617b 100644
--- a/bfd/elfxx-loongarch.c
+++ b/bfd/elfxx-loongarch.c
@@ -2171,11 +2171,11 @@ loongarch_elf_add_sub_reloc_uleb128 (bfd *abfd,
if (output_bfd != NULL)
return bfd_reloc_continue;
- relocation = symbol->value + symbol->section->output_section->vma
- + symbol->section->output_offset + reloc_entry->addend;
+ relocation = (symbol->value + symbol->section->output_section->vma
+ + symbol->section->output_offset + reloc_entry->addend);
- bfd_size_type octets = reloc_entry->address
- * bfd_octets_per_byte (abfd, input_section);
+ bfd_size_type octets = (reloc_entry->address
+ * bfd_octets_per_byte (abfd, input_section));
if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
input_section, octets))
return bfd_reloc_outofrange;
@@ -2195,8 +2195,11 @@ loongarch_elf_add_sub_reloc_uleb128 (bfd *abfd,
break;
}
- bfd_vma mask = (1 << (7 * len)) - 1;
- relocation = relocation & mask;
+ if (7 * len < sizeof (bfd_vma))
+ {
+ bfd_vma mask = ((bfd_vma) 1 << (7 * len)) - 1;
+ relocation = relocation & mask;
+ }
loongarch_write_unsigned_leb128 (p, len, relocation);
return bfd_reloc_ok;
}