diff options
-rw-r--r-- | bfd/aoutx.h | 20 | ||||
-rw-r--r-- | bfd/coffgen.c | 22 | ||||
-rw-r--r-- | bfd/elf64-sparc.c | 19 | ||||
-rw-r--r-- | bfd/mach-o.c | 22 | ||||
-rw-r--r-- | bfd/pdp11.c | 20 |
5 files changed, 69 insertions, 34 deletions
diff --git a/bfd/aoutx.h b/bfd/aoutx.h index 4aed234..61ea9f7 100644 --- a/bfd/aoutx.h +++ b/bfd/aoutx.h @@ -2485,13 +2485,7 @@ NAME (aout, canonicalize_reloc) (bfd *abfd, long NAME (aout, get_reloc_upper_bound) (bfd *abfd, sec_ptr asect) { - bfd_size_type count; - - if (bfd_get_format (abfd) != bfd_object) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } + size_t count, raw; if (asect->flags & SEC_CONSTRUCTOR) count = asect->reloc_count; @@ -2507,11 +2501,21 @@ NAME (aout, get_reloc_upper_bound) (bfd *abfd, sec_ptr asect) return -1; } - if (count >= LONG_MAX / sizeof (arelent *)) + if (count >= LONG_MAX / sizeof (arelent *) + || _bfd_mul_overflow (count, obj_reloc_entry_size (abfd), &raw)) { bfd_set_error (bfd_error_file_too_big); return -1; } + if (!bfd_write_p (abfd)) + { + ufile_ptr filesize = bfd_get_file_size (abfd); + if (filesize != 0 && raw > filesize) + { + bfd_set_error (bfd_error_file_truncated); + return -1; + } + } return (count + 1) * sizeof (arelent *); } diff --git a/bfd/coffgen.c b/bfd/coffgen.c index 3e0fbc6..aab41c3 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -1976,19 +1976,25 @@ coff_get_normalized_symtab (bfd *abfd) long coff_get_reloc_upper_bound (bfd *abfd, sec_ptr asect) { - if (bfd_get_format (abfd) != bfd_object) + size_t count, raw; + + count = asect->reloc_count; + if (count >= LONG_MAX / sizeof (arelent *) + || _bfd_mul_overflow (count, bfd_coff_relsz (abfd), &raw)) { - bfd_set_error (bfd_error_invalid_operation); + bfd_set_error (bfd_error_file_too_big); return -1; } -#if SIZEOF_LONG == SIZEOF_INT - if (asect->reloc_count >= LONG_MAX / sizeof (arelent *)) + if (!bfd_write_p (abfd)) { - bfd_set_error (bfd_error_file_too_big); - return -1; + ufile_ptr filesize = bfd_get_file_size (abfd); + if (filesize != 0 && raw > filesize) + { + bfd_set_error (bfd_error_file_truncated); + return -1; + } } -#endif - return (asect->reloc_count + 1L) * sizeof (arelent *); + return (count + 1) * sizeof (arelent *); } asymbol * diff --git a/bfd/elf64-sparc.c b/bfd/elf64-sparc.c index e9f03cf..fb4483d 100644 --- a/bfd/elf64-sparc.c +++ b/bfd/elf64-sparc.c @@ -37,14 +37,25 @@ static long elf64_sparc_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec) { -#if SIZEOF_LONG == SIZEOF_INT - if (sec->reloc_count >= LONG_MAX / 2 / sizeof (arelent *)) + size_t count, raw; + + count = sec->reloc_count; + if (count >= LONG_MAX / 2 / sizeof (arelent *) + || _bfd_mul_overflow (count, sizeof (Elf64_External_Rela), &raw)) { bfd_set_error (bfd_error_file_too_big); return -1; } -#endif - return (sec->reloc_count * 2L + 1) * sizeof (arelent *); + if (!bfd_write_p (abfd)) + { + ufile_ptr filesize = bfd_get_file_size (abfd); + if (filesize != 0 && raw > filesize) + { + bfd_set_error (bfd_error_file_truncated); + return -1; + } + } + return (count * 2 + 1) * sizeof (arelent *); } static long diff --git a/bfd/mach-o.c b/bfd/mach-o.c index 5279343..664ff44 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -1407,17 +1407,27 @@ bfd_mach_o_write_dyld_info (bfd *abfd, bfd_mach_o_load_command *command) } long -bfd_mach_o_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, - asection *asect) +bfd_mach_o_get_reloc_upper_bound (bfd *abfd, asection *asect) { -#if SIZEOF_LONG == SIZEOF_INT - if (asect->reloc_count >= LONG_MAX / sizeof (arelent *)) + size_t count, raw; + + count = asect->reloc_count; + if (count >= LONG_MAX / sizeof (arelent *) + || _bfd_mul_overflow (count, BFD_MACH_O_RELENT_SIZE, &raw)) { bfd_set_error (bfd_error_file_too_big); return -1; } -#endif - return (asect->reloc_count + 1L) * sizeof (arelent *); + if (!bfd_write_p (abfd)) + { + ufile_ptr filesize = bfd_get_file_size (abfd); + if (filesize != 0 && raw > filesize) + { + bfd_set_error (bfd_error_file_truncated); + return -1; + } + } + return (count + 1) * sizeof (arelent *); } /* In addition to the need to byte-swap the symbol number, the bit positions diff --git a/bfd/pdp11.c b/bfd/pdp11.c index 9ef63cc..de9c869 100644 --- a/bfd/pdp11.c +++ b/bfd/pdp11.c @@ -2125,13 +2125,7 @@ NAME (aout, canonicalize_reloc) (bfd *abfd, long NAME (aout, get_reloc_upper_bound) (bfd *abfd, sec_ptr asect) { - bfd_size_type count; - - if (bfd_get_format (abfd) != bfd_object) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } + size_t count, raw; if (asect->flags & SEC_CONSTRUCTOR) count = asect->reloc_count; @@ -2147,11 +2141,21 @@ NAME (aout, get_reloc_upper_bound) (bfd *abfd, sec_ptr asect) return -1; } - if (count >= LONG_MAX / sizeof (arelent *)) + if (count >= LONG_MAX / sizeof (arelent *) + || _bfd_mul_overflow (count, obj_reloc_entry_size (abfd), &raw)) { bfd_set_error (bfd_error_file_too_big); return -1; } + if (!bfd_write_p (abfd)) + { + ufile_ptr filesize = bfd_get_file_size (abfd); + if (filesize != 0 && raw > filesize) + { + bfd_set_error (bfd_error_file_truncated); + return -1; + } + } return (count + 1) * sizeof (arelent *); } |