aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArmin Kuster <akuster@mvista.com>2018-08-07 15:52:10 -0700
committerRichard Purdie <richard.purdie@linuxfoundation.org>2018-08-15 10:22:29 +0100
commit98e5e27514a19d31038aec22408e27b84514c5b8 (patch)
tree053bf755055a2c03c9459d57cdb256492839a2d4
parent9fa2d818018420f3c9afc30012267e6a46fe1d09 (diff)
downloadopenembedded-core-98e5e27514a19d31038aec22408e27b84514c5b8.tar.gz
binutls: Security fix for CVE-2017-16828
Affects: <= 2.29.1 Signed-off-by: Armin Kuster <akuster@mvista.com>
-rw-r--r--meta/recipes-devtools/binutils/binutils-2.29.1.inc2
-rw-r--r--meta/recipes-devtools/binutils/binutils/CVE-2017-16828_p1.patch79
-rw-r--r--meta/recipes-devtools/binutils/binutils/CVE-2017-16828_p2.patch149
3 files changed, 230 insertions, 0 deletions
diff --git a/meta/recipes-devtools/binutils/binutils-2.29.1.inc b/meta/recipes-devtools/binutils/binutils-2.29.1.inc
index e6cfe33859..ba60eccf87 100644
--- a/meta/recipes-devtools/binutils/binutils-2.29.1.inc
+++ b/meta/recipes-devtools/binutils/binutils-2.29.1.inc
@@ -54,6 +54,8 @@ SRC_URI = "\
file://CVE-2017-15996.patch \
file://CVE-2017-16826.patch \
file://CVE-2017-16827.patch \
+ file://CVE-2017-16828_p1.patch \
+ file://CVE-2017-16828_p2.patch \
"
S = "${WORKDIR}/git"
diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-16828_p1.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-16828_p1.patch
new file mode 100644
index 0000000000..310908f86d
--- /dev/null
+++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-16828_p1.patch
@@ -0,0 +1,79 @@
+From 9c0f3d3f2017829ffd908c9893b85094985c3b58 Mon Sep 17 00:00:00 2001
+From: Alan Modra <amodra@gmail.com>
+Date: Thu, 5 Oct 2017 17:32:18 +1030
+Subject: [PATCH] PR22239 - invalid memory read in display_debug_frames
+
+Pointer comparisons have traps for the unwary. After adding a large
+unknown value to "start", the test "start < end" depends on where
+"start" is originally in memory.
+
+ PR 22239
+ * dwarf.c (read_cie): Don't compare "start" and "end" pointers
+ after adding a possibly wild length to "start", compare the length
+ to the difference of the pointers instead. Remove now redundant
+ "negative" length test.
+
+Upstream-Status: Backport
+Affects: <= 2.29.1
+CVE: CVE-2017-16828 patch1
+Signed-off-by: Armin Kuster <akuster@mvista.com>
+
+---
+ binutils/ChangeLog | 8 ++++++++
+ binutils/dwarf.c | 15 ++++-----------
+ 2 files changed, 12 insertions(+), 11 deletions(-)
+
+Index: git/binutils/dwarf.c
+===================================================================
+--- git.orig/binutils/dwarf.c
++++ git/binutils/dwarf.c
+@@ -6652,14 +6652,14 @@ read_cie (unsigned char *start, unsigned
+ {
+ READ_ULEB (augmentation_data_len);
+ augmentation_data = start;
+- start += augmentation_data_len;
+ /* PR 17512: file: 11042-2589-0.004. */
+- if (start > end)
++ if (augmentation_data_len > (size_t) (end - start))
+ {
+ warn (_("Augmentation data too long: %#lx, expected at most %#lx\n"),
+- augmentation_data_len, (long)((end - start) + augmentation_data_len));
++ augmentation_data_len, (unsigned long) (end - start));
+ return end;
+ }
++ start += augmentation_data_len;
+ }
+
+ if (augmentation_data_len)
+@@ -6672,14 +6672,7 @@ read_cie (unsigned char *start, unsigned
+ q = augmentation_data;
+ qend = q + augmentation_data_len;
+
+- /* PR 17531: file: 015adfaa. */
+- if (qend < q)
+- {
+- warn (_("Negative augmentation data length: 0x%lx"), augmentation_data_len);
+- augmentation_data_len = 0;
+- }
+-
+- while (p < end && q < augmentation_data + augmentation_data_len)
++ while (p < end && q < qend)
+ {
+ if (*p == 'L')
+ q++;
+Index: git/binutils/ChangeLog
+===================================================================
+--- git.orig/binutils/ChangeLog
++++ git/binutils/ChangeLog
+@@ -1,3 +1,11 @@
++2017-10-05 Alan Modra <amodra@gmail.com>
++
++ PR 22239
++ * dwarf.c (read_cie): Don't compare "start" and "end" pointers
++ after adding a possibly wild length to "start", compare the length
++ to the difference of the pointers instead. Remove now redundant
++ "negative" length test.
++
+ 2017-09-27 Nick Clifton <nickc@redhat.com>
+
+ PR 22219
diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-16828_p2.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-16828_p2.patch
new file mode 100644
index 0000000000..5073d31ce0
--- /dev/null
+++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-16828_p2.patch
@@ -0,0 +1,149 @@
+From bf59c5d5f4f5b8b4da1f5f605cfa546f8029b43d Mon Sep 17 00:00:00 2001
+From: Nick Clifton <nickc@redhat.com>
+Date: Fri, 3 Nov 2017 13:57:15 +0000
+Subject: [PATCH] Fix integer overflow problems when reading an ELF binary with
+ corrupt augmentation data.
+
+ PR 22386
+ * dwarf.c (read_cie): Use bfd_size_type for
+ augmentation_data_len.
+ (display_augmentation_data): New function.
+ (display_debug_frames): Use it.
+ Check for integer overflow when testing augmentation_data_len.
+
+Upstream-Status: Backport
+Affects: <= 2.29.1
+CVE: CVE-2017-16828 patch2
+Signed-off-by: Armin Kuster <akuster@mvista.com>
+
+---
+ binutils/ChangeLog | 10 +++++++++
+ binutils/dwarf.c | 65 +++++++++++++++++++++++++++++++++---------------------
+ 2 files changed, 50 insertions(+), 25 deletions(-)
+
+Index: git/binutils/dwarf.c
+===================================================================
+--- git.orig/binutils/dwarf.c
++++ git/binutils/dwarf.c
+@@ -6577,13 +6577,13 @@ frame_display_row (Frame_Chunk *fc, int
+ static unsigned char *
+ read_cie (unsigned char *start, unsigned char *end,
+ Frame_Chunk **p_cie, int *p_version,
+- unsigned long *p_aug_len, unsigned char **p_aug)
++ bfd_size_type *p_aug_len, unsigned char **p_aug)
+ {
+ int version;
+ Frame_Chunk *fc;
+ unsigned int length_return;
+ unsigned char *augmentation_data = NULL;
+- unsigned long augmentation_data_len = 0;
++ bfd_size_type augmentation_data_len = 0;
+
+ * p_cie = NULL;
+ /* PR 17512: file: 001-228113-0.004. */
+@@ -6653,10 +6653,11 @@ read_cie (unsigned char *start, unsigned
+ READ_ULEB (augmentation_data_len);
+ augmentation_data = start;
+ /* PR 17512: file: 11042-2589-0.004. */
+- if (augmentation_data_len > (size_t) (end - start))
++ if (augmentation_data_len > (bfd_size_type) (end - start))
+ {
+- warn (_("Augmentation data too long: %#lx, expected at most %#lx\n"),
+- augmentation_data_len, (unsigned long) (end - start));
++ warn (_("Augmentation data too long: 0x%s, expected at most %#lx\n"),
++ dwarf_vmatoa ("x", augmentation_data_len),
++ (unsigned long) (end - start));
+ return end;
+ }
+ start += augmentation_data_len;
+@@ -6701,6 +6702,31 @@ read_cie (unsigned char *start, unsigned
+ return start;
+ }
+
++/* Prints out the contents on the augmentation data array.
++ If do_wide is not enabled, then formats the output to fit into 80 columns. */
++
++static void
++display_augmentation_data (const unsigned char * data, const bfd_size_type len)
++{
++ bfd_size_type i;
++
++ i = printf (_(" Augmentation data: "));
++
++ if (do_wide || len < ((80 - i) / 3))
++ for (i = 0; i < len; ++i)
++ printf (" %02x", data[i]);
++ else
++ {
++ for (i = 0; i < len; ++i)
++ {
++ if (i % (80 / 3) == 0)
++ putchar ('\n');
++ printf (" %02x", data[i]);
++ }
++ }
++ putchar ('\n');
++}
++
+ static int
+ display_debug_frames (struct dwarf_section *section,
+ void *file ATTRIBUTE_UNUSED)
+@@ -6729,7 +6755,7 @@ display_debug_frames (struct dwarf_secti
+ Frame_Chunk *cie;
+ int need_col_headers = 1;
+ unsigned char *augmentation_data = NULL;
+- unsigned long augmentation_data_len = 0;
++ bfd_size_type augmentation_data_len = 0;
+ unsigned int encoded_ptr_size = saved_eh_addr_size;
+ unsigned int offset_size;
+ unsigned int initial_length_size;
+@@ -6823,16 +6849,8 @@ display_debug_frames (struct dwarf_secti
+ printf (" Return address column: %d\n", fc->ra);
+
+ if (augmentation_data_len)
+- {
+- unsigned long i;
++ display_augmentation_data (augmentation_data, augmentation_data_len);
+
+- printf (" Augmentation data: ");
+- for (i = 0; i < augmentation_data_len; ++i)
+- /* FIXME: If do_wide is FALSE, then we should
+- add carriage returns at 80 columns... */
+- printf (" %02x", augmentation_data[i]);
+- putchar ('\n');
+- }
+ putchar ('\n');
+ }
+ }
+@@ -6988,11 +7006,13 @@ display_debug_frames (struct dwarf_secti
+ READ_ULEB (augmentation_data_len);
+ augmentation_data = start;
+ start += augmentation_data_len;
+- /* PR 17512: file: 722-8446-0.004. */
+- if (start >= end || ((signed long) augmentation_data_len) < 0)
++ /* PR 17512 file: 722-8446-0.004 and PR 22386. */
++ if (start >= end
++ || ((bfd_signed_vma) augmentation_data_len) < 0
++ || augmentation_data > start)
+ {
+- warn (_("Corrupt augmentation data length: %lx\n"),
+- augmentation_data_len);
++ warn (_("Corrupt augmentation data length: 0x%s\n"),
++ dwarf_vmatoa ("x", augmentation_data_len));
+ start = end;
+ augmentation_data = NULL;
+ augmentation_data_len = 0;
+@@ -7014,12 +7034,7 @@ display_debug_frames (struct dwarf_secti
+
+ if (! do_debug_frames_interp && augmentation_data_len)
+ {
+- unsigned long i;
+-
+- printf (" Augmentation data: ");
+- for (i = 0; i < augmentation_data_len; ++i)
+- printf (" %02x", augmentation_data[i]);
+- putchar ('\n');
++ display_augmentation_data (augmentation_data, augmentation_data_len);
+ putchar ('\n');
+ }
+ }