xref: /OK3568_Linux_fs/yocto/poky/meta/recipes-devtools/binutils/binutils/0017-CVE-2022-38127-2.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1From ec41dd75c866599fc03c390c6afb5736c159c0ff Mon Sep 17 00:00:00 2001
2From: Nick Clifton <nickc@redhat.com>
3Date: Tue, 21 Jun 2022 16:37:27 +0100
4Subject: [PATCH] Binutils support for dwarf-5 (location and range lists
5 related)
6
7	* dwarf.h (struct debug_info): Add rnglists_base field.
8	* dwarf.c (read_and_display_attr_value): Read attribute DW_AT_rnglists_base.
9	(display_debug_rnglists_list): While handling DW_RLE_base_addressx,
10  	DW_RLE_startx_endx, DW_RLE_startx_length items, pass the proper parameter
11	value to fetch_indexed_addr(), i.e. fetch the proper entry in .debug_addr section.
12	(display_debug_ranges): Add rnglists_base to the .debug_rnglists base address.
13	(load_separate_debug_files): Load .debug_addr section, if exists.
14
15Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=ec41dd75c866599fc03c390c6afb5736c159c0ff]
16
17Signed-off-by: Pgowda <pgowda.cve@gmail.com>
18---
19 binutils/ChangeLog | 10 +++++++++
20 binutils/dwarf.c   | 53 ++++++++++++++++++++++++++++++++++------------
21 binutils/dwarf.h   |  1 +
22 3 files changed, 51 insertions(+), 13 deletions(-)
23
24diff --git a/binutils/dwarf.c b/binutils/dwarf.c
25index cb2523af1f3..30b64ac68a8 100644
26--- a/binutils/dwarf.c
27+++ b/binutils/dwarf.c
28@@ -2812,7 +2812,12 @@ read_and_display_attr_value (unsigned lo
29 		  dwarf_vmatoa ("x", debug_info_p->cu_offset));
30 	  debug_info_p->loclists_base = uvalue;
31 	  break;
32-
33+	case DW_AT_rnglists_base:
34+	  if (debug_info_p->rnglists_base)
35+	    warn (_("CU @ 0x%s has multiple rnglists_base values"),
36+	          dwarf_vmatoa ("x", debug_info_p->cu_offset));
37+	  debug_info_p->rnglists_base = uvalue;
38+	  break;
39 	case DW_AT_frame_base:
40 	  have_frame_base = 1;
41 	  /* Fall through.  */
42@@ -3303,6 +3308,7 @@ read_and_display_attr_value (unsigned lo
43       /* Fall through.  */
44     case DW_AT_location:
45     case DW_AT_loclists_base:
46+    case DW_AT_rnglists_base:
47     case DW_AT_string_length:
48     case DW_AT_return_addr:
49     case DW_AT_data_member_location:
50@@ -3322,7 +3328,10 @@ read_and_display_attr_value (unsigned lo
51 	   && (form == DW_FORM_data4 || form == DW_FORM_data8))
52 	  || form == DW_FORM_sec_offset
53 	  || form == DW_FORM_loclistx)
54-	printf (_(" (location list)"));
55+	{
56+	  if (attribute != DW_AT_rnglists_base)
57+	    printf (_(" (location list)"));
58+	}
59       /* Fall through.  */
60     case DW_AT_allocated:
61     case DW_AT_associated:
62@@ -3809,6 +3818,7 @@ process_debug_info (struct dwarf_section
63 	  debug_information [unit].range_lists = NULL;
64 	  debug_information [unit].max_range_lists= 0;
65 	  debug_information [unit].num_range_lists = 0;
66+	  debug_information [unit].rnglists_base = 0;
67 	}
68
69       if (!do_loc && dwarf_start_die == 0)
70@@ -7932,9 +7942,16 @@ display_debug_rnglists_list (unsigned ch
71 			     unsigned char * finish,
72 			     unsigned int    pointer_size,
73 			     dwarf_vma       offset,
74-			     dwarf_vma       base_address)
75+			     dwarf_vma       base_address,
76+			     unsigned int    offset_size)
77 {
78   unsigned char *next = start;
79+  unsigned int debug_addr_section_hdr_len;
80+
81+  if (offset_size == 4)
82+    debug_addr_section_hdr_len = 8;
83+  else
84+    debug_addr_section_hdr_len = 16;
85
86   while (1)
87     {
88@@ -7964,20 +7981,24 @@ display_debug_rnglists_list (unsigned ch
89 	  READ_ULEB (base_address, start, finish);
90 	  print_dwarf_vma (base_address, pointer_size);
91 	  printf (_("(base address index) "));
92-	  base_address = fetch_indexed_addr (base_address, pointer_size);
93+	  base_address = fetch_indexed_addr ((base_address * pointer_size)
94+			                     + debug_addr_section_hdr_len, pointer_size);
95 	  print_dwarf_vma (base_address, pointer_size);
96 	  printf (_("(base address)\n"));
97 	  break;
98 	case DW_RLE_startx_endx:
99 	  READ_ULEB (begin, start, finish);
100 	  READ_ULEB (end, start, finish);
101-	  begin = fetch_indexed_addr (begin, pointer_size);
102-	  end   = fetch_indexed_addr (begin, pointer_size);
103+	  begin = fetch_indexed_addr ((begin * pointer_size)
104+			              + debug_addr_section_hdr_len, pointer_size);
105+	  end   = fetch_indexed_addr ((begin * pointer_size)
106+			              + debug_addr_section_hdr_len, pointer_size);
107 	  break;
108 	case DW_RLE_startx_length:
109 	  READ_ULEB (begin, start, finish);
110 	  READ_ULEB (length, start, finish);
111-	  begin = fetch_indexed_addr (begin, pointer_size);
112+	  begin = fetch_indexed_addr ((begin * pointer_size)
113+			              + debug_addr_section_hdr_len, pointer_size);
114 	  end = begin + length;
115 	  break;
116 	case DW_RLE_offset_pair:
117@@ -8003,6 +8024,7 @@ display_debug_rnglists_list (unsigned ch
118 	  rlet = DW_RLE_end_of_list;
119 	  break;
120 	}
121+
122       if (rlet == DW_RLE_end_of_list)
123 	break;
124       if (rlet == DW_RLE_base_address || rlet == DW_RLE_base_addressx)
125@@ -8043,6 +8065,7 @@ display_debug_ranges (struct dwarf_secti
126   /* Initialize it due to a false compiler warning.  */
127   unsigned char         address_size = 0;
128   dwarf_vma             last_offset = 0;
129+  unsigned int          offset_size = 0;
130
131   if (bytes == 0)
132     {
133@@ -8054,10 +8077,10 @@ display_debug_ranges (struct dwarf_secti
134
135   if (is_rnglists)
136     {
137-      dwarf_vma initial_length;
138-      unsigned char segment_selector_size;
139-      unsigned int offset_size, offset_entry_count;
140-      unsigned short version;
141+      dwarf_vma       initial_length;
142+      unsigned char   segment_selector_size;
143+      unsigned int    offset_entry_count;
144+      unsigned short  version;
145
146       /* Get and check the length of the block.  */
147       SAFE_BYTE_GET_AND_INC (initial_length, start, 4, finish);
148@@ -8230,7 +8253,8 @@ display_debug_ranges (struct dwarf_secti
149 		(unsigned long) offset, i);
150 	  continue;
151 	}
152-      next = section_begin + offset;
153+
154+      next = section_begin + offset + debug_info_p->rnglists_base;
155
156       /* If multiple DWARF entities reference the same range then we will
157          have multiple entries in the `range_entries' list for the same
158@@ -8262,7 +8286,7 @@ display_debug_ranges (struct dwarf_secti
159
160       if (is_rnglists)
161 	display_debug_rnglists_list
162-	  (start, finish, pointer_size, offset, base_address);
163+	  (start, finish, pointer_size, offset, base_address, offset_size);
164       else
165 	display_debug_ranges_list
166 	  (start, finish, pointer_size, offset, base_address);
167@@ -11911,6 +11935,9 @@ load_separate_debug_files (void * file,
168       && load_debug_section (abbrev, file)
169       && load_debug_section (info, file))
170     {
171+      /* Load the .debug_addr section, if it exists.  */
172+      load_debug_section (debug_addr, file);
173+
174       free_dwo_info ();
175
176       if (process_debug_info (& debug_displays[info].section, file, abbrev,
177diff --git a/binutils/dwarf.h b/binutils/dwarf.h
178index 040e674c6ce..8a89c08e7c2 100644
179--- a/binutils/dwarf.h
180+++ b/binutils/dwarf.h
181@@ -192,6 +192,7 @@ typedef struct
182   dwarf_vma *    range_lists;
183   unsigned int   num_range_lists;
184   unsigned int   max_range_lists;
185+  dwarf_vma      rnglists_base;
186 }
187 debug_info;
188
189