summaryrefslogtreecommitdiff
path: root/poky/meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-2.patch
blob: a58b8dccdc883902c1680560d60c710b98f240f3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
From 1e716c1b160d56c2ab8711e199cad5b4db47cedf Mon Sep 17 00:00:00 2001
From: Nick Clifton <nickc@redhat.com>
Date: Tue, 30 Aug 2022 16:01:20 +0100
Subject: [PATCH] BFD library: Use entry 0 in directory and filename tables of

 DWARF-5 debug info.

	PR 29529
	* dwarf2.c (struct line_info_table): Add new field:
	use_dir_and_file_0.
	(concat_filename): Use new field to help select the correct table
	slot.
	(read_formatted_entries): Do not skip entry 0.
	(decode_line_info): Set new field depending upon the version of
	DWARF being parsed.  Initialise filename based upon the setting of
	the new field.

Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=37833b966576c5d25e797ea3b6c33d0459a71892]
CVE: CVE-2023-22608

Signed-off-by: Yash Shinde <Yash.Shinde@windriver.com>

---
 bfd/dwarf2.c                       | 86 ++++++++++++++++++++----------
 ld/testsuite/ld-x86-64/pr27587.err |  2 +-
 2 files changed, 59 insertions(+), 29 deletions(-)

diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c
index 0ae50a37..b7839ad6 100644
--- a/bfd/dwarf2.c
+++ b/bfd/dwarf2.c
@@ -1571,6 +1571,7 @@ struct line_info_table
   unsigned int		num_files;
   unsigned int		num_dirs;
   unsigned int		num_sequences;
+  bool                  use_dir_and_file_0;
   char *		comp_dir;
   char **		dirs;
   struct fileinfo*	files;
@@ -1791,16 +1792,30 @@ concat_filename (struct line_info_table *table, unsigned int file)
 {
   char *filename;
 
-  if (table == NULL || file - 1 >= table->num_files)
+  /* Pre DWARF-5 entry 0 in the directory and filename tables was not used.
+     So in order to save space in the tables used here the info for, eg
+     directory 1 is stored in slot 0 of the directory table, directory 2
+     in slot 1 and so on.
+
+     Starting with DWARF-5 the 0'th entry is used so there is a one to one
+     mapping between DWARF slots and internal table entries.  */
+  if (! table->use_dir_and_file_0)
     {
-      /* FILE == 0 means unknown.  */
-      if (file)
-	_bfd_error_handler
-	  (_("DWARF error: mangled line number section (bad file number)"));
+      /* Pre DWARF-5, FILE == 0 means unknown.  */
+      if (file == 0)
+	return strdup ("<unknown>");
+      -- file;
+    }
+
+  if (table == NULL || file >= table->num_files)
+    {
+      _bfd_error_handler
+	(_("DWARF error: mangled line number section (bad file number)"));
       return strdup ("<unknown>");
     }
 
-  filename = table->files[file - 1].name;
+  filename = table->files[file].name;
+
   if (filename == NULL)
     return strdup ("<unknown>");
 
@@ -1811,12 +1826,17 @@ concat_filename (struct line_info_table *table, unsigned int file)
       char *name;
       size_t len;
 
-      if (table->files[file - 1].dir
+      if (table->files[file].dir
 	  /* PR 17512: file: 0317e960.  */
-	  && table->files[file - 1].dir <= table->num_dirs
+	  && table->files[file].dir <= table->num_dirs
 	  /* PR 17512: file: 7f3d2e4b.  */
 	  && table->dirs != NULL)
-	subdir_name = table->dirs[table->files[file - 1].dir - 1];
+	{
+	  if (table->use_dir_and_file_0)
+	    subdir_name = table->dirs[table->files[file].dir];
+	  else
+	    subdir_name = table->dirs[table->files[file].dir - 1];
+	}
 
       if (!subdir_name || !IS_ABSOLUTE_PATH (subdir_name))
 	dir_name = table->comp_dir;
@@ -1857,10 +1877,12 @@ concat_filename (struct line_info_table *table, unsigned int file)
 
 /* Check whether [low1, high1) can be combined with [low2, high2),
    i.e., they touch or overlap.  */
-static bool ranges_overlap (bfd_vma low1,
-			    bfd_vma high1,
-			    bfd_vma low2,
-			    bfd_vma high2)
+
+static bool
+ranges_overlap (bfd_vma low1,
+		bfd_vma high1,
+		bfd_vma low2,
+		bfd_vma high2)
 {
   if (low1 == low2 || high1 == high2)
     return true;
@@ -1887,15 +1909,16 @@ static bool ranges_overlap (bfd_vma low1,
 /* Insert an address range in the trie mapping addresses to compilation units.
    Will return the new trie node (usually the same as is being sent in, but
    in case of a leaf-to-interior conversion, or expansion of a leaf, it may be
-   different), or NULL on failure.
- */
-static struct trie_node *insert_arange_in_trie(bfd *abfd,
-					       struct trie_node *trie,
-					       bfd_vma trie_pc,
-					       unsigned int trie_pc_bits,
-					       struct comp_unit *unit,
-					       bfd_vma low_pc,
-					       bfd_vma high_pc)
+   different), or NULL on failure.  */
+
+static struct trie_node *
+insert_arange_in_trie (bfd *abfd,
+		       struct trie_node *trie,
+		       bfd_vma trie_pc,
+		       unsigned int trie_pc_bits,
+		       struct comp_unit *unit,
+		       bfd_vma low_pc,
+		       bfd_vma high_pc)
 {
   bfd_vma clamped_low_pc, clamped_high_pc;
   int ch, from_ch, to_ch;
@@ -2031,7 +2054,6 @@ static struct trie_node *insert_arange_in_trie(bfd *abfd,
     return trie;
 }
 
-
 static bool
 arange_add (struct comp_unit *unit, struct arange *first_arange,
 	    struct trie_node **trie_root, bfd_vma low_pc, bfd_vma high_pc)
@@ -2412,10 +2434,8 @@ read_formatted_entries (struct comp_unit *unit, bfd_byte **bufp,
 	    }
 	}
 
-      /* Skip the first "zero entry", which is the compilation dir/file.  */
-      if (datai != 0)
-	if (!callback (table, fe.name, fe.dir, fe.time, fe.size))
-	  return false;
+      if (!callback (table, fe.name, fe.dir, fe.time, fe.size))
+	return false;
     }
 
   *bufp = buf;
@@ -2592,6 +2612,7 @@ decode_line_info (struct comp_unit *unit)
       if (!read_formatted_entries (unit, &line_ptr, line_end, table,
 				   line_info_add_file_name))
 	goto fail;
+      table->use_dir_and_file_0 = true;
     }
   else
     {
@@ -2614,6 +2635,7 @@ decode_line_info (struct comp_unit *unit)
 	  if (!line_info_add_file_name (table, cur_file, dir, xtime, size))
 	    goto fail;
 	}
+      table->use_dir_and_file_0 = false;
     }
 
   /* Read the statement sequences until there's nothing left.  */
@@ -2622,7 +2644,7 @@ decode_line_info (struct comp_unit *unit)
       /* State machine registers.  */
       bfd_vma address = 0;
       unsigned char op_index = 0;
-      char * filename = table->num_files ? concat_filename (table, 1) : NULL;
+      char * filename = NULL;
       unsigned int line = 1;
       unsigned int column = 0;
       unsigned int discriminator = 0;
@@ -2637,6 +2659,14 @@ decode_line_info (struct comp_unit *unit)
       bfd_vma low_pc  = (bfd_vma) -1;
       bfd_vma high_pc = 0;
 
+      if (table->num_files)
+	{
+	  if (table->use_dir_and_file_0)
+	    filename = concat_filename (table, 0);
+	  else
+	    filename = concat_filename (table, 1);
+	}
+
       /* Decode the table.  */
       while (!end_sequence && line_ptr < line_end)
 	{
diff --git a/ld/testsuite/ld-x86-64/pr27587.err b/ld/testsuite/ld-x86-64/pr27587.err
index fa870790..807750ca 100644
--- a/ld/testsuite/ld-x86-64/pr27587.err
+++ b/ld/testsuite/ld-x86-64/pr27587.err
@@ -1,3 +1,3 @@
 #...
-.*pr27587.i:4: undefined reference to `stack_size'
+.*pr27587/<artificial>:4: undefined reference to `stack_size'
 #...