diff options
Diffstat (limited to 'poky/meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-3.patch')
-rw-r--r-- | poky/meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-3.patch | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/poky/meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-3.patch b/poky/meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-3.patch new file mode 100644 index 0000000000..6a838ea3ea --- /dev/null +++ b/poky/meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-3.patch @@ -0,0 +1,156 @@ +From 31d6c13defeba7716ebc9d5c8f81f2f35fe39980 Mon Sep 17 00:00:00 2001 +From: Alan Modra <amodra@gmail.com> +Date: Tue, 14 Jun 2022 12:46:42 +0930 +Subject: [PATCH] PR29230, segv in lookup_symbol_in_variable_table + +The PR23230 testcase uses indexed strings without specifying +SW_AT_str_offsets_base. In this case we left u.str with garbage (from +u.val) which then led to a segfault when attempting to access the +string. Fix that by clearing u.str. The patch also adds missing +sanity checks in the recently committed read_indexed_address and +read_indexed_string functions. + + PR 29230 + * dwarf2.c (read_indexed_address): Return uint64_t. Sanity check idx. + (read_indexed_string): Use uint64_t for str_offset. Sanity check idx. + (read_attribute_value): Clear u.str for indexed string forms when + DW_AT_str_offsets_base is not yet read or missing. + +Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=31d6c13defeba7716ebc9d5c8f81f2f35fe39980] + +CVE: CVE-2023-1579 + +Signed-off-by: Yash Shinde <Yash.Shinde@windriver.com> + +--- + bfd/dwarf2.c | 51 ++++++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 42 insertions(+), 9 deletions(-) + +diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c +index 51018e1ab45..aaa2d84887f 100644 +--- a/bfd/dwarf2.c ++++ b/bfd/dwarf2.c +@@ -1353,13 +1353,13 @@ is_addrx_form (enum dwarf_form form) + + /* Returns the address in .debug_addr section using DW_AT_addr_base. + Used to implement DW_FORM_addrx*. */ +-static bfd_vma ++static uint64_t + read_indexed_address (uint64_t idx, struct comp_unit *unit) + { + struct dwarf2_debug *stash = unit->stash; + struct dwarf2_debug_file *file = unit->file; +- size_t addr_base = unit->dwarf_addr_offset; + bfd_byte *info_ptr; ++ size_t offset; + + if (stash == NULL) + return 0; +@@ -1369,12 +1369,23 @@ read_indexed_address (uint64_t idx, struct comp_unit *unit) + &file->dwarf_addr_buffer, &file->dwarf_addr_size)) + return 0; + +- info_ptr = file->dwarf_addr_buffer + addr_base + idx * unit->offset_size; ++ if (_bfd_mul_overflow (idx, unit->offset_size, &offset)) ++ return 0; ++ ++ offset += unit->dwarf_addr_offset; ++ if (offset < unit->dwarf_addr_offset ++ || offset > file->dwarf_addr_size ++ || file->dwarf_addr_size - offset < unit->offset_size) ++ return 0; ++ ++ info_ptr = file->dwarf_addr_buffer + offset; + + if (unit->offset_size == 4) + return bfd_get_32 (unit->abfd, info_ptr); +- else ++ else if (unit->offset_size == 8) + return bfd_get_64 (unit->abfd, info_ptr); ++ else ++ return 0; + } + + /* Returns the string using DW_AT_str_offsets_base. +@@ -1385,7 +1396,8 @@ read_indexed_string (uint64_t idx, struct comp_unit *unit) + struct dwarf2_debug *stash = unit->stash; + struct dwarf2_debug_file *file = unit->file; + bfd_byte *info_ptr; +- unsigned long str_offset; ++ uint64_t str_offset; ++ size_t offset; + + if (stash == NULL) + return NULL; +@@ -1401,15 +1413,26 @@ read_indexed_string (uint64_t idx, struct comp_unit *unit) + &file->dwarf_str_offsets_size)) + return NULL; + +- info_ptr = (file->dwarf_str_offsets_buffer +- + unit->dwarf_str_offset +- + idx * unit->offset_size); ++ if (_bfd_mul_overflow (idx, unit->offset_size, &offset)) ++ return NULL; ++ ++ offset += unit->dwarf_str_offset; ++ if (offset < unit->dwarf_str_offset ++ || offset > file->dwarf_str_offsets_size ++ || file->dwarf_str_offsets_size - offset < unit->offset_size) ++ return NULL; ++ ++ info_ptr = file->dwarf_str_offsets_buffer + offset; + + if (unit->offset_size == 4) + str_offset = bfd_get_32 (unit->abfd, info_ptr); +- else ++ else if (unit->offset_size == 8) + str_offset = bfd_get_64 (unit->abfd, info_ptr); ++ else ++ return NULL; + ++ if (str_offset >= file->dwarf_str_size) ++ return NULL; + return (const char *) file->dwarf_str_buffer + str_offset; + } + +@@ -1534,27 +1557,37 @@ read_attribute_value (struct attribute * attr, + is not yet read. */ + if (unit->dwarf_str_offset != 0) + attr->u.str = (char *) read_indexed_string (attr->u.val, unit); ++ else ++ attr->u.str = NULL; + break; + case DW_FORM_strx2: + attr->u.val = read_2_bytes (abfd, &info_ptr, info_ptr_end); + if (unit->dwarf_str_offset != 0) + attr->u.str = (char *) read_indexed_string (attr->u.val, unit); ++ else ++ attr->u.str = NULL; + break; + case DW_FORM_strx3: + attr->u.val = read_3_bytes (abfd, &info_ptr, info_ptr_end); + if (unit->dwarf_str_offset != 0) + attr->u.str = (char *) read_indexed_string (attr->u.val, unit); ++ else ++ attr->u.str = NULL; + break; + case DW_FORM_strx4: + attr->u.val = read_4_bytes (abfd, &info_ptr, info_ptr_end); + if (unit->dwarf_str_offset != 0) + attr->u.str = (char *) read_indexed_string (attr->u.val, unit); ++ else ++ attr->u.str = NULL; + break; + case DW_FORM_strx: + attr->u.val = _bfd_safe_read_leb128 (abfd, &info_ptr, + false, info_ptr_end); + if (unit->dwarf_str_offset != 0) + attr->u.str = (char *) read_indexed_string (attr->u.val, unit); ++ else ++ attr->u.str = NULL; + break; + case DW_FORM_exprloc: + case DW_FORM_block: +-- +2.31.1 + |