diff --git a/0001-CVE-2018-18309.patch b/0001-CVE-2018-18309.patch new file mode 100644 index 0000000..85262d2 --- /dev/null +++ b/0001-CVE-2018-18309.patch @@ -0,0 +1,110 @@ +From 370e4b5079ff8d62be3adee7396948d4c5795091 Mon Sep 17 00:00:00 2001 +From: John Darrington +Date: Tue, 24 Jul 2018 12:58:43 +0200 +Subject: [PATCH] Add functions and macros to read and write 24 bit values. + + * libbfd.c (bfd_getb24, bfd_getl24): New functions. + (bfd_get_24, bfd_put_24): New macros. + * bfd-in2.h: Regenerate. + +url:https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=370e4b5079ff8d62be3adee7396948d4c5795091 + +diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h +index 3414682988..414ca54515 100644 +--- a/bfd/bfd-in2.h ++++ b/bfd/bfd-in2.h +@@ -1160,6 +1160,20 @@ char *bfd_follow_build_id_debuglink (bfd *abfd, const char *dir); + #define bfd_get_signed_16(abfd, ptr) \ + BFD_SEND (abfd, bfd_getx_signed_16, (ptr)) + ++#define bfd_put_24(abfd, val, ptr) \ ++ do \ ++ if (bfd_big_endian (abfd)) \ ++ bfd_putb24 ((val), (ptr)); \ ++ else \ ++ bfd_putl24 ((val), (ptr)); \ ++ while (0) ++ ++bfd_vma bfd_getb24 (const void *p); ++bfd_vma bfd_getl24 (const void *p); ++ ++#define bfd_get_24(abfd, ptr) \ ++ (bfd_big_endian (abfd) ? bfd_getb24 (ptr) : bfd_getl24 (ptr)) ++ + #define bfd_put_32(abfd, val, ptr) \ + BFD_SEND (abfd, bfd_putx32, ((val),(ptr))) + #define bfd_put_signed_32 \ +diff --git a/bfd/libbfd.c b/bfd/libbfd.c +index 971be4f3de..7c45d52aaf 100644 +--- a/bfd/libbfd.c ++++ b/bfd/libbfd.c +@@ -458,6 +458,20 @@ DESCRIPTION + .#define bfd_get_signed_16(abfd, ptr) \ + . BFD_SEND (abfd, bfd_getx_signed_16, (ptr)) + . ++.#define bfd_put_24(abfd, val, ptr) \ ++. do \ ++. if (bfd_big_endian (abfd)) \ ++. bfd_putb24 ((val), (ptr)); \ ++. else \ ++. bfd_putl24 ((val), (ptr)); \ ++. while (0) ++. ++.bfd_vma bfd_getb24 (const void *p); ++.bfd_vma bfd_getl24 (const void *p); ++. ++.#define bfd_get_24(abfd, ptr) \ ++. (bfd_big_endian (abfd) ? bfd_getb24 (ptr) : bfd_getl24 (ptr)) ++. + .#define bfd_put_32(abfd, val, ptr) \ + . BFD_SEND (abfd, bfd_putx32, ((val),(ptr))) + .#define bfd_put_signed_32 \ +@@ -613,7 +627,6 @@ bfd_putl16 (bfd_vma data, void *p) + addr[1] = (data >> 8) & 0xff; + } + +- + void + bfd_putb24 (bfd_vma data, void *p) + { +@@ -623,7 +636,6 @@ bfd_putb24 (bfd_vma data, void *p) + addr[2] = data & 0xff; + } + +- + void + bfd_putl24 (bfd_vma data, void *p) + { +@@ -633,6 +645,29 @@ bfd_putl24 (bfd_vma data, void *p) + addr[2] = (data >> 16) & 0xff; + } + ++bfd_vma ++bfd_getb24 (const void *p) ++{ ++ const bfd_byte *addr = (const bfd_byte *) p; ++ unsigned long v; ++ ++ v = (unsigned long) addr[0] << 16; ++ v |= (unsigned long) addr[1] << 8; ++ v |= (unsigned long) addr[2]; ++ return v; ++} ++ ++bfd_vma ++bfd_getl24 (const void *p) ++{ ++ const bfd_byte *addr = (const bfd_byte *) p; ++ unsigned long v; ++ ++ v = (unsigned long) addr[0]; ++ v |= (unsigned long) addr[1] << 8; ++ v |= (unsigned long) addr[2] << 16; ++ return v; ++} + + bfd_vma + bfd_getb32 (const void *p) +-- +2.19.1 + diff --git a/0002-CVE-2018-18309.patch b/0002-CVE-2018-18309.patch new file mode 100644 index 0000000..0daa735 --- /dev/null +++ b/0002-CVE-2018-18309.patch @@ -0,0 +1,86 @@ +From 7cf9ebc6958462c3ef1372071d1ced5dae7bef3c Mon Sep 17 00:00:00 2001 +From: John Darrington +Date: Thu, 9 Aug 2018 18:46:51 +0200 +Subject: [PATCH 1/2] Deal with relocations which are 3 bytes in size + + * reloc.c (_bfd_relocate_contents): Handle 3 byte relocs. + (_bfd_clear_contents): Likewise. + (bfd_perform_relocation): Likewise. + (bfd_install_relocation): Likewise. +url:https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=7cf9ebc6958462c3ef1372071d1ced5dae7bef3c + +diff --git a/bfd/reloc.c b/bfd/reloc.c +index b63473e12a..775a4403ef 100644 +--- a/bfd/reloc.c ++++ b/bfd/reloc.c +@@ -920,11 +920,9 @@ space consuming. For each target: + { + case 5: + { +- long x = bfd_get_32 (abfd, (bfd_byte *) data + octets); +- x >>= 8; ++ long x = bfd_get_24 (abfd, (bfd_byte *) data + octets); + DOIT (x); +- bfd_put_16 (abfd, (bfd_vma) (x >> 8), (bfd_byte *) data + octets); +- bfd_put_8 (abfd, (x & 0xFF), (unsigned char *) data + 2 + octets); ++ bfd_put_24 (abfd, (bfd_vma) x, (unsigned char *) data + octets); + } + break; + +@@ -1340,6 +1338,13 @@ space consuming. For each target: + bfd_put_32 (abfd, (bfd_vma) x, data); + } + break; ++ case 5: ++ { ++ long x = bfd_get_24 (abfd, data); ++ DOIT (x); ++ bfd_put_24 (abfd, (bfd_vma) x, data); ++ } ++ break; + case -2: + { + long x = bfd_get_32 (abfd, data); +@@ -1467,6 +1472,9 @@ _bfd_relocate_contents (reloc_howto_type *howto, + case 2: + x = bfd_get_16 (input_bfd, location); + break; ++ case 3: ++ x = bfd_get_24 (input_bfd, location); ++ break; + case 4: + x = bfd_get_32 (input_bfd, location); + break; +@@ -1593,6 +1601,9 @@ _bfd_relocate_contents (reloc_howto_type *howto, + case 2: + bfd_put_16 (input_bfd, x, location); + break; ++ case 3: ++ bfd_put_24 (input_bfd, x, location); ++ break; + case 4: + bfd_put_32 (input_bfd, x, location); + break; +@@ -1636,6 +1647,9 @@ _bfd_clear_contents (reloc_howto_type *howto, + case 2: + x = bfd_get_16 (input_bfd, location); + break; ++ case 3: ++ x = bfd_get_24 (input_bfd, location); ++ break; + case 4: + x = bfd_get_32 (input_bfd, location); + break; +@@ -1670,6 +1684,9 @@ _bfd_clear_contents (reloc_howto_type *howto, + case 2: + bfd_put_16 (input_bfd, x, location); + break; ++ case 3: ++ bfd_put_24 (input_bfd, x, location); ++ break; + case 4: + bfd_put_32 (input_bfd, x, location); + break; +-- +2.19.1 + diff --git a/0003-CVE-2018-18309.patch b/0003-CVE-2018-18309.patch new file mode 100644 index 0000000..514fdee --- /dev/null +++ b/0003-CVE-2018-18309.patch @@ -0,0 +1,446 @@ +From 1dc9e2d63e37839ff1768346b2e3f52e338baba5 Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Sat, 11 Aug 2018 11:07:07 +0930 +Subject: [PATCH 2/2] Factor out common relocation processing + +This patch factors out some code common to both bfd_perform_relocation +and bfd_install_relocation, in the process fixing the omission of +"case -1" in bfd_install_relocation. + + * reloc.c (bfd_get_reloc_size): Sort switch. + (read_reloc, write_reloc, apply_reloc): New functions. + (bfd_perform_relocation, bfd_install_relocation): Use apply_reloc. + (_bfd_relocate_contents): Use read_reloc and write_reloc. + (_bfd_clear_contents): Likewise. + +url:https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1dc9e2d63e37839ff1768346b2e3f52e338baba5 + +diff --git a/bfd/reloc.c b/bfd/reloc.c +index 775a4403ef..aaf3a801fd 100644 +--- a/bfd/reloc.c ++++ b/bfd/reloc.c +@@ -431,15 +431,15 @@ bfd_get_reloc_size (reloc_howto_type *howto) + { + switch (howto->size) + { +- case 5: return 3; + case 0: return 1; +- case 1: return 2; +- case 2: return 4; ++ case 1: ++ case -1: return 2; ++ case 2: ++ case -2: return 4; + case 3: return 0; + case 4: return 8; ++ case 5: return 3; + case 8: return 16; +- case -1: return 2; +- case -2: return 4; + default: abort (); + } + } +@@ -574,6 +574,100 @@ bfd_reloc_offset_in_range (reloc_howto_type *howto, + return octet <= octet_end && octet + reloc_size <= octet_end; + } + ++/* Read and return the section contents at DATA converted to a host ++ integer (bfd_vma). The number of bytes read is given by the HOWTO. */ ++ ++static bfd_vma ++read_reloc (bfd *abfd, bfd_byte *data, reloc_howto_type *howto) ++{ ++ switch (howto->size) ++ { ++ case 0: ++ return bfd_get_8 (abfd, data); ++ ++ case 1: ++ case -1: ++ return bfd_get_16 (abfd, data); ++ ++ case 2: ++ case -2: ++ return bfd_get_32 (abfd, data); ++ ++ case 3: ++ break; ++ ++#ifdef BFD64 ++ case 4: ++ return bfd_get_64 (abfd, data); ++#endif ++ ++ case 5: ++ return bfd_get_24 (abfd, data); ++ ++ default: ++ abort (); ++ } ++ return 0; ++} ++ ++/* Convert VAL to target format and write to DATA. The number of ++ bytes written is given by the HOWTO. */ ++ ++static void ++write_reloc (bfd *abfd, bfd_vma val, bfd_byte *data, reloc_howto_type *howto) ++{ ++ switch (howto->size) ++ { ++ case 0: ++ bfd_put_8 (abfd, val, data); ++ break; ++ ++ case 1: ++ case -1: ++ bfd_put_16 (abfd, val, data); ++ break; ++ ++ case 2: ++ case -2: ++ bfd_put_32 (abfd, val, data); ++ break; ++ ++ case 3: ++ break; ++ ++#ifdef BFD64 ++ case 4: ++ bfd_put_64 (abfd, val, data); ++ break; ++#endif ++ ++ case 5: ++ bfd_put_24 (abfd, val, data); ++ break; ++ ++ default: ++ abort (); ++ } ++} ++ ++/* Apply RELOCATION value to target bytes at DATA, according to ++ HOWTO. */ ++ ++static void ++apply_reloc (bfd *abfd, bfd_byte *data, reloc_howto_type *howto, ++ bfd_vma relocation) ++{ ++ bfd_vma val = read_reloc (abfd, data, howto); ++ ++ if (howto->size < 0) ++ relocation = -relocation; ++ ++ val = ((val & ~howto->dst_mask) ++ | (((val & howto->src_mask) + relocation) & howto->dst_mask)); ++ ++ write_reloc (abfd, val, data, howto); ++} ++ + /* + FUNCTION + bfd_perform_relocation +@@ -913,78 +1007,8 @@ space consuming. For each target: + = R R R R R R R R R R put into bfd_put + */ + +-#define DOIT(x) \ +- x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask)) +- +- switch (howto->size) +- { +- case 5: +- { +- long x = bfd_get_24 (abfd, (bfd_byte *) data + octets); +- DOIT (x); +- bfd_put_24 (abfd, (bfd_vma) x, (unsigned char *) data + octets); +- } +- break; +- +- case 0: +- { +- char x = bfd_get_8 (abfd, (char *) data + octets); +- DOIT (x); +- bfd_put_8 (abfd, x, (unsigned char *) data + octets); +- } +- break; +- +- case 1: +- { +- short x = bfd_get_16 (abfd, (bfd_byte *) data + octets); +- DOIT (x); +- bfd_put_16 (abfd, (bfd_vma) x, (unsigned char *) data + octets); +- } +- break; +- case 2: +- { +- long x = bfd_get_32 (abfd, (bfd_byte *) data + octets); +- DOIT (x); +- bfd_put_32 (abfd, (bfd_vma) x, (bfd_byte *) data + octets); +- } +- break; +- case -2: +- { +- long x = bfd_get_32 (abfd, (bfd_byte *) data + octets); +- relocation = -relocation; +- DOIT (x); +- bfd_put_32 (abfd, (bfd_vma) x, (bfd_byte *) data + octets); +- } +- break; +- +- case -1: +- { +- long x = bfd_get_16 (abfd, (bfd_byte *) data + octets); +- relocation = -relocation; +- DOIT (x); +- bfd_put_16 (abfd, (bfd_vma) x, (bfd_byte *) data + octets); +- } +- break; +- +- case 3: +- /* Do nothing */ +- break; +- +- case 4: +-#ifdef BFD64 +- { +- bfd_vma x = bfd_get_64 (abfd, (bfd_byte *) data + octets); +- DOIT (x); +- bfd_put_64 (abfd, x, (bfd_byte *) data + octets); +- } +-#else +- abort (); +-#endif +- break; +- default: +- return bfd_reloc_other; +- } +- ++ data = (bfd_byte *) data + octets; ++ apply_reloc (abfd, data, howto, relocation); + return flag; + } + +@@ -1309,66 +1333,8 @@ space consuming. For each target: + = R R R R R R R R R R put into bfd_put + */ + +-#define DOIT(x) \ +- x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask)) +- + data = (bfd_byte *) data_start + (octets - data_start_offset); +- +- switch (howto->size) +- { +- case 0: +- { +- char x = bfd_get_8 (abfd, data); +- DOIT (x); +- bfd_put_8 (abfd, x, data); +- } +- break; +- +- case 1: +- { +- short x = bfd_get_16 (abfd, data); +- DOIT (x); +- bfd_put_16 (abfd, (bfd_vma) x, data); +- } +- break; +- case 2: +- { +- long x = bfd_get_32 (abfd, data); +- DOIT (x); +- bfd_put_32 (abfd, (bfd_vma) x, data); +- } +- break; +- case 5: +- { +- long x = bfd_get_24 (abfd, data); +- DOIT (x); +- bfd_put_24 (abfd, (bfd_vma) x, data); +- } +- break; +- case -2: +- { +- long x = bfd_get_32 (abfd, data); +- relocation = -relocation; +- DOIT (x); +- bfd_put_32 (abfd, (bfd_vma) x, data); +- } +- break; +- +- case 3: +- /* Do nothing */ +- break; +- +- case 4: +- { +- bfd_vma x = bfd_get_64 (abfd, data); +- DOIT (x); +- bfd_put_64 (abfd, x, data); +- } +- break; +- default: +- return bfd_reloc_other; +- } +- ++ apply_reloc (abfd, data, howto, relocation); + return flag; + } + +@@ -1447,8 +1413,7 @@ _bfd_relocate_contents (reloc_howto_type *howto, + bfd_vma relocation, + bfd_byte *location) + { +- int size; +- bfd_vma x = 0; ++ bfd_vma x; + bfd_reloc_status_type flag; + unsigned int rightshift = howto->rightshift; + unsigned int bitpos = howto->bitpos; +@@ -1459,33 +1424,7 @@ _bfd_relocate_contents (reloc_howto_type *howto, + relocation = -relocation; + + /* Get the value we are going to relocate. */ +- size = bfd_get_reloc_size (howto); +- switch (size) +- { +- default: +- abort (); +- case 0: +- return bfd_reloc_ok; +- case 1: +- x = bfd_get_8 (input_bfd, location); +- break; +- case 2: +- x = bfd_get_16 (input_bfd, location); +- break; +- case 3: +- x = bfd_get_24 (input_bfd, location); +- break; +- case 4: +- x = bfd_get_32 (input_bfd, location); +- break; +- case 8: +-#ifdef BFD64 +- x = bfd_get_64 (input_bfd, location); +-#else +- abort (); +-#endif +- break; +- } ++ x = read_reloc (input_bfd, location, howto); + + /* Check for overflow. FIXME: We may drop bits during the addition + which we don't check for. We must either check at every single +@@ -1591,31 +1530,7 @@ _bfd_relocate_contents (reloc_howto_type *howto, + | (((x & howto->src_mask) + relocation) & howto->dst_mask)); + + /* Put the relocated value back in the object file. */ +- switch (size) +- { +- default: +- abort (); +- case 1: +- bfd_put_8 (input_bfd, x, location); +- break; +- case 2: +- bfd_put_16 (input_bfd, x, location); +- break; +- case 3: +- bfd_put_24 (input_bfd, x, location); +- break; +- case 4: +- bfd_put_32 (input_bfd, x, location); +- break; +- case 8: +-#ifdef BFD64 +- bfd_put_64 (input_bfd, x, location); +-#else +- abort (); +-#endif +- break; +- } +- ++ write_reloc (input_bfd, x, location, howto); + return flag; + } + +@@ -1630,37 +1545,10 @@ _bfd_clear_contents (reloc_howto_type *howto, + asection *input_section, + bfd_byte *location) + { +- int size; +- bfd_vma x = 0; ++ bfd_vma x; + + /* Get the value we are going to relocate. */ +- size = bfd_get_reloc_size (howto); +- switch (size) +- { +- default: +- abort (); +- case 0: +- return; +- case 1: +- x = bfd_get_8 (input_bfd, location); +- break; +- case 2: +- x = bfd_get_16 (input_bfd, location); +- break; +- case 3: +- x = bfd_get_24 (input_bfd, location); +- break; +- case 4: +- x = bfd_get_32 (input_bfd, location); +- break; +- case 8: +-#ifdef BFD64 +- x = bfd_get_64 (input_bfd, location); +-#else +- abort (); +-#endif +- break; +- } ++ x = read_reloc (input_bfd, location, howto); + + /* Zero out the unwanted bits of X. */ + x &= ~howto->dst_mask; +@@ -1673,31 +1561,7 @@ _bfd_clear_contents (reloc_howto_type *howto, + x |= 1; + + /* Put the relocated value back in the object file. */ +- switch (size) +- { +- default: +- case 0: +- abort (); +- case 1: +- bfd_put_8 (input_bfd, x, location); +- break; +- case 2: +- bfd_put_16 (input_bfd, x, location); +- break; +- case 3: +- bfd_put_24 (input_bfd, x, location); +- break; +- case 4: +- bfd_put_32 (input_bfd, x, location); +- break; +- case 8: +-#ifdef BFD64 +- bfd_put_64 (input_bfd, x, location); +-#else +- abort (); +-#endif +- break; +- } ++ write_reloc (input_bfd, x, location, howto); + } + + /* +-- +2.19.1 + diff --git a/0004-CVE-2018-18309.patch b/0004-CVE-2018-18309.patch new file mode 100644 index 0000000..449fb37 --- /dev/null +++ b/0004-CVE-2018-18309.patch @@ -0,0 +1,280 @@ +From 0930cb3021b8078b34cf216e79eb8608d017864f Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Sat, 13 Oct 2018 22:03:02 +1030 +Subject: [PATCH] _bfd_clear_contents bounds checking + +This PR shows a fuzzed binary triggering a segfault via a bad +relocation in .debug_line. It turns out that unlike normal +relocations applied to a section, the linker applies those with +symbols from discarded sections via _bfd_clear_contents without +checking that the relocation is within the section bounds. The same +thing now happens when reading debug sections since commit +a4cd947aca23, the PR23425 fix. + + PR 23770 + PR 23425 + * reloc.c (_bfd_clear_contents): Replace "location" param with + "buf" and "off". Bounds check "off". Return status. + * cofflink.c (_bfd_coff_generic_relocate_section): Update + _bfd_clear_contents call. + * elf-bfd.h (RELOC_AGAINST_DISCARDED_SECTION): Likewise. + * elf32-arc.c (elf_arc_relocate_section): Likewise. + * elf32-i386.c (elf_i386_relocate_section): Likewise. + * elf32-metag.c (metag_final_link_relocate): Likewise. + * elf32-nds32.c (nds32_elf_get_relocated_section_contents): + * Likewise. + * elf32-ppc.c (ppc_elf_relocate_section): Likewise. + * elf32-visium.c (visium_elf_relocate_section): Likewise. + * elf64-ppc.c (ppc64_elf_relocate_section): Likewise. + * elf64-x86-64.c *(elf_x86_64_relocate_section): Likewise. + * libbfd-in.h (_bfd_clear_contents): Update prototype. + * libbfd.h: Regenerate. + +Subject: [PATCH] binutils: CVE-2018-18309 + +url:https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=0930cb3021b8078b34cf216e79eb8608d017864f + +--- + bfd/cofflink.c | 2 +- + bfd/elf-bfd.h | 2 +- + bfd/elf32-arc.c | 2 +- + bfd/elf32-i386.c | 2 +- + bfd/elf32-metag.c | 2 +- + bfd/elf32-nds32.c | 8 ++++---- + bfd/elf32-ppc.c | 2 +- + bfd/elf32-visium.c | 2 +- + bfd/elf64-ppc.c | 2 +- + bfd/elf64-x86-64.c | 2 +- + bfd/libbfd-in.h | 4 ++-- + bfd/libbfd.h | 4 ++-- + bfd/reloc.c | 19 +++++++++++++------ + 13 files changed, 30 insertions(+), 23 deletions(-) + +diff --git a/bfd/cofflink.c b/bfd/cofflink.c +index 2f73f72..b7ea69b 100644 +--- a/bfd/cofflink.c ++++ b/bfd/cofflink.c +@@ -3080,7 +3080,7 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd, + if (sec != NULL && discarded_section (sec)) + { + _bfd_clear_contents (howto, input_bfd, input_section, +- contents + (rel->r_vaddr - input_section->vma)); ++ contents, rel->r_vaddr - input_section->vma); + continue; + } + +diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h +index e8eac7b..bf7dda0 100644 +--- a/bfd/elf-bfd.h ++++ b/bfd/elf-bfd.h +@@ -2811,7 +2811,7 @@ extern asection _bfd_elf_large_com_section; + { \ + int i_; \ + _bfd_clear_contents (howto, input_bfd, input_section, \ +- contents + rel[index].r_offset); \ ++ contents, rel[index].r_offset); \ + \ + if (bfd_link_relocatable (info) \ + && (input_section->flags & SEC_DEBUGGING)) \ +diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c +index a48ef0c..2d0346c 100644 +--- a/bfd/elf32-arc.c ++++ b/bfd/elf32-arc.c +@@ -1551,7 +1551,7 @@ elf_arc_relocate_section (bfd * output_bfd, + if (sec != NULL && discarded_section (sec)) + { + _bfd_clear_contents (howto, input_bfd, input_section, +- contents + rel->r_offset); ++ contents, rel->r_offset); + rel->r_info = 0; + rel->r_addend = 0; + +diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c +index 49797dc..1774717 100644 +--- a/bfd/elf32-i386.c ++++ b/bfd/elf32-i386.c +@@ -2197,7 +2197,7 @@ elf_i386_relocate_section (bfd *output_bfd, + if (sec != NULL && discarded_section (sec)) + { + _bfd_clear_contents (howto, input_bfd, input_section, +- contents + rel->r_offset); ++ contents, rel->r_offset); + wrel->r_offset = rel->r_offset; + wrel->r_info = 0; + wrel->r_addend = 0; +diff --git a/bfd/elf32-metag.c b/bfd/elf32-metag.c +index efe95bd..7f96246 100644 +--- a/bfd/elf32-metag.c ++++ b/bfd/elf32-metag.c +@@ -1396,7 +1396,7 @@ metag_final_link_relocate (reloc_howto_type *howto, + rel, relend, howto, contents) \ + { \ + _bfd_clear_contents (howto, input_bfd, input_section, \ +- contents + rel->r_offset); \ ++ contents, rel->r_offset); \ + \ + if (bfd_link_relocatable (info) \ + && (input_section->flags & SEC_DEBUGGING)) \ +diff --git a/bfd/elf32-nds32.c b/bfd/elf32-nds32.c +index 1b30d12..c2e4b49 100644 +--- a/bfd/elf32-nds32.c ++++ b/bfd/elf32-nds32.c +@@ -12582,14 +12582,14 @@ nds32_elf_get_relocated_section_contents (bfd *abfd, + symbol = *(*parent)->sym_ptr_ptr; + if (symbol->section && discarded_section (symbol->section)) + { +- bfd_byte *p; ++ bfd_vma off; + static reloc_howto_type none_howto + = HOWTO (0, 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, + "unused", FALSE, 0, 0, FALSE); + +- p = data + (*parent)->address * bfd_octets_per_byte (input_bfd); +- _bfd_clear_contents ((*parent)->howto, input_bfd, input_section, +- p); ++ off = (*parent)->address * bfd_octets_per_byte (input_bfd); ++ _bfd_clear_contents ((*parent)->howto, input_bfd, ++ input_section, data, off); + (*parent)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; + (*parent)->addend = 0; + (*parent)->howto = &none_howto; +diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c +index a54b80d..5dcaa57 100644 +--- a/bfd/elf32-ppc.c ++++ b/bfd/elf32-ppc.c +@@ -8232,7 +8232,7 @@ ppc_elf_relocate_section (bfd *output_bfd, + howto = ppc_elf_howto_table[r_type]; + + _bfd_clear_contents (howto, input_bfd, input_section, +- contents + rel->r_offset); ++ contents, rel->r_offset); + wrel->r_offset = rel->r_offset; + wrel->r_info = 0; + wrel->r_addend = 0; +diff --git a/bfd/elf32-visium.c b/bfd/elf32-visium.c +index e8f1c4c..961366c 100644 +--- a/bfd/elf32-visium.c ++++ b/bfd/elf32-visium.c +@@ -621,7 +621,7 @@ visium_elf_relocate_section (bfd *output_bfd, + or sections discarded by a linker script, we just want the + section contents zeroed. Avoid any special processing. */ + _bfd_clear_contents (howto, input_bfd, input_section, +- contents + rel->r_offset); ++ contents, rel->r_offset); + + rel->r_info = 0; + rel->r_addend = 0; +diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c +index e95db96..addb6a3 100644 +--- a/bfd/elf64-ppc.c ++++ b/bfd/elf64-ppc.c +@@ -14073,7 +14073,7 @@ ppc64_elf_relocate_section (bfd *output_bfd, + { + _bfd_clear_contents (ppc64_elf_howto_table[r_type], + input_bfd, input_section, +- contents + rel->r_offset); ++ contents, rel->r_offset); + wrel->r_offset = rel->r_offset; + wrel->r_info = 0; + wrel->r_addend = 0; +diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c +index c3a6c31..4dcab43 100644 +--- a/bfd/elf64-x86-64.c ++++ b/bfd/elf64-x86-64.c +@@ -2490,7 +2490,7 @@ elf_x86_64_relocate_section (bfd *output_bfd, + if (sec != NULL && discarded_section (sec)) + { + _bfd_clear_contents (howto, input_bfd, input_section, +- contents + rel->r_offset); ++ contents, rel->r_offset); + wrel->r_offset = rel->r_offset; + wrel->r_info = 0; + wrel->r_addend = 0; +diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h +index 3c55adf..5b7abb8 100644 +--- a/bfd/libbfd-in.h ++++ b/bfd/libbfd-in.h +@@ -696,8 +696,8 @@ extern bfd_reloc_status_type _bfd_relocate_contents + (reloc_howto_type *, bfd *, bfd_vma, bfd_byte *) ATTRIBUTE_HIDDEN; + + /* Clear a given location using a given howto. */ +-extern void _bfd_clear_contents +- (reloc_howto_type *, bfd *, asection *, bfd_byte *) ATTRIBUTE_HIDDEN; ++extern bfd_reloc_status_type _bfd_clear_contents ++ (reloc_howto_type *, bfd *, asection *, bfd_byte *, bfd_vma) ATTRIBUTE_HIDDEN; + + /* Link stabs in sections in the first pass. */ + +diff --git a/bfd/libbfd.h b/bfd/libbfd.h +index 85f61b2..65d34c3 100644 +--- a/bfd/libbfd.h ++++ b/bfd/libbfd.h +@@ -701,8 +701,8 @@ extern bfd_reloc_status_type _bfd_relocate_contents + (reloc_howto_type *, bfd *, bfd_vma, bfd_byte *) ATTRIBUTE_HIDDEN; + + /* Clear a given location using a given howto. */ +-extern void _bfd_clear_contents +- (reloc_howto_type *, bfd *, asection *, bfd_byte *) ATTRIBUTE_HIDDEN; ++extern bfd_reloc_status_type _bfd_clear_contents ++ (reloc_howto_type *, bfd *, asection *, bfd_byte *, bfd_vma) ATTRIBUTE_HIDDEN; + + /* Link stabs in sections in the first pass. */ + +diff --git a/bfd/reloc.c b/bfd/reloc.c +index bf2dcb1..ac1e20b 100644 +--- a/bfd/reloc.c ++++ b/bfd/reloc.c +@@ -1539,15 +1539,21 @@ _bfd_relocate_contents (reloc_howto_type *howto, + relocations against discarded symbols, to make ignorable debug or unwind + information more obvious. */ + +-void ++bfd_reloc_status_type + _bfd_clear_contents (reloc_howto_type *howto, + bfd *input_bfd, + asection *input_section, +- bfd_byte *location) ++ bfd_byte *buf, ++ bfd_vma off) + { + bfd_vma x; ++ bfd_byte *location; ++ ++ if (!bfd_reloc_offset_in_range (howto, input_bfd, input_section, off)) ++ return bfd_reloc_outofrange; + + /* Get the value we are going to relocate. */ ++ location = buf + off; + x = read_reloc (input_bfd, location, howto); + + /* Zero out the unwanted bits of X. */ +@@ -1562,6 +1568,7 @@ _bfd_clear_contents (reloc_howto_type *howto, + + /* Put the relocated value back in the object file. */ + write_reloc (input_bfd, x, location, howto); ++ return bfd_reloc_ok; + } + + /* +@@ -8149,14 +8156,14 @@ bfd_generic_get_relocated_section_contents (bfd *abfd, + + if (symbol->section && discarded_section (symbol->section)) + { +- bfd_byte *p; ++ bfd_vma off; + static reloc_howto_type none_howto + = HOWTO (0, 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, + "unused", FALSE, 0, 0, FALSE); + +- p = data + (*parent)->address * bfd_octets_per_byte (input_bfd); +- _bfd_clear_contents ((*parent)->howto, input_bfd, input_section, +- p); ++ off = (*parent)->address * bfd_octets_per_byte (input_bfd); ++ _bfd_clear_contents ((*parent)->howto, input_bfd, ++ input_section, data, off); + (*parent)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; + (*parent)->addend = 0; + (*parent)->howto = &none_howto; +-- +2.19.1 + diff --git a/CVE-2018-1000876.patch b/CVE-2018-1000876.patch new file mode 100644 index 0000000..cebbc0d --- /dev/null +++ b/CVE-2018-1000876.patch @@ -0,0 +1,170 @@ +From 3a551c7a1b80fca579461774860574eabfd7f18f Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Sun, 16 Dec 2018 23:02:50 +1030 +Subject: [PATCH] PR23994, libbfd integer overflow + + PR 23994 + * aoutx.h: Include limits.h. + (get_reloc_upper_bound): Detect long overflow and return a file + too big error if it occurs. + * elf.c: Include limits.h. + (_bfd_elf_get_symtab_upper_bound): Detect long overflow and return + a file too big error if it occurs. + (_bfd_elf_get_dynamic_symtab_upper_bound): Likewise. + (_bfd_elf_get_dynamic_reloc_upper_bound): Likewise. +url:https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3a551c7a1b80fca579461774860574eabfd7f18f +diff --git a/bfd/aoutx.h b/bfd/aoutx.h +index 023843b0be..78eaa9c503 100644 +--- a/bfd/aoutx.h ++++ b/bfd/aoutx.h +@@ -117,6 +117,7 @@ DESCRIPTION + #define KEEPIT udata.i + + #include "sysdep.h" ++#include + #include "bfd.h" + #include "safe-ctype.h" + #include "bfdlink.h" +@@ -2491,6 +2492,8 @@ NAME (aout, canonicalize_reloc) (bfd *abfd, + long + NAME (aout, get_reloc_upper_bound) (bfd *abfd, sec_ptr asect) + { ++ bfd_size_type count; ++ + if (bfd_get_format (abfd) != bfd_object) + { + bfd_set_error (bfd_error_invalid_operation); +@@ -2498,26 +2501,25 @@ NAME (aout, get_reloc_upper_bound) (bfd *abfd, sec_ptr asect) + } + + if (asect->flags & SEC_CONSTRUCTOR) +- return sizeof (arelent *) * (asect->reloc_count + 1); +- +- if (asect == obj_datasec (abfd)) +- return sizeof (arelent *) +- * ((exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd)) +- + 1); +- +- if (asect == obj_textsec (abfd)) +- return sizeof (arelent *) +- * ((exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd)) +- + 1); +- +- if (asect == obj_bsssec (abfd)) +- return sizeof (arelent *); +- +- if (asect == obj_bsssec (abfd)) +- return 0; ++ count = asect->reloc_count; ++ else if (asect == obj_datasec (abfd)) ++ count = exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd); ++ else if (asect == obj_textsec (abfd)) ++ count = exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd); ++ else if (asect == obj_bsssec (abfd)) ++ count = 0; ++ else ++ { ++ bfd_set_error (bfd_error_invalid_operation); ++ return -1; ++ } + +- bfd_set_error (bfd_error_invalid_operation); +- return -1; ++ if (count >= LONG_MAX / sizeof (arelent *)) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ return -1; ++ } ++ return (count + 1) * sizeof (arelent *); + } + + long +diff --git a/bfd/elf.c b/bfd/elf.c +index 688429b73e..b10dcd83c5 100644 +--- a/bfd/elf.c ++++ b/bfd/elf.c +@@ -35,6 +35,7 @@ SECTION + /* For sparc64-cross-sparc32. */ + #define _SYSCALL32 + #include "sysdep.h" ++#include + #include "bfd.h" + #include "bfdlink.h" + #include "libbfd.h" +@@ -8215,11 +8216,16 @@ error_return: + long + _bfd_elf_get_symtab_upper_bound (bfd *abfd) + { +- long symcount; ++ bfd_size_type symcount; + long symtab_size; + Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->symtab_hdr; + + symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym; ++ if (symcount >= LONG_MAX / sizeof (asymbol *)) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ return -1; ++ } + symtab_size = (symcount + 1) * (sizeof (asymbol *)); + if (symcount > 0) + symtab_size -= sizeof (asymbol *); +@@ -8230,7 +8236,7 @@ _bfd_elf_get_symtab_upper_bound (bfd *abfd) + long + _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd) + { +- long symcount; ++ bfd_size_type symcount; + long symtab_size; + Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->dynsymtab_hdr; + +@@ -8241,6 +8247,11 @@ _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd) + } + + symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym; ++ if (symcount >= LONG_MAX / sizeof (asymbol *)) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ return -1; ++ } + symtab_size = (symcount + 1) * (sizeof (asymbol *)); + if (symcount > 0) + symtab_size -= sizeof (asymbol *); +@@ -8310,7 +8321,7 @@ _bfd_elf_canonicalize_dynamic_symtab (bfd *abfd, + long + _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd) + { +- long ret; ++ bfd_size_type count; + asection *s; + + if (elf_dynsymtab (abfd) == 0) +@@ -8319,15 +8330,20 @@ _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd) + return -1; + } + +- ret = sizeof (arelent *); ++ count = 1; + for (s = abfd->sections; s != NULL; s = s->next) + if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd) + && (elf_section_data (s)->this_hdr.sh_type == SHT_REL + || elf_section_data (s)->this_hdr.sh_type == SHT_RELA)) +- ret += ((s->size / elf_section_data (s)->this_hdr.sh_entsize) +- * sizeof (arelent *)); +- +- return ret; ++ { ++ count += s->size / elf_section_data (s)->this_hdr.sh_entsize; ++ if (count > LONG_MAX / sizeof (arelent *)) ++ { ++ bfd_set_error (bfd_error_file_too_big); ++ return -1; ++ } ++ } ++ return count * sizeof (arelent *); + } + + /* Canonicalize the dynamic relocation entries. Note that we return the +-- +2.19.1 + diff --git a/binutils-CVE-2018-17358.patch b/CVE-2018-17358.patch similarity index 100% rename from binutils-CVE-2018-17358.patch rename to CVE-2018-17358.patch diff --git a/binutils-CVE-2018-17360.patch b/CVE-2018-17360.patch similarity index 100% rename from binutils-CVE-2018-17360.patch rename to CVE-2018-17360.patch diff --git a/CVE-2018-18605.patch b/CVE-2018-18605.patch new file mode 100644 index 0000000..ec21371 --- /dev/null +++ b/CVE-2018-18605.patch @@ -0,0 +1,26 @@ +From ab419ddbb2cdd17ca83618990f2cacf904ce1d61 Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Tue, 23 Oct 2018 18:29:24 +1030 +Subject: [PATCH] PR23804, buffer overflow in sec_merge_hash_lookup + + PR 23804 + * merge.c (_bfd_add_merge_section): Don't attempt to merge + sections where size is not a multiple of entsize. +url:https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ab419ddbb2cdd17ca83618990f2cacf904ce1d61 +diff --git a/bfd/merge.c b/bfd/merge.c +index 7904552942..5e3bba0982 100644 +--- a/bfd/merge.c ++++ b/bfd/merge.c +@@ -376,6 +376,9 @@ _bfd_add_merge_section (bfd *abfd, void **psinfo, asection *sec, + || sec->entsize == 0) + return TRUE; + ++ if (sec->size % sec->entsize != 0) ++ return TRUE; ++ + if ((sec->flags & SEC_RELOC) != 0) + { + /* We aren't prepared to handle relocations in merged sections. */ +-- +2.19.1 + diff --git a/CVE-2018-18606.patch b/CVE-2018-18606.patch new file mode 100644 index 0000000..ed57ced --- /dev/null +++ b/CVE-2018-18606.patch @@ -0,0 +1,47 @@ +From 45a0eaf77022963d639d6d19871dbab7b79703fc Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Tue, 23 Oct 2018 19:02:06 +1030 +Subject: [PATCH] PR23806, NULL pointer dereference in merge_strings + + PR 23806 + * merge.c (_bfd_add_merge_section): Don't attempt to merge + sections with ridiculously large alignments. +url:https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=45a0eaf77022963d639d6d19871dbab7b79703fc +diff --git a/bfd/merge.c b/bfd/merge.c +index 5e3bba0982..7de0c886df 100644 +--- a/bfd/merge.c ++++ b/bfd/merge.c +@@ -24,6 +24,7 @@ + as used in ELF SHF_MERGE. */ + + #include "sysdep.h" ++#include + #include "bfd.h" + #include "elf-bfd.h" + #include "libbfd.h" +@@ -385,12 +386,18 @@ _bfd_add_merge_section (bfd *abfd, void **psinfo, asection *sec, + return TRUE; + } + +- align = sec->alignment_power; +- if ((sec->entsize < (unsigned) 1 << align ++#ifndef CHAR_BIT ++#define CHAR_BIT 8 ++#endif ++ if (sec->alignment_power >= sizeof (align) * CHAR_BIT) ++ return TRUE; ++ ++ align = 1u << sec->alignment_power; ++ if ((sec->entsize < align + && ((sec->entsize & (sec->entsize - 1)) + || !(sec->flags & SEC_STRINGS))) +- || (sec->entsize > (unsigned) 1 << align +- && (sec->entsize & (((unsigned) 1 << align) - 1)))) ++ || (sec->entsize > align ++ && (sec->entsize & (align - 1)))) + { + /* Sanity check. If string character size is smaller than + alignment, then we require character size to be a power +-- +2.19.1 + diff --git a/CVE-2018-18607.patch b/CVE-2018-18607.patch new file mode 100644 index 0000000..2f30aee --- /dev/null +++ b/CVE-2018-18607.patch @@ -0,0 +1,53 @@ +From 102def4da826b3d9e169741421e5e67e8731909a Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Tue, 23 Oct 2018 18:30:22 +1030 +Subject: [PATCH] PR23805, NULL pointer dereference in elf_link_input_bfd + + PR 23805 + * elflink.c (elf_link_input_bfd): Don't segfault on finding + STT_TLS symbols without any TLS sections. Instead, change the + symbol type to STT_NOTYPE. +url:https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=102def4da826b3d9e169741421e5e67e8731909a +diff --git a/bfd/elflink.c b/bfd/elflink.c +index c3876cbf3e..87440db960 100644 +--- a/bfd/elflink.c ++++ b/bfd/elflink.c +@@ -10489,8 +10489,11 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd) + if (ELF_ST_TYPE (osym.st_info) == STT_TLS) + { + /* STT_TLS symbols are relative to PT_TLS segment base. */ +- BFD_ASSERT (elf_hash_table (flinfo->info)->tls_sec != NULL); +- osym.st_value -= elf_hash_table (flinfo->info)->tls_sec->vma; ++ if (elf_hash_table (flinfo->info)->tls_sec != NULL) ++ osym.st_value -= elf_hash_table (flinfo->info)->tls_sec->vma; ++ else ++ osym.st_info = ELF_ST_INFO (ELF_ST_BIND (osym.st_info), ++ STT_NOTYPE); + } + } + +@@ -11046,12 +11049,17 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd) + sym.st_value += osec->vma; + if (ELF_ST_TYPE (sym.st_info) == STT_TLS) + { ++ struct elf_link_hash_table *htab ++ = elf_hash_table (flinfo->info); ++ + /* STT_TLS symbols are relative to PT_TLS + segment base. */ +- BFD_ASSERT (elf_hash_table (flinfo->info) +- ->tls_sec != NULL); +- sym.st_value -= (elf_hash_table (flinfo->info) +- ->tls_sec->vma); ++ if (htab->tls_sec != NULL) ++ sym.st_value -= htab->tls_sec->vma; ++ else ++ sym.st_info ++ = ELF_ST_INFO (ELF_ST_BIND (sym.st_info), ++ STT_NOTYPE); + } + } + +-- +2.19.1 + diff --git a/CVE-2018-20002.patch b/CVE-2018-20002.patch new file mode 100644 index 0000000..cd393fa --- /dev/null +++ b/CVE-2018-20002.patch @@ -0,0 +1,65 @@ +From c2f5dc30afa34696f2da0081c4ac50b958ecb0e9 Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Fri, 7 Dec 2018 23:39:42 +1030 +Subject: [PATCH] PR23952, memory leak in _bfd_generic_read_minisymbols + +bfd/ + PR 23952 + * syms.c (_bfd_generic_read_minisymbols): Free syms before + returning with zero symcount. +binutils/ + * nm.c (display_rel_file): Use xrealloc to increase minisyms + for synthetic symbols. +url:https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=c2f5dc30afa34696f2da0081c4ac50b958ecb0e9 +diff --git a/bfd/syms.c b/bfd/syms.c +index e09640ab74..cbf85cb16d 100644 +--- a/bfd/syms.c ++++ b/bfd/syms.c +@@ -822,9 +822,16 @@ _bfd_generic_read_minisymbols (bfd *abfd, + if (symcount < 0) + goto error_return; + +- *minisymsp = syms; +- *sizep = sizeof (asymbol *); +- ++ if (symcount == 0) ++ /* We return 0 above when storage is 0. Exit in the same state ++ here, so as to not complicate callers with having to deal with ++ freeing memory for zero symcount. */ ++ free (syms); ++ else ++ { ++ *minisymsp = syms; ++ *sizep = sizeof (asymbol *); ++ } + return symcount; + + error_return: +diff --git a/binutils/nm.c b/binutils/nm.c +index 8807832f97..39083c3f4e 100644 +--- a/binutils/nm.c ++++ b/binutils/nm.c +@@ -1175,17 +1175,14 @@ display_rel_file (bfd *abfd, bfd *archive_bfd) + if (synth_count > 0) + { + asymbol **symp; +- void *new_mini; + long i; + +- new_mini = xmalloc ((symcount + synth_count + 1) * sizeof (*symp)); +- symp = (asymbol **) new_mini; +- memcpy (symp, minisyms, symcount * sizeof (*symp)); +- symp += symcount; ++ minisyms = xrealloc (minisyms, ++ (symcount + synth_count + 1) * sizeof (*symp)); ++ symp = (asymbol **) minisyms + symcount; + for (i = 0; i < synth_count; i++) + *symp++ = synthsyms + i; + *symp = 0; +- minisyms = new_mini; + symcount += synth_count; + } + } +-- +2.19.1 + diff --git a/binutils-CVE-2018-20623.patch b/CVE-2018-20623.patch similarity index 100% rename from binutils-CVE-2018-20623.patch rename to CVE-2018-20623.patch diff --git a/binutils-CVE-2018-20651.patch b/CVE-2018-20651.patch similarity index 100% rename from binutils-CVE-2018-20651.patch rename to CVE-2018-20651.patch diff --git a/CVE-2018-20671.patch b/CVE-2018-20671.patch new file mode 100644 index 0000000..21797ac --- /dev/null +++ b/CVE-2018-20671.patch @@ -0,0 +1,42 @@ +From 11fa9f134fd658075c6f74499c780df045d9e9ca Mon Sep 17 00:00:00 2001 +From: Nick Clifton +Date: Fri, 4 Jan 2019 13:44:34 +0000 +Subject: [PATCH] Fix a possible integer overflow problem when examining + corrupt binaries using a 32-bit binutil. + + PR 24005 + * objdump.c (load_specific_debug_section): Check for integer + overflow before attempting to allocate contents. +--- + binutils/objdump.c | 13 ++++++++++--- + 1 files changed, 10 insertions(+), 3 deletions(-) + +diff --git a/binutils/objdump.c b/binutils/objdump.c +index 220d93a..f1e6d2e 100644 +--- a/binutils/objdump.c ++++ b/binutils/objdump.c +@@ -2539,12 +2539,19 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, + section->reloc_info = NULL; + section->num_relocs = 0; + section->address = bfd_get_section_vma (abfd, sec); ++ section->user_data = sec; + section->size = bfd_get_section_size (sec); + amt = section->size + 1; ++ if (amt == 0 || amt > bfd_get_file_size (abfd)) ++ { ++ section->start = NULL; ++ free_debug_section (debug); ++ printf (_("\nSection '%s' has an invalid size: %#llx.\n"), ++ section->name, (unsigned long long) section->size); ++ return FALSE; ++ } + section->start = contents = malloc (amt); +- section->user_data = sec; +- if (amt == 0 +- || section->start == NULL ++ if (section->start == NULL + || !bfd_get_full_section_contents (abfd, sec, &contents)) + { + free_debug_section (debug); +-- +2.9.3 diff --git a/CVE-2019-1010180.patch b/CVE-2019-1010180.patch new file mode 100644 index 0000000..a3b0a57 --- /dev/null +++ b/CVE-2019-1010180.patch @@ -0,0 +1,32 @@ +From 8ff71a9c80cfcf64c54d4ae938c644b1b1ea19fb Mon Sep 17 00:00:00 2001 +From: Nick Clifton +Date: Tue, 18 Sep 2018 16:54:07 +0100 +Subject: [PATCH] Add a warning to the bfd library for when it encounters an + ELF file with an invalid section size. + + PR 23657 + * elfcode.h (elf_swap_shdr_in): Generate a warning message if an + ELF section has contents and size larger than the file size. +url:https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=8ff71a9c80cfcf64c54d4ae938c644b1b1ea19fb +diff --git a/bfd/elfcode.h b/bfd/elfcode.h +index fb02e255fd..f224c8b79d 100644 +--- a/bfd/elfcode.h ++++ b/bfd/elfcode.h +@@ -314,6 +314,14 @@ elf_swap_shdr_in (bfd *abfd, + dst->sh_addr = H_GET_WORD (abfd, src->sh_addr); + dst->sh_offset = H_GET_WORD (abfd, src->sh_offset); + dst->sh_size = H_GET_WORD (abfd, src->sh_size); ++ /* PR 23657. Check for invalid section size, in sections with contents. ++ Note - we do not set an error value here because the contents ++ of this particular section might not be needed by the consumer. */ ++ if (dst->sh_type != SHT_NOBITS ++ && dst->sh_size > bfd_get_file_size (abfd)) ++ _bfd_error_handler ++ (_("warning: %pB has a corrupt section with a size (%" BFD_VMA_FMT "x) larger than the file size"), ++ abfd, dst->sh_size); + dst->sh_link = H_GET_32 (abfd, src->sh_link); + dst->sh_info = H_GET_32 (abfd, src->sh_info); + dst->sh_addralign = H_GET_WORD (abfd, src->sh_addralign); +-- +2.19.1 + diff --git a/binutils-CVE-2019-1010204.patch b/CVE-2019-1010204.patch similarity index 100% rename from binutils-CVE-2019-1010204.patch rename to CVE-2019-1010204.patch diff --git a/CVE-2019-12972.patch b/CVE-2019-12972.patch new file mode 100644 index 0000000..c4a5a7a --- /dev/null +++ b/CVE-2019-12972.patch @@ -0,0 +1,32 @@ +From 890f750a3b053532a4b839a2dd6243076de12031 Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Fri, 21 Jun 2019 11:51:38 +0930 +Subject: [PATCH] PR24689, string table corruption + +The testcase in the PR had a e_shstrndx section of type SHT_GROUP. +hdr->contents were initialized by setup_group rather than being read +from the file, thus last byte was not zero and string dereference ran +off the end of the buffer. + + PR 24689 + * elfcode.h (elf_object_p): Check type of e_shstrndx section. +--- + bfd/elfcode.h | 3 ++- + 1 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/bfd/elfcode.h b/bfd/elfcode.h +index a0487b0..5180f79 100644 +--- a/bfd/elfcode.h ++++ b/bfd/elfcode.h +@@ -754,7 +754,8 @@ elf_object_p (bfd *abfd) + /* A further sanity check. */ + if (i_ehdrp->e_shnum != 0) + { +- if (i_ehdrp->e_shstrndx >= elf_numsections (abfd)) ++ if (i_ehdrp->e_shstrndx >= elf_numsections (abfd) ++ || i_shdrp[i_ehdrp->e_shstrndx].sh_type != SHT_STRTAB) + { + /* PR 2257: + We used to just goto got_wrong_format_error here +-- +2.9.3 diff --git a/CVE-2019-14444.patch b/CVE-2019-14444.patch new file mode 100644 index 0000000..46e8e67 --- /dev/null +++ b/CVE-2019-14444.patch @@ -0,0 +1,26 @@ +From e17869db99195849826eaaf5d2d0eb2cfdd7a2a7 Mon Sep 17 00:00:00 2001 +From: Nick Clifton +Date: Mon, 5 Aug 2019 10:40:35 +0100 +Subject: [PATCH] Catch potential integer overflow in readelf when processing + corrupt binaries. + + PR 24829 + * readelf.c (apply_relocations): Catch potential integer overflow + whilst checking reloc location against section size. +url:https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=e17869db99195849826eaaf5d2d0eb2cfdd7a2a7 +diff --git a/binutils/readelf.c b/binutils/readelf.c +index b896ad9f40..e785fde43e 100644 +--- a/binutils/readelf.c ++++ b/binutils/readelf.c +@@ -13366,7 +13366,7 @@ apply_relocations (Filedata * filedata, + } + + rloc = start + rp->r_offset; +- if ((rloc + reloc_size) > end || (rloc < start)) ++ if (rloc >= end || (rloc + reloc_size) > end || (rloc < start)) + { + warn (_("skipping invalid relocation offset 0x%lx in section %s\n"), + (unsigned long) rp->r_offset, +-- +2.19.1 + diff --git a/CVE-2019-17450.patch b/CVE-2019-17450.patch new file mode 100644 index 0000000..a558a71 --- /dev/null +++ b/CVE-2019-17450.patch @@ -0,0 +1,90 @@ +From 6d4f8af90e2256f58c9e02ad72c3dd37201a7349 Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Wed, 9 Oct 2019 00:07:29 +1030 +Subject: [PATCH] PR25078, stack overflow in function find_abstract_instance + + PR 25078 + * dwarf2.c (find_abstract_instance): Delete orig_info_ptr, add + recur_count. Error on recur_count reaching 100 rather than + info_ptr matching orig_info_ptr. Adjust calls. +--- + bfd/dwarf2.c | 35 +++++++++++++++++------------------ + 1 file changed, 17 insertions(+), 18 deletions(-) + +diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c +index 26bfb25eb3..d05af5af9c 100644 +--- a/bfd/dwarf2.c ++++ b/bfd/dwarf2.c +@@ -2803,13 +2803,13 @@ lookup_symbol_in_variable_table (struct comp_unit *unit, + } + + static bfd_boolean +-find_abstract_instance (struct comp_unit * unit, +- bfd_byte * orig_info_ptr, +- struct attribute * attr_ptr, +- const char ** pname, +- bfd_boolean * is_linkage, +- char ** filename_ptr, +- int * linenumber_ptr) ++find_abstract_instance (struct comp_unit *unit, ++ struct attribute *attr_ptr, ++ unsigned int recur_count, ++ const char **pname, ++ bfd_boolean *is_linkage, ++ char **filename_ptr, ++ int *linenumber_ptr) + { + bfd *abfd = unit->abfd; + bfd_byte *info_ptr; +@@ -2820,6 +2820,14 @@ find_abstract_instance (struct comp_unit * unit, + struct attribute attr; + const char *name = NULL; + ++ if (recur_count == 100) ++ { ++ _bfd_error_handler ++ (_("DWARF error: abstract instance recursion detected")); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ + /* 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. */ + if (attr_ptr->form == DW_FORM_ref_addr) +@@ -2937,15 +2945,6 @@ find_abstract_instance (struct comp_unit * unit, + 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: +@@ -2959,7 +2958,7 @@ find_abstract_instance (struct comp_unit * unit, + } + break; + case DW_AT_specification: +- if (!find_abstract_instance (unit, info_ptr, &attr, ++ if (!find_abstract_instance (unit, &attr, recur_count + 1, + &name, is_linkage, + filename_ptr, linenumber_ptr)) + return FALSE; +@@ -3173,7 +3172,7 @@ scan_unit_for_symbols (struct comp_unit *unit) + + case DW_AT_abstract_origin: + case DW_AT_specification: +- if (!find_abstract_instance (unit, info_ptr, &attr, ++ if (!find_abstract_instance (unit, &attr, 0, + &func->name, + &func->is_linkage, + &func->file, +-- +2.19.1 + diff --git a/CVE-2019-17451.patch b/CVE-2019-17451.patch new file mode 100644 index 0000000..552e6ed --- /dev/null +++ b/CVE-2019-17451.patch @@ -0,0 +1,41 @@ +From 7e030e9e32ad36334dd5ca6781f619f52095ceed Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Wed, 9 Oct 2019 10:47:13 +1030 +Subject: [PATCH 2/2] PR25070, SEGV in function _bfd_dwarf2_find_nearest_line + +Evil testcase with two debug info sections, with sizes of 2aaaabac4ec1 +and ffffd5555453b140 result in a total size of 1. Reading the first +section of course overflows the buffer and tramples on other memory. + + PR 25070 + * dwarf2.c (_bfd_dwarf2_slurp_debug_info): Catch overflow of + total_size calculation. +--- + bfd/dwarf2.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c +index af312b30d5..26bfb25eb3 100644 +--- a/bfd/dwarf2.c ++++ b/bfd/dwarf2.c +@@ -4424,7 +4424,16 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd, + for (total_size = 0; + msec; + msec = find_debug_info (debug_bfd, debug_sections, msec)) +- total_size += msec->size; ++ { ++ /* Catch PR25070 testcase overflowing size calculation here. */ ++ if (total_size + msec->size < total_size ++ || total_size + msec->size < msec->size) ++ { ++ bfd_set_error (bfd_error_no_memory); ++ return FALSE; ++ } ++ total_size += msec->size; ++ } + + stash->info_ptr_memory = (bfd_byte *) bfd_malloc (total_size); + if (stash->info_ptr_memory == NULL) +-- +2.19.1 + diff --git a/Fix-a-failure-in-the-libiberty-testsuite-by-increasi.patch b/Fix-a-failure-in-the-libiberty-testsuite-by-increasi.patch new file mode 100644 index 0000000..caf8864 --- /dev/null +++ b/Fix-a-failure-in-the-libiberty-testsuite-by-increasi.patch @@ -0,0 +1,28 @@ +From 69799d67e8872dcd3feee81ed2ff0fc47beb52d7 Mon Sep 17 00:00:00 2001 +From: Nick Clifton +Date: Tue, 11 Dec 2018 12:01:15 +0000 +Subject: [PATCH] Fix a failure in the libiberty testsuite by increasing the + recursion limit to 2048. + + PR 88409 +include * demangle.h (DEMANGLE_RECURSION_LIMIT): Increase to 2048. + +binutils* NEWS: Note that recursion limit has increased to 2048. + * doc/binutils.texi: Likewise. +--- + include/demangle.h | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/include/demangle.h b/include/demangle.h +index 1e67fe2fb3..fadf7082c0 100644 +--- a/include/demangle.h ++++ b/include/demangle.h +@@ -77,7 +77,7 @@ extern "C" { + /* If DMGL_NO_RECURSE_LIMIT is not enabled, then this is the value used as + the maximum depth of recursion allowed. It should be enough for any + real-world mangled name. */ +-#define DEMANGLE_RECURSION_LIMIT 1024 ++#define DEMANGLE_RECURSION_LIMIT 2048 + + /* Enumeration of possible demangling styles. + diff --git a/Fix-array-overrun-when-disassembling-corrupt-TIC30-binaries.patch b/Fix-array-overrun-when-disassembling-corrupt-TIC30-binaries.patch new file mode 100644 index 0000000..87ce88e --- /dev/null +++ b/Fix-array-overrun-when-disassembling-corrupt-TIC30-binaries.patch @@ -0,0 +1,26 @@ +From efea62b44631289f995db16faf70979d6592580b Mon Sep 17 00:00:00 2001 +From: Nick Clifton +Date: Tue, 29 Oct 2019 15:35:30 +0000 +Subject: [PATCH] Fix array overrun when disassembling corrupt TIC30 binaries. + + * tic30-dis.c (print_branch): Correct size of operand array. +--- + opcodes/tic30-dis.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletion(-) + +diff --git a/opcodes/tic30-dis.c b/opcodes/tic30-dis.c +index a28be83..29948f4 100644 +--- a/opcodes/tic30-dis.c ++++ b/opcodes/tic30-dis.c +@@ -607,7 +607,7 @@ print_branch (disassemble_info *info, + unsigned long insn_word, + struct instruction *insn) + { +- char operand[2][13] = ++ char operand[2][OPERAND_BUFFER_LEN] = + { + {0}, + {0} +-- +2.9.3 + diff --git a/Fix-buffer-overrun-in-TIC30-disassembler.patch b/Fix-buffer-overrun-in-TIC30-disassembler.patch new file mode 100644 index 0000000..00d5036 --- /dev/null +++ b/Fix-buffer-overrun-in-TIC30-disassembler.patch @@ -0,0 +1,98 @@ +From bbf9a0b5eef3599a1c6a7a3bea40da9f2c37df83 Mon Sep 17 00:00:00 2001 +From: Nick Clifton +Date: Mon, 28 Oct 2019 16:15:34 +0000 +Subject: [PATCH] Fix buffer overrun in TIC30 disassembler. + + * tic30-dis.c (OPERAND_BUFFER_LEN): Define. Use as length of + operand buffer. Set value to 15 not 13. + (get_register_operand): Use OPERAND_BUFFER_LEN. + (get_indirect_operand): Likewise. + (print_two_operand): Likewise. + (print_three_operand): Likewise. + (print_oar_insn): Likewise. +--- + opcodes/tic30-dis.c | 24 +++++++++++++++++------- + 1 files changed, 17 insertions(+), 7 deletions(-) + +diff --git a/opcodes/tic30-dis.c b/opcodes/tic30-dis.c +index 668c519..a28be83 100644 +--- a/opcodes/tic30-dis.c ++++ b/opcodes/tic30-dis.c +@@ -188,6 +188,8 @@ get_tic30_instruction (unsigned long insn_word, struct instruction *insn) + return 1; + } + ++#define OPERAND_BUFFER_LEN 15 ++ + static int + get_register_operand (unsigned char fragment, char *buffer) + { +@@ -199,7 +201,8 @@ get_register_operand (unsigned char fragment, char *buffer) + { + if ((fragment & 0x1F) == current_reg->opcode) + { +- strcpy (buffer, current_reg->name); ++ strncpy (buffer, current_reg->name, OPERAND_BUFFER_LEN); ++ buffer[OPERAND_BUFFER_LEN - 1] = 0; + return 1; + } + } +@@ -250,18 +253,25 @@ get_indirect_operand (unsigned short fragment, + int bufcnt; + + len = strlen (current_ind->syntax); ++ + for (i = 0, bufcnt = 0; i < len; i++, bufcnt++) + { + buffer[bufcnt] = current_ind->syntax[i]; ++ + if (bufcnt > 0 ++ && bufcnt < OPERAND_BUFFER_LEN - 1 + && buffer[bufcnt - 1] == 'a' + && buffer[bufcnt] == 'r') + buffer[++bufcnt] = arnum + '0'; +- if (buffer[bufcnt] == '(' ++ ++ if (bufcnt < OPERAND_BUFFER_LEN - 1 ++ && buffer[bufcnt] == '(' + && current_ind->displacement == DISP_REQUIRED) + { +- sprintf (&buffer[bufcnt + 1], "%u", disp); +- bufcnt += strlen (&buffer[bufcnt + 1]); ++ snprintf (buffer + (bufcnt + 1), ++ OPERAND_BUFFER_LEN - (bufcnt + 1), ++ "%u", disp); ++ bufcnt += strlen (buffer + (bufcnt + 1)); + } + } + buffer[bufcnt + 1] = '\0'; +@@ -342,7 +352,7 @@ print_two_operand (disassemble_info *info, + struct instruction *insn) + { + char name[12]; +- char operand[2][13] = ++ char operand[2][OPERAND_BUFFER_LEN] = + { + {0}, + {0} +@@ -429,7 +439,7 @@ print_three_operand (disassemble_info *info, + unsigned long insn_word, + struct instruction *insn) + { +- char operand[3][13] = ++ char operand[3][OPERAND_BUFFER_LEN] = + { + {0}, + {0}, +@@ -475,7 +485,7 @@ print_par_insn (disassemble_info *info, + { + size_t i, len; + char *name1, *name2; +- char operand[2][3][13] = ++ char operand[2][3][OPERAND_BUFFER_LEN] = + { + { + {0}, +-- +2.9.3 + diff --git a/Fix-buffer-underrun-bug-in-the-TI-C30-disassembler.patch b/Fix-buffer-underrun-bug-in-the-TI-C30-disassembler.patch new file mode 100644 index 0000000..08e3b7c --- /dev/null +++ b/Fix-buffer-underrun-bug-in-the-TI-C30-disassembler.patch @@ -0,0 +1,30 @@ +From f44b758d3133ef0a7f3131c1e12ed20feb33ee61 Mon Sep 17 00:00:00 2001 +From: Nick Clifton +Date: Tue, 3 Sep 2019 15:37:12 +0100 +Subject: [PATCH] Fix buffer underrun bug in the TI C30 disassembler. + + PR 24961 + * tic30-dis.c (get_indirect_operand): Check for bufcnt being + greater than zero before indexing via (bufcnt -1). +--- + opcodes/tic30-dis.c | 4 +++- + 1 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/opcodes/tic30-dis.c b/opcodes/tic30-dis.c +index c64aceb..668c519 100644 +--- a/opcodes/tic30-dis.c ++++ b/opcodes/tic30-dis.c +@@ -253,7 +253,9 @@ get_indirect_operand (unsigned short fragment, + for (i = 0, bufcnt = 0; i < len; i++, bufcnt++) + { + buffer[bufcnt] = current_ind->syntax[i]; +- if (buffer[bufcnt - 1] == 'a' && buffer[bufcnt] == 'r') ++ if (bufcnt > 0 ++ && buffer[bufcnt - 1] == 'a' ++ && buffer[bufcnt] == 'r') + buffer[++bufcnt] = arnum + '0'; + if (buffer[bufcnt] == '(' + && current_ind->displacement == DISP_REQUIRED) +-- +2.9.3 + diff --git a/Fix-incorrect-extraction-of-signe-dconstants-in-nios2.patch b/Fix-incorrect-extraction-of-signe-dconstants-in-nios2.patch new file mode 100644 index 0000000..8b5a47c --- /dev/null +++ b/Fix-incorrect-extraction-of-signe-dconstants-in-nios2.patch @@ -0,0 +1,120 @@ +From 6031ac352c05c5c9f44e24fa1c5a8222a7a7d02d Mon Sep 17 00:00:00 2001 +From: Sandra Loosemore +Date: Sun, 23 Sep 2018 12:31:23 -0700 +Subject: [PATCH] Fix incorrect extraction of signed constants in nios2 + disassembler. + +2018-09-23 Sandra Loosemore + + opcodes/ + * nios2-dis.c (nios2_print_insn_arg): Make sure signed conversions + are used when extracting signed fields and converting them to + potentially 64-bit types. +--- + opcodes/ChangeLog | 6 ++++++ + opcodes/nios2-dis.c | 28 +++++++++++++++------------- + 2 files changed, 21 insertions(+), 13 deletions(-) + +diff --git a/opcodes/nios2-dis.c b/opcodes/nios2-dis.c +index 257e5bb..51027b5 100644 +--- a/opcodes/nios2-dis.c ++++ b/opcodes/nios2-dis.c +@@ -275,6 +275,8 @@ nios2_print_insn_arg (const char *argptr, + const struct nios2_opcode *op) + { + unsigned long i = 0; ++ long s = 0; ++ bfd_signed_vma o = 0; + struct nios2_reg *reg_base; + + switch (*argptr) +@@ -552,15 +554,15 @@ nios2_print_insn_arg (const char *argptr, + switch (op->format) + { + case iw_i_type: +- i = (signed) (GET_IW_I_IMM16 (opcode) << 16) >> 16; ++ s = (int32_t) (GET_IW_I_IMM16 (opcode) << 16) >> 16; + break; + case iw_F2I16_type: +- i = (signed) (GET_IW_F2I16_IMM16 (opcode) << 16) >> 16; ++ s = (int32_t) (GET_IW_F2I16_IMM16 (opcode) << 16) >> 16; + break; + default: + bad_opcode (op); + } +- (*info->fprintf_func) (info->stream, "%ld", i); ++ (*info->fprintf_func) (info->stream, "%ld", s); + break; + + case 'I': +@@ -568,15 +570,15 @@ nios2_print_insn_arg (const char *argptr, + switch (op->format) + { + case iw_F2X4I12_type: +- i = (signed) (GET_IW_F2X4I12_IMM12 (opcode) << 20) >> 20; ++ s = (int32_t) (GET_IW_F2X4I12_IMM12 (opcode) << 20) >> 20; + break; + case iw_F1X4I12_type: +- i = (signed) (GET_IW_F1X4I12_IMM12 (opcode) << 20) >> 20; ++ s = (int32_t) (GET_IW_F1X4I12_IMM12 (opcode) << 20) >> 20; + break; + default: + bad_opcode (op); + } +- (*info->fprintf_func) (info->stream, "%ld", i); ++ (*info->fprintf_func) (info->stream, "%ld", s); + break; + + case 'u': +@@ -671,15 +673,15 @@ nios2_print_insn_arg (const char *argptr, + switch (op->format) + { + case iw_i_type: +- i = (signed) (GET_IW_I_IMM16 (opcode) << 16) >> 16; ++ o = (int32_t) (GET_IW_I_IMM16 (opcode) << 16) >> 16; + break; + case iw_F2I16_type: +- i = (signed) (GET_IW_F2I16_IMM16 (opcode) << 16) >> 16; ++ o = (int32_t) (GET_IW_F2I16_IMM16 (opcode) << 16) >> 16; + break; + default: + bad_opcode (op); + } +- address = address + 4 + i; ++ address = address + 4 + o; + (*info->print_address_func) (address, info); + break; + +@@ -688,12 +690,12 @@ nios2_print_insn_arg (const char *argptr, + switch (op->format) + { + case iw_I10_type: +- i = (signed) (GET_IW_I10_IMM10 (opcode) << 22) >> 21; ++ o = (int32_t) (GET_IW_I10_IMM10 (opcode) << 22) >> 21; + break; + default: + bad_opcode (op); + } +- address = address + 2 + i; ++ address = address + 2 + o; + (*info->print_address_func) (address, info); + break; + +@@ -702,12 +704,12 @@ nios2_print_insn_arg (const char *argptr, + switch (op->format) + { + case iw_T1I7_type: +- i = (signed) (GET_IW_T1I7_IMM7 (opcode) << 25) >> 24; ++ o = (int32_t) (GET_IW_T1I7_IMM7 (opcode) << 25) >> 24; + break; + default: + bad_opcode (op); + } +- address = address + 2 + i; ++ address = address + 2 + o; + (*info->print_address_func) (address, info); + break; + +-- +2.9.3 + diff --git a/Fix-potential-array-overruns-when-disassembling-corrupt-v850.patch b/Fix-potential-array-overruns-when-disassembling-corrupt-v850.patch new file mode 100644 index 0000000..546c1db --- /dev/null +++ b/Fix-potential-array-overruns-when-disassembling-corrupt-v850.patch @@ -0,0 +1,284 @@ +From 5103274ffc537711574f9611cb64c51fa9a65546 Mon Sep 17 00:00:00 2001 +From: Nick Clifton +Date: Mon, 4 Nov 2019 12:02:20 +0000 +Subject: [PATCH] Fix potential array overruns when disassembling corrupt v850 + binaries. + + * v850-dis.c (get_v850_sreg_name): New function. Returns the name + of a v850 system register. Move the v850_sreg_names array into + this function. + (get_v850_reg_name): Likewise for ordinary register names. + (get_v850_vreg_name): Likewise for vector register names. + (get_v850_cc_name): Likewise for condition codes. + * get_v850_float_cc_name): Likewise for floating point condition + codes. + (get_v850_cacheop_name): Likewise for cache-ops. + (get_v850_prefop_name): Likewise for pref-ops. + (disassemble): Use the new accessor functions. +--- + opcodes/ChangeLog | 14 +++++ + opcodes/v850-dis.c | 175 +++++++++++++++++++++++++++++++++++------------------ + 1 files changed, 115 insertions(+), 60 deletions(-) + +diff --git a/opcodes/v850-dis.c b/opcodes/v850-dis.c +index 84cf2d3..f8b5d1c 100644 +--- a/opcodes/v850-dis.c ++++ b/opcodes/v850-dis.c +@@ -25,53 +25,7 @@ + #include "opcode/v850.h" + #include "disassemble.h" + #include "opintl.h" +- +-static const char *const v850_reg_names[] = +-{ +- "r0", "r1", "r2", "sp", "gp", "r5", "r6", "r7", +- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", +- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", +- "r24", "r25", "r26", "r27", "r28", "r29", "ep", "lp" +-}; +- +-static const char *const v850_sreg_names[] = +-{ +- "eipc/vip/mpm", "eipsw/mpc", "fepc/tid", "fepsw/ppa", "ecr/vmecr", "psw/vmtid", +- "sr6/fpsr/vmadr/dcc", "sr7/fpepc/dc0", +- "sr8/fpst/vpecr/dcv1", "sr9/fpcc/vptid", "sr10/fpcfg/vpadr/spal", "sr11/spau", +- "sr12/vdecr/ipa0l", "eiic/vdtid/ipa0u", "feic/ipa1l", "dbic/ipa1u", +- "ctpc/ipa2l", "ctpsw/ipa2u", "dbpc/ipa3l", "dbpsw/ipa3u", "ctbp/dpa0l", +- "dir/dpa0u", "bpc/dpa0u", "asid/dpa1l", +- "bpav/dpa1u", "bpam/dpa2l", "bpdv/dpa2u", "bpdm/dpa3l", "eiwr/dpa3u", +- "fewr", "dbwr", "bsel" +-}; +- +-static const char *const v850_cc_names[] = +-{ +- "v", "c/l", "z", "nh", "s/n", "t", "lt", "le", +- "nv", "nc/nl", "nz", "h", "ns/p", "sa", "ge", "gt" +-}; +- +-static const char *const v850_float_cc_names[] = +-{ +- "f/t", "un/or", "eq/neq", "ueq/ogl", "olt/uge", "ult/oge", "ole/ugt", "ule/ogt", +- "sf/st", "ngle/gle", "seq/sne", "ngl/gl", "lt/nlt", "nge/ge", "le/nle", "ngt/gt" +-}; +- +- +-static const char *const v850_vreg_names[] = +-{ +- "vr0", "vr1", "vr2", "vr3", "vr4", "vr5", "vr6", "vr7", "vr8", "vr9", +- "vr10", "vr11", "vr12", "vr13", "vr14", "vr15", "vr16", "vr17", "vr18", +- "vr19", "vr20", "vr21", "vr22", "vr23", "vr24", "vr25", "vr26", "vr27", +- "vr28", "vr29", "vr30", "vr31" +-}; +- +-static const char *const v850_cacheop_names[] = +-{ +- "chbii", "cibii", "cfali", "cisti", "cildi", "chbid", "chbiwbd", +- "chbwbd", "cibid", "cibiwbd", "cibwbd", "cfald", "cistd", "cildd" +-}; ++#include "libiberty.h" + + static const int v850_cacheop_codes[] = + { +@@ -79,9 +33,6 @@ static const int v850_cacheop_codes[] = + 0x07, 0x24, 0x26, 0x27, 0x44, 0x64, 0x65, -1 + }; + +-static const char *const v850_prefop_names[] = +-{ "prefi", "prefd" }; +- + static const int v850_prefop_codes[] = + { 0x00, 0x04, -1}; + +@@ -217,6 +168,110 @@ get_operand_value (const struct v850_operand *operand, + return value; + } + ++static const char * ++get_v850_sreg_name (unsigned int reg) ++{ ++ static const char *const v850_sreg_names[] = ++ { ++ "eipc/vip/mpm", "eipsw/mpc", "fepc/tid", "fepsw/ppa", "ecr/vmecr", "psw/vmtid", ++ "sr6/fpsr/vmadr/dcc", "sr7/fpepc/dc0", ++ "sr8/fpst/vpecr/dcv1", "sr9/fpcc/vptid", "sr10/fpcfg/vpadr/spal", "sr11/spau", ++ "sr12/vdecr/ipa0l", "eiic/vdtid/ipa0u", "feic/ipa1l", "dbic/ipa1u", ++ "ctpc/ipa2l", "ctpsw/ipa2u", "dbpc/ipa3l", "dbpsw/ipa3u", "ctbp/dpa0l", ++ "dir/dpa0u", "bpc/dpa0u", "asid/dpa1l", ++ "bpav/dpa1u", "bpam/dpa2l", "bpdv/dpa2u", "bpdm/dpa3l", "eiwr/dpa3u", ++ "fewr", "dbwr", "bsel" ++ }; ++ ++ if (reg < ARRAY_SIZE (v850_sreg_names)) ++ return v850_sreg_names[reg]; ++ return _(""); ++} ++ ++static const char * ++get_v850_reg_name (unsigned int reg) ++{ ++ static const char *const v850_reg_names[] = ++ { ++ "r0", "r1", "r2", "sp", "gp", "r5", "r6", "r7", ++ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", ++ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", ++ "r24", "r25", "r26", "r27", "r28", "r29", "ep", "lp" ++ }; ++ ++ if (reg < ARRAY_SIZE (v850_reg_names)) ++ return v850_reg_names[reg]; ++ return _(""); ++} ++ ++static const char * ++get_v850_vreg_name (unsigned int reg) ++{ ++ static const char *const v850_vreg_names[] = ++ { ++ "vr0", "vr1", "vr2", "vr3", "vr4", "vr5", "vr6", "vr7", "vr8", "vr9", ++ "vr10", "vr11", "vr12", "vr13", "vr14", "vr15", "vr16", "vr17", "vr18", ++ "vr19", "vr20", "vr21", "vr22", "vr23", "vr24", "vr25", "vr26", "vr27", ++ "vr28", "vr29", "vr30", "vr31" ++ }; ++ ++ if (reg < ARRAY_SIZE (v850_vreg_names)) ++ return v850_vreg_names[reg]; ++ return _(""); ++} ++ ++static const char * ++get_v850_cc_name (unsigned int reg) ++{ ++ static const char *const v850_cc_names[] = ++ { ++ "v", "c/l", "z", "nh", "s/n", "t", "lt", "le", ++ "nv", "nc/nl", "nz", "h", "ns/p", "sa", "ge", "gt" ++ }; ++ ++ if (reg < ARRAY_SIZE (v850_cc_names)) ++ return v850_cc_names[reg]; ++ return _(""); ++} ++ ++static const char * ++get_v850_float_cc_name (unsigned int reg) ++{ ++ static const char *const v850_float_cc_names[] = ++ { ++ "f/t", "un/or", "eq/neq", "ueq/ogl", "olt/uge", "ult/oge", "ole/ugt", "ule/ogt", ++ "sf/st", "ngle/gle", "seq/sne", "ngl/gl", "lt/nlt", "nge/ge", "le/nle", "ngt/gt" ++ }; ++ ++ if (reg < ARRAY_SIZE (v850_float_cc_names)) ++ return v850_float_cc_names[reg]; ++ return _(""); ++} ++ ++static const char * ++get_v850_cacheop_name (unsigned int reg) ++{ ++ static const char *const v850_cacheop_names[] = ++ { ++ "chbii", "cibii", "cfali", "cisti", "cildi", "chbid", "chbiwbd", ++ "chbwbd", "cibid", "cibiwbd", "cibwbd", "cfald", "cistd", "cildd" ++ }; ++ ++ if (reg < ARRAY_SIZE (v850_cacheop_names)) ++ return v850_cacheop_names[reg]; ++ return _(""); ++} ++ ++static const char * ++get_v850_prefop_name (unsigned int reg) ++{ ++ static const char *const v850_prefop_names[] = ++ { "prefi", "prefd" }; ++ ++ if (reg < ARRAY_SIZE (v850_prefop_names)) ++ return v850_prefop_names[reg]; ++ return _(""); ++} + + static int + disassemble (bfd_vma memaddr, +@@ -425,16 +480,16 @@ disassemble (bfd_vma memaddr, + switch (flag) + { + case V850_OPERAND_REG: +- info->fprintf_func (info->stream, "%s", v850_reg_names[value]); ++ info->fprintf_func (info->stream, "%s", get_v850_reg_name (value)); + break; + case (V850_OPERAND_REG|V850_REG_EVEN): +- info->fprintf_func (info->stream, "%s", v850_reg_names[value * 2]); ++ info->fprintf_func (info->stream, "%s", get_v850_reg_name (value * 2)); + break; + case V850_OPERAND_EP: + info->fprintf_func (info->stream, "ep"); + break; + case V850_OPERAND_SRG: +- info->fprintf_func (info->stream, "%s", v850_sreg_names[value]); ++ info->fprintf_func (info->stream, "%s", get_v850_sreg_name (value)); + break; + case V850E_OPERAND_REG_LIST: + { +@@ -496,7 +551,7 @@ disassemble (bfd_vma memaddr, + else + shown_one = 1; + +- info->fprintf_func (info->stream, "%s", v850_reg_names[first]); ++ info->fprintf_func (info->stream, "%s", get_v850_reg_name (first)); + + for (bit++; bit < 32; bit++) + if ((mask & (1 << bit)) == 0) +@@ -506,7 +561,7 @@ disassemble (bfd_vma memaddr, + + if (last > first + 1) + { +- info->fprintf_func (info->stream, " - %s", v850_reg_names[ last - 1 ]); ++ info->fprintf_func (info->stream, " - %s", get_v850_reg_name (last - 1)); + } + } + } +@@ -520,11 +575,11 @@ disassemble (bfd_vma memaddr, + break; + + case V850_OPERAND_CC: +- info->fprintf_func (info->stream, "%s", v850_cc_names[value]); ++ info->fprintf_func (info->stream, "%s", get_v850_cc_name (value)); + break; + + case V850_OPERAND_FLOAT_CC: +- info->fprintf_func (info->stream, "%s", v850_float_cc_names[value]); ++ info->fprintf_func (info->stream, "%s", get_v850_float_cc_name (value)); + break; + + case V850_OPERAND_CACHEOP: +@@ -536,7 +591,7 @@ disassemble (bfd_vma memaddr, + if (value == v850_cacheop_codes[idx]) + { + info->fprintf_func (info->stream, "%s", +- v850_cacheop_names[idx]); ++ get_v850_cacheop_name (idx)); + goto MATCH_CACHEOP_CODE; + } + } +@@ -554,7 +609,7 @@ disassemble (bfd_vma memaddr, + if (value == v850_prefop_codes[idx]) + { + info->fprintf_func (info->stream, "%s", +- v850_prefop_names[idx]); ++ get_v850_prefop_name (idx)); + goto MATCH_PREFOP_CODE; + } + } +@@ -564,7 +619,7 @@ disassemble (bfd_vma memaddr, + break; + + case V850_OPERAND_VREG: +- info->fprintf_func (info->stream, "%s", v850_vreg_names[value]); ++ info->fprintf_func (info->stream, "%s", get_v850_vreg_name (value)); + break; + + default: +-- +2.9.3 + diff --git a/Fix-the-handling-of-inlined-frames-in-DWARF-debug-in.patch b/Fix-the-handling-of-inlined-frames-in-DWARF-debug-in.patch new file mode 100644 index 0000000..5476837 --- /dev/null +++ b/Fix-the-handling-of-inlined-frames-in-DWARF-debug-in.patch @@ -0,0 +1,59 @@ +From 514017551643b962e1ae1a37ed277418dc2919f1 Mon Sep 17 00:00:00 2001 +From: Millan Wolff +Date: Wed, 3 Oct 2018 12:06:09 +0100 +Subject: [PATCH 1/2] Fix the handling of inlined frames in DWARF debug info. + + PR 23715 + * dwarf2.c (find_abstract_instance): Allow recursive invocations + of find_abstract_instance to override the name variable. +--- + bfd/dwarf2.c | 2 +- + bfd/section.c | 14 +++++++++----- + 2 files changed, 10 insertions(+), 6 deletions(-) + +diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c +index a464388cc9..af312b30d5 100644 +--- a/bfd/dwarf2.c ++++ b/bfd/dwarf2.c +@@ -2960,7 +2960,7 @@ find_abstract_instance (struct comp_unit * unit, + break; + case DW_AT_specification: + if (!find_abstract_instance (unit, info_ptr, &attr, +- pname, is_linkage, ++ &name, is_linkage, + filename_ptr, linenumber_ptr)) + return FALSE; + break; +diff --git a/bfd/section.c b/bfd/section.c +index 7ee3f6915b..cc23922814 100644 +--- a/bfd/section.c ++++ b/bfd/section.c +@@ -1457,16 +1457,20 @@ SYNOPSIS + + DESCRIPTION + Sets the contents of the section @var{section} in BFD +- @var{abfd} to the data starting in memory at @var{data}. The +- data is written to the output section starting at offset ++ @var{abfd} to the data starting in memory at @var{location}. ++ The data is written to the output section starting at offset + @var{offset} for @var{count} octets. + +- Normally <> is returned, else <>. Possible error +- returns are: ++ Normally <> is returned, but <> is returned if ++ there was an error. Possible error returns are: + o <> - + The output section does not have the <> + attribute, so nothing can be written to it. +- o and some more too ++ o <> - ++ The section is unable to contain all of the data. ++ o <> - ++ The BFD is not writeable. ++ o and some more too. + + This routine is front end to the back end function + <<_bfd_set_section_contents>>. +-- +2.19.1 + diff --git a/Prevent-a-left-shift-by-a-negative-value-when-disassembling.patch b/Prevent-a-left-shift-by-a-negative-value-when-disassembling.patch new file mode 100644 index 0000000..5f04cfe --- /dev/null +++ b/Prevent-a-left-shift-by-a-negative-value-when-disassembling.patch @@ -0,0 +1,47 @@ +From 993a00a986d0795a3cbb7a2dd0c640d8e6d66734 Mon Sep 17 00:00:00 2001 +From: Nick Clifton +Date: Tue, 29 Oct 2019 10:01:27 +0000 +Subject: [PATCH] Prevent a left shift by a negative value when disassembling + IA64 binaries. + + * ia64-opc.c (locate_opcode_ent): Prevent a negative shift when + locating the bit to be tested. +--- + opcodes/ia64-opc.c | 9 ++++++--- + 1 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/opcodes/ia64-opc.c b/opcodes/ia64-opc.c +index 5aa1198..ba60f8a 100644 +--- a/opcodes/ia64-opc.c ++++ b/opcodes/ia64-opc.c +@@ -372,13 +372,16 @@ locate_opcode_ent (ia64_insn opcode, enum ia64_insn_type type) + + bitpos[currstatenum] = currbitnum; + +- /* Skip opval[0] bits in the instruction. */ ++ /* Skip opval[0] bits in the instruction. */ + if (op & 0x40) + { + currbitnum -= opval[0]; + } + +- /* The value of the current bit being tested. */ ++ if (currbitnum < 0) ++ currbitnum = 0; ++ ++ /* The value of the current bit being tested. */ + currbit = opcode & (((ia64_insn) 1) << currbitnum) ? 1 : 0; + next_op = -1; + +@@ -463,7 +466,7 @@ locate_opcode_ent (ia64_insn opcode, enum ia64_insn_type type) + + if (next_op > 65535) + { +- abort (); ++ return -1; + } + + /* Run through the list of opcodes to check, trying to find +-- +2.9.3 + diff --git a/Prevent-objdump-from-aborting.patch b/Prevent-objdump-from-aborting.patch new file mode 100644 index 0000000..1eea315 --- /dev/null +++ b/Prevent-objdump-from-aborting.patch @@ -0,0 +1,105 @@ +From d88bdcb4a52bc041ed9b607dda22f478ec61a67b Mon Sep 17 00:00:00 2001 +From: Phillipe Antoine +Date: Wed, 7 Aug 2019 17:22:29 +0100 +Subject: [PATCH] Prevent objdump from aborting when asked to disassemble an + unknown type of ARC binary file. + + PR 24854 + * arc-dis.c (arc_insn_length): Return 0 rather than aborting when + encountering an unknown machine type. + (print_insn_arc): Handle arc_insn_length returning 0. In error + cases return -1 rather than calling abort. +--- + opcodes/ChangeLog | 8 ++++++++ + opcodes/arc-dis.c | 17 +++++++++++------ + 2 files changed, 19 insertions(+), 6 deletions(-) + +diff --git a/opcodes/arc-dis.c b/opcodes/arc-dis.c +index 8207c05..3c88c33 100644 +--- a/opcodes/arc-dis.c ++++ b/opcodes/arc-dis.c +@@ -672,7 +672,7 @@ arc_insn_length (bfd_byte msb, bfd_byte lsb, struct disassemble_info *info) + break; + + default: +- abort (); ++ return 0; + } + } + +@@ -1009,7 +1009,6 @@ print_insn_arc (bfd_vma memaddr, + the number of bytes objdump should display on a single line. If + the instruction decoder sets this, it should always set it to + the same value in order to get reasonable looking output. */ +- + info->bytes_per_line = 8; + + /* In the next lines, we set two info variables control the way +@@ -1017,7 +1016,6 @@ print_insn_arc (bfd_vma memaddr, + 8 and bytes_per_chunk is 4, the output will look like this: + 00: 00000000 00000000 + with the chunks displayed according to "display_endian". */ +- + if (info->section + && !(info->section->flags & SEC_CODE)) + { +@@ -1072,13 +1070,16 @@ print_insn_arc (bfd_vma memaddr, + (*info->fprintf_func) (info->stream, ".word\t0x%08lx", data); + break; + default: +- abort (); ++ return -1; + } + return size; + } + + insn_len = arc_insn_length (buffer[highbyte], buffer[lowbyte], info); + pr_debug ("instruction length = %d bytes\n", insn_len); ++ if (insn_len == 0) ++ return -1; ++ + arc_infop = info->private_data; + arc_infop->insn_len = insn_len; + +@@ -1131,7 +1132,7 @@ print_insn_arc (bfd_vma memaddr, + + default: + /* There is no instruction whose length is not 2, 4, 6, or 8. */ +- abort (); ++ return -1; + } + + pr_debug ("instruction value = %llx\n", insn); +@@ -1159,24 +1160,28 @@ print_insn_arc (bfd_vma memaddr, + (*info->fprintf_func) (info->stream, ".shor\t%#04llx", + insn & 0xffff); + break; ++ + case 4: + (*info->fprintf_func) (info->stream, ".word\t%#08llx", + insn & 0xffffffff); + break; ++ + case 6: + (*info->fprintf_func) (info->stream, ".long\t%#08llx", + insn & 0xffffffff); + (*info->fprintf_func) (info->stream, ".long\t%#04llx", + (insn >> 32) & 0xffff); + break; ++ + case 8: + (*info->fprintf_func) (info->stream, ".long\t%#08llx", + insn & 0xffffffff); + (*info->fprintf_func) (info->stream, ".long\t%#08llx", + insn >> 32); + break; ++ + default: +- abort (); ++ return -1; + } + + info->insn_type = dis_noninsn; +-- +2.9.3 + diff --git a/Remove-more-shifts-for-sign-zero-extension.patch b/Remove-more-shifts-for-sign-zero-extension.patch new file mode 100644 index 0000000..cb076a0 --- /dev/null +++ b/Remove-more-shifts-for-sign-zero-extension.patch @@ -0,0 +1,307 @@ +From 1d61b032265e69317f42e8019e072506f11890c5 Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Wed, 11 Dec 2019 16:45:14 +1030 +Subject: [PATCH 026/109] Remove more shifts for sign/zero extension + +cpu/ + * epiphany.cpu (f-sdisp11): Don't sign extend with shifts. + * lm32.cpu (f-branch, f-vall): Likewise. + * m32.cpu (f-lab-8-16): Likewise. +opcodes/ + * arc-dis.c (BITS): Don't truncate high bits with shifts. + * nios2-dis.c (nios2_print_insn_arg): Don't sign extend with shifts. + * tic54x-dis.c (print_instruction): Likewise. + * tilegx-opc.c (parse_insn_tilegx): Likewise. + * tilepro-opc.c (parse_insn_tilepro): Likewise. + * visium-dis.c (disassem_class0): Likewise. + * pdp11-dis.c (sign_extend): Likewise. + (SIGN_BITS): Delete. + * epiphany-ibld.c: Regenerate. + * lm32-ibld.c: Regenerate. + * m32c-ibld.c: Regenerate. +--- + cpu/ChangeLog | 6 ++++++ + cpu/epiphany.cpu | 9 +++++---- + cpu/lm32.cpu | 8 ++++++-- + cpu/m32c.cpu | 9 ++++++--- + opcodes/ChangeLog | 14 ++++++++++++++ + opcodes/arc-dis.c | 3 +-- + opcodes/epiphany-ibld.c | 2 +- + opcodes/lm32-ibld.c | 4 ++-- + opcodes/m32c-ibld.c | 4 ++-- + opcodes/nios2-dis.c | 16 ++++++++-------- + opcodes/pdp11-dis.c | 3 +-- + opcodes/tic54x-dis.c | 3 +-- + opcodes/tilegx-opc.c | 4 ++-- + opcodes/tilepro-opc.c | 4 ++-- + opcodes/visium-dis.c | 2 +- + 15 files changed, 58 insertions(+), 33 deletions(-) + +diff --git a/cpu/epiphany.cpu b/cpu/epiphany.cpu +index 9f873b3..02bce07 100644 +--- a/cpu/epiphany.cpu ++++ b/cpu/epiphany.cpu +@@ -228,10 +228,11 @@ + (set (ifield f-disp3) (and SI (ifield f-sdisp11) 7))) + (sequence () ;decode + (set (ifield f-sdisp11) +- (sra SI (sll SI (or SI (sll (ifield f-disp8) 3) +- (ifield f-disp3)) +- 21) +- 21))) ++ (sub SI (xor (and (or (sll (ifield f-disp8) 3) ++ (ifield f-disp3)) ++ #x7ff) ++ #x400) ++ #x400))) + ) + + (dnmf f-imm16 "Short immediate for move/add/sub" () UINT (f-imm8 f-imm-27-8) +diff --git a/cpu/lm32.cpu b/cpu/lm32.cpu +index 83c839f..ecd8160 100644 +--- a/cpu/lm32.cpu ++++ b/cpu/lm32.cpu +@@ -128,11 +128,15 @@ + + (df f-branch "branch offset field" (PCREL-ADDR) 15 16 INT + ((value pc) (sra SI (sub SI value pc) 2)) +- ((value pc) (add SI pc (sra SI (sll SI value 16) 14))) ++ ((value pc) (add SI pc (sub (xor (sll (and value #xffff) 2) ++ #x20000) ++ #x20000))) + ) + (df f-call "call offset field" (PCREL-ADDR) 25 26 INT + ((value pc) (sra SI (sub SI value pc) 2)) +- ((value pc) (add SI pc (sra SI (sll SI value 6) 4))) ++ ((value pc) (add SI pc (sub (xor (sll (and value #x3ffffff) 2) ++ #x8000000) ++ #x8000000))) + ) + + +diff --git a/cpu/m32c.cpu b/cpu/m32c.cpu +index bcc3616..5a38f1b 100644 +--- a/cpu/m32c.cpu ++++ b/cpu/m32c.cpu +@@ -956,9 +956,12 @@ + ) + (df f-lab-8-16 "16 bit pc relative signed offset" (PCREL-ADDR SIGN-OPT all-isas) 8 16 UINT + ((value pc) (or SI (sll (and (sub value (add pc 1)) #xff) 8) +- (srl (and (sub value (add pc 1)) #xffff) 8))) +- ((value pc) (add SI (or (srl (and value #xffff) 8) +- (sra (sll (and value #xff) 24) 16)) (add pc 1))) ++ (srl (and (sub value (add pc 1)) #xff00) 8))) ++ ((value pc) (add SI (sub (xor (or (srl (and value #xff00) 8) ++ (sll (and value #xff) 8)) ++ #x8000) ++ #x8000) ++ (add pc 1))) + ) + (df f-lab-8-24 "24 bit absolute" (all-isas ABS-ADDR) 8 24 UINT + ((value pc) (or SI +diff --git a/opcodes/arc-dis.c b/opcodes/arc-dis.c +index a038fa0..a47e81f 100644 +--- a/opcodes/arc-dis.c ++++ b/opcodes/arc-dis.c +@@ -137,8 +137,7 @@ static bfd_boolean print_hex = FALSE; + (info->endian == BFD_ENDIAN_LITTLE ? bfd_getm32 (bfd_getl32 (buf)) \ + : bfd_getb32 (buf)) + +-#define BITS(word,s,e) (((word) << (sizeof (word) * 8 - 1 - e)) >> \ +- (s + (sizeof (word) * 8 - 1 - e))) ++#define BITS(word,s,e) (((word) >> (s)) & ((1ull << ((e) - (s)) << 1) - 1)) + #define OPCODE_32BIT_INSN(word) (BITS ((word), 27, 31)) + + /* Functions implementation. */ +diff --git a/opcodes/epiphany-ibld.c b/opcodes/epiphany-ibld.c +index 6e6fd7b..aa567d8 100644 +--- a/opcodes/epiphany-ibld.c ++++ b/opcodes/epiphany-ibld.c +@@ -1092,7 +1092,7 @@ epiphany_cgen_extract_operand (CGEN_CPU_DESC cd, + length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 8, 32, total_length, pc, & fields->f_disp8); + if (length <= 0) break; + { +- FLD (f_sdisp11) = ((SI) (((((((FLD (f_disp8)) << (3))) | (FLD (f_disp3)))) << (21))) >> (21)); ++ FLD (f_sdisp11) = ((((((((((FLD (f_disp8)) << (3))) | (FLD (f_disp3)))) & (2047))) ^ (1024))) - (1024)); + } + } + break; +diff --git a/opcodes/lm32-ibld.c b/opcodes/lm32-ibld.c +index 4bc63fb..a79398d 100644 +--- a/opcodes/lm32-ibld.c ++++ b/opcodes/lm32-ibld.c +@@ -680,7 +680,7 @@ lm32_cgen_extract_operand (CGEN_CPU_DESC cd, + { + long value; + length = extract_normal (cd, ex_info, insn_value, 0|(1<> (14)))); ++ value = ((pc) + (((((((((value) & (65535))) << (2))) ^ (131072))) - (131072)))); + fields->f_branch = value; + } + break; +@@ -688,7 +688,7 @@ lm32_cgen_extract_operand (CGEN_CPU_DESC cd, + { + long value; + length = extract_normal (cd, ex_info, insn_value, 0|(1<> (4)))); ++ value = ((pc) + (((((((((value) & (67108863))) << (2))) ^ (134217728))) - (134217728)))); + fields->f_call = value; + } + break; +diff --git a/opcodes/m32c-ibld.c b/opcodes/m32c-ibld.c +index 29c9411..8473e17 100644 +--- a/opcodes/m32c-ibld.c ++++ b/opcodes/m32c-ibld.c +@@ -1489,7 +1489,7 @@ m32c_cgen_insert_operand (CGEN_CPU_DESC cd, + case M32C_OPERAND_LAB_8_16 : + { + long value = fields->f_lab_8_16; +- value = ((((((((value) - (((pc) + (1))))) & (255))) << (8))) | (((USI) (((((value) - (((pc) + (1))))) & (65535))) >> (8)))); ++ value = ((((((((value) - (((pc) + (1))))) & (255))) << (8))) | (((USI) (((((value) - (((pc) + (1))))) & (65280))) >> (8)))); + errmsg = insert_normal (cd, value, 0|(1<> (8))) | (((SI) (((((value) & (255))) << (24))) >> (16))))) + (((pc) + (1)))); ++ value = ((((((((((USI) (((value) & (65280))) >> (8))) | (((((value) & (255))) << (8))))) ^ (32768))) - (32768))) + (((pc) + (1)))); + fields->f_lab_8_16 = value; + } + break; +diff --git a/opcodes/nios2-dis.c b/opcodes/nios2-dis.c +index adf0091..731860c 100644 +--- a/opcodes/nios2-dis.c ++++ b/opcodes/nios2-dis.c +@@ -554,10 +554,10 @@ nios2_print_insn_arg (const char *argptr, + switch (op->format) + { + case iw_i_type: +- s = (int32_t) (GET_IW_I_IMM16 (opcode) << 16) >> 16; ++ s = ((GET_IW_I_IMM16 (opcode) & 0xffff) ^ 0x8000) - 0x8000; + break; + case iw_F2I16_type: +- s = (int32_t) (GET_IW_F2I16_IMM16 (opcode) << 16) >> 16; ++ s = ((GET_IW_F2I16_IMM16 (opcode) & 0xffff) ^ 0x8000) - 0x8000; + break; + default: + bad_opcode (op); +@@ -570,10 +570,10 @@ nios2_print_insn_arg (const char *argptr, + switch (op->format) + { + case iw_F2X4I12_type: +- s = (int32_t) (GET_IW_F2X4I12_IMM12 (opcode) << 20) >> 20; ++ s = ((GET_IW_F2X4I12_IMM12 (opcode) & 0xfff) ^ 0x800) - 0x800; + break; + case iw_F1X4I12_type: +- s = (int32_t) (GET_IW_F1X4I12_IMM12 (opcode) << 20) >> 20; ++ s = ((GET_IW_F1X4I12_IMM12 (opcode) & 0xfff) ^ 0x800) - 0x800; + break; + default: + bad_opcode (op); +@@ -673,10 +673,10 @@ nios2_print_insn_arg (const char *argptr, + switch (op->format) + { + case iw_i_type: +- o = (int32_t) (GET_IW_I_IMM16 (opcode) << 16) >> 16; ++ o = ((GET_IW_I_IMM16 (opcode) & 0xffff) ^ 0x8000) - 0x8000; + break; + case iw_F2I16_type: +- o = (int32_t) (GET_IW_F2I16_IMM16 (opcode) << 16) >> 16; ++ o = ((GET_IW_F2I16_IMM16 (opcode) & 0xffff) ^ 0x8000) - 0x8000; + break; + default: + bad_opcode (op); +@@ -690,7 +690,7 @@ nios2_print_insn_arg (const char *argptr, + switch (op->format) + { + case iw_I10_type: +- o = (int32_t) (GET_IW_I10_IMM10 (opcode) << 22) >> 21; ++ o = (((GET_IW_I10_IMM10 (opcode) & 0x3ff) ^ 0x400) - 0x400) << 1; + break; + default: + bad_opcode (op); +@@ -704,7 +704,7 @@ nios2_print_insn_arg (const char *argptr, + switch (op->format) + { + case iw_T1I7_type: +- o = (int32_t) (GET_IW_T1I7_IMM7 (opcode) << 25) >> 24; ++ o = (((GET_IW_T1I7_IMM7 (opcode) & 0x7f) ^ 0x40) - 0x40) << 1; + break; + default: + bad_opcode (op); +diff --git a/opcodes/pdp11-dis.c b/opcodes/pdp11-dis.c +index e9708e6..a19fbc0 100644 +--- a/opcodes/pdp11-dis.c ++++ b/opcodes/pdp11-dis.c +@@ -31,8 +31,7 @@ + #define F info->stream + + /* Sign-extend a 16-bit number in an int. */ +-#define SIGN_BITS (8 * sizeof (int) - 16) +-#define sign_extend(x) (((x) << SIGN_BITS) >> SIGN_BITS) ++#define sign_extend(x) ((((x) & 0xffff) ^ 0x8000) - 0x8000) + + static int + read_word (bfd_vma memaddr, int *word, disassemble_info *info) +diff --git a/opcodes/tic54x-dis.c b/opcodes/tic54x-dis.c +index c4ecdda..d8b80a3 100644 +--- a/opcodes/tic54x-dis.c ++++ b/opcodes/tic54x-dis.c +@@ -394,8 +394,7 @@ print_instruction (disassemble_info *info, + break; + } + case OP_k5: +- sprintf (operand[i], "#%d", +- (int) (((signed char) opcode & 0x1F) << 3) >> 3); ++ sprintf (operand[i], "#%d", ((opcode & 0x1F) ^ 0x10) - 0x10); + info->fprintf_func (info->stream, "%s%s", comma, operand[i]); + break; + case OP_k8u: +diff --git a/opcodes/tilegx-opc.c b/opcodes/tilegx-opc.c +index 49819e8..cc9ce86 100644 +--- a/opcodes/tilegx-opc.c ++++ b/opcodes/tilegx-opc.c +@@ -8102,8 +8102,8 @@ parse_insn_tilegx (tilegx_bundle_bits bits, + if (op->is_signed) + { + /* Sign-extend the operand. */ +- int shift = (int)((sizeof(int) * 8) - op->num_bits); +- raw_opval = (raw_opval << shift) >> shift; ++ unsigned int sign = 1u << (op->num_bits - 1); ++ raw_opval = ((raw_opval & (sign + sign - 1)) ^ sign) - sign; + } + + /* Adjust PC-relative scaled branch offsets. */ +diff --git a/opcodes/tilepro-opc.c b/opcodes/tilepro-opc.c +index ea15822..c71da3d 100644 +--- a/opcodes/tilepro-opc.c ++++ b/opcodes/tilepro-opc.c +@@ -10220,8 +10220,8 @@ parse_insn_tilepro (tilepro_bundle_bits bits, + if (op->is_signed) + { + /* Sign-extend the operand. */ +- int shift = (int)((sizeof(int) * 8) - op->num_bits); +- opval = (opval << shift) >> shift; ++ unsigned int sign = 1u << (op->num_bits - 1); ++ opval = ((opval & (sign + sign - 1)) ^ sign) - sign; + } + + /* Adjust PC-relative scaled branch offsets. */ +diff --git a/opcodes/visium-dis.c b/opcodes/visium-dis.c +index c71f8cf..41943ad 100644 +--- a/opcodes/visium-dis.c ++++ b/opcodes/visium-dis.c +@@ -94,7 +94,7 @@ disassem_class0 (disassemble_info *info, unsigned int ins) + /* BRR instruction. */ + { + unsigned cbf = (ins >> 27) & 0x000f; +- int displacement = ((int) (ins << 16)) >> 16; ++ int displacement = ((ins & 0xffff) ^ 0x8000) - 0x8000; + + if (ins == 0) + (*info->fprintf_func) (info->stream, "nop"); +-- +1.8.3.1 + diff --git a/Stop-potential-illegal-memory-access-in-the-NS32K.patch b/Stop-potential-illegal-memory-access-in-the-NS32K.patch new file mode 100644 index 0000000..d2cc0fb --- /dev/null +++ b/Stop-potential-illegal-memory-access-in-the-NS32K.patch @@ -0,0 +1,61 @@ +From d1e304bc27b737e0e7daf0029dd5f1e91a4898ed Mon Sep 17 00:00:00 2001 +From: Nick Clifton +Date: Mon, 28 Oct 2019 15:44:23 +0000 +Subject: [PATCH] Stop potential illegal memory access in the NS32K + disassembler. + + * ns32k-dis.c (bit_extract): Add sanitiy check of parameters. + (bit_extract_simple): Likewise. + (bit_copy): Likewise. + (pirnt_insn_ns32k): Ensure that uninitialised elements in the + index_offset array are not accessed. +--- + opcodes/ns32k-dis.c | 10 +++++++++- + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/opcodes/ns32k-dis.c b/opcodes/ns32k-dis.c +index 1fffbd8..22a9389 100644 +--- a/opcodes/ns32k-dis.c ++++ b/opcodes/ns32k-dis.c +@@ -265,6 +265,8 @@ bit_extract (bfd_byte *buffer, int offset, int count) + int result; + int bit; + ++ if (offset < 0 || count < 0) ++ return 0; + buffer += offset >> 3; + offset &= 7; + bit = 1; +@@ -292,6 +294,8 @@ bit_extract_simple (bfd_byte *buffer, int offset, int count) + int result; + int bit; + ++ if (offset < 0 || count < 0) ++ return 0; + buffer += offset >> 3; + offset &= 7; + bit = 1; +@@ -313,6 +317,8 @@ bit_extract_simple (bfd_byte *buffer, int offset, int count) + static void + bit_copy (bfd_byte *buffer, int offset, int count, char *to) + { ++ if (offset < 0 || count < 0) ++ return; + for (; count > 8; count -= 8, to++, offset += 8) + *to = bit_extract (buffer, offset, 8); + *to = bit_extract (buffer, offset, count); +@@ -836,8 +842,10 @@ print_insn_ns32k (bfd_vma memaddr, disassemble_info *info) + memaddr, arg_bufs[argnum], + index_offset[whicharg]); + d++; +- whicharg++; ++ if (whicharg++ >= 1) ++ break; + } ++ + for (argnum = 0; argnum <= maxarg; argnum++) + { + bfd_vma addr; +-- +2.9.3 + diff --git a/binutils.spec b/binutils.spec index 6a3f73b..6863630 100644 --- a/binutils.spec +++ b/binutils.spec @@ -1,7 +1,7 @@ Summary: Binary utilities Name: binutils Version: 2.31.1 -Release: 15 +Release: 16 License: GPLv3+ URL: https://sourceware.org/binutils @@ -32,13 +32,43 @@ Patch16: binutils-delay-ld-script-constant-eval.patch Patch6000: CVE-2018-19931.patch Patch6001: CVE-2018-19932.patch Patch6002: CVE-2019-9077.patch -Patch6003: binutils-CVE-2018-17358.patch -Patch6004: binutils-CVE-2018-17360.patch -Patch6005: binutils-CVE-2018-20623.patch -Patch6006: binutils-CVE-2018-20651.patch +Patch6003: CVE-2018-17358.patch +Patch6004: CVE-2018-17360.patch +Patch6005: CVE-2018-20623.patch +Patch6006: CVE-2018-20651.patch Patch6007: CVE-2019-9075.patch Patch6008: CVE-2018-12697.patch -Patch6009: binutils-CVE-2019-1010204.patch +Patch6009: CVE-2019-1010204.patch +Patch6010: 0001-CVE-2018-18309.patch +Patch6011: 0002-CVE-2018-18309.patch +Patch6012: 0003-CVE-2018-18309.patch +Patch6013: 0004-CVE-2018-18309.patch +Patch6014: CVE-2018-18605.patch +Patch6015: CVE-2018-18607.patch +Patch6016: CVE-2018-18606.patch +Patch6017: CVE-2018-1000876.patch +Patch6018: CVE-2018-20002.patch +Patch6019: CVE-2019-14444.patch +Patch6020: CVE-2019-1010180.patch +Patch6021: Fix-the-handling-of-inlined-frames-in-DWARF-debug-in.patch +Patch6022: CVE-2019-17450.patch +Patch6023: CVE-2019-17451.patch +Patch6024: CVE-2019-12972.patch +Patch6025: Fix-a-failure-in-the-libiberty-testsuite-by-increasi.patch +Patch6026: CVE-2018-20671.patch + +Patch6027: Fix-array-overrun-when-disassembling-corrupt-TIC30-binaries.patch +Patch6028: Fix-buffer-underrun-bug-in-the-TI-C30-disassembler.patch +Patch6029: Fix-potential-array-overruns-when-disassembling-corrupt-v850.patch +Patch6030: Prevent-a-left-shift-by-a-negative-value-when-disassembling.patch +Patch6031: Stop-potential-illegal-memory-access-in-the-NS32K.patch +Patch6032: Fix-buffer-overrun-in-TIC30-disassembler.patch +Patch6033: ubsan-ia64-left-shift-of-negative-value.patch +Patch6034: Fix-incorrect-extraction-of-signe-dconstants-in-nios2.patch +Patch6035: Remove-more-shifts-for-sign-zero-extension.patch +Patch6036: left-shift-of-cannot-be-represented-in-type-int.patch +Patch6037: Prevent-objdump-from-aborting.patch +Patch6038: ubsan-cr16-left-shift-cannot-be-represented-in-type-int.patch Provides: bundled(libiberty) @@ -46,7 +76,8 @@ Buildroot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) BuildRequires: gcc, perl, sed, coreutils, dejagnu, zlib-devel, glibc-static, sharutils, bc, libstdc++-static BuildRequires: bison, m4, gcc-c++, gettext, flex, zlib-devel, texinfo >= 4.0, perl-podlators -Requires: info, coreutils, chkconfig +Requires(post): info coreutils chkconfig +Requires(preun):info chkconfig %define _gnu %{nil} # The higher of these two numbers determines the default ld. @@ -80,7 +111,9 @@ windres - A compiler for Windows resource files. %package devel Summary: devel package including header files and libraries. Provides: binutils-static = %{version}-%{release} -Requires: info, zlib-devel, binutils = %{version}-%{release}, coreutils +Requires: zlib-devel, binutils = %{version}-%{release}, coreutils +Requires(post): info +Requires(preun):info %description devel The devel package contains BFD and opcodes static and dynamic libraries. @@ -307,6 +340,16 @@ fi %{_infodir}/bfd*info* %changelog +* Mon Dec 20 2019 openEuler Buildteam - 2.31.1-16 +- Type:cves +- ID:CVE +- SUG:NA +- DESC:fix CVE-2018-20671 CVE-2019-12972 CVE-2019-17450 CVE-2019-17451 + CVE-2018-18309 CVE-2018-18309 CVE-2018-18605 CVE-2018-18607 CVE-2018-18606 + CVE-2018-1000876 CVE-2018-20002 CVE-2018-20002 CVE-2019-1010180 + fix failure in the libiberty testsuite + fix stack-buffer-overflow, and use-of-uninitialized-value and shift exponent -1 is negative + * Mon Sep 23 2019 luhuaxin - 2.31.1-15 - Patch synchronization and update dependency name - Type:cves diff --git a/left-shift-of-cannot-be-represented-in-type-int.patch b/left-shift-of-cannot-be-represented-in-type-int.patch new file mode 100644 index 0000000..1f418fe --- /dev/null +++ b/left-shift-of-cannot-be-represented-in-type-int.patch @@ -0,0 +1,166 @@ +From 76bba5ee850ea391ebdbb54dda5a06a567526dbf Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Tue, 10 Dec 2019 18:58:38 +1030 +Subject: [PATCH] ubsan: left shift of cannot be represented in type 'int' + + * dis-asm.h (INSN_HAS_RELOC, DISASSEMBLE_DATA), + (USER_SPECIFIED_MACHINE_TYPE, WIDE_OUTPUT): Make unsigned. + * opcode/tic80.h (TIC80_OPERAND_*): Likewise. +--- + include/ChangeLog | 6 ++++++ + include/dis-asm.h | 8 ++++---- + include/opcode/tic80.h | 36 ++++++++++++++++++------------------ + 3 files changed, 28 insertions(+), 22 deletions(-) + +diff --git a/include/dis-asm.h b/include/dis-asm.h +index 82bf4dc..b2a09f8 100644 +--- a/include/dis-asm.h ++++ b/include/dis-asm.h +@@ -105,12 +105,12 @@ typedef struct disassemble_info + unsigned long flags; + /* Set if the disassembler has determined that there are one or more + relocations associated with the instruction being disassembled. */ +-#define INSN_HAS_RELOC (1 << 31) ++#define INSN_HAS_RELOC (1u << 31) + /* Set if the user has requested the disassembly of data as well as code. */ +-#define DISASSEMBLE_DATA (1 << 30) ++#define DISASSEMBLE_DATA (1u << 30) + /* Set if the user has specifically set the machine type encoded in the + mach field of this structure. */ +-#define USER_SPECIFIED_MACHINE_TYPE (1 << 29) ++#define USER_SPECIFIED_MACHINE_TYPE (1u << 29) + + /* Use internally by the target specific disassembly code. */ + void *private_data; +diff --git a/include/opcode/tic80.h b/include/opcode/tic80.h +index 6a68859..ac1249f 100644 +--- a/include/opcode/tic80.h ++++ b/include/opcode/tic80.h +@@ -138,68 +138,68 @@ extern const struct tic80_operand tic80_operands[]; + /* This operand must be an even register number. Floating point numbers + for example are stored in even/odd register pairs. */ + +-#define TIC80_OPERAND_EVEN (1 << 0) ++#define TIC80_OPERAND_EVEN (1u << 0) + + /* This operand must be an odd register number and must be one greater than + the register number of the previous operand. I.E. the second register in + an even/odd register pair. */ + +-#define TIC80_OPERAND_ODD (1 << 1) ++#define TIC80_OPERAND_ODD (1u << 1) + + /* This operand takes signed values. */ + +-#define TIC80_OPERAND_SIGNED (1 << 2) ++#define TIC80_OPERAND_SIGNED (1u << 2) + + /* This operand may be either a predefined constant name or a numeric value. + An example would be a condition code like "eq0.b" which has the numeric + value 0x2. */ + +-#define TIC80_OPERAND_NUM (1 << 3) ++#define TIC80_OPERAND_NUM (1u << 3) + + /* This operand should be wrapped in parentheses rather than separated + from the previous one by a comma. This is used for various + instructions, like the load and store instructions, which want + their operands to look like "displacement(reg)" */ + +-#define TIC80_OPERAND_PARENS (1 << 4) ++#define TIC80_OPERAND_PARENS (1u << 4) + + /* This operand is a PC relative branch offset. The disassembler prints + these symbolically if possible. Note that the offsets are taken as word + offsets. */ + +-#define TIC80_OPERAND_PCREL (1 << 5) ++#define TIC80_OPERAND_PCREL (1u << 5) + + /* This flag is a hint to the disassembler for using hex as the prefered + printing format, even for small positive or negative immediate values. + Normally values in the range -999 to 999 are printed as signed decimal + values and other values are printed in hex. */ + +-#define TIC80_OPERAND_BITFIELD (1 << 6) ++#define TIC80_OPERAND_BITFIELD (1u << 6) + + /* This operand may have a ":m" modifier specified by bit 17 in a short + immediate form instruction. */ + +-#define TIC80_OPERAND_M_SI (1 << 7) ++#define TIC80_OPERAND_M_SI (1u << 7) + + /* This operand may have a ":m" modifier specified by bit 15 in a long + immediate or register form instruction. */ + +-#define TIC80_OPERAND_M_LI (1 << 8) ++#define TIC80_OPERAND_M_LI (1u << 8) + + /* This operand may have a ":s" modifier specified in bit 11 in a long + immediate or register form instruction. */ + +-#define TIC80_OPERAND_SCALED (1 << 9) ++#define TIC80_OPERAND_SCALED (1u << 9) + + /* This operand is a floating point value */ + +-#define TIC80_OPERAND_FLOAT (1 << 10) ++#define TIC80_OPERAND_FLOAT (1u << 10) + + /* This operand is an byte offset from a base relocation. The lower + two bits of the final relocated address are ignored when the value is + written to the program counter. */ + +-#define TIC80_OPERAND_BASEREL (1 << 11) ++#define TIC80_OPERAND_BASEREL (1u << 11) + + /* This operand is an "endmask" field for a shift instruction. + It is treated special in that it can have values of 0-32, +@@ -208,29 +208,29 @@ extern const struct tic80_operand tic80_operands[]; + has no way of knowing from the instruction which value was + given at assembly time, so it just uses '0'. */ + +-#define TIC80_OPERAND_ENDMASK (1 << 12) ++#define TIC80_OPERAND_ENDMASK (1u << 12) + + /* This operand is one of the 32 general purpose registers. + The disassembler prints these with a leading 'r'. */ + +-#define TIC80_OPERAND_GPR (1 << 27) ++#define TIC80_OPERAND_GPR (1u << 27) + + /* This operand is a floating point accumulator register. + The disassembler prints these with a leading 'a'. */ + +-#define TIC80_OPERAND_FPA ( 1 << 28) ++#define TIC80_OPERAND_FPA (1u << 28) + + /* This operand is a control register number, either numeric or + symbolic (like "EIF", "EPC", etc). + The disassembler prints these symbolically. */ + +-#define TIC80_OPERAND_CR (1 << 29) ++#define TIC80_OPERAND_CR (1u << 29) + + /* This operand is a condition code, either numeric or + symbolic (like "eq0.b", "ne0.w", etc). + The disassembler prints these symbolically. */ + +-#define TIC80_OPERAND_CC (1 << 30) ++#define TIC80_OPERAND_CC (1u << 30) + + /* This operand is a bit number, either numeric or + symbolic (like "eq.b", "or.f", etc). +@@ -238,7 +238,7 @@ extern const struct tic80_operand tic80_operands[]; + Note that they appear in the instruction in 1's complement relative + to the values given in the manual. */ + +-#define TIC80_OPERAND_BITNUM (1 << 31) ++#define TIC80_OPERAND_BITNUM (1u << 31) + + /* This mask is used to strip operand bits from an int that contains + both operand bits and a numeric value in the lsbs. */ +-- +2.9.3 + diff --git a/ubsan-cr16-left-shift-cannot-be-represented-in-type-int.patch b/ubsan-cr16-left-shift-cannot-be-represented-in-type-int.patch new file mode 100644 index 0000000..bcacdcb --- /dev/null +++ b/ubsan-cr16-left-shift-cannot-be-represented-in-type-int.patch @@ -0,0 +1,55 @@ +From 0ef562a4b5da6bc1f16b2ea801b228acafd033d8 Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Tue, 10 Dec 2019 23:02:37 +1030 +Subject: [PATCH] ubsan: cr16: left shift cannot be represented in type 'int' + +This was: + unsigned long mask = SBM (instruction->match_bits); +with + #define SBM(offs) ((((1 << (32 - offs)) -1) << (offs))) + +Well, there are a couple of problems. Firstly, the expression uses +int values (1 rather than 1u or 1ul) resulting in the ubsan error, and +secondly, a zero offs will result in a 32-bit shift which is undefined +if ints are only 32 bits. + + * cr16-dis.c (EXTRACT, SBM): Rewrite. + (cr16_match_opcode): Delete duplicate bcond test. +--- + opcodes/ChangeLog | 5 +++++ + opcodes/cr16-dis.c | 11 ++++------- + 2 files changed, 9 insertions(+), 7 deletions(-) + +diff --git a/opcodes/cr16-dis.c b/opcodes/cr16-dis.c +index 65cf91c..68fbe42 100644 +--- a/opcodes/cr16-dis.c ++++ b/opcodes/cr16-dis.c +@@ -30,11 +30,11 @@ + + /* Extract 'n_bits' from 'a' starting from offset 'offs'. */ + #define EXTRACT(a, offs, n_bits) \ +- (n_bits == 32 ? (((a) >> (offs)) & 0xffffffffL) \ +- : (((a) >> (offs)) & ((1 << (n_bits)) -1))) ++ (((a) >> (offs)) & ((1ul << ((n_bits) - 1) << 1) - 1)) + +-/* Set Bit Mask - a mask to set all bits starting from offset 'offs'. */ +-#define SBM(offs) ((((1 << (32 - offs)) -1) << (offs))) ++/* Set Bit Mask - a mask to set all bits in a 32-bit word starting ++ from offset 'offs'. */ ++#define SBM(offs) ((1ul << 31 << 1) - (1ul << (offs))) + + typedef struct + { +@@ -329,9 +329,6 @@ cr16_match_opcode (void) + while (instruction >= cr16_instruction) + { + mask = build_mask (); +- /* Adjust mask for bcond with 32-bit size instruction */ +- if ((IS_INSN_MNEMONIC("b") && instruction->size == 2)) +- mask = 0xff0f0000; + + if ((doubleWord & mask) == BIN (instruction->match, + instruction->match_bits)) +-- +2.9.3 + diff --git a/ubsan-ia64-left-shift-of-negative-value.patch b/ubsan-ia64-left-shift-of-negative-value.patch new file mode 100644 index 0000000..963c77b --- /dev/null +++ b/ubsan-ia64-left-shift-of-negative-value.patch @@ -0,0 +1,44 @@ +From 8ff23dba80b80a9f47d75dd43812e041f6674763 Mon Sep 17 00:00:00 2001 +From: Alan Modra +Date: Tue, 10 Dec 2019 17:57:14 +1030 +Subject: [PATCH] ubsan: ia64: left shift of negative value + +Here, since val is signed: + *valuep = (val << scale); + + * cpu-ia64-opc.c (ext_imms_scaled): Avoid undefined left shift + of negative values by using unsigned vars. +--- + bfd/ChangeLog | 5 +++++ + bfd/cpu-ia64-opc.c | 6 +++--- + 2 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/bfd/cpu-ia64-opc.c b/bfd/cpu-ia64-opc.c +index 84ee0e2..8df90be 100644 +--- a/bfd/cpu-ia64-opc.c ++++ b/bfd/cpu-ia64-opc.c +@@ -186,7 +186,7 @@ ext_imms_scaled (const struct ia64_operand *self, ia64_insn code, + ia64_insn *valuep, int scale) + { + int i, bits = 0, total = 0; +- BFD_HOST_64_BIT val = 0, sign; ++ BFD_HOST_U_64_BIT val = 0, sign; + + for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i) + { +@@ -196,10 +196,10 @@ ext_imms_scaled (const struct ia64_operand *self, ia64_insn code, + total += bits; + } + /* sign extend: */ +- sign = (BFD_HOST_64_BIT) 1 << (total - 1); ++ sign = (BFD_HOST_U_64_BIT) 1 << (total - 1); + val = (val ^ sign) - sign; + +- *valuep = (val << scale); ++ *valuep = val << scale; + return 0; + } + +-- +2.9.3 +