summaryrefslogtreecommitdiff
path: root/poky/meta/recipes-devtools/binutils/binutils/0021-CVE-2023-1579-3.patch
diff options
context:
space:
mode:
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.patch156
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
+