]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
ubsan: undefined shift in loongarch_elf_add_sub_reloc_uleb128
authorAlan Modra <amodra@gmail.com>
Tue, 20 May 2025 05:52:13 +0000 (15:22 +0930)
committerAlan Modra <amodra@gmail.com>
Tue, 20 May 2025 06:03:36 +0000 (15:33 +0930)
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.

bfd/elfxx-loongarch.c

index 9498022950160f945ef31c94422fe2b7744dfbd9..182617b38c1071dd0ffa2cb34d8f089520c870a2 100644 (file)
@@ -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;
 }