mirror of
https://git.yoctoproject.org/poky
synced 2026-03-12 18:29:42 +01:00
Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3e307d538c351aa9327cbad672c884059ecc20dd] (From OE-Core rev: d478e7ea0bb897e13d86c476966924ef9927f11a) Signed-off-by: Yash Shinde <Yash.Shinde@windriver.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
157 lines
5.0 KiB
Diff
157 lines
5.0 KiB
Diff
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
|
|
|