From 1e716c1b160d56c2ab8711e199cad5b4db47cedf Mon Sep 17 00:00:00 2001 From: Nick Clifton 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 --- 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 (""); + -- file; + } + + if (table == NULL || file >= table->num_files) + { + _bfd_error_handler + (_("DWARF error: mangled line number section (bad file number)")); return strdup (""); } - filename = table->files[file - 1].name; + filename = table->files[file].name; + if (filename == NULL) return strdup (""); @@ -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/:4: undefined reference to `stack_size' #...