From: Alan Modra Date: Tue, 20 May 2025 05:52:13 +0000 (+0930) Subject: ubsan: undefined shift in loongarch_elf_add_sub_reloc_uleb128 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=50095e94928f244b8ad0cb93201b05499e25ad6e;p=thirdparty%2Fbinutils-gdb.git 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. --- diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c index 94980229501..182617b38c1 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; }