xref: /OK3568_Linux_fs/yocto/poky/meta/recipes-devtools/binutils/binutils/0017-CVE-2022-38127-3.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1From f18acc9c4e5d18f4783f3a7d59e3ec95d7af0199 Mon Sep 17 00:00:00 2001
2From: "Kumar N, Bhuvanendra" <Kavitha.Natarajan@amd.com>
3Date: Wed, 22 Jun 2022 17:07:25 +0100
4Subject: [PATCH] Binutils support for split-dwarf and dwarf-5
5
6	* dwarf.c (fetch_indexed_string): Added new parameter
7	str_offsets_base to calculate the string offset.
8	(read_and_display_attr_value): Read DW_AT_str_offsets_base
9	attribute.
10	(process_debug_info): While allocating memory and initializing
11	debug_information, do it for do_debug_info also, if its true.
12	(load_separate_debug_files): Load .debug_str_offsets if exists.
13	* dwarf.h (struct debug_info): Add str_offsets_base field.
14
15Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=f18acc9c4e5d18f4783f3a7d59e3ec95d7af0199]
16
17Signed-off-by: Pgowda <pgowda.cve@gmail.com>
18---
19 binutils/ChangeLog | 13 ++++++++++-
20 binutils/dwarf.c   | 57 ++++++++++++++++++++++++++++++++++------------
21 binutils/dwarf.h   |  1 +
22 3 files changed, 56 insertions(+), 15 deletions(-)
23
24diff --git a/binutils/dwarf.c b/binutils/dwarf.c
25index f9c46cf54dd..d9a3144023c 100644
26--- a/binutils/dwarf.c
27+++ b/binutils/dwarf.c
28@@ -687,8 +687,11 @@ fetch_indirect_line_string (dwarf_vma of
29 }
30
31 static const char *
32-fetch_indexed_string (dwarf_vma idx, struct cu_tu_set *this_set,
33-		      dwarf_vma offset_size, bool dwo)
34+fetch_indexed_string (dwarf_vma           idx,
35+		      struct cu_tu_set *  this_set,
36+		      dwarf_vma           offset_size,
37+		      bool                dwo,
38+		      dwarf_vma           str_offsets_base)
39 {
40   enum dwarf_section_display_enum str_sec_idx = dwo ? str_dwo : str;
41   enum dwarf_section_display_enum idx_sec_idx = dwo ? str_index_dwo : str_index;
42@@ -776,7 +779,15 @@ fetch_indexed_string (dwarf_vma idx, str
43       return _("<index offset is too big>");
44     }
45
46-  str_offset = byte_get (curr + index_offset, offset_size);
47+  if (str_offsets_base > 0)
48+    {
49+      if (offset_size == 8)
50+        str_offsets_base -= 16;
51+      else
52+        str_offsets_base -= 8;
53+    }
54+
55+  str_offset = byte_get (curr + index_offset + str_offsets_base, offset_size);
56   str_offset -= str_section->address;
57   if (str_offset >= str_section->size)
58     {
59@@ -2721,11 +2732,13 @@ read_and_display_attr_value (unsigned lo
60 	    /* We have already displayed the form name.  */
61 	    printf (_("%c(offset: 0x%s): %s"), delimiter,
62 		    dwarf_vmatoa ("x", uvalue),
63-		    fetch_indexed_string (uvalue, this_set, offset_size, dwo));
64+		    fetch_indexed_string (uvalue, this_set, offset_size, dwo,
65+	                                  debug_info_p->str_offsets_base));
66 	  else
67 	    printf (_("%c(indexed string: 0x%s): %s"), delimiter,
68 		    dwarf_vmatoa ("x", uvalue),
69-		    fetch_indexed_string (uvalue, this_set, offset_size, dwo));
70+		    fetch_indexed_string (uvalue, this_set, offset_size, dwo,
71+	                                  debug_info_p->str_offsets_base));
72 	}
73       break;
74
75@@ -2800,7 +2813,7 @@ read_and_display_attr_value (unsigned lo
76       break;
77     }
78
79-  if ((do_loc || do_debug_loc || do_debug_ranges)
80+  if ((do_loc || do_debug_loc || do_debug_ranges || do_debug_info)
81       && num_debug_info_entries == 0
82       && debug_info_p != NULL)
83     {
84@@ -2818,6 +2831,13 @@ read_and_display_attr_value (unsigned lo
85 	          dwarf_vmatoa ("x", debug_info_p->cu_offset));
86 	  debug_info_p->rnglists_base = uvalue;
87 	  break;
88+	case DW_AT_str_offsets_base:
89+	  if (debug_info_p->str_offsets_base)
90+	    warn (_("CU @ 0x%s has multiple str_offsets_base values"),
91+		  dwarf_vmatoa ("x", debug_info_p->cu_offset));
92+	  debug_info_p->str_offsets_base = uvalue;
93+	  break;
94+
95 	case DW_AT_frame_base:
96 	  have_frame_base = 1;
97 	  /* Fall through.  */
98@@ -2956,7 +2976,9 @@ read_and_display_attr_value (unsigned lo
99 	      case DW_FORM_strx2:
100 	      case DW_FORM_strx3:
101 	      case DW_FORM_strx4:
102-		add_dwo_name (fetch_indexed_string (uvalue, this_set, offset_size, false), cu_offset);
103+		add_dwo_name (fetch_indexed_string (uvalue, this_set, offset_size, false,
104+		                                    debug_info_p->str_offsets_base),
105+			      cu_offset);
106 		break;
107 	      case DW_FORM_string:
108 		add_dwo_name ((const char *) orig_data, cu_offset);
109@@ -2988,7 +3010,9 @@ read_and_display_attr_value (unsigned lo
110 	      case DW_FORM_strx2:
111 	      case DW_FORM_strx3:
112 	      case DW_FORM_strx4:
113-		add_dwo_dir (fetch_indexed_string (uvalue, this_set, offset_size, false), cu_offset);
114+		add_dwo_dir (fetch_indexed_string (uvalue, this_set, offset_size, false,
115+		                                   debug_info_p->str_offsets_base),
116+			     cu_offset);
117 		break;
118 	      case DW_FORM_string:
119 		add_dwo_dir ((const char *) orig_data, cu_offset);
120@@ -3309,6 +3333,7 @@ read_and_display_attr_value (unsigned lo
121     case DW_AT_location:
122     case DW_AT_loclists_base:
123     case DW_AT_rnglists_base:
124+    case DW_AT_str_offsets_base:
125     case DW_AT_string_length:
126     case DW_AT_return_addr:
127     case DW_AT_data_member_location:
128@@ -3329,7 +3354,8 @@ read_and_display_attr_value (unsigned lo
129 	  || form == DW_FORM_sec_offset
130 	  || form == DW_FORM_loclistx)
131 	{
132-	  if (attribute != DW_AT_rnglists_base)
133+	  if (attribute != DW_AT_rnglists_base
134+	      && attribute != DW_AT_str_offsets_base)
135 	    printf (_(" (location list)"));
136 	}
137       /* Fall through.  */
138@@ -3562,7 +3588,7 @@ process_debug_info (struct dwarf_section
139       return false;
140     }
141
142-  if ((do_loc || do_debug_loc || do_debug_ranges)
143+  if ((do_loc || do_debug_loc || do_debug_ranges || do_debug_info)
144       && num_debug_info_entries == 0
145       && ! do_types)
146     {
147@@ -3797,7 +3823,7 @@ process_debug_info (struct dwarf_section
148 	  continue;
149 	}
150
151-      if ((do_loc || do_debug_loc || do_debug_ranges)
152+      if ((do_loc || do_debug_loc || do_debug_ranges || do_debug_info)
153 	  && num_debug_info_entries == 0
154 	  && alloc_num_debug_info_entries > unit
155 	  && ! do_types)
156@@ -3819,6 +3845,7 @@ process_debug_info (struct dwarf_section
157 	  debug_information [unit].max_range_lists= 0;
158 	  debug_information [unit].num_range_lists = 0;
159 	  debug_information [unit].rnglists_base = 0;
160+	  debug_information [unit].str_offsets_base = 0;
161 	}
162
163       if (!do_loc && dwarf_start_die == 0)
164@@ -4089,7 +4116,7 @@ process_debug_info (struct dwarf_section
165
166   /* Set num_debug_info_entries here so that it can be used to check if
167      we need to process .debug_loc and .debug_ranges sections.  */
168-  if ((do_loc || do_debug_loc || do_debug_ranges)
169+  if ((do_loc || do_debug_loc || do_debug_ranges || do_debug_info)
170       && num_debug_info_entries == 0
171       && ! do_types)
172     {
173@@ -6237,7 +6264,7 @@ display_debug_macro (struct dwarf_sectio
174 	      READ_ULEB (lineno, curr, end);
175 	      READ_ULEB (offset, curr, end);
176 	      string = (const unsigned char *)
177-		fetch_indexed_string (offset, NULL, offset_size, false);
178+		fetch_indexed_string (offset, NULL, offset_size, false, 0);
179 	      if (op == DW_MACRO_define_strx)
180 		printf (" DW_MACRO_define_strx ");
181 	      else
182@@ -7851,7 +7878,7 @@ display_debug_str_offsets (struct dwarf_
183 	  SAFE_BYTE_GET_AND_INC (offset, curr, entry_length, entries_end);
184 	  if (dwo)
185 	    string = (const unsigned char *)
186-	      fetch_indexed_string (idx, NULL, entry_length, dwo);
187+	      fetch_indexed_string (idx, NULL, entry_length, dwo, 0);
188 	  else
189 	    string = fetch_indirect_string (offset);
190
191@@ -11937,6 +11964,8 @@ load_separate_debug_files (void * file,
192     {
193       /* Load the .debug_addr section, if it exists.  */
194       load_debug_section (debug_addr, file);
195+      /* Load the .debug_str_offsets section, if it exists.  */
196+      load_debug_section (str_index, file);
197
198       free_dwo_info ();
199
200diff --git a/binutils/dwarf.h b/binutils/dwarf.h
201index 8a89c08e7c2..adbf20f9a28 100644
202--- a/binutils/dwarf.h
203+++ b/binutils/dwarf.h
204@@ -193,6 +193,7 @@ typedef struct
205   unsigned int   num_range_lists;
206   unsigned int   max_range_lists;
207   dwarf_vma      rnglists_base;
208+  dwarf_vma      str_offsets_base;
209 }
210 debug_info;
211
212