103 lines
3.3 KiB
Diff
103 lines
3.3 KiB
Diff
|
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||
|
From: Tom Tromey <tromey@adacore.com>
|
||
|
Date: Tue, 6 Dec 2022 12:07:12 -0700
|
||
|
Subject: gdb-bz2237515-debuginfod-double-free.patch
|
||
|
|
||
|
;; Backport upstream commit f96328accde1e63 to fix a potential double
|
||
|
;; free issue in the debuginfod code.
|
||
|
|
||
|
Avoid double-free with debuginfod
|
||
|
|
||
|
PR gdb/29257 points out a possible double free when debuginfod is in
|
||
|
use. Aside from some ugly warts in the symbol code (an ongoing
|
||
|
issue), the underlying issue in this particular case is that elfread.c
|
||
|
seems to assume that symfile_bfd_open will return NULL on error,
|
||
|
whereas in reality it throws an exception. As this code isn't
|
||
|
prepared for an exception, bad things result.
|
||
|
|
||
|
This patch fixes the problem by introducing a non-throwing variant of
|
||
|
symfile_bfd_open and using it in the affected places.
|
||
|
|
||
|
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29257
|
||
|
|
||
|
diff --git a/gdb/elfread.c b/gdb/elfread.c
|
||
|
--- a/gdb/elfread.c
|
||
|
+++ b/gdb/elfread.c
|
||
|
@@ -1222,10 +1222,12 @@ elf_symfile_read_dwarf2 (struct objfile *objfile,
|
||
|
|
||
|
if (!debugfile.empty ())
|
||
|
{
|
||
|
- gdb_bfd_ref_ptr debug_bfd (symfile_bfd_open (debugfile.c_str ()));
|
||
|
+ gdb_bfd_ref_ptr debug_bfd
|
||
|
+ (symfile_bfd_open_no_error (debugfile.c_str ()));
|
||
|
|
||
|
- symbol_file_add_separate (debug_bfd, debugfile.c_str (),
|
||
|
- symfile_flags, objfile);
|
||
|
+ if (debug_bfd != nullptr)
|
||
|
+ symbol_file_add_separate (debug_bfd, debugfile.c_str (),
|
||
|
+ symfile_flags, objfile);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
@@ -1245,13 +1247,12 @@ elf_symfile_read_dwarf2 (struct objfile *objfile,
|
||
|
if (fd.get () >= 0)
|
||
|
{
|
||
|
/* File successfully retrieved from server. */
|
||
|
- gdb_bfd_ref_ptr debug_bfd (symfile_bfd_open (symfile_path.get ()));
|
||
|
+ gdb_bfd_ref_ptr debug_bfd
|
||
|
+ (symfile_bfd_open_no_error (symfile_path.get ()));
|
||
|
|
||
|
- if (debug_bfd == nullptr)
|
||
|
- warning (_("File \"%s\" from debuginfod cannot be opened as bfd"),
|
||
|
- filename);
|
||
|
- else if (build_id_verify (debug_bfd.get (), build_id->size,
|
||
|
- build_id->data))
|
||
|
+ if (debug_bfd != nullptr
|
||
|
+ && build_id_verify (debug_bfd.get (), build_id->size,
|
||
|
+ build_id->data))
|
||
|
{
|
||
|
symbol_file_add_separate (debug_bfd, symfile_path.get (),
|
||
|
symfile_flags, objfile);
|
||
|
diff --git a/gdb/symfile.c b/gdb/symfile.c
|
||
|
--- a/gdb/symfile.c
|
||
|
+++ b/gdb/symfile.c
|
||
|
@@ -1744,6 +1744,23 @@ symfile_bfd_open (const char *name)
|
||
|
return sym_bfd;
|
||
|
}
|
||
|
|
||
|
+/* See symfile.h. */
|
||
|
+
|
||
|
+gdb_bfd_ref_ptr
|
||
|
+symfile_bfd_open_no_error (const char *name) noexcept
|
||
|
+{
|
||
|
+ try
|
||
|
+ {
|
||
|
+ return symfile_bfd_open (name);
|
||
|
+ }
|
||
|
+ catch (const gdb_exception_error &err)
|
||
|
+ {
|
||
|
+ warning ("%s", err.what ());
|
||
|
+ }
|
||
|
+
|
||
|
+ return nullptr;
|
||
|
+}
|
||
|
+
|
||
|
/* Return the section index for SECTION_NAME on OBJFILE. Return -1 if
|
||
|
the section was not found. */
|
||
|
|
||
|
diff --git a/gdb/symfile.h b/gdb/symfile.h
|
||
|
--- a/gdb/symfile.h
|
||
|
+++ b/gdb/symfile.h
|
||
|
@@ -269,6 +269,11 @@ extern void set_initial_language (void);
|
||
|
|
||
|
extern gdb_bfd_ref_ptr symfile_bfd_open (const char *);
|
||
|
|
||
|
+/* Like symfile_bfd_open, but will not throw an exception on error.
|
||
|
+ Instead, it issues a warning and returns nullptr. */
|
||
|
+
|
||
|
+extern gdb_bfd_ref_ptr symfile_bfd_open_no_error (const char *) noexcept;
|
||
|
+
|
||
|
extern int get_section_index (struct objfile *, const char *);
|
||
|
|
||
|
extern int print_symbol_loading_p (int from_tty, int mainline, int full);
|