| From cfd14a500e0485374596234de4db10e88ebc7618 Mon Sep 17 00:00:00 2001 |
| From: Nick Clifton <nickc@redhat.com> |
| Date: Mon, 26 Jun 2017 15:25:08 +0100 |
| Subject: [PATCH] Fix address violations when atempting to parse fuzzed |
| binaries. |
| |
| PR binutils/21665 |
| bfd * opncls.c (get_build_id): Check that the section is beig enough |
| to contain the whole note. |
| * compress.c (bfd_get_full_section_contents): Check for and reject |
| a section whoes size is greater than the size of the entire file. |
| * elf32-v850.c (v850_elf_copy_notes): Allow for the ouput to not |
| contain a notes section. |
| |
| binutils* objdump.c (disassemble_section): Skip any section that is bigger |
| than the entire file. |
| |
| Upstream-Status: Backport |
| CVE: CVE-2017-9955 #1 |
| Signed-off-by: Armin Kuster <akuster@mvista.com> |
| |
| --- |
| bfd/ChangeLog | 10 ++++++++++ |
| bfd/compress.c | 6 ++++++ |
| bfd/elf32-v850.c | 4 +++- |
| bfd/opncls.c | 18 ++++++++++++++++-- |
| binutils/ChangeLog | 6 ++++++ |
| binutils/objdump.c | 4 ++-- |
| 6 files changed, 43 insertions(+), 5 deletions(-) |
| |
| Index: git/bfd/compress.c |
| =================================================================== |
| --- git.orig/bfd/compress.c |
| +++ git/bfd/compress.c |
| @@ -239,6 +239,12 @@ bfd_get_full_section_contents (bfd *abfd |
| *ptr = NULL; |
| return TRUE; |
| } |
| + else if (bfd_get_file_size (abfd) > 0 |
| + && sz > (bfd_size_type) bfd_get_file_size (abfd)) |
| + { |
| + *ptr = NULL; |
| + return FALSE; |
| + } |
| |
| switch (sec->compress_status) |
| { |
| Index: git/bfd/elf32-v850.c |
| =================================================================== |
| --- git.orig/bfd/elf32-v850.c |
| +++ git/bfd/elf32-v850.c |
| @@ -2450,7 +2450,9 @@ v850_elf_copy_notes (bfd *ibfd, bfd *obf |
| BFD_ASSERT (bfd_malloc_and_get_section (ibfd, inotes, & icont)); |
| |
| if ((ocont = elf_section_data (onotes)->this_hdr.contents) == NULL) |
| - BFD_ASSERT (bfd_malloc_and_get_section (obfd, onotes, & ocont)); |
| + /* If the output is being stripped then it is possible for |
| + the notes section to disappear. In this case do nothing. */ |
| + return; |
| |
| /* Copy/overwrite notes from the input to the output. */ |
| memcpy (ocont, icont, bfd_section_size (obfd, onotes)); |
| Index: git/bfd/opncls.c |
| =================================================================== |
| --- git.orig/bfd/opncls.c |
| +++ git/bfd/opncls.c |
| @@ -1776,6 +1776,7 @@ get_build_id (bfd *abfd) |
| Elf_External_Note *enote; |
| bfd_byte *contents; |
| asection *sect; |
| + bfd_size_type size; |
| |
| BFD_ASSERT (abfd); |
| |
| @@ -1790,8 +1791,9 @@ get_build_id (bfd *abfd) |
| return NULL; |
| } |
| |
| + size = bfd_get_section_size (sect); |
| /* FIXME: Should we support smaller build-id notes ? */ |
| - if (bfd_get_section_size (sect) < 0x24) |
| + if (size < 0x24) |
| { |
| bfd_set_error (bfd_error_invalid_operation); |
| return NULL; |
| @@ -1804,6 +1806,17 @@ get_build_id (bfd *abfd) |
| return NULL; |
| } |
| |
| + /* FIXME: Paranoia - allow for compressed build-id sections. |
| + Maybe we should complain if this size is different from |
| + the one obtained above... */ |
| + size = bfd_get_section_size (sect); |
| + if (size < sizeof (Elf_External_Note)) |
| + { |
| + bfd_set_error (bfd_error_invalid_operation); |
| + free (contents); |
| + return NULL; |
| + } |
| + |
| enote = (Elf_External_Note *) contents; |
| inote.type = H_GET_32 (abfd, enote->type); |
| inote.namesz = H_GET_32 (abfd, enote->namesz); |
| @@ -1815,7 +1828,8 @@ get_build_id (bfd *abfd) |
| if (inote.descsz == 0 |
| || inote.type != NT_GNU_BUILD_ID |
| || inote.namesz != 4 /* sizeof "GNU" */ |
| - || strcmp (inote.namedata, "GNU") != 0) |
| + || strncmp (inote.namedata, "GNU", 4) != 0 |
| + || size < (12 + BFD_ALIGN (inote.namesz, 4) + inote.descsz)) |
| { |
| free (contents); |
| bfd_set_error (bfd_error_invalid_operation); |
| Index: git/binutils/objdump.c |
| =================================================================== |
| --- git.orig/binutils/objdump.c |
| +++ git/binutils/objdump.c |
| @@ -2048,7 +2048,7 @@ disassemble_section (bfd *abfd, asection |
| return; |
| |
| datasize = bfd_get_section_size (section); |
| - if (datasize == 0) |
| + if (datasize == 0 || datasize >= (bfd_size_type) bfd_get_file_size (abfd)) |
| return; |
| |
| if (start_address == (bfd_vma) -1 |
| @@ -2912,7 +2912,7 @@ dump_target_specific (bfd *abfd) |
| static void |
| dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED) |
| { |
| - bfd_byte *data = 0; |
| + bfd_byte *data = NULL; |
| bfd_size_type datasize; |
| bfd_vma addr_offset; |
| bfd_vma start_offset; |
| Index: git/bfd/ChangeLog |
| =================================================================== |
| --- git.orig/bfd/ChangeLog |
| +++ git/bfd/ChangeLog |
| @@ -1,4 +1,14 @@ |
| 2017-06-26 Nick Clifton <nickc@redhat.com> |
| + |
| + PR binutils/21665 |
| + * opncls.c (get_build_id): Check that the section is beig enough |
| + to contain the whole note. |
| + * compress.c (bfd_get_full_section_contents): Check for and reject |
| + a section whoes size is greater than the size of the entire file. |
| + * elf32-v850.c (v850_elf_copy_notes): Allow for the ouput to not |
| + contain a notes section. |
| + |
| +2017-06-26 Nick Clifton <nickc@redhat.com> |
| |
| PR binutils/21670 |
| * tekhex.c (getvalue): Check for the source pointer exceeding the |
| Index: git/binutils/ChangeLog |
| =================================================================== |
| --- git.orig/binutils/ChangeLog |
| +++ git/binutils/ChangeLog |
| @@ -1,3 +1,9 @@ |
| +2017-06-26 Nick Clifton <nickc@redhat.com> |
| + |
| + PR binutils/21665 |
| + * objdump.c (disassemble_section): Skip any section that is bigger |
| + than the entire file. |
| + |
| 2017-04-03 Nick Clifton <nickc@redhat.com> |
| |
| PR binutils/21345 |