summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBhushan Attarde <bhushan.attarde@imgtec.com>2016-09-14 13:49:16 +0100
committerNikola Veljkovic <Nikola.Veljkovic@imgtec.com>2016-09-16 18:07:56 +0000
commit6b4897a1e418cf776d2bab7e8d55c28e2d77506f (patch)
tree85831808c37bcc7176da7a224e8e3cda9314d428
parentb66267cc5491513a9ad0369761a1c1b52bf15fed (diff)
downloadgdb-6b4897a1e418cf776d2bab7e8d55c28e2d77506f.tar.gz
Prevent segfault in GDB when searching for architecture matches
Cherry-picked from upstream: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=5d9bbb73c1df68741048c3d0f837b50c289ea608 This fixes gdb host crash when trying to read symbols from target. While patch is arch-neutral, we could only reproduce the issue for mips. * format.c (struct bfd_preserve): New "build_id" field. (bfd_preserve_save): Save "build_id". (bfd_preserve_restore): Restore "build_id". From https://sourceware.org/ml/gdb-patches/2016-09/msg00070.html : Currently the "build_id" field of "struct bfd" is not preserved by "struct bfd_preserve" when "bfd_check_format_matches" is going through all target vectors trying to find a compatible target vector. This leads to a segmentation fault in GDB. Consider a case where one compatible target vector has already been found (so the subset of bfd state is saved in struct bfd_preserve) and then an attempt to find a better match fails after it has modified bfd's build_id pointer. Since this attempt is failed, all its side effects will be undone and all memory allocations done by this vector will be free'd. This will eventually free the memory block that build_id pointer is pointing to. This free'd block then gets reallocated and used for storing something else -- leaving build_id pointing to incorrect contents. This patch adds "build_id" pointer to "struct bfd_preserve" so that it will be preserved on success which can then be recoverable on failure. Change-Id: I3e81c3a8a1d25869659bbf99bebe8b00062cea72
-rw-r--r--gdb-7.11/bfd/ChangeLog6
-rw-r--r--gdb-7.11/bfd/format.c3
2 files changed, 9 insertions, 0 deletions
diff --git a/gdb-7.11/bfd/ChangeLog b/gdb-7.11/bfd/ChangeLog
index dc8b2934f..e4fc17e29 100644
--- a/gdb-7.11/bfd/ChangeLog
+++ b/gdb-7.11/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2016-09-14 Bhushan Attarde <bhushan.attarde@imgtec.com>
+
+ * format.c (struct bfd_preserve): New "build_id" field.
+ (bfd_preserve_save): Save "build_id".
+ (bfd_preserve_restore): Restore "build_id".
+
2016-02-10 Joel Brobecker <brobecker@adacore.com>
* development.sh (development): Set to false.
diff --git a/gdb-7.11/bfd/format.c b/gdb-7.11/bfd/format.c
index aad4dc26f..129740f5f 100644
--- a/gdb-7.11/bfd/format.c
+++ b/gdb-7.11/bfd/format.c
@@ -104,6 +104,7 @@ struct bfd_preserve
struct bfd_section *section_last;
unsigned int section_count;
struct bfd_hash_table section_htab;
+ const struct bfd_build_id *build_id;
};
/* When testing an object for compatibility with a particular target
@@ -126,6 +127,7 @@ bfd_preserve_save (bfd *abfd, struct bfd_preserve *preserve)
preserve->section_count = abfd->section_count;
preserve->section_htab = abfd->section_htab;
preserve->marker = bfd_alloc (abfd, 1);
+ preserve->build_id = abfd->build_id;
if (preserve->marker == NULL)
return FALSE;
@@ -158,6 +160,7 @@ bfd_preserve_restore (bfd *abfd, struct bfd_preserve *preserve)
abfd->sections = preserve->sections;
abfd->section_last = preserve->section_last;
abfd->section_count = preserve->section_count;
+ abfd->build_id = preserve->build_id;
/* bfd_release frees all memory more recently bfd_alloc'd than
its arg, as well as its arg. */