[gnome-continuous-yocto/gnomeostree-3.28-rocko: 5601/8267] binutils: Fix CVE-2017-6965 and CVE-2017-6966



commit ca22ef73d03ec5140493f29d1fe0cb6c0400c307
Author: Yuanjie Huang <yuanjie huang windriver com>
Date:   Tue Apr 11 00:00:24 2017 -0700

    binutils: Fix CVE-2017-6965 and CVE-2017-6966
    
    Backport upstream commit to address vulnerabilities:
    
    CVE: CVE-2017-6965
    [BZ 21137] -- https://sourceware.org/bugzilla/show_bug.cgi?id=21137
    
    Fix readelf writing to illegal addresses whilst processing corrupt input
    files containing symbol-difference relocations.
    
        PR binutils/21137
        * readelf.c (target_specific_reloc_handling): Add end parameter.
        Check for buffer overflow before writing relocated values.
        (apply_relocations): Pass end to target_specific_reloc_handling.
    
    CVE: CVE-2017-6966
    [BZ 21139] -- https://sourceware.org/bugzilla/show_bug.cgi?id=21139
    
    Fix read-after-free error in readelf when processing multiple, relocated
    sections in an MSP430 binary.
    
        PR binutils/21139
        * readelf.c (target_specific_reloc_handling): Add num_syms
        parameter.  Check for symbol table overflow before accessing
        symbol value.  If reloc pointer is NULL, discard all saved state.
        (apply_relocations): Pass num_syms to target_specific_reloc_handling.
        Call target_specific_reloc_handling with a NULL reloc pointer
        after processing all of the relocs.
    
    (From OE-Core rev: 8c52a530ba2beb438aa47956bcec3777a1eafe5f)
    
    Signed-off-by: Yuanjie Huang <yuanjie huang windriver com>
    Signed-off-by: Richard Purdie <richard purdie linuxfoundation org>

 meta/recipes-devtools/binutils/binutils-2.28.inc   |    2 +
 .../binutils/binutils/CVE-2017-6965.patch          |  124 ++++++++++
 .../binutils/binutils/CVE-2017-6966.patch          |  241 ++++++++++++++++++++
 3 files changed, 367 insertions(+), 0 deletions(-)
---
diff --git a/meta/recipes-devtools/binutils/binutils-2.28.inc 
b/meta/recipes-devtools/binutils/binutils-2.28.inc
index 76b81b0..7585da1 100644
--- a/meta/recipes-devtools/binutils/binutils-2.28.inc
+++ b/meta/recipes-devtools/binutils/binutils-2.28.inc
@@ -35,6 +35,8 @@ SRC_URI = "\
      file://0014-fix-the-incorrect-assembling-for-ppc-wait-mnemonic.patch \
      file://0015-sync-with-OE-libtool-changes.patch \
      file://0016-Detect-64-bit-MIPS-targets.patch \
+     file://CVE-2017-6965.patch \
+     file://CVE-2017-6966.patch \
 "
 S  = "${WORKDIR}/git"
 
diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-6965.patch 
b/meta/recipes-devtools/binutils/binutils/CVE-2017-6965.patch
new file mode 100644
index 0000000..1334c94
--- /dev/null
+++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-6965.patch
@@ -0,0 +1,124 @@
+From bdc5166c274b842f83f8328e7cfaaf80fd29934e Mon Sep 17 00:00:00 2001
+From: Nick Clifton <nickc redhat com>
+Date: Mon, 13 Feb 2017 13:08:32 +0000
+Subject: [PATCH 1/2] Fix readelf writing to illegal addresses whilst
+ processing corrupt input files containing symbol-difference relocations.
+
+       PR binutils/21137
+       * readelf.c (target_specific_reloc_handling): Add end parameter.
+       Check for buffer overflow before writing relocated values.
+       (apply_relocations): Pass end to target_specific_reloc_handling.
+
+(cherry pick from commit 03f7786e2f440b9892b1c34a58fb26222ce1b493)
+Upstream-Status: Backport [master]
+CVE: CVE-2017-6965
+
+Signed-off-by: Yuanjie Huang <yuanjie huang windriver com>
+---
+ binutils/ChangeLog |  7 +++++++
+ binutils/readelf.c | 30 +++++++++++++++++++++++++-----
+ 2 files changed, 32 insertions(+), 5 deletions(-)
+
+diff --git a/binutils/ChangeLog b/binutils/ChangeLog
+index f21867f98c..e789a3b99b 100644
+--- a/binutils/ChangeLog
++++ b/binutils/ChangeLog
+@@ -1,3 +1,10 @@
++2017-02-13  Nick Clifton  <nickc redhat com>
++
++      PR binutils/21137
++      * readelf.c (target_specific_reloc_handling): Add end parameter.
++      Check for buffer overflow before writing relocated values.
++      (apply_relocations): Pass end to target_specific_reloc_handling.
++
+ 2017-03-02  Tristan Gingold  <gingold adacore com>
+ 
+       * configure: Regenerate.
+diff --git a/binutils/readelf.c b/binutils/readelf.c
+index b5f577f5a1..8cdaae3b8c 100644
+--- a/binutils/readelf.c
++++ b/binutils/readelf.c
+@@ -11585,6 +11585,7 @@ process_syminfo (FILE * file ATTRIBUTE_UNUSED)
+ static bfd_boolean
+ target_specific_reloc_handling (Elf_Internal_Rela * reloc,
+                               unsigned char *     start,
++                              unsigned char *     end,
+                               Elf_Internal_Sym *  symtab)
+ {
+   unsigned int reloc_type = get_reloc_type (reloc->r_info);
+@@ -11625,13 +11626,19 @@ target_specific_reloc_handling (Elf_Internal_Rela * reloc,
+         handle_sym_diff:
+           if (saved_sym != NULL)
+             {
++              int reloc_size = reloc_type == 1 ? 4 : 2;
+               bfd_vma value;
+ 
+               value = reloc->r_addend
+                 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
+                    - saved_sym->st_value);
+ 
+-              byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
++              if (start + reloc->r_offset + reloc_size >= end)
++                /* PR 21137 */
++                error (_("MSP430 sym diff reloc writes past end of section (%p vs %p)\n"),
++                       start + reloc->r_offset + reloc_size, end);
++              else
++                byte_put (start + reloc->r_offset, value, reloc_size);
+ 
+               saved_sym = NULL;
+               return TRUE;
+@@ -11662,13 +11669,18 @@ target_specific_reloc_handling (Elf_Internal_Rela * reloc,
+         case 2: /* R_MN10300_16 */
+           if (saved_sym != NULL)
+             {
++              int reloc_size = reloc_type == 1 ? 4 : 2;
+               bfd_vma value;
+ 
+               value = reloc->r_addend
+                 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
+                    - saved_sym->st_value);
+ 
+-              byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
++              if (start + reloc->r_offset + reloc_size >= end)
++                error (_("MN10300 sym diff reloc writes past end of section (%p vs %p)\n"),
++                       start + reloc->r_offset + reloc_size, end);
++              else
++                byte_put (start + reloc->r_offset, value, reloc_size);
+ 
+               saved_sym = NULL;
+               return TRUE;
+@@ -11703,12 +11715,20 @@ target_specific_reloc_handling (Elf_Internal_Rela * reloc,
+           break;
+ 
+         case 0x41: /* R_RL78_ABS32.  */
+-          byte_put (start + reloc->r_offset, value, 4);
++          if (start + reloc->r_offset + 4 >= end)
++            error (_("RL78 sym diff reloc writes past end of section (%p vs %p)\n"),
++                   start + reloc->r_offset + 2, end);
++          else
++            byte_put (start + reloc->r_offset, value, 4);
+           value = 0;
+           return TRUE;
+ 
+         case 0x43: /* R_RL78_ABS16.  */
+-          byte_put (start + reloc->r_offset, value, 2);
++          if (start + reloc->r_offset + 2 >= end)
++            error (_("RL78 sym diff reloc writes past end of section (%p vs %p)\n"),
++                   start + reloc->r_offset + 2, end);
++          else
++            byte_put (start + reloc->r_offset, value, 2);
+           value = 0;
+           return TRUE;
+ 
+@@ -12325,7 +12345,7 @@ apply_relocations (void *                     file,
+ 
+         reloc_type = get_reloc_type (rp->r_info);
+ 
+-        if (target_specific_reloc_handling (rp, start, symtab))
++        if (target_specific_reloc_handling (rp, start, end, symtab))
+           continue;
+         else if (is_none_reloc (reloc_type))
+           continue;
+-- 
+2.11.0
+
diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-6966.patch 
b/meta/recipes-devtools/binutils/binutils/CVE-2017-6966.patch
new file mode 100644
index 0000000..dd58df5
--- /dev/null
+++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-6966.patch
@@ -0,0 +1,241 @@
+From 383ec757d27652448d1511169e1133f486abf54f Mon Sep 17 00:00:00 2001
+From: Nick Clifton <nickc redhat com>
+Date: Mon, 13 Feb 2017 14:03:22 +0000
+Subject: [PATCH] Fix read-after-free error in readelf when processing
+ multiple, relocated sections in an MSP430 binary.
+
+       PR binutils/21139
+       * readelf.c (target_specific_reloc_handling): Add num_syms
+       parameter.  Check for symbol table overflow before accessing
+       symbol value.  If reloc pointer is NULL, discard all saved state.
+       (apply_relocations): Pass num_syms to target_specific_reloc_handling.
+       Call target_specific_reloc_handling with a NULL reloc pointer
+       after processing all of the relocs.
+
+(cherry pick from commit f84ce13b6708801ca1d6289b7c4003e2f5a6d7f9)
+Upstream-Status: Backport [master]
+CVE: CVE-2017-6966
+
+Signed-off-by: Yuanjie Huang <yuanjie huang windriver com>
+---
+ binutils/ChangeLog |  10 +++++
+ binutils/readelf.c | 109 +++++++++++++++++++++++++++++++++++++++++------------
+ 2 files changed, 94 insertions(+), 25 deletions(-)
+
+diff --git a/binutils/ChangeLog b/binutils/ChangeLog
+index e789a3b99b..bd63c8a0d8 100644
+--- a/binutils/ChangeLog
++++ b/binutils/ChangeLog
+@@ -1,5 +1,15 @@
+ 2017-02-13  Nick Clifton  <nickc redhat com>
+ 
++      PR binutils/21139
++      * readelf.c (target_specific_reloc_handling): Add num_syms
++      parameter.  Check for symbol table overflow before accessing
++      symbol value.  If reloc pointer is NULL, discard all saved state.
++      (apply_relocations): Pass num_syms to target_specific_reloc_handling.
++      Call target_specific_reloc_handling with a NULL reloc pointer
++      after processing all of the relocs.
++
++2017-02-13  Nick Clifton  <nickc redhat com>
++
+       PR binutils/21137
+       * readelf.c (target_specific_reloc_handling): Add end parameter.
+       Check for buffer overflow before writing relocated values.
+diff --git a/binutils/readelf.c b/binutils/readelf.c
+index 8cdaae3b8c..7c158c6342 100644
+--- a/binutils/readelf.c
++++ b/binutils/readelf.c
+@@ -11580,15 +11580,27 @@ process_syminfo (FILE * file ATTRIBUTE_UNUSED)
+ 
+ /* Check to see if the given reloc needs to be handled in a target specific
+    manner.  If so then process the reloc and return TRUE otherwise return
+-   FALSE.  */
++   FALSE.
++
++   If called with reloc == NULL, then this is a signal that reloc processing
++   for the current section has finished, and any saved state should be
++   discarded.  */
+ 
+ static bfd_boolean
+ target_specific_reloc_handling (Elf_Internal_Rela * reloc,
+                               unsigned char *     start,
+                               unsigned char *     end,
+-                              Elf_Internal_Sym *  symtab)
++                              Elf_Internal_Sym *  symtab,
++                              unsigned long       num_syms)
+ {
+-  unsigned int reloc_type = get_reloc_type (reloc->r_info);
++  unsigned int reloc_type = 0;
++  unsigned long sym_index = 0;
++
++  if (reloc)
++    {
++      reloc_type = get_reloc_type (reloc->r_info);
++      sym_index = get_reloc_symindex (reloc->r_info);
++    }
+ 
+   switch (elf_header.e_machine)
+     {
+@@ -11597,6 +11609,12 @@ target_specific_reloc_handling (Elf_Internal_Rela * reloc,
+       {
+       static Elf_Internal_Sym * saved_sym = NULL;
+ 
++      if (reloc == NULL)
++        {
++          saved_sym = NULL;
++          return TRUE;
++        }
++
+       switch (reloc_type)
+         {
+         case 10: /* R_MSP430_SYM_DIFF */
+@@ -11604,7 +11622,12 @@ target_specific_reloc_handling (Elf_Internal_Rela * reloc,
+             break;
+           /* Fall through.  */
+         case 21: /* R_MSP430X_SYM_DIFF */
+-          saved_sym = symtab + get_reloc_symindex (reloc->r_info);
++          /* PR 21139.  */
++          if (sym_index >= num_syms)
++            error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
++                   sym_index);
++          else
++            saved_sym = symtab + sym_index;
+           return TRUE;
+ 
+         case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
+@@ -11629,16 +11652,21 @@ target_specific_reloc_handling (Elf_Internal_Rela * reloc,
+               int reloc_size = reloc_type == 1 ? 4 : 2;
+               bfd_vma value;
+ 
+-              value = reloc->r_addend
+-                + (symtab[get_reloc_symindex (reloc->r_info)].st_value
+-                   - saved_sym->st_value);
+-
+-              if (start + reloc->r_offset + reloc_size >= end)
+-                /* PR 21137 */
+-                error (_("MSP430 sym diff reloc writes past end of section (%p vs %p)\n"),
+-                       start + reloc->r_offset + reloc_size, end);
++              if (sym_index >= num_syms)
++                error (_("MSP430 reloc contains invalid symbol index %lu\n"),
++                       sym_index);
+               else
+-                byte_put (start + reloc->r_offset, value, reloc_size);
++                {
++                  value = reloc->r_addend + (symtab[sym_index].st_value
++                                             - saved_sym->st_value);
++
++                  if (start + reloc->r_offset + reloc_size >= end)
++                    /* PR 21137 */
++                    error (_("MSP430 sym diff reloc writes past end of section (%p vs %p)\n"),
++                           start + reloc->r_offset + reloc_size, end);
++                  else
++                    byte_put (start + reloc->r_offset, value, reloc_size);
++                }
+ 
+               saved_sym = NULL;
+               return TRUE;
+@@ -11658,13 +11686,24 @@ target_specific_reloc_handling (Elf_Internal_Rela * reloc,
+       {
+       static Elf_Internal_Sym * saved_sym = NULL;
+ 
++      if (reloc == NULL)
++        {
++          saved_sym = NULL;
++          return TRUE;
++        }
++
+       switch (reloc_type)
+         {
+         case 34: /* R_MN10300_ALIGN */
+           return TRUE;
+         case 33: /* R_MN10300_SYM_DIFF */
+-          saved_sym = symtab + get_reloc_symindex (reloc->r_info);
++          if (sym_index >= num_syms)
++            error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
++                   sym_index);
++          else
++            saved_sym = symtab + sym_index;
+           return TRUE;
++
+         case 1: /* R_MN10300_32 */
+         case 2: /* R_MN10300_16 */
+           if (saved_sym != NULL)
+@@ -11672,15 +11711,20 @@ target_specific_reloc_handling (Elf_Internal_Rela * reloc,
+               int reloc_size = reloc_type == 1 ? 4 : 2;
+               bfd_vma value;
+ 
+-              value = reloc->r_addend
+-                + (symtab[get_reloc_symindex (reloc->r_info)].st_value
+-                   - saved_sym->st_value);
+-
+-              if (start + reloc->r_offset + reloc_size >= end)
+-                error (_("MN10300 sym diff reloc writes past end of section (%p vs %p)\n"),
+-                       start + reloc->r_offset + reloc_size, end);
++              if (sym_index >= num_syms)
++                error (_("MN10300 reloc contains invalid symbol index %lu\n"),
++                       sym_index);
+               else
+-                byte_put (start + reloc->r_offset, value, reloc_size);
++                {
++                  value = reloc->r_addend + (symtab[sym_index].st_value
++                                             - saved_sym->st_value);
++
++                  if (start + reloc->r_offset + reloc_size >= end)
++                    error (_("MN10300 sym diff reloc writes past end of section (%p vs %p)\n"),
++                           start + reloc->r_offset + reloc_size, end);
++                  else
++                    byte_put (start + reloc->r_offset, value, reloc_size);
++                }
+ 
+               saved_sym = NULL;
+               return TRUE;
+@@ -11700,12 +11744,24 @@ target_specific_reloc_handling (Elf_Internal_Rela * reloc,
+       static bfd_vma saved_sym2 = 0;
+       static bfd_vma value;
+ 
++      if (reloc == NULL)
++        {
++          saved_sym1 = saved_sym2 = 0;
++          return TRUE;
++        }
++
+       switch (reloc_type)
+         {
+         case 0x80: /* R_RL78_SYM.  */
+           saved_sym1 = saved_sym2;
+-          saved_sym2 = symtab[get_reloc_symindex (reloc->r_info)].st_value;
+-          saved_sym2 += reloc->r_addend;
++          if (sym_index >= num_syms)
++            error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
++                   sym_index);
++          else
++            {
++              saved_sym2 = symtab[sym_index].st_value;
++              saved_sym2 += reloc->r_addend;
++            }
+           return TRUE;
+ 
+         case 0x83: /* R_RL78_OPsub.  */
+@@ -12345,7 +12401,7 @@ apply_relocations (void *                     file,
+ 
+         reloc_type = get_reloc_type (rp->r_info);
+ 
+-        if (target_specific_reloc_handling (rp, start, end, symtab))
++        if (target_specific_reloc_handling (rp, start, end, symtab, num_syms))
+           continue;
+         else if (is_none_reloc (reloc_type))
+           continue;
+@@ -12441,6 +12497,9 @@ apply_relocations (void *                     file,
+       }
+ 
+       free (symtab);
++      /* Let the target specific reloc processing code know that
++       we have finished with these relocs.  */
++      target_specific_reloc_handling (NULL, NULL, NULL, NULL, 0);
+ 
+       if (relocs_return)
+       {
+-- 
+2.11.0
+


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]