Package: release.debian.org Severity: normal Tags: jessie User: release.debian.org@packages.debian.org Usertags: pu Dear release team, I would like to propose the following changes to the dwarfutils package in jessie: * New maintainer. * Add patch CVE-2015-8538.patch to fix CVE-2015-8538 (Closes: #807817). * Add patch CVE-2015-8750.patch to fix CVE-2015-8750 (Closes: #813182). * Add patch CVE-2016-2050.patch to fix CVE-2016-2050. * Add patch CVE-2016-2091.patch to fix CVE-2016-2091 (Closes: #813148). * Add patch CVE-2016-5034.patch to fix CVE-2016-5034. * Add patch CVE-2016-5036.patch to fix CVE-2016-5036. * Add patch CVE-2016-5038.patch to fix CVE-2016-5038. * Add patch CVE-2016-5039.patch to fix CVE-2016-5039. * Add patch CVE-2016-5042.patch to fix CVE-2016-5042. The current version in stable is rather old and still has Troy Heber listed as the package maintainer, who orphaned the package a few years ago. I am the new maintainer. Because of the rather large number of patches, I have decided against replicating them in this bug report, but each one of them features a DEP-3 conformant header with information regarding its origin and, if applicable, the corresponding Debian bug, so I hope you won't have much trouble navigating them. I have attached the debdiff I would like to apply to the current version in stable. Thank you! Kind regards, Fabian
diff -u dwarfutils-20120410/debian/changelog dwarfutils-20120410/debian/changelog
--- dwarfutils-20120410/debian/changelog
+++ dwarfutils-20120410/debian/changelog
@@ -1,3 +1,18 @@
+dwarfutils (20120410-2+deb8u1) stable; urgency=medium
+
+ * New maintainer.
+ * Add patch CVE-2015-8538.patch to fix CVE-2015-8538 (Closes: #807817).
+ * Add patch CVE-2015-8750.patch to fix CVE-2015-8750 (Closes: #813182).
+ * Add patch CVE-2016-2050.patch to fix CVE-2016-2050.
+ * Add patch CVE-2016-2091.patch to fix CVE-2016-2091 (Closes: #813148).
+ * Add patch CVE-2016-5034.patch to fix CVE-2016-5034.
+ * Add patch CVE-2016-5036.patch to fix CVE-2016-5036.
+ * Add patch CVE-2016-5038.patch to fix CVE-2016-5038.
+ * Add patch CVE-2016-5039.patch to fix CVE-2016-5039.
+ * Add patch CVE-2016-5042.patch to fix CVE-2016-5042.
+
+ -- Fabian Wolff <fabi.wolff@arcor.de> Tue, 16 Aug 2016 15:27:35 +0200
+
dwarfutils (20120410-2) unstable; urgency=low
* Fix FTBFS on Debian GNU/Hurd by Barry deFreese <bdefreese@debian.org>
diff -u dwarfutils-20120410/debian/control dwarfutils-20120410/debian/control
--- dwarfutils-20120410/debian/control
+++ dwarfutils-20120410/debian/control
@@ -1,8 +1,7 @@
Source: dwarfutils
Section: libs
Priority: optional
-Maintainer: Troy Heber <troyh@debian.org>
-Uploaders:
+Maintainer: Fabian Wolff <fabi.wolff@arcor.de>
Build-Depends: debhelper (>> 9), quilt (>= 0.47), libelf-dev, binutils-dev
Standards-Version: 3.9.3.1
diff -u dwarfutils-20120410/debian/patches/series dwarfutils-20120410/debian/patches/series
--- dwarfutils-20120410/debian/patches/series
+++ dwarfutils-20120410/debian/patches/series
@@ -2,0 +3,9 @@
+CVE-2016-5034.patch
+CVE-2016-2050.patch
+CVE-2015-8538.patch
+CVE-2015-8750.patch
+CVE-2016-2091.patch
+CVE-2016-5042.patch
+CVE-2016-5039.patch
+CVE-2016-5038.patch
+CVE-2016-5036.patch
only in patch2:
unchanged:
--- dwarfutils-20120410.orig/debian/patches/CVE-2015-8538.patch
+++ dwarfutils-20120410/debian/patches/CVE-2015-8538.patch
@@ -0,0 +1,340 @@
+Description: Fix for CVE-2015-8538 (OOB read)
+Origin: http://sourceforge.net/p/libdwarf/code/ci/da724a0bc5eec8e9ec0b0cb0c238a80e34466459/
+Bug-Debian: https://bugs.debian.org/807817
+
+--- a/libdwarf/dwarf_abbrev.c
++++ b/libdwarf/dwarf_abbrev.c
+@@ -126,6 +126,10 @@
+ attr = (Dwarf_Half) utmp2;
+ DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
+ attr_form = (Dwarf_Half) utmp2;
++ if (!_dwarf_valid_form_we_know(dbg,attr_form,attr)) {
++ _dwarf_error(NULL, error, DW_DLE_UNKNOWN_FORM);
++ return DW_DLV_ERROR;
++ }
+
+ if (attr != 0)
+ (labbr_count)++;
+--- a/libdwarf/dwarf_die_deliv.c
++++ b/libdwarf/dwarf_die_deliv.c
+@@ -657,13 +657,15 @@
+ Dwarf_Byte_Ptr info_ptr = 0;
+ Dwarf_Byte_Ptr abbrev_ptr = 0;
+ Dwarf_Word abbrev_code = 0;
+- Dwarf_Abbrev_List abbrev_list;
++ Dwarf_Abbrev_List abbrev_list = 0;
+ Dwarf_Half attr = 0;
+ Dwarf_Half attr_form = 0;
+ Dwarf_Unsigned offset = 0;
+ Dwarf_Word leb128_length = 0;
+ Dwarf_Unsigned utmp = 0;
+ Dwarf_Debug dbg = 0;
++ Dwarf_Error error = 0;
++ int lres = 0;
+
+ info_ptr = die_info_ptr;
+ DECODE_LEB128_UWORD(info_ptr, utmp);
+@@ -673,8 +675,8 @@
+ }
+
+
+- abbrev_list = _dwarf_get_abbrev_for_code(cu_context, abbrev_code);
+- if (abbrev_list == NULL) {
++ lres = _dwarf_get_abbrev_for_code(cu_context, abbrev_code, &abbrev_list, &error);
++ if (lres == DW_DLV_ERROR || lres == DW_DLV_NO_ENTRY) {
+ return (NULL);
+ }
+ dbg = cu_context->cc_dbg;
+@@ -833,6 +835,7 @@
+ Dwarf_Byte_Ptr die_info_end = 0;
+ Dwarf_Word abbrev_code = 0;
+ Dwarf_Unsigned utmp = 0;
++ int lres = 0;
+ /* Since die may be NULL, we rely on the input argument. */
+ Dwarf_Debug_InfoTypes dis = is_info? &dbg->de_info_reading:
+ &dbg->de_types_reading;
+@@ -962,9 +965,13 @@
+ return (DW_DLV_NO_ENTRY);
+ }
+ ret_die->di_abbrev_code = abbrev_code;
+- ret_die->di_abbrev_list =
+- _dwarf_get_abbrev_for_code(ret_die->di_cu_context, abbrev_code);
+- if (ret_die->di_abbrev_list == NULL ) {
++ lres = _dwarf_get_abbrev_for_code(ret_die->di_cu_context, abbrev_code,
++ &ret_die->di_abbrev_list, error);
++ if (lres == DW_DLV_ERROR) {
++ dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
++ return lres;
++ }
++ if (lres == DW_DLV_NO_ENTRY) {
+ dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
+ _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_LIST_NULL);
+ return (DW_DLV_ERROR);
+@@ -1073,12 +1080,19 @@
+ return DW_DLV_NO_ENTRY;
+ }
+ ret_die->di_abbrev_code = abbrev_code;
+- ret_die->di_abbrev_list =
+- _dwarf_get_abbrev_for_code(die->di_cu_context, abbrev_code);
+- if (ret_die->di_abbrev_list == NULL) {
+- dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
+- _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
+- return (DW_DLV_ERROR);
++
++ {
++ int lres = _dwarf_get_abbrev_for_code(die->di_cu_context, abbrev_code,
++ &ret_die->di_abbrev_list, error);
++ if (lres == DW_DLV_ERROR) {
++ dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
++ return lres;
++ }
++ if (lres == DW_DLV_NO_ENTRY) {
++ dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
++ _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
++ return (DW_DLV_ERROR);
++ }
+ }
+
+ *caller_ret_die = ret_die;
+@@ -1111,6 +1125,7 @@
+ Dwarf_Byte_Ptr info_ptr = 0;
+ Dwarf_Unsigned abbrev_code = 0;
+ Dwarf_Unsigned utmp = 0;
++ int lres = 0;
+ Dwarf_Debug_InfoTypes dis = 0;
+
+
+@@ -1201,9 +1216,13 @@
+ return DW_DLV_NO_ENTRY;
+ }
+ die->di_abbrev_code = abbrev_code;
+- die->di_abbrev_list =
+- _dwarf_get_abbrev_for_code(cu_context, abbrev_code);
+- if (die->di_abbrev_list == NULL) {
++ lres = _dwarf_get_abbrev_for_code(cu_context, abbrev_code,
++ &die->di_abbrev_list, error);
++ if (lres == DW_DLV_ERROR) {
++ dwarf_dealloc(dbg, die, DW_DLA_DIE);
++ return lres;
++ }
++ if (lres == DW_DLV_NO_ENTRY) {
+ dwarf_dealloc(dbg, die, DW_DLA_DIE);
+ _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_LIST_NULL);
+ return (DW_DLV_ERROR);
+--- a/libdwarf/dwarf_error.c
++++ b/libdwarf/dwarf_error.c
+@@ -328,6 +328,7 @@
+ "DW_DLE_DEBUG_TYPEOFFSET_BAD (239)",
+ "DW_DLE_GNU_OPCODE_ERROR (240)",
+ "DW_DLE_RELOC_INVALID (241)",
++ "DW_DLE_UNKNOWN_FORM (242) Possibly corrupt DWARF data",
+ };
+
+
+--- a/libdwarf/dwarf_query.c
++++ b/libdwarf/dwarf_query.c
+@@ -189,14 +189,19 @@
+ Dwarf_Attribute *attr_ptr = 0;
+ Dwarf_Debug dbg = 0;
+ Dwarf_Byte_Ptr info_ptr = 0;
++ int lres = 0;
+
+ CHECK_DIE(die, DW_DLV_ERROR);
+ dbg = die->di_cu_context->cc_dbg;
+
+- abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context,
+- die->di_abbrev_list->ab_code);
+- if (abbrev_list == NULL) {
+- _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_BAD);
++ lres = _dwarf_get_abbrev_for_code(die->di_cu_context,
++ die->di_abbrev_list->ab_code,
++ &abbrev_list,error);
++ if (lres == DW_DLV_ERROR) {
++ return lres;
++ }
++ if (lres == DW_DLV_NO_ENTRY) {
++ _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
+ return (DW_DLV_ERROR);
+ }
+ abbrev_ptr = abbrev_list->ab_abbrev_ptr;
+@@ -211,6 +216,10 @@
+ attr = (Dwarf_Half) utmp2;
+ DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
+ attr_form = (Dwarf_Half) utmp2;
++ if (!_dwarf_valid_form_we_know(dbg,attr_form,attr)) {
++ _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM);
++ return DW_DLV_ERROR;
++ }
+
+ if (attr != 0) {
+ new_attr =
+@@ -298,10 +307,14 @@
+ Dwarf_Half curr_attr = 0;
+ Dwarf_Half curr_attr_form = 0;
+ Dwarf_Byte_Ptr info_ptr = 0;
++ Dwarf_Error error = 0;
++ int lres = 0;
+
+- abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context,
+- die->di_abbrev_list->ab_code);
+- if (abbrev_list == NULL) {
++ lres = _dwarf_get_abbrev_for_code(die->di_cu_context,
++ die->di_abbrev_list->ab_code,
++ &abbrev_list,
++ &error);
++ if (lres == DW_DLV_NO_ENTRY || lres == DW_DLV_ERROR) {
+ *attr_form = 0;
+ return (NULL);
+ }
+--- a/libdwarf/dwarf_util.c
++++ b/libdwarf/dwarf_util.c
+@@ -222,6 +222,23 @@
+ }
+ }
+
++#define TRUE 1
++#define FALSE 0
++
++int _dwarf_valid_form_we_know (Dwarf_Debug dbg, Dwarf_Unsigned at_form, Dwarf_Unsigned at_name)
++{
++ if (at_form == 0 && at_name == 0) {
++ return TRUE;
++ }
++ if (at_name == 0) {
++ return FALSE;
++ }
++ if (at_form <= DW_FORM_ref_sig8) {
++ return TRUE;
++ }
++ return FALSE;
++}
++
+ /* This function returns a pointer to a Dwarf_Abbrev_List_s
+ struct for the abbrev with the given code. It puts the
+ struct on the appropriate hash table. It also adds all
+@@ -247,8 +264,8 @@
+ never moves once allocated, so the pointer is safe to return.
+
+ Returns NULL on error. */
+-Dwarf_Abbrev_List
+-_dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Unsigned code)
++int _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Unsigned code,
++ Dwarf_Abbrev_List *list_out, Dwarf_Error *error)
+ {
+ Dwarf_Debug dbg = cu_context->cc_dbg;
+ Dwarf_Hash_Table hash_table_base = cu_context->cc_abbrev_hash_table;
+@@ -276,7 +293,7 @@
+ DW_DLA_HASH_TABLE_ENTRY,
+ hash_table_base->tb_table_entry_count);
+ if(! hash_table_base->tb_entries) {
+- return NULL;
++ return DW_DLV_NO_ENTRY;
+ }
+
+ } else if (hash_table_base->tb_total_abbrev_count >
+@@ -290,7 +307,7 @@
+ newht.tb_table_entry_count);
+
+ if(! newht.tb_entries) {
+- return NULL;
++ return DW_DLV_NO_ENTRY;
+ }
+ /* Copy the existing entries to the new table,
+ rehashing each. */
+@@ -318,7 +335,8 @@
+ if (hash_abbrev_entry != NULL) {
+ /* This returns a pointer to an abbrev list entry, not
+ the list itself. */
+- return (hash_abbrev_entry);
++ *list_out = hash_abbrev_entry;
++ return DW_DLV_OK;
+ }
+
+ abbrev_ptr = cu_context->cc_last_abbrev_ptr != NULL ?
+@@ -330,22 +348,23 @@
+ /* End of abbrev's as we are past the end entirely.
+ THis can happen */
+ if (abbrev_ptr > end_abbrev_ptr) {
+- return (NULL);
++ return DW_DLV_NO_ENTRY;
+ }
+ /* End of abbrev's for this cu, since abbrev code is 0. */
+ if (*abbrev_ptr == 0) {
+- return (NULL);
++ return DW_DLV_NO_ENTRY;
+ }
+
+ do {
+ unsigned new_hashable_val = 0;
+ DECODE_LEB128_UWORD(abbrev_ptr, abbrev_code);
+ DECODE_LEB128_UWORD(abbrev_ptr, abbrev_tag);
++ unsigned long abcount = 0;
+
+ inner_list_entry = (Dwarf_Abbrev_List)
+ _dwarf_get_alloc(cu_context->cc_dbg, DW_DLA_ABBREV_LIST, 1);
+ if (inner_list_entry == NULL) {
+- return (NULL);
++ return DW_DLV_NO_ENTRY;
+ }
+
+ new_hashable_val = abbrev_code;
+@@ -363,11 +382,17 @@
+ inner_list_entry->ab_has_child = *(abbrev_ptr++);
+ inner_list_entry->ab_abbrev_ptr = abbrev_ptr;
+
++ hash_table_base->tb_total_abbrev_count++;
++
+ /* Cycle thru the abbrev content, ignoring the content except
+ to find the end of the content. */
+ do {
+ DECODE_LEB128_UWORD(abbrev_ptr, attr_name);
+ DECODE_LEB128_UWORD(abbrev_ptr, attr_form);
++ if (!_dwarf_valid_form_we_know(dbg,attr_form,attr_name)) {
++ _dwarf_error(dbg,error,DW_DLE_UNKNOWN_FORM);
++ return DW_DLV_ERROR;
++ }
+ } while (attr_name != 0 && attr_form != 0);
+
+ /* We may have fallen off the end of content, that is not
+@@ -377,7 +402,11 @@
+ *abbrev_ptr != 0 && abbrev_code != code);
+
+ cu_context->cc_last_abbrev_ptr = abbrev_ptr;
+- return (abbrev_code == code ? inner_list_entry : NULL);
++ if(abbrev_code == code) {
++ *list_out = inner_list_entry;
++ return DW_DLV_OK;
++ }
++ return DW_DLV_NO_ENTRY;
+ }
+
+
+--- a/libdwarf/dwarf_util.h
++++ b/libdwarf/dwarf_util.h
+@@ -300,9 +300,8 @@
+
+
+
+-Dwarf_Abbrev_List
+-_dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context,
+- Dwarf_Unsigned code);
++int _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Unsigned code,
++ Dwarf_Abbrev_List *list_out, Dwarf_Error *error);
+
+
+ /* return 1 if string ends before 'endptr' else
+--- a/libdwarf/libdwarf.h
++++ b/libdwarf/libdwarf.h
+@@ -1062,10 +1062,11 @@
+ #define DW_DLE_DEBUG_TYPEOFFSET_BAD 239
+ #define DW_DLE_GNU_OPCODE_ERROR 240
+ #define DW_DLE_RELOC_INVALID 241
++#define DW_DLE_UNKNOWN_FORM 242
+
+
+ /* DW_DLE_LAST MUST EQUAL LAST ERROR NUMBER */
+-#define DW_DLE_LAST 241
++#define DW_DLE_LAST 242
+ #define DW_DLE_LO_USER 0x10000
+
+ /* Taken as meaning 'undefined value', this is not
only in patch2:
unchanged:
--- dwarfutils-20120410.orig/debian/patches/CVE-2015-8750.patch
+++ dwarfutils-20120410/debian/patches/CVE-2015-8750.patch
@@ -0,0 +1,17 @@
+Description: Fix for CVE-2015-8750 (NULL dereference)
+Origin: https://github.com/tomhughes/libdwarf/commit/11750a2838e52953013e3114ef27b3c7b1780697
+Bug-Debian: https://bugs.debian.org/813182
+
+--- a/libdwarf/dwarf_elf_access.c
++++ b/libdwarf/dwarf_elf_access.c
+@@ -932,6 +932,10 @@
+ *error = DW_DLE_MDE;
+ return DW_DLV_ERROR;
+ }
++ if (!data->d_buf) {
++ *error = DW_DLE_MDE;
++ return DW_DLV_ERROR;
++ }
+ *section_data = data->d_buf;
+ }
+ return DW_DLV_OK;
only in patch2:
unchanged:
--- dwarfutils-20120410.orig/debian/patches/CVE-2016-2050.patch
+++ dwarfutils-20120410/debian/patches/CVE-2016-2050.patch
@@ -0,0 +1,14 @@
+Description: Fix for CVE-2016-2050 (OOB write in get_abbrev_array_info)
+Origin: https://sourceforge.net/p/libdwarf/code/ci/a05f5e2ae6a5f34daa566975894fc2803d6ec684
+
+--- a/dwarfdump/print_abbrevs.c
++++ b/dwarfdump/print_abbrevs.c
+@@ -252,7 +252,7 @@
+ } else {
+ /* Valid abbreviation code */
+ if (abbrev_code > 0) {
+- if (abbrev_code > abbrev_array_size) {
++ while (abbrev_code > abbrev_array_size) {
+ /* Resize abbreviation array */
+ abbrev_array_size *= 2;
+ abbrev_array = (Dwarf_Signed *)
only in patch2:
unchanged:
--- dwarfutils-20120410.orig/debian/patches/CVE-2016-2091.patch
+++ dwarfutils-20120410/debian/patches/CVE-2016-2091.patch
@@ -0,0 +1,33 @@
+Description: Fix for CVE-2016-2091
+ The dwarf_read_cie_fde_prefix function in dwarf_frame2.c in libdwarf
+ allows attackers to cause a denial of service (out-of-bounds read)
+ via a crafted ELF object file.
+Origin: https://sourceforge.net/p/libdwarf/code/ci/9565964f26966d8391fe2cfa8e6e8e59278c5f91
+Bug-Debian: https://bugs.debian.org/813148
+
+--- a/libdwarf/dwarf_frame2.c
++++ b/libdwarf/dwarf_frame2.c
+@@ -939,7 +939,12 @@
+ Dwarf_Small *frame_ptr = frame_ptr_in;
+ Dwarf_Small *cie_ptr_addr = 0;
+ Dwarf_Unsigned cie_id = 0;
++ Dwarf_Small *section_end = section_ptr_in + section_length_in;
+
++ if (section_end < (frame_ptr + 4)) {
++ _dwarf_error (dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
++ return DW_DLV_ERROR;
++ }
+ /* READ_AREA_LENGTH updates frame_ptr for consumed bytes */
+ READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
+ frame_ptr, local_length_size,
+@@ -951,6 +956,10 @@
+ data. We should be very close to end of section. */
+ return DW_DLV_NO_ENTRY;
+ }
++ if ((frame_ptr + local_length_size) >= section_end) {
++ _dwarf_error (dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
++ return DW_DLV_ERROR;
++ }
+
+ cie_ptr_addr = frame_ptr;
+ READ_UNALIGNED(dbg, cie_id, Dwarf_Unsigned,
only in patch2:
unchanged:
--- dwarfutils-20120410.orig/debian/patches/CVE-2016-5034.patch
+++ dwarfutils-20120410/debian/patches/CVE-2016-5034.patch
@@ -0,0 +1,93 @@
+Description: Fix for CVE-2016-5034 (OOB write from relocation records)
+Origin: https://sourceforge.net/p/libdwarf/code/ci/10ca310f64368dc083efacac87732c02ef560a92
+
+--- a/libdwarf/dwarf_elf_access.c
++++ b/libdwarf/dwarf_elf_access.c
+@@ -617,7 +617,8 @@
+ update_entry(Dwarf_Debug dbg,
+ Dwarf_Bool is_64bit, Dwarf_Endianness endianess,
+ Dwarf_Half machine, struct Dwarf_Elf_Rela *rela,
+- Dwarf_Small *target_section,
++ Dwarf_Small *target_section,
++ Dwarf_Unsigned target_section_size,
+ Dwarf_Small *symtab_section_data,
+ Dwarf_Unsigned symtab_section_size,
+ Dwarf_Unsigned symtab_section_entrysize,
+@@ -654,7 +655,10 @@
+ return DW_DLV_ERROR;
+ }
+
+-
++ if (offset >= target_section_size) {
++ *error = DW_DLE_RELOC_INVALID;
++ return DW_DLV_ERROR;
++ }
+
+ if (is_64bit) {
+ #ifdef HAVE_ELF64_SYM
+@@ -685,6 +689,14 @@
+ return DW_DLV_ERROR;
+ }
+
++ if ( (offset + reloc_size) < offset) {
++ *error = DW_DLE_RELOC_INVALID;
++ return DW_DLV_ERROR;
++ }
++ if ( (offset + reloc_size) > target_section_size) {
++ *error = DW_DLE_RELOC_INVALID;
++ return DW_DLV_ERROR;
++ }
+
+ {
+ /* Assuming we do not need to do a READ_UNALIGNED here
+@@ -709,6 +721,7 @@
+ Dwarf_Endianness endianess,
+ Dwarf_Half machine,
+ Dwarf_Small *target_section,
++ Dwarf_Unsigned target_section_size,
+ Dwarf_Small *symtab_section,
+ Dwarf_Unsigned symtab_section_size,
+ Dwarf_Unsigned symtab_section_entrysize,
+@@ -732,6 +745,7 @@
+ machine,
+ &(relas)[i],
+ target_section,
++ target_section_size,
+ symtab_section,
+ symtab_section_size,
+ symtab_section_entrysize,
+@@ -796,7 +810,8 @@
+ dbg,
+ obj->is_64bit,
+ obj->endianness, obj->machine,
+- target_section,
++ target_section,
++ relocatablesec->dss_size,
+ symtab_section,
+ symtab_section_size,
+ symtab_section_entrysize,
+--- a/libdwarf/libdwarf.h
++++ b/libdwarf/libdwarf.h
+@@ -1061,10 +1061,11 @@
+ #define DW_DLE_DEBUG_TYPES_ONLY_DWARF4 238
+ #define DW_DLE_DEBUG_TYPEOFFSET_BAD 239
+ #define DW_DLE_GNU_OPCODE_ERROR 240
++#define DW_DLE_RELOC_INVALID 241
+
+
+ /* DW_DLE_LAST MUST EQUAL LAST ERROR NUMBER */
+-#define DW_DLE_LAST 239
++#define DW_DLE_LAST 241
+ #define DW_DLE_LO_USER 0x10000
+
+ /* Taken as meaning 'undefined value', this is not
+--- a/libdwarf/dwarf_error.c
++++ b/libdwarf/dwarf_error.c
+@@ -327,6 +327,7 @@
+ "DW_DLE_DEBUG_TYPES_ONLY_DWARF4 (238)",
+ "DW_DLE_DEBUG_TYPEOFFSET_BAD (239)",
+ "DW_DLE_GNU_OPCODE_ERROR (240)",
++ "DW_DLE_RELOC_INVALID (241)",
+ };
+
+
only in patch2:
unchanged:
--- dwarfutils-20120410.orig/debian/patches/CVE-2016-5036.patch
+++ dwarfutils-20120410/debian/patches/CVE-2016-5036.patch
@@ -0,0 +1,15 @@
+Description: fix of CVE-2016-5036 (OOB read bug in dump_block)
+Author: Fabian Wolff <fabi.wolff@arcor.de>
+Origin: backport, https://sourceforge.net/p/libdwarf/code/ci/82d8e007851805af0dcaaff41f49a2d48473334b/
+
+--- a/dwarfdump2/dieholder.h
++++ b/dwarfdump2/dieholder.h
+@@ -45,7 +45,7 @@
+ (*refcount_)--;
+ if( (*refcount_) == 0) {
+ delete refcount_;
+- if(die_) dwarf_dealloc(dbg_,die_,DW_DLA_DIE);
++ //if(die_) dwarf_dealloc(dbg_,die_,DW_DLA_DIE);
+ }
+ };
+ DieHolder(const DieHolder & d):dbg_(d.dbg_),die_(d.die_),
only in patch2:
unchanged:
--- dwarfutils-20120410.orig/debian/patches/CVE-2016-5038.patch
+++ dwarfutils-20120410/debian/patches/CVE-2016-5038.patch
@@ -0,0 +1,208 @@
+Description: Fix for CVE-2016-5038 (OOB read in dwarf_get_macro_startend_file())
+Author: Fabian Wolff <fabi.wolff@arcor.de>
+Origin: backport, https://sourceforge.net/p/libdwarf/code/ci/82d8e007851805af0dcaaff41f49a2d48473334b/
+
+--- a/libdwarf/dwarf_die_deliv.c
++++ b/libdwarf/dwarf_die_deliv.c
+@@ -655,7 +655,7 @@
+ Dwarf_Bool * has_die_child)
+ {
+ Dwarf_Byte_Ptr info_ptr = 0;
+- Dwarf_Byte_Ptr abbrev_ptr = 0;
++ Dwarf_Byte_Ptr abbrev_ptr = 0, abbrev_end = 0;
+ Dwarf_Word abbrev_code = 0;
+ Dwarf_Abbrev_List abbrev_list = 0;
+ Dwarf_Half attr = 0;
+@@ -684,12 +684,14 @@
+ *has_die_child = abbrev_list->ab_has_child;
+
+ abbrev_ptr = abbrev_list->ab_abbrev_ptr;
++ abbrev_end = (&dbg->de_debug_abbrev)->dss_data
++ + (&dbg->de_debug_abbrev)->dss_size;
+ do {
+ Dwarf_Unsigned utmp2;
+
+- DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
++ DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp2,dbg,&error,abbrev_end);
+ attr = (Dwarf_Half) utmp2;
+- DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
++ DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp2,dbg,&error,abbrev_end);
+ attr_form = (Dwarf_Half) utmp2;
+ if (attr_form == DW_FORM_indirect) {
+ Dwarf_Unsigned utmp6;
+@@ -1032,7 +1034,7 @@
+ _dwarf_next_die_info_ptr(die_info_ptr, die->di_cu_context,
+ die_info_end, NULL, false,
+ &has_die_child);
+- if (die_info_ptr == NULL) {
++ if ((die_info_ptr == NULL) || (die_info_ptr == (void *) 1)) {
+ _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PTR_NULL);
+ return (DW_DLV_ERROR);
+ }
+--- a/libdwarf/dwarf_error.c
++++ b/libdwarf/dwarf_error.c
+@@ -332,6 +332,7 @@
+ "DW_DLE_READ_LITTLEENDIAN_ERROR (243)",
+ "DW_DLE_READ_BIGENDIAN_ERROR (244)",
+ "DW_DLE_ARANGES_HEADER_ERROR (245)",
++ "DW_DLE_LEB_IMPROPER (246)",
+ };
+
+
+--- a/libdwarf/dwarf_leb.c
++++ b/libdwarf/dwarf_leb.c
+@@ -108,6 +108,85 @@
+ }
+ }
+
++#define BYTESLEBMAX 10
++
++/* Decode ULEB with checking */
++int
++_dwarf_decode_u_leb128_chk(Dwarf_Small * leb128, Dwarf_Word * leb128_length,
++ Dwarf_Unsigned *outval,Dwarf_Byte_Ptr endptr)
++{
++ unsigned char byte = 0;
++ Dwarf_Word word_number = 0;
++ Dwarf_Unsigned number = 0;
++ Dwarf_Sword shift = 0;
++ /* The byte_length value will be a small non-negative integer. */
++ unsigned byte_length = 0;
++
++ if (leb128 >=endptr) {
++ return DW_DLV_ERROR;
++ }
++ /* The following unrolls-the-loop for the first two bytes and
++ unpacks into 32 bits to make this as fast as possible.
++ word_number is assumed big enough that the shift has a defined
++ result. */
++ if ((*leb128 & 0x80) == 0) {
++ if (leb128_length) {
++ *leb128_length = 1;
++ }
++ *outval = *leb128;
++ return DW_DLV_OK;
++ } else {
++ if ((leb128+1) >=endptr) {
++ return DW_DLV_ERROR;
++ }
++ if ((*(leb128 + 1) & 0x80) == 0) {
++ if (leb128_length) {
++ *leb128_length = 2;
++ }
++ word_number = *leb128 & 0x7f;
++ word_number |= (*(leb128 + 1) & 0x7f) << 7;
++ *outval = word_number;
++ return DW_DLV_OK;
++ }
++ /* Gets messy to hand-inline more byte checking. */
++ }
++
++ /* The rest handles long numbers Because the 'number' may be larger
++ than the default int/unsigned, we must cast the 'byte' before
++ the shift for the shift to have a defined result. */
++ number = 0;
++ shift = 0;
++ byte_length = 1;
++ byte = *leb128;
++ for (;;) {
++ number |= ((Dwarf_Unsigned) (byte & 0x7f)) << shift;
++
++ if ((byte & 0x80) == 0) {
++ if (leb128_length) {
++ *leb128_length = byte_length;
++ }
++ *outval = number;
++ return DW_DLV_OK;
++ }
++ shift += 7;
++
++ byte_length++;
++ if (byte_length > BYTESLEBMAX) {
++ /* Erroneous input. */
++ if( leb128_length) {
++ *leb128_length = BYTESLEBMAX;
++ }
++ break;
++ }
++ ++leb128;
++ if ((leb128) >=endptr) {
++ return DW_DLV_ERROR;
++ }
++ byte = *leb128;
++ }
++ return DW_DLV_ERROR;
++}
++
+ #define BITSINBYTE 8
+
+ /* decode SLEB */
+--- a/libdwarf/dwarf_util.h
++++ b/libdwarf/dwarf_util.h
+@@ -43,7 +43,19 @@
+ */
+
+
+-
++#define DECODE_LEB128_UWORD_CK(ptr, value,dbg,errptr,endptr) \
++ do { \
++ Dwarf_Word lu_leblen = 0; \
++ Dwarf_Unsigned lu_local = 0; \
++ int lu_res = 0; \
++ lu_res = _dwarf_decode_u_leb128_chk(ptr,&lu_leblen,&lu_local,endptr); \
++ if (lu_res == DW_DLV_ERROR) { \
++ _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \
++ return DW_DLV_ERROR; \
++ } \
++ value = lu_local; \
++ ptr += lu_leblen; \
++ } while (0)
+
+ /*
+ Decodes unsigned leb128 encoded numbers.
+--- a/libdwarf/libdwarf.h
++++ b/libdwarf/libdwarf.h
+@@ -1066,10 +1066,11 @@
+ #define DW_DLE_READ_LITTLEENDIAN_ERROR 243
+ #define DW_DLE_READ_BIGENDIAN_ERROR 244
+ #define DW_DLE_ARANGES_HEADER_ERROR 245
++#define DW_DLE_LEB_IMPROPER 246
+
+
+ /* DW_DLE_LAST MUST EQUAL LAST ERROR NUMBER */
+-#define DW_DLE_LAST 245
++#define DW_DLE_LAST 246
+ #define DW_DLE_LO_USER 0x10000
+
+ /* Taken as meaning 'undefined value', this is not
+--- a/libdwarf/dwarf_query.c
++++ b/libdwarf/dwarf_query.c
+@@ -181,7 +181,7 @@
+ Dwarf_Word i = 0;
+ Dwarf_Half attr = 0;
+ Dwarf_Half attr_form = 0;
+- Dwarf_Byte_Ptr abbrev_ptr = 0;
++ Dwarf_Byte_Ptr abbrev_ptr = 0, abbrev_end = 0;
+ Dwarf_Abbrev_List abbrev_list = 0;
+ Dwarf_Attribute new_attr = 0;
+ Dwarf_Attribute head_attr = NULL;
+@@ -205,6 +205,7 @@
+ return (DW_DLV_ERROR);
+ }
+ abbrev_ptr = abbrev_list->ab_abbrev_ptr;
++ abbrev_end = (&dbg->de_debug_abbrev)->dss_data + (&dbg->de_debug_abbrev)->dss_size;
+
+ info_ptr = die->di_debug_ptr;
+ SKIP_LEB128_WORD(info_ptr);
+@@ -212,9 +213,9 @@
+ do {
+ Dwarf_Unsigned utmp2;
+
+- DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
++ DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp2,dbg,error,abbrev_end);
+ attr = (Dwarf_Half) utmp2;
+- DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
++ DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp2,dbg,error,abbrev_end);
+ attr_form = (Dwarf_Half) utmp2;
+ if (!_dwarf_valid_form_we_know(dbg,attr_form,attr)) {
+ _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM);
only in patch2:
unchanged:
--- dwarfutils-20120410.orig/debian/patches/CVE-2016-5039.patch
+++ dwarfutils-20120410/debian/patches/CVE-2016-5039.patch
@@ -0,0 +1,43 @@
+Description: Fix for CVE-2016-5039 (OOB read bug in get_attr_value())
+Author: Fabian Wolff <fabi.wolff@arcor.de>
+Origin: backport, https://sourceforge.net/p/libdwarf/code/ci/eb1472afac95031d0c9dd8c11d527b865fe7deb8/
+
+--- a/libdwarf/dwarf_form.c
++++ b/libdwarf/dwarf_form.c
+@@ -766,10 +766,17 @@
+ Dwarf_Word leb128_length = 0;
+ Dwarf_Block *ret_block = 0;
+
++ Dwarf_Unsigned section_length = 0;
++
+ int res = get_attr_dbg(&dbg,&cu_context,attr,error);
+ if(res != DW_DLV_OK) {
+ return res;
+- }
++ }
++
++ section_length = (cu_context->cc_is_info
++ ? (&dbg->de_debug_info)
++ : (&dbg->de_debug_types))->dss_size;
++
+ switch (attr->ar_attribute_form) {
+
+ case DW_FORM_block1:
+@@ -801,11 +808,12 @@
+ }
+
+ /* Check that block lies within current cu in .debug_info. */
+- if (attr->ar_debug_ptr + length >=
+- dbg->de_debug_info.dss_data + cu_context->cc_debug_offset +
+- cu_context->cc_length + cu_context->cc_length_size +
+- cu_context->cc_extension_size) {
+- _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD);
++ if ((attr->ar_debug_ptr + length >=
++ dbg->de_debug_info.dss_data + cu_context->cc_debug_offset +
++ cu_context->cc_length + cu_context->cc_length_size +
++ cu_context->cc_extension_size)
++ || (length >= section_length)) {
++ _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD);
+ return (DW_DLV_ERROR);
+ }
+
only in patch2:
unchanged:
--- dwarfutils-20120410.orig/debian/patches/CVE-2016-5042.patch
+++ dwarfutils-20120410/debian/patches/CVE-2016-5042.patch
@@ -0,0 +1,155 @@
+Description: Fix for CVE-2016-5042
+ In dwarf_get_aranges_list() an invalid count will iterate, reading
+ from memory addresses that increase till it all fails.
+Origin: backport, https://sourceforge.net/p/libdwarf/code/ci/98a3da1e8237fe0d45b67ef77f3fa5ed9ff0215f
+
+--- a/libdwarf/dwarf_arange.c
++++ b/libdwarf/dwarf_arange.c
+@@ -102,13 +102,12 @@
+ /* Length of current set of aranges. */
+ Dwarf_Unsigned length = 0;
+ Dwarf_Small remainder = 0;
+- Dwarf_Small *arange_ptr_past_end = 0;
+ Dwarf_Unsigned range_entry_size = 0;
+-
+ int local_length_size;
+
+ /*REFERENCED*/ /* Not used in this instance of the macro */
+ int local_extension_size = 0;
++ Dwarf_Small *end_this_arange = 0;
+
+ header_ptr = arange_ptr;
+
+@@ -116,11 +115,19 @@
+ READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
+ arange_ptr, local_length_size,
+ local_extension_size);
+- arange_ptr_past_end = arange_ptr + length;
++
++ if ((length + local_length_size + local_extension_size) >
++ dbg->de_debug_aranges.dss_size) {
++ _dwarf_error(dbg, error, DW_DLE_ARANGES_HEADER_ERROR);
++ return DW_DLV_ERROR;
++ }
++
++ end_this_arange = arange_ptr + length;
+
+
+- READ_UNALIGNED(dbg, version, Dwarf_Half,
+- arange_ptr, sizeof(Dwarf_Half));
++ READ_UNALIGNED_CK(dbg, version, Dwarf_Half,
++ arange_ptr, sizeof(Dwarf_Half),
++ error,end_this_arange);
+ arange_ptr += sizeof(Dwarf_Half);
+ length = length - sizeof(Dwarf_Half);
+ if (version != CURRENT_VERSION_STAMP) {
+@@ -128,8 +135,9 @@
+ return (DW_DLV_ERROR);
+ }
+
+- READ_UNALIGNED(dbg, info_offset, Dwarf_Off,
+- arange_ptr, local_length_size);
++ READ_UNALIGNED_CK(dbg, info_offset, Dwarf_Off,
++ arange_ptr, local_length_size,
++ error, end_this_arange);
+ arange_ptr += local_length_size;
+ length = length - local_length_size;
+ /* This applies to debug_info only, not to debug_types. */
+@@ -243,14 +251,14 @@
+ DWARF2,3,4 section 7.20
+ We stop short to avoid overrun of the end of the CU. */
+
+- } while (arange_ptr_past_end >= (arange_ptr + range_entry_size));
++ } while (end_this_arange >= (arange_ptr + range_entry_size));
+
+ /* A compiler could emit some padding bytes here. dwarf2/3
+ (dwarf4 sec 7.20) does not clearly make extra padding
+ bytes illegal. */
+- if (arange_ptr_past_end < arange_ptr) {
++ if (end_this_arange < arange_ptr) {
+ char buf[200];
+- Dwarf_Unsigned pad_count = arange_ptr - arange_ptr_past_end;
++ Dwarf_Unsigned pad_count = arange_ptr - end_this_arange;
+ Dwarf_Unsigned offset = arange_ptr - arange_ptr_start;
+ snprintf(buf,sizeof(buf),"DW_DLE_ARANGE_LENGTH_BAD."
+ " 0x%" DW_PR_XZEROS DW_PR_DUx
+@@ -259,9 +267,9 @@
+ pad_count, offset);
+ dwarf_insert_harmless_error(dbg,buf);
+ }
+- /* For most compilers, arange_ptr == arange_ptr_past_end at
++ /* For most compilers, arange_ptr == end_this_arange at
+ this point. But not if there were padding bytes */
+- arange_ptr = arange_ptr_past_end;
++ arange_ptr = end_this_arange;
+ } while (arange_ptr <
+ dbg->de_debug_aranges.dss_data + dbg->de_debug_aranges.dss_size);
+
+--- a/libdwarf/dwarf_error.c
++++ b/libdwarf/dwarf_error.c
+@@ -329,6 +329,9 @@
+ "DW_DLE_GNU_OPCODE_ERROR (240)",
+ "DW_DLE_RELOC_INVALID (241)",
+ "DW_DLE_UNKNOWN_FORM (242) Possibly corrupt DWARF data",
++ "DW_DLE_READ_LITTLEENDIAN_ERROR (243)",
++ "DW_DLE_READ_BIGENDIAN_ERROR (244)",
++ "DW_DLE_ARANGES_HEADER_ERROR (245)",
+ };
+
+
+--- a/libdwarf/dwarf_util.h
++++ b/libdwarf/dwarf_util.h
+@@ -130,6 +130,18 @@
+ dest = (desttype)_ltmp; \
+ } while (0)
+
++#define READ_UNALIGNED_CK(dbg,dest,desttype, source, length,error,endptr) \
++ do { \
++ BIGGEST_UINT _ltmp = 0; \
++ Dwarf_Byte_Ptr readend = source+length; \
++ if (readend > endptr) { \
++ _dwarf_error(dbg, error, DW_DLE_READ_LITTLEENDIAN_ERROR); \
++ return DW_DLV_ERROR; \
++ } \
++ dbg->de_copy_word( (((char *)(&_ltmp)) + sizeof(_ltmp) - length), \
++ source, length); \
++ dest = (desttype)_ltmp; \
++ } while (0)
+
+ /*
+ This macro sign-extends a variable depending on the length.
+@@ -155,6 +167,17 @@
+ dest = (desttype)_ltmp; \
+ } while (0)
+
++#define READ_UNALIGNED_CK(dbg,dest,desttype, source, length,error,endptr) \
++ do { \
++ BIGGEST_UINT _ltmp = 0; \
++ Dwarf_Byte_Ptr readend = source+length; \
++ if (readend > endptr) { \
++ _dwarf_error(dbg, error, DW_DLE_READ_BIGENDIAN_ERROR); \
++ return DW_DLV_ERROR; \
++ } \
++ dbg->de_copy_word( (char *)(&_ltmp), source, length); \
++ dest = (desttype)_ltmp; \
++ } while (0)
+
+ /*
+ This macro sign-extends a variable depending on the length.
+--- a/libdwarf/libdwarf.h
++++ b/libdwarf/libdwarf.h
+@@ -1063,10 +1063,13 @@
+ #define DW_DLE_GNU_OPCODE_ERROR 240
+ #define DW_DLE_RELOC_INVALID 241
+ #define DW_DLE_UNKNOWN_FORM 242
++#define DW_DLE_READ_LITTLEENDIAN_ERROR 243
++#define DW_DLE_READ_BIGENDIAN_ERROR 244
++#define DW_DLE_ARANGES_HEADER_ERROR 245
+
+
+ /* DW_DLE_LAST MUST EQUAL LAST ERROR NUMBER */
+-#define DW_DLE_LAST 242
++#define DW_DLE_LAST 245
+ #define DW_DLE_LO_USER 0x10000
+
+ /* Taken as meaning 'undefined value', this is not
Attachment:
signature.asc
Description: PGP signature