From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 30A0E385734D; Thu, 23 Jun 2022 13:53:44 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 30A0E385734D From: "mhov at undo dot io" To: gdb-prs@sourceware.org Subject: [Bug gdb/29257] Double free of demangled symbol name Date: Thu, 23 Jun 2022 13:53:43 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gdb X-Bugzilla-Component: gdb X-Bugzilla-Version: 10.1 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: mhov at undo dot io X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned at sourceware dot org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://sourceware.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gdb-prs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-prs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 23 Jun 2022 13:53:44 -0000 https://sourceware.org/bugzilla/show_bug.cgi?id=3D29257 --- Comment #3 from Magne Hov --- Turns out that this is caused by a truncated separate debug info file provi= ded by debuginfod. --- Reproduction details: ------------------------ // lib.cpp: void foo(void) {} ------------------------ // main.cpp: void foo(void); int main(void) { foo(); return 0; } ------------------------ # Makefile all: c++ -shared lib.cpp -o libtest.so c++ -L. main.cpp -ltest -o test ------------------------ Check the Build ID of libtest.so and populate an empty debuginfo file in the debuginfod cache: $ mkdir -p /home/mhov/.cache/debuginfod_client/cac153df26d5e817739e1b234746cb368da0566= 4/ $ touch /home/mhov/.cache/debuginfod_client/cac153df26d5e817739e1b234746cb368da0566= 4/debuginfo Now launch the program in GDB and see that it fail to load the separate deb= ug info file. Do a set solib-search-path to trigger a reload of the libraries,= and see glibc complain: $ LD_LIBRARY_PATH=3D. DEBUGINFOD_URLS=3Dfoo gdb --silent ./test Reading symbols from ./test... Download failed: No route to host. Continuing without debug info for /home/mhov/work/GDB29257/./test. (No debugging symbols found in ./test) (gdb) start Temporary breakpoint 1 at 0x1151 Starting program: /home/mhov/work/GDB29257/test Download failed: No route to host. Continuing without debug info for /home/mhov/work/GDB29257/system-supplied DSO at 0x7ffff7fce000. Error while reading shared library symbols for ./libtest.so: `/home/mhov/.cache/debuginfod_client/cac153df26d5e817739e1b234746cb368da056= 64/debuginfo': can't read symbols: file format not recognized. Temporary breakpoint 1, 0x0000555555555151 in main () (gdb) set solib-search-path Reading symbols from ./libtest.so... Error while reading shared library symbols for ./libtest.so: `/home/mhov/.cache/debuginfod_client/cac153df26d5e817739e1b234746cb368da056= 64/debuginfo': can't read symbols: file format not recognized. Reading symbols from ./libtest.so... free(): double free detected in tcache 2 Aborted (core dumped) Sometime I must run set solib-search-path multiple times, and glibc reports different failure modes. --- Analysis: When opening a separate debug file via Build ID we normally verify its buil= d id after opening it: https://sourceware.org/git/?p=3Dbinutils-gdb.git;a=3Dblob;f=3Dgdb/build-id.= c;hb=3Dce35d7163e779b1321058b22f005c70ce1524b25#l107 This is part of `find_separate_debug_file_by_buildid`, so if it returns a v= alid string (path) we can be fairly sure that the object is somewhat valid and i= t's safe to pass it to `symfile_bfd_open`. When a build id file has been provided by debuginfod, however, we don't use `find_separate_debug_file_by_buildid`, and we first check it with `build_id_verify` after already having tried to open it with `symfile_bfd_open`. https://sourceware.org/git/?p=3Dbinutils-gdb.git;a=3Dblob;f=3Dgdb/elfread.c= ;hb=3Dce35d7163e779b1321058b22f005c70ce1524b25#l1329 This means that the failure modes of a truncated separate debug info file a= re different depending on whether the debug info file was found "locally" or v= ia the debuginfod cache. - For the "local" case the failure mode is that `find_separate_debug_file_by_buildid` returns an empty string. - For the debuginfod case the failure mode is that `symfile_bfd_open` raise= s an exception. The exception is caught here: https://sourceware.org/git/?p=3Dbinutils-gdb.git;a=3Dblob;f=3Dgdb/solib.c;h= b=3Dce35d7163e779b1321058b22f005c70ce1524b25#l696 That means that we got interrupted at this point in the sequence of loading symbols: ``` solib_read_symbols ... read_symbols elf_symfile_read elf_read_minimal_symbols (this function completes fully) symfile_bfd_open (for separate debug file fetched by debuginfod) throw (exception is thrown due to truncated separate debug file) (this is where minsyms_read would have been set, but it's skipped by the non-local exit) catch exception ``` Since elf_read_minimal_symbols completed successfully we have in fact read = in minimal symbols. However, the exception that is caused by the truncated separate debug file prevents read_symbols from tracking this in objfile->per_bfd->minsyms_read. --- Ideas of ways to fix this: - Change the order of `symbfile_bfd_open` and `build_id_verify` for files provided from debuginfod. This would prevent `symfile_bfd_open` from being called with a corrupt file and thus prevent the exception from being raised. - Catch this kind of exception when trying to open the file provided from debuginfod. - Mark minimal symbols as read (objfile->per_bfd->minsyms_read =3D true) as= soon as elf_read_minimal_symbols has completed. I'm not confident about this. Th= ere could be some other state that must also have been completed before we want= to set this to true? --=20 You are receiving this mail because: You are on the CC list for the bug.=