From 33e0a9a056bd23e923b929a4f2ab049ade0b1c32 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 26 Sep 2017 23:20:06 +0930 Subject: [PATCH] Tidy reading data in read_formatted_entries Using read_attribute_value accomplishes two things: It checks for unexpected formats, and ensures the buffer pointer always increments. PR 22210 * dwarf2.c (read_formatted_entries): Use read_attribute_value to read data. Upstream-Status: Backport Affects: <= 2.29.1 CVE: CVE-2017-14933 #2 Signed-off-by: Armin Kuster --- bfd/ChangeLog | 6 ++++++ bfd/dwarf2.c | 37 +++++++------------------------------ 2 files changed, 13 insertions(+), 30 deletions(-) Index: git/bfd/ChangeLog =================================================================== --- git.orig/bfd/ChangeLog +++ git/bfd/ChangeLog @@ -1,3 +1,9 @@ +2017-09-26 Alan Modra + + PR 22210 + * dwarf2.c (read_formatted_entries): Use read_attribute_value to + read data. + 2017-09-26 Nick Clifton PR 22210 Index: git/bfd/dwarf2.c =================================================================== --- git.orig/bfd/dwarf2.c +++ git/bfd/dwarf2.c @@ -1955,6 +1955,7 @@ read_formatted_entries (struct comp_unit char *string_trash; char **stringp = &string_trash; unsigned int uint_trash, *uintp = &uint_trash; + struct attribute attr; content_type = _bfd_safe_read_leb128 (abfd, format, &bytes_read, FALSE, buf_end); @@ -1986,47 +1987,23 @@ read_formatted_entries (struct comp_unit form = _bfd_safe_read_leb128 (abfd, format, &bytes_read, FALSE, buf_end); format += bytes_read; + + buf = read_attribute_value (&attr, form, 0, unit, buf, buf_end); + if (buf == NULL) + return FALSE; switch (form) { case DW_FORM_string: - *stringp = read_string (abfd, buf, buf_end, &bytes_read); - buf += bytes_read; - break; - case DW_FORM_line_strp: - *stringp = read_indirect_line_string (unit, buf, buf_end, &bytes_read); - buf += bytes_read; + *stringp = attr.u.str; break; case DW_FORM_data1: - *uintp = read_1_byte (abfd, buf, buf_end); - buf += 1; - break; - case DW_FORM_data2: - *uintp = read_2_bytes (abfd, buf, buf_end); - buf += 2; - break; - case DW_FORM_data4: - *uintp = read_4_bytes (abfd, buf, buf_end); - buf += 4; - break; - case DW_FORM_data8: - *uintp = read_8_bytes (abfd, buf, buf_end); - buf += 8; - break; - case DW_FORM_udata: - *uintp = _bfd_safe_read_leb128 (abfd, buf, &bytes_read, FALSE, - buf_end); - buf += bytes_read; - break; - - case DW_FORM_block: - /* It is valid only for DW_LNCT_timestamp which is ignored by - current GDB. */ + *uintp = attr.u.val; break; } }