From: "Christian Biesinger via gdb-patches" <gdb-patches@sourceware.org>
To: Tom Tromey <tromey@adacore.com>
Cc: gdb-patches <gdb-patches@sourceware.org>
Subject: Re: [PATCH 1/3] Avoid hash table corruption in gdb_bfd.c
Date: Tue, 14 Jan 2020 22:26:00 -0000 [thread overview]
Message-ID: <CAPTJ0XEs3=gy0sX=pOBCpfNr_=VDH6gv5NmH-hx_Z6Vu56Viqg@mail.gmail.com> (raw)
In-Reply-To: <20200114210956.25115-2-tromey@adacore.com>
On Tue, Jan 14, 2020 at 4:10 PM Tom Tromey <tromey@adacore.com> wrote:
>
> gdb caches BFDs that come from ordinary files. This code turns out to
> have a bug where the hash table can become corrupted, causing gdb to
> crash.
>
> When gdb_bfd_open opens the BFD, it uses fstat to get the BFD's mtime.
> This is used when inserting the entry into gdb_bfd_cache. Then, the
> function creates the gdb_bfd_data object as a side effect of calling
> new_reference. This object is used when finding objects in the hash
> table, and its constructor uses bfd_get_mtime. So, if the file
> changes between the time the BFD is put into the cache and the time
> that this object is created, the hash table will be incorrect. When
> the BFD is later deleted, its entry in the hash table will not be
> found, and at this point the hash table will point to invalid memory.
>
> This patch fixes the bug by ensuring that the mtime that is used for
> insertion is also used when creating the gdb_bfd_data.
>
> gdb/ChangeLog
> 2020-01-14 Tom Tromey <tromey@adacore.com>
>
> PR win32/25302:
> * gdb_bfd.c (gdb_bfd_data): Add "mt" parameter.
> (gdb_bfd_init_data): New function.
> (gdb_bfd_open, gdb_bfd_ref): Use gdb_bfd_init_data.
>
> Change-Id: I649ef7060651ac12188fa99d6ae1546caec93594
> ---
> gdb/ChangeLog | 7 +++++++
> gdb/gdb_bfd.c | 50 +++++++++++++++++++++++++++++++++++---------------
> 2 files changed, 42 insertions(+), 15 deletions(-)
>
> diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c
> index 5a6dee2d51a..a1ee7814f32 100644
> --- a/gdb/gdb_bfd.c
> +++ b/gdb/gdb_bfd.c
> @@ -59,8 +59,8 @@ static htab_t all_bfds;
>
> struct gdb_bfd_data
> {
> - gdb_bfd_data (bfd *abfd)
> - : mtime (bfd_get_mtime (abfd)),
> + gdb_bfd_data (bfd *abfd, time_t mt)
> + : mtime (mt),
> size (bfd_get_size (abfd)),
> relocation_computed (0),
> needs_relocations (0),
> @@ -376,6 +376,30 @@ gdb_bfd_iovec_fileio_fstat (struct bfd *abfd, void *stream,
> return result;
> }
>
> +/* A helper function to initialize the data that gdb attaches to each
> + BFD. */
> +
> +static void
> +gdb_bfd_init_data (struct bfd *abfd, time_t mtime)
> +{
> + struct gdb_bfd_data *gdata;
> + void **slot;
Any reason not to move these down to where they are used?
> + gdb_assert (bfd_usrdata (abfd) == nullptr);
> +
> + /* Ask BFD to decompress sections in bfd_get_full_section_contents. */
> + abfd->flags |= BFD_DECOMPRESS;
> +
> + gdata = new gdb_bfd_data (abfd, mtime);
> + bfd_set_usrdata (abfd, gdata);
> + bfd_alloc_data (abfd);
> +
> + /* This is the first we've seen it, so add it to the hash table. */
> + slot = htab_find_slot (all_bfds, abfd, INSERT);
> + gdb_assert (slot && !*slot);
> + *slot = abfd;
> +}
> +
> /* See gdb_bfd.h. */
>
> gdb_bfd_ref_ptr
> @@ -469,7 +493,14 @@ gdb_bfd_open (const char *name, const char *target, int fd)
> *slot = abfd;
> }
>
> - return gdb_bfd_ref_ptr::new_reference (abfd);
> + /* It's important to pass the already-computed mtime here, rather
> + than, say, calling gdb_bfd_ref_ptr::new_reference here. BFD by
> + default will "stat" the file each time bfd_get_mtime is called --
> + and since we already entered it into the hash table using this
> + mtime, if the file changed at the wrong moment, the race would
> + lead to a hash table corruption. */
> + gdb_bfd_init_data (abfd, search.mtime);
> + return gdb_bfd_ref_ptr (abfd);
> }
>
> /* A helper function that releases any section data attached to the
> @@ -522,7 +553,6 @@ void
> gdb_bfd_ref (struct bfd *abfd)
> {
> struct gdb_bfd_data *gdata;
> - void **slot;
>
> if (abfd == NULL)
> return;
> @@ -541,17 +571,7 @@ gdb_bfd_ref (struct bfd *abfd)
> return;
> }
>
> - /* Ask BFD to decompress sections in bfd_get_full_section_contents. */
> - abfd->flags |= BFD_DECOMPRESS;
> -
> - gdata = new gdb_bfd_data (abfd);
> - bfd_set_usrdata (abfd, gdata);
> - bfd_alloc_data (abfd);
> -
> - /* This is the first we've seen it, so add it to the hash table. */
> - slot = htab_find_slot (all_bfds, abfd, INSERT);
> - gdb_assert (slot && !*slot);
> - *slot = abfd;
> + gdb_bfd_init_data (abfd, bfd_get_mtime (abfd));
> }
>
> /* See gdb_bfd.h. */
> --
> 2.21.1
>
next prev parent reply other threads:[~2020-01-14 22:13 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-14 21:10 [PATCH 0/3] Fix gdb's BFD cache Tom Tromey
2020-01-14 21:10 ` [PATCH 1/3] Avoid hash table corruption in gdb_bfd.c Tom Tromey
2020-01-14 22:26 ` Christian Biesinger via gdb-patches [this message]
2020-01-14 21:10 ` [PATCH 2/3] Consistently use BFD's time Tom Tromey
2020-01-14 23:17 ` Christian Biesinger via gdb-patches
2020-01-15 17:51 ` Eli Zaretskii
2020-01-16 20:47 ` Pedro Alves
2020-01-16 21:58 ` Christian Biesinger via gdb-patches
2020-01-16 22:31 ` Pedro Alves
2020-01-17 8:48 ` Eli Zaretskii
2020-01-17 18:32 ` Tom Tromey
2020-01-17 21:03 ` Tom Tromey
2020-01-18 11:07 ` Eli Zaretskii
2020-01-20 15:52 ` Pedro Alves
2020-01-20 15:53 ` Pedro Alves
2020-01-20 20:50 ` Eli Zaretskii
2020-01-20 20:58 ` Pedro Alves
2020-01-21 15:50 ` Pedro Alves
2020-01-21 19:38 ` Eli Zaretskii
2020-01-21 17:56 ` Eli Zaretskii
2020-01-23 22:05 ` Tom Tromey
2020-06-19 17:51 ` Tom Tromey
2020-04-01 20:20 ` Tom Tromey
2020-06-18 14:14 ` Tom Tromey
2020-06-18 15:04 ` Eli Zaretskii
2020-06-18 16:00 ` Tom Tromey
2020-06-18 17:27 ` Eli Zaretskii
2020-06-18 17:32 ` Pedro Alves
2020-06-18 17:54 ` Eli Zaretskii
2020-06-19 12:02 ` Pedro Alves
2020-06-19 12:13 ` Eli Zaretskii
2020-06-19 17:09 ` Tom Tromey
2020-06-19 20:24 ` Tom Tromey
2020-06-19 23:05 ` Pedro Alves
2020-07-21 19:39 ` Tom Tromey
2020-07-28 19:31 ` Tom Tromey
2020-08-13 12:15 ` Tom de Vries
2020-08-14 23:40 ` Joel Brobecker
2020-08-23 16:09 ` Joel Brobecker
2020-08-23 23:32 ` Pedro Alves
2020-08-24 20:04 ` Joel Brobecker
2020-09-02 14:45 ` Tom Tromey
2020-09-02 14:59 ` Joel Brobecker
2020-06-18 17:57 ` Tom Tromey
2020-01-14 22:13 ` [PATCH 3/3] Further simplify gdb BFD caching Tom Tromey
2020-01-23 22:30 ` Tom Tromey
2020-09-02 18:45 ` Tom Tromey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAPTJ0XEs3=gy0sX=pOBCpfNr_=VDH6gv5NmH-hx_Z6Vu56Viqg@mail.gmail.com' \
--to=gdb-patches@sourceware.org \
--cc=cbiesinger@google.com \
--cc=tromey@adacore.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox