mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-22 02:50:08 +08:00
ELF core file size checks
Catch fuzzed segments where p_offset + p_filesz wraps, and limit error output. * elfcore.h (elf_core_file_p): Rewrite segment checks using bfd_get_file_size. Set read_only on file size errors. * elfcode.h (elf_swap_shdr_in): Don't repeat error message.
This commit is contained in:
@ -325,9 +325,10 @@ elf_swap_shdr_in (bfd *abfd,
|
|||||||
&& ((ufile_ptr) dst->sh_offset > filesize
|
&& ((ufile_ptr) dst->sh_offset > filesize
|
||||||
|| dst->sh_size > filesize - dst->sh_offset))
|
|| dst->sh_size > filesize - dst->sh_offset))
|
||||||
{
|
{
|
||||||
|
if (!abfd->read_only)
|
||||||
|
_bfd_error_handler (_("warning: %pB has a section "
|
||||||
|
"extending past end of file"), abfd);
|
||||||
abfd->read_only = 1;
|
abfd->read_only = 1;
|
||||||
_bfd_error_handler (_("warning: %pB has a section "
|
|
||||||
"extending past end of file"), abfd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dst->sh_link = H_GET_32 (abfd, src->sh_link);
|
dst->sh_link = H_GET_32 (abfd, src->sh_link);
|
||||||
|
@ -92,6 +92,7 @@ elf_core_file_p (bfd *abfd)
|
|||||||
unsigned int phindex;
|
unsigned int phindex;
|
||||||
const struct elf_backend_data *ebd;
|
const struct elf_backend_data *ebd;
|
||||||
bfd_size_type amt;
|
bfd_size_type amt;
|
||||||
|
ufile_ptr filesize;
|
||||||
|
|
||||||
/* Read in the ELF header in external format. */
|
/* Read in the ELF header in external format. */
|
||||||
if (bfd_bread (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr))
|
if (bfd_bread (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr))
|
||||||
@ -286,29 +287,21 @@ elf_core_file_p (bfd *abfd)
|
|||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* Check for core truncation. */
|
/* Check for core truncation. */
|
||||||
{
|
filesize = bfd_get_file_size (abfd);
|
||||||
bfd_size_type high = 0;
|
if (filesize != 0)
|
||||||
struct stat statbuf;
|
{
|
||||||
for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
|
for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
|
||||||
{
|
{
|
||||||
Elf_Internal_Phdr *p = i_phdrp + phindex;
|
Elf_Internal_Phdr *p = i_phdrp + phindex;
|
||||||
if (p->p_filesz)
|
if (p->p_filesz
|
||||||
{
|
&& (p->p_offset >= filesize
|
||||||
bfd_size_type current = p->p_offset + p->p_filesz;
|
|| p->p_filesz > filesize - p->p_offset))
|
||||||
if (high < current)
|
{
|
||||||
high = current;
|
_bfd_error_handler (_("warning: %pB has a segment "
|
||||||
}
|
"extending past end of file"), abfd);
|
||||||
}
|
abfd->read_only = 1;
|
||||||
if (bfd_stat (abfd, &statbuf) == 0)
|
break;
|
||||||
{
|
}
|
||||||
if ((bfd_size_type) statbuf.st_size < high)
|
|
||||||
{
|
|
||||||
_bfd_error_handler
|
|
||||||
/* xgettext:c-format */
|
|
||||||
(_("warning: %pB is truncated: expected core file "
|
|
||||||
"size >= %" PRIu64 ", found: %" PRIu64),
|
|
||||||
abfd, (uint64_t) high, (uint64_t) statbuf.st_size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user