| From 0630b49c470ca2e3c3f74da4c7e4ff63440dd71f Mon Sep 17 00:00:00 2001 |
| From: "H.J. Lu" <hjl.tools@gmail.com> |
| Date: Mon, 26 Jun 2017 09:24:49 -0700 |
| Subject: [PATCH] Check file size before getting section contents |
| |
| Don't check the section size in bfd_get_full_section_contents since |
| the size of a decompressed section may be larger than the file size. |
| Instead, check file size in _bfd_generic_get_section_contents. |
| |
| PR binutils/21665 |
| * compress.c (bfd_get_full_section_contents): Don't check the |
| file size here. |
| * libbfd.c (_bfd_generic_get_section_contents): Check for and |
| reject a section whoes size + offset is greater than the size |
| of the entire file. |
| (_bfd_generic_get_section_contents_in_window): Likewise. |
| |
| Upstream-Status: Backport |
| CVE: CVE-2017-9955 #2 |
| Signed-off-by: Armin Kuster <akuster@mvista.com> |
| |
| --- |
| bfd/ChangeLog | 10 +++++++++- |
| bfd/compress.c | 8 +------- |
| bfd/libbfd.c | 17 ++++++++++++++++- |
| 3 files changed, 26 insertions(+), 9 deletions(-) |
| |
| Index: git/bfd/compress.c |
| =================================================================== |
| --- git.orig/bfd/compress.c |
| +++ git/bfd/compress.c |
| @@ -239,12 +239,6 @@ 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) |
| { |
| @@ -260,7 +254,7 @@ bfd_get_full_section_contents (bfd *abfd |
| /* xgettext:c-format */ |
| (_("error: %B(%A) is too large (%#lx bytes)"), |
| abfd, sec, (long) sz); |
| - return FALSE; |
| + return FALSE; |
| } |
| } |
| |
| Index: git/bfd/libbfd.c |
| =================================================================== |
| --- git.orig/bfd/libbfd.c |
| +++ git/bfd/libbfd.c |
| @@ -780,6 +780,7 @@ _bfd_generic_get_section_contents (bfd * |
| bfd_size_type count) |
| { |
| bfd_size_type sz; |
| + file_ptr filesz; |
| if (count == 0) |
| return TRUE; |
| |
| @@ -802,8 +803,15 @@ _bfd_generic_get_section_contents (bfd * |
| sz = section->rawsize; |
| else |
| sz = section->size; |
| + filesz = bfd_get_file_size (abfd); |
| + if (filesz < 0) |
| + { |
| + /* This should never happen. */ |
| + abort (); |
| + } |
| if (offset + count < count |
| - || offset + count > sz) |
| + || offset + count > sz |
| + || (section->filepos + offset + sz) > (bfd_size_type) filesz) |
| { |
| bfd_set_error (bfd_error_invalid_operation); |
| return FALSE; |
| @@ -826,6 +834,7 @@ _bfd_generic_get_section_contents_in_win |
| { |
| #ifdef USE_MMAP |
| bfd_size_type sz; |
| + file_ptr filesz; |
| |
| if (count == 0) |
| return TRUE; |
| @@ -858,7 +867,13 @@ _bfd_generic_get_section_contents_in_win |
| sz = section->rawsize; |
| else |
| sz = section->size; |
| + filesz = bfd_get_file_size (abfd); |
| + { |
| + /* This should never happen. */ |
| + abort (); |
| + } |
| if (offset + count > sz |
| + || (section->filepos + offset + sz) > (bfd_size_type) filesz |
| || ! bfd_get_file_window (abfd, section->filepos + offset, count, w, |
| TRUE)) |
| return FALSE; |
| Index: git/bfd/ChangeLog |
| =================================================================== |
| --- git.orig/bfd/ChangeLog |
| +++ git/bfd/ChangeLog |
| @@ -1,3 +1,13 @@ |
| +2017-06-26 H.J. Lu <hongjiu.lu@intel.com> |
| + |
| + PR binutils/21665 |
| + * compress.c (bfd_get_full_section_contents): Don't check the |
| + file size here. |
| + * libbfd.c (_bfd_generic_get_section_contents): Check for and |
| + reject a section whoes size + offset is greater than the size |
| + of the entire file. |
| + (_bfd_generic_get_section_contents_in_window): Likewise. |
| + |
| 2017-06-26 Nick Clifton <nickc@redhat.com> |
| |
| PR binutils/21665 |