aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThiruvadi Rajaraman <trajaraman@mvista.com>2017-11-08 13:41:00 +0530
committerArmin Kuster <akuster@mvista.com>2017-11-23 17:40:49 -0800
commitd842b34140feaf18d1848bd7d039e2ed1d7d4d35 (patch)
tree1e4dfc1f321ff0bd6ba4998744da78f42ecbb01d
parent5bb1d9c4ae9e959a4405f372a7ef7307fc1f1deb (diff)
downloadmeta-openembedded-contrib-d842b34140feaf18d1848bd7d039e2ed1d7d4d35.tar.gz
binutils: CVE-2017-15024
Source: binutils-gdb.git MR: 76524 Type: Security Fix Disposition: Backport from binutils master ChangeID: 5f22a66eabb228b655605b964ecd350aee700806 Description: PR22187, infinite loop in find_abstract_instance_name This patch prevents the simple case of infinite recursion in find_abstract_instance_name by ensuring that the attributes being processed are not the same as the previous call. The patch also does a little cleanup, and leaves in place some changes to the nested_funcs array that I made when I wrongly thought looping might occur in scan_unit_for_symbols. PR 22187 * dwarf2.c (find_abstract_instance_name): Add orig_info_ptr and pname param. Return status. Make name const. Don't abort, return an error. Formatting. Exit if current info_ptr matches orig_info_ptr. Update callers. (scan_unit_for_symbols): Start at nesting_level of zero. Make nested_funcs an array of structs for extensibility. Formatting. Affects: <= 2.29 Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> Reviewed-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Armin Kuster <akuster808@gmail.com>
-rw-r--r--meta/recipes-devtools/binutils/binutils-2.27.inc1
-rw-r--r--meta/recipes-devtools/binutils/binutils/CVE-2017-15024.patch241
2 files changed, 242 insertions, 0 deletions
diff --git a/meta/recipes-devtools/binutils/binutils-2.27.inc b/meta/recipes-devtools/binutils/binutils-2.27.inc
index b1669a4ef0..ae43d2a5d2 100644
--- a/meta/recipes-devtools/binutils/binutils-2.27.inc
+++ b/meta/recipes-devtools/binutils/binutils-2.27.inc
@@ -101,6 +101,7 @@ SRC_URI = "\
file://CVE-2017-9955_8.patch \
file://CVE-2017-9955_9.patch \
file://CVE-2017-14729.patch \
+ file://CVE-2017-15024.patch \
"
S = "${WORKDIR}/git"
diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-15024.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-15024.patch
new file mode 100644
index 0000000000..ef42b13597
--- /dev/null
+++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-15024.patch
@@ -0,0 +1,241 @@
+commit 52a93b95ec0771c97e26f0bb28630a271a667bd2
+Author: Alan Modra <amodra@gmail.com>
+Date: Sun Sep 24 14:37:16 2017 +0930
+
+ PR22187, infinite loop in find_abstract_instance_name
+
+ This patch prevents the simple case of infinite recursion in
+ find_abstract_instance_name by ensuring that the attributes being
+ processed are not the same as the previous call.
+
+ The patch also does a little cleanup, and leaves in place some changes
+ to the nested_funcs array that I made when I wrongly thought looping
+ might occur in scan_unit_for_symbols.
+
+ PR 22187
+ * dwarf2.c (find_abstract_instance_name): Add orig_info_ptr and
+ pname param. Return status. Make name const. Don't abort,
+ return an error. Formatting. Exit if current info_ptr matches
+ orig_info_ptr. Update callers.
+ (scan_unit_for_symbols): Start at nesting_level of zero. Make
+ nested_funcs an array of structs for extensibility. Formatting.
+
+Upstream-Status: Backport
+
+CVE: CVE-2017-15024
+Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com>
+
+Index: git/bfd/dwarf2.c
+===================================================================
+--- git.orig/bfd/dwarf2.c 2017-11-08 12:44:59.198052588 +0530
++++ git/bfd/dwarf2.c 2017-11-08 12:45:10.670155730 +0530
+@@ -2273,9 +2273,11 @@
+ return FALSE;
+ }
+
+-static char *
++static bfd_boolean
+ find_abstract_instance_name (struct comp_unit *unit,
++ bfd_byte *orig_info_ptr,
+ struct attribute *attr_ptr,
++ const char **pname,
+ bfd_boolean *is_linkage)
+ {
+ bfd *abfd = unit->abfd;
+@@ -2285,7 +2287,7 @@
+ struct abbrev_info *abbrev;
+ bfd_uint64_t die_ref = attr_ptr->u.val;
+ struct attribute attr;
+- char *name = NULL;
++ const char *name = NULL;
+
+ /* DW_FORM_ref_addr can reference an entry in a different CU. It
+ is an offset from the .debug_info section, not the current CU. */
+@@ -2294,7 +2296,12 @@
+ /* We only support DW_FORM_ref_addr within the same file, so
+ any relocations should be resolved already. */
+ if (!die_ref)
+- abort ();
++ {
++ _bfd_error_handler
++ (_("Dwarf Error: Abstract instance DIE ref zero."));
++ bfd_set_error (bfd_error_bad_value);
++ return FALSE;
++ }
+
+ info_ptr = unit->sec_info_ptr + die_ref;
+ info_ptr_end = unit->end_ptr;
+@@ -2329,9 +2336,10 @@
+ (*_bfd_error_handler)
+ (_("Dwarf Error: Unable to read alt ref %u."), die_ref);
+ bfd_set_error (bfd_error_bad_value);
+- return NULL;
++ return FALSE;
+ }
+- info_ptr_end = unit->stash->alt_dwarf_info_buffer + unit->stash->alt_dwarf_info_size;
++ info_ptr_end = (unit->stash->alt_dwarf_info_buffer
++ + unit->stash->alt_dwarf_info_size);
+
+ /* FIXME: Do we need to locate the correct CU, in a similar
+ fashion to the code in the DW_FORM_ref_addr case above ? */
+@@ -2353,6 +2361,7 @@
+ (*_bfd_error_handler)
+ (_("Dwarf Error: Could not find abbrev number %u."), abbrev_number);
+ bfd_set_error (bfd_error_bad_value);
++ return FALSE;
+ }
+ else
+ {
+@@ -2362,6 +2371,15 @@
+ info_ptr, info_ptr_end);
+ if (info_ptr == NULL)
+ break;
++ /* It doesn't ever make sense for DW_AT_specification to
++ refer to the same DIE. Stop simple recursion. */
++ if (info_ptr == orig_info_ptr)
++ {
++ _bfd_error_handler
++ (_("Dwarf Error: Abstract instance recursion detected."));
++ bfd_set_error (bfd_error_bad_value);
++ return FALSE;
++ }
+ switch (attr.name)
+ {
+ case DW_AT_name:
+@@ -2375,7 +2393,9 @@
+ }
+ break;
+ case DW_AT_specification:
+- name = find_abstract_instance_name (unit, &attr, is_linkage);
++ if (!find_abstract_instance_name (unit, info_ptr, &attr,
++ pname, is_linkage))
++ return FALSE;
+ break;
+ case DW_AT_linkage_name:
+ case DW_AT_MIPS_linkage_name:
+@@ -2393,7 +2413,8 @@
+ }
+ }
+ }
+- return name;
++ *pname = name;
++ return TRUE;
+ }
+
+ static bfd_boolean
+@@ -2454,20 +2475,22 @@
+ bfd *abfd = unit->abfd;
+ bfd_byte *info_ptr = unit->first_child_die_ptr;
+ bfd_byte *info_ptr_end = unit->stash->info_ptr_end;
+- int nesting_level = 1;
+- struct funcinfo **nested_funcs;
++ int nesting_level = 0;
++ struct nest_funcinfo {
++ struct funcinfo *func;
++ } *nested_funcs;
+ int nested_funcs_size;
+
+ /* Maintain a stack of in-scope functions and inlined functions, which we
+ can use to set the caller_func field. */
+ nested_funcs_size = 32;
+- nested_funcs = (struct funcinfo **)
+- bfd_malloc (nested_funcs_size * sizeof (struct funcinfo *));
++ nested_funcs = (struct nest_funcinfo *)
++ bfd_malloc (nested_funcs_size * sizeof (*nested_funcs));
+ if (nested_funcs == NULL)
+ return FALSE;
+- nested_funcs[nesting_level] = 0;
++ nested_funcs[nesting_level].func = 0;
+
+- while (nesting_level)
++ while (nesting_level >= 0)
+ {
+ unsigned int abbrev_number, bytes_read, i;
+ struct abbrev_info *abbrev;
+@@ -2516,13 +2539,13 @@
+ BFD_ASSERT (!unit->cached);
+
+ if (func->tag == DW_TAG_inlined_subroutine)
+- for (i = nesting_level - 1; i >= 1; i--)
+- if (nested_funcs[i])
++ for (i = nesting_level; i-- != 0; )
++ if (nested_funcs[i].func)
+ {
+- func->caller_func = nested_funcs[i];
++ func->caller_func = nested_funcs[i].func;
+ break;
+ }
+- nested_funcs[nesting_level] = func;
++ nested_funcs[nesting_level].func = func;
+ }
+ else
+ {
+@@ -2541,12 +2564,13 @@
+ }
+
+ /* No inline function in scope at this nesting level. */
+- nested_funcs[nesting_level] = 0;
++ nested_funcs[nesting_level].func = 0;
+ }
+
+ for (i = 0; i < abbrev->num_attrs; ++i)
+ {
+- info_ptr = read_attribute (&attr, &abbrev->attrs[i], unit, info_ptr, info_ptr_end);
++ info_ptr = read_attribute (&attr, &abbrev->attrs[i],
++ unit, info_ptr, info_ptr_end);
+ if (info_ptr == NULL)
+ goto fail;
+
+@@ -2565,8 +2589,10 @@
+
+ case DW_AT_abstract_origin:
+ case DW_AT_specification:
+- func->name = find_abstract_instance_name (unit, &attr,
+- &func->is_linkage);
++ if (!find_abstract_instance_name (unit, info_ptr, &attr,
++ &func->name,
++ &func->is_linkage))
++ goto fail;
+ break;
+
+ case DW_AT_name:
+@@ -2691,17 +2717,17 @@
+
+ if (nesting_level >= nested_funcs_size)
+ {
+- struct funcinfo **tmp;
++ struct nest_funcinfo *tmp;
+
+ nested_funcs_size *= 2;
+- tmp = (struct funcinfo **)
++ tmp = (struct nest_funcinfo *)
+ bfd_realloc (nested_funcs,
+- nested_funcs_size * sizeof (struct funcinfo *));
++ nested_funcs_size * sizeof (*nested_funcs));
+ if (tmp == NULL)
+ goto fail;
+ nested_funcs = tmp;
+ }
+- nested_funcs[nesting_level] = 0;
++ nested_funcs[nesting_level].func = 0;
+ }
+ }
+
+Index: git/bfd/ChangeLog
+===================================================================
+--- git.orig/bfd/ChangeLog 2017-11-08 12:45:10.614155229 +0530
++++ git/bfd/ChangeLog 2017-11-08 12:46:55.791054918 +0530
+@@ -1,3 +1,13 @@
++2017-09-24 Alan Modra <amodra@gmail.com>
++
++ PR 22187
++ * dwarf2.c (find_abstract_instance_name): Add orig_info_ptr and
++ pname param. Return status. Make name const. Don't abort,
++ return an error. Formatting. Exit if current info_ptr matches
++ orig_info_ptr. Update callers.
++ (scan_unit_for_symbols): Start at nesting_level of zero. Make
++ nested_funcs an array of structs for extensibility. Formatting.
++
+ 2017-09-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/22170