file size check in _bfd_alloc_and_read
* coffgen.c (_bfd_coff_get_external_symbols): Remove file size check. * elf.c (bfd_elf_get_str_section): Likewise. (_bfd_elf_slurp_version_tables): Likewise. * libbfd-in.h (_bfd_constant_p): Define. (_bfd_alloc_and_read, _bfd_malloc_and_read): Check read size against file size before allocating memory. * libbfd.h: Regenerate.
This commit is contained in:
parent
2bb3687ba8
commit
2c7c5554df
@ -1,3 +1,13 @@
|
|||||||
|
2020-02-19 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* libbfd-in.h (_bfd_constant_p): Define.
|
||||||
|
(_bfd_alloc_and_read, _bfd_malloc_and_read): Check read size against
|
||||||
|
file size before allocating memory.
|
||||||
|
* coffgen.c (_bfd_coff_get_external_symbols): Remove file size check.
|
||||||
|
* elf.c (bfd_elf_get_str_section): Likewise.
|
||||||
|
(_bfd_elf_slurp_version_tables): Likewise.
|
||||||
|
* libbfd.h: Regenerate.
|
||||||
|
|
||||||
2020-02-19 Alan Modra <amodra@gmail.com>
|
2020-02-19 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* libbfd-in.h (_bfd_alloc_and_read, _bfd_malloc_and_read): New.
|
* libbfd-in.h (_bfd_alloc_and_read, _bfd_malloc_and_read): New.
|
||||||
|
@ -1632,20 +1632,14 @@ _bfd_coff_get_external_symbols (bfd *abfd)
|
|||||||
size_t symesz;
|
size_t symesz;
|
||||||
size_t size;
|
size_t size;
|
||||||
void * syms;
|
void * syms;
|
||||||
ufile_ptr filesize;
|
|
||||||
|
|
||||||
if (obj_coff_external_syms (abfd) != NULL)
|
if (obj_coff_external_syms (abfd) != NULL)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* Check for integer overflow and for unreasonable symbol counts. */
|
|
||||||
filesize = bfd_get_file_size (abfd);
|
|
||||||
symesz = bfd_coff_symesz (abfd);
|
symesz = bfd_coff_symesz (abfd);
|
||||||
if (_bfd_mul_overflow (obj_raw_syment_count (abfd), symesz, &size)
|
if (_bfd_mul_overflow (obj_raw_syment_count (abfd), symesz, &size))
|
||||||
|| (filesize != 0 && size > filesize))
|
|
||||||
{
|
{
|
||||||
bfd_set_error (bfd_error_file_truncated);
|
bfd_set_error (bfd_error_file_truncated);
|
||||||
_bfd_error_handler (_("%pB: corrupt symbol count: %#" PRIx64 ""),
|
|
||||||
abfd, (uint64_t) obj_raw_syment_count (abfd));
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
bfd/elf.c
14
bfd/elf.c
@ -296,7 +296,6 @@ bfd_elf_get_str_section (bfd *abfd, unsigned int shindex)
|
|||||||
/* Allocate and clear an extra byte at the end, to prevent crashes
|
/* Allocate and clear an extra byte at the end, to prevent crashes
|
||||||
in case the string table is not terminated. */
|
in case the string table is not terminated. */
|
||||||
if (shstrtabsize + 1 <= 1
|
if (shstrtabsize + 1 <= 1
|
||||||
|| shstrtabsize > bfd_get_file_size (abfd)
|
|
||||||
|| bfd_seek (abfd, offset, SEEK_SET) != 0
|
|| bfd_seek (abfd, offset, SEEK_SET) != 0
|
||||||
|| (shstrtab = _bfd_alloc_and_read (abfd, shstrtabsize + 1,
|
|| (shstrtab = _bfd_alloc_and_read (abfd, shstrtabsize + 1,
|
||||||
shstrtabsize)) == NULL)
|
shstrtabsize)) == NULL)
|
||||||
@ -8586,19 +8585,6 @@ error_return_verref:
|
|||||||
goto error_return;
|
goto error_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ufile_ptr filesize = bfd_get_file_size (abfd);
|
|
||||||
if (filesize > 0 && filesize < hdr->sh_size)
|
|
||||||
{
|
|
||||||
/* PR 24708: Avoid attempts to allocate a ridiculous amount
|
|
||||||
of memory. */
|
|
||||||
bfd_set_error (bfd_error_no_memory);
|
|
||||||
_bfd_error_handler
|
|
||||||
/* xgettext:c-format */
|
|
||||||
(_("error: %pB version reference section is too large (%#" PRIx64 " bytes)"),
|
|
||||||
abfd, (uint64_t) hdr->sh_size);
|
|
||||||
goto error_return_verref;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0)
|
if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0)
|
||||||
goto error_return_verref;
|
goto error_return_verref;
|
||||||
contents = _bfd_malloc_and_read (abfd, hdr->sh_size, hdr->sh_size);
|
contents = _bfd_malloc_and_read (abfd, hdr->sh_size, hdr->sh_size);
|
||||||
|
@ -904,10 +904,26 @@ extern bfd_vma _bfd_safe_read_leb128
|
|||||||
((*res) = (a), (*res) *= (b), (b) != 0 && (*res) / (b) != (a))
|
((*res) = (a), (*res) *= (b), (b) != 0 && (*res) / (b) != (a))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define _bfd_constant_p(v) __builtin_constant_p (v)
|
||||||
|
#else
|
||||||
|
#define _bfd_constant_p(v) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline bfd_byte *
|
static inline bfd_byte *
|
||||||
_bfd_alloc_and_read (bfd *abfd, bfd_size_type asize, bfd_size_type rsize)
|
_bfd_alloc_and_read (bfd *abfd, bfd_size_type asize, bfd_size_type rsize)
|
||||||
{
|
{
|
||||||
bfd_byte *mem = bfd_alloc (abfd, asize);
|
bfd_byte *mem;
|
||||||
|
if (!_bfd_constant_p (rsize))
|
||||||
|
{
|
||||||
|
ufile_ptr filesize = bfd_get_file_size (abfd);
|
||||||
|
if (filesize != 0 && rsize > filesize)
|
||||||
|
{
|
||||||
|
bfd_set_error (bfd_error_file_truncated);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mem = bfd_alloc (abfd, asize);
|
||||||
if (mem != NULL)
|
if (mem != NULL)
|
||||||
{
|
{
|
||||||
if (bfd_bread (mem, rsize, abfd) == rsize)
|
if (bfd_bread (mem, rsize, abfd) == rsize)
|
||||||
@ -920,7 +936,17 @@ _bfd_alloc_and_read (bfd *abfd, bfd_size_type asize, bfd_size_type rsize)
|
|||||||
static inline bfd_byte *
|
static inline bfd_byte *
|
||||||
_bfd_malloc_and_read (bfd *abfd, bfd_size_type asize, bfd_size_type rsize)
|
_bfd_malloc_and_read (bfd *abfd, bfd_size_type asize, bfd_size_type rsize)
|
||||||
{
|
{
|
||||||
bfd_byte *mem = bfd_malloc (asize);
|
bfd_byte *mem;
|
||||||
|
if (!_bfd_constant_p (rsize))
|
||||||
|
{
|
||||||
|
ufile_ptr filesize = bfd_get_file_size (abfd);
|
||||||
|
if (filesize != 0 && rsize > filesize)
|
||||||
|
{
|
||||||
|
bfd_set_error (bfd_error_file_truncated);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mem = bfd_malloc (asize);
|
||||||
if (mem != NULL)
|
if (mem != NULL)
|
||||||
{
|
{
|
||||||
if (bfd_bread (mem, rsize, abfd) == rsize)
|
if (bfd_bread (mem, rsize, abfd) == rsize)
|
||||||
|
30
bfd/libbfd.h
30
bfd/libbfd.h
@ -909,10 +909,26 @@ extern bfd_vma _bfd_safe_read_leb128
|
|||||||
((*res) = (a), (*res) *= (b), (b) != 0 && (*res) / (b) != (a))
|
((*res) = (a), (*res) *= (b), (b) != 0 && (*res) / (b) != (a))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define _bfd_constant_p(v) __builtin_constant_p (v)
|
||||||
|
#else
|
||||||
|
#define _bfd_constant_p(v) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline bfd_byte *
|
static inline bfd_byte *
|
||||||
_bfd_alloc_and_read (bfd *abfd, bfd_size_type asize, bfd_size_type rsize)
|
_bfd_alloc_and_read (bfd *abfd, bfd_size_type asize, bfd_size_type rsize)
|
||||||
{
|
{
|
||||||
bfd_byte *mem = bfd_alloc (abfd, asize);
|
bfd_byte *mem;
|
||||||
|
if (!_bfd_constant_p (rsize))
|
||||||
|
{
|
||||||
|
ufile_ptr filesize = bfd_get_file_size (abfd);
|
||||||
|
if (filesize != 0 && rsize > filesize)
|
||||||
|
{
|
||||||
|
bfd_set_error (bfd_error_file_truncated);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mem = bfd_alloc (abfd, asize);
|
||||||
if (mem != NULL)
|
if (mem != NULL)
|
||||||
{
|
{
|
||||||
if (bfd_bread (mem, rsize, abfd) == rsize)
|
if (bfd_bread (mem, rsize, abfd) == rsize)
|
||||||
@ -925,7 +941,17 @@ _bfd_alloc_and_read (bfd *abfd, bfd_size_type asize, bfd_size_type rsize)
|
|||||||
static inline bfd_byte *
|
static inline bfd_byte *
|
||||||
_bfd_malloc_and_read (bfd *abfd, bfd_size_type asize, bfd_size_type rsize)
|
_bfd_malloc_and_read (bfd *abfd, bfd_size_type asize, bfd_size_type rsize)
|
||||||
{
|
{
|
||||||
bfd_byte *mem = bfd_malloc (asize);
|
bfd_byte *mem;
|
||||||
|
if (!_bfd_constant_p (rsize))
|
||||||
|
{
|
||||||
|
ufile_ptr filesize = bfd_get_file_size (abfd);
|
||||||
|
if (filesize != 0 && rsize > filesize)
|
||||||
|
{
|
||||||
|
bfd_set_error (bfd_error_file_truncated);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mem = bfd_malloc (asize);
|
||||||
if (mem != NULL)
|
if (mem != NULL)
|
||||||
{
|
{
|
||||||
if (bfd_bread (mem, rsize, abfd) == rsize)
|
if (bfd_bread (mem, rsize, abfd) == rsize)
|
||||||
|
Loading…
Reference in New Issue
Block a user