aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p1.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p1.patch')
-rw-r--r--meta/recipes-devtools/binutils/binutils/CVE-2018-7568_p1.patch161
1 files changed, 161 insertions, 0 deletions
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 0000000000..b014080a7e
--- /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@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@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@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@gmail.com>
+
+ PR 22741