From 327301a4604da40da264c554daa8c1e97aa2fbe2 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 31 Jan 2020 00:53:59 +1030 Subject: [PATCH] OOM in setup_group We alloc, seek and read using section sizes in object files. Fuzzed objects can have silly sizes, but that's OK if the system supports memory over-commit. The read fails because we hit EOF and that usually results in a graceful exit. But if we memset before the read then the invalid size results in attempting to write to a huge number of memory pages, and an eventual Out Of Memory after probably swapping like crazy. So don't memset. There really isn't a need to clear the section contents anyway. All bytes are written with a good object file by the read and following loop converting section index in target order to ELF section header pointer, and the only untidy bytes are the 4 bytes past the group flags when pointers are 8 bytes. Those don't matter but the patch clears them for anyone poking around in a debugger. On error paths it's as good to free section contents as it is to clear them. Noticed when looking at PR4110 fourth test case. PR 4110 * elf.c (setup_group): Don't clear entire section contents, just the padding after group flags. Release alloc'd memory after a seek or read failure. --- bfd/ChangeLog | 7 +++++++ bfd/elf.c | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 30766c113e3..0061b6f3557 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2020-01-31 Alan Modra + + PR 4110 + * elf.c (setup_group): Don't clear entire section contents, + just the padding after group flags. Release alloc'd memory + after a seek or read failure. + 2020-01-16 Jon Turney * peXXigen.c (pe_is_repro): New function. diff --git a/bfd/elf.c b/bfd/elf.c index a8d98a60f4e..5e6b9a0f416 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -676,8 +676,6 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect) continue; } - memset (shdr->contents, 0, amt); - if (bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0 || (bfd_bread (shdr->contents, shdr->sh_size, abfd) != shdr->sh_size)) @@ -692,7 +690,8 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect) /* PR 17510: If the group contents are even partially corrupt, do not allow any of the contents to be used. */ - memset (shdr->contents, 0, amt); + bfd_release (abfd, shdr->contents); + shdr->contents = NULL; continue; } @@ -712,6 +711,7 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect) idx = H_GET_32 (abfd, src); if (src == shdr->contents) { + dest->shdr = NULL; dest->flags = idx; if (shdr->bfd_section != NULL && (idx & GRP_COMDAT)) shdr->bfd_section->flags -- 2.30.2