[OE-core] [ROCKO][PATCH 10/12] Binutils: Security fix for CVE-2018-7568

Armin Kuster akuster808 at gmail.com
Wed Aug 8 21:54:17 UTC 2018


From: Armin Kuster <akuster at mvista.com>

Affects: <= 2.30

Signed-off-by: Armin Kuster <akuster at mvista.com>
---
 meta/recipes-devtools/binutils/binutils-2.29.1.inc |   2 +
 .../binutils/binutils/CVE-2018-7568_p1.patch       | 161 +++++++++++++++++++++
 .../binutils/binutils/CVE-2018-7568_p2.patch       |  73 ++++++++++
 3 files changed, 236 insertions(+)
 create mode 100644 meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p1.patch
 create mode 100644 meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p2.patch

diff --git a/meta/recipes-devtools/binutils/binutils-2.29.1.inc b/meta/recipes-devtools/binutils/binutils-2.29.1.inc
index 13389a1..ceb8e85 100644
--- a/meta/recipes-devtools/binutils/binutils-2.29.1.inc
+++ b/meta/recipes-devtools/binutils/binutils-2.29.1.inc
@@ -73,6 +73,8 @@ SRC_URI = "\
      file://CVE-2018-6323.patch \
      file://CVE-2018-6759.patch \
      file://CVE-2018-7208.patch \
+     file://CVE-2018-7568_p1.patch \
+     file://CVE-2018-7568_p2.patch \
 "
 S  = "${WORKDIR}/git"
 
diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p1.patch b/meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p1.patch
new file mode 100644
index 0000000..b014080
--- /dev/null
+++ b/meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p1.patch
@@ -0,0 +1,161 @@
+From 1da5c9a485f3dcac4c45e96ef4b7dae5948314b5 Mon Sep 17 00:00:00 2001
+From: Alan Modra <amodra at gmail.com>
+Date: Mon, 25 Sep 2017 20:20:38 +0930
+Subject: [PATCH] PR22202, buffer overflow in parse_die
+
+There was a complete lack of sanity checking in dwarf1.c
+
+	PR 22202
+	* dwarf1.c (parse_die): Sanity check pointer against section limit
+	before dereferencing.
+	(parse_line_table): Likewise.
+
+Upstream-Status: Backport
+Affects: <= 2.30
+CVE: CVE-2018-7568 patch1
+Signed-off-by: Armin Kuster <akuster at mvista.com>
+
+---
+ bfd/ChangeLog |  7 +++++++
+ bfd/dwarf1.c  | 56 ++++++++++++++++++++++++++++++++++++++------------------
+ 2 files changed, 45 insertions(+), 18 deletions(-)
+
+Index: git/bfd/dwarf1.c
+===================================================================
+--- git.orig/bfd/dwarf1.c
++++ git/bfd/dwarf1.c
+@@ -189,11 +189,14 @@ parse_die (bfd *             abfd,
+   memset (aDieInfo, 0, sizeof (* aDieInfo));
+ 
+   /* First comes the length.  */
+-  aDieInfo->length = bfd_get_32 (abfd, (bfd_byte *) xptr);
++  if (xptr + 4 > aDiePtrEnd)
++    return FALSE;
++  aDieInfo->length = bfd_get_32 (abfd, xptr);
+   xptr += 4;
+   if (aDieInfo->length == 0
+-      || (this_die + aDieInfo->length) >= aDiePtrEnd)
++      || this_die + aDieInfo->length > aDiePtrEnd)
+     return FALSE;
++  aDiePtrEnd = this_die + aDieInfo->length;
+   if (aDieInfo->length < 6)
+     {
+       /* Just padding bytes.  */
+@@ -202,18 +205,20 @@ parse_die (bfd *             abfd,
+     }
+ 
+   /* Then the tag.  */
+-  aDieInfo->tag = bfd_get_16 (abfd, (bfd_byte *) xptr);
++  if (xptr + 2 > aDiePtrEnd)
++    return FALSE;
++  aDieInfo->tag = bfd_get_16 (abfd, xptr);
+   xptr += 2;
+ 
+   /* Then the attributes.  */
+-  while (xptr < (this_die + aDieInfo->length))
++  while (xptr + 2 <= aDiePtrEnd)
+     {
+       unsigned short attr;
+ 
+       /* Parse the attribute based on its form.  This section
+          must handle all dwarf1 forms, but need only handle the
+ 	 actual attributes that we care about.  */
+-      attr = bfd_get_16 (abfd, (bfd_byte *) xptr);
++      attr = bfd_get_16 (abfd, xptr);
+       xptr += 2;
+ 
+       switch (FORM_FROM_ATTR (attr))
+@@ -223,12 +228,15 @@ parse_die (bfd *             abfd,
+ 	  break;
+ 	case FORM_DATA4:
+ 	case FORM_REF:
+-	  if (attr == AT_sibling)
+-	    aDieInfo->sibling = bfd_get_32 (abfd, (bfd_byte *) xptr);
+-	  else if (attr == AT_stmt_list)
++	  if (xptr + 4 <= aDiePtrEnd)
+ 	    {
+-	      aDieInfo->stmt_list_offset = bfd_get_32 (abfd, (bfd_byte *) xptr);
+-	      aDieInfo->has_stmt_list = 1;
++	      if (attr == AT_sibling)
++		aDieInfo->sibling = bfd_get_32 (abfd, xptr);
++	      else if (attr == AT_stmt_list)
++		{
++		  aDieInfo->stmt_list_offset = bfd_get_32 (abfd, xptr);
++		  aDieInfo->has_stmt_list = 1;
++		}
+ 	    }
+ 	  xptr += 4;
+ 	  break;
+@@ -236,22 +244,29 @@ parse_die (bfd *             abfd,
+ 	  xptr += 8;
+ 	  break;
+ 	case FORM_ADDR:
+-	  if (attr == AT_low_pc)
+-	    aDieInfo->low_pc = bfd_get_32 (abfd, (bfd_byte *) xptr);
+-	  else if (attr == AT_high_pc)
+-	    aDieInfo->high_pc = bfd_get_32 (abfd, (bfd_byte *) xptr);
++	  if (xptr + 4 <= aDiePtrEnd)
++	    {
++	      if (attr == AT_low_pc)
++		aDieInfo->low_pc = bfd_get_32 (abfd, xptr);
++	      else if (attr == AT_high_pc)
++		aDieInfo->high_pc = bfd_get_32 (abfd, xptr);
++	    }
+ 	  xptr += 4;
+ 	  break;
+ 	case FORM_BLOCK2:
+-	  xptr += 2 + bfd_get_16 (abfd, (bfd_byte *) xptr);
++	  if (xptr + 2 <= aDiePtrEnd)
++	    xptr += bfd_get_16 (abfd, xptr);
++	  xptr += 2;
+ 	  break;
+ 	case FORM_BLOCK4:
+-	  xptr += 4 + bfd_get_32 (abfd, (bfd_byte *) xptr);
++	  if (xptr + 4 <= aDiePtrEnd)
++	    xptr += bfd_get_32 (abfd, xptr);
++	  xptr += 4;
+ 	  break;
+ 	case FORM_STRING:
+ 	  if (attr == AT_name)
+ 	    aDieInfo->name = (char *) xptr;
+-	  xptr += strlen ((char *) xptr) + 1;
++	  xptr += strnlen ((char *) xptr, aDiePtrEnd - xptr) + 1;
+ 	  break;
+ 	}
+     }
+@@ -290,7 +305,7 @@ parse_line_table (struct dwarf1_debug* s
+     }
+ 
+   xptr = stash->line_section + aUnit->stmt_list_offset;
+-  if (xptr < stash->line_section_end)
++  if (xptr + 8 <= stash->line_section_end)
+     {
+       unsigned long eachLine;
+       bfd_byte *tblend;
+@@ -318,6 +333,11 @@ parse_line_table (struct dwarf1_debug* s
+ 
+       for (eachLine = 0; eachLine < aUnit->line_count; eachLine++)
+ 	{
++	  if (xptr + 10 > stash->line_section_end)
++	    {
++	      aUnit->line_count = eachLine;
++	      break;
++	    }
+ 	  /* A line number.  */
+ 	  aUnit->linenumber_table[eachLine].linenumber
+ 	    = bfd_get_32 (stash->abfd, (bfd_byte *) xptr);
+Index: git/bfd/ChangeLog
+===================================================================
+--- git.orig/bfd/ChangeLog
++++ git/bfd/ChangeLog
+@@ -1,3 +1,10 @@
++2017-09-25  Alan Modra  <amodra at gmail.com>
++
++       PR 22202
++       * dwarf1.c (parse_die): Sanity check pointer against section limit
++       before dereferencing.
++       (parse_line_table): Likewise.
++
+ 2018-01-29  Alan Modra  <amodra at gmail.com>
+ 
+        PR 22741
diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p2.patch b/meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p2.patch
new file mode 100644
index 0000000..b5511d7
--- /dev/null
+++ b/meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p2.patch
@@ -0,0 +1,73 @@
+From eef104664efb52965d85a28bc3fc7c77e52e48e2 Mon Sep 17 00:00:00 2001
+From: Nick Clifton <nickc at redhat.com>
+Date: Wed, 28 Feb 2018 10:13:54 +0000
+Subject: [PATCH] Fix potential integer overflow when reading corrupt dwarf1
+ debug information.
+
+	PR 22894
+	* dwarf1.c (parse_die): Check the length of form blocks before
+	advancing the data pointer.
+
+Upstream-Status: Backport
+Affects: <= 2.30
+CVE: CVE-2018-7568 patch2
+Signed-off-by: Armin Kuster <akuster at mvista.com>
+
+---
+ bfd/ChangeLog |  6 ++++++
+ bfd/dwarf1.c  | 17 +++++++++++++++--
+ 2 files changed, 21 insertions(+), 2 deletions(-)
+
+Index: git/bfd/dwarf1.c
+===================================================================
+--- git.orig/bfd/dwarf1.c
++++ git/bfd/dwarf1.c
+@@ -213,6 +213,7 @@ parse_die (bfd *             abfd,
+   /* Then the attributes.  */
+   while (xptr + 2 <= aDiePtrEnd)
+     {
++      unsigned int   block_len;
+       unsigned short attr;
+ 
+       /* Parse the attribute based on its form.  This section
+@@ -255,12 +256,24 @@ parse_die (bfd *             abfd,
+ 	  break;
+ 	case FORM_BLOCK2:
+ 	  if (xptr + 2 <= aDiePtrEnd)
+-	    xptr += bfd_get_16 (abfd, xptr);
++	    {
++	      block_len = bfd_get_16 (abfd, xptr);
++	      if (xptr + block_len > aDiePtrEnd
++		  || xptr + block_len < xptr)
++		return FALSE;
++	      xptr += block_len;
++	    }
+ 	  xptr += 2;
+ 	  break;
+ 	case FORM_BLOCK4:
+ 	  if (xptr + 4 <= aDiePtrEnd)
+-	    xptr += bfd_get_32 (abfd, xptr);
++	    {
++	      block_len = bfd_get_32 (abfd, xptr);
++	      if (xptr + block_len > aDiePtrEnd
++		  || xptr + block_len < xptr)
++		return FALSE;
++	      xptr += block_len;
++	    }
+ 	  xptr += 4;
+ 	  break;
+ 	case FORM_STRING:
+Index: git/bfd/ChangeLog
+===================================================================
+--- git.orig/bfd/ChangeLog
++++ git/bfd/ChangeLog
+@@ -1,3 +1,9 @@
++2018-02-28  Nick Clifton  <nickc at redhat.com>
++
++       PR 22894
++       * dwarf1.c (parse_die): Check the length of form blocks before
++       advancing the data pointer.
++
+ 2017-09-25  Alan Modra  <amodra at gmail.com>
+ 
+        PR 22202
-- 
2.7.4




More information about the Openembedded-core mailing list