From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id C0C993858430; Mon, 26 Feb 2024 15:28:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C0C993858430 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1708961334; bh=Mu1/J/gd8s3XYmoBRLkiCkxC8kVBafHQYti9SSqV4sk=; h=From:To:Subject:Date:In-Reply-To:References:From; b=KfuOd9CMQlxtAydXRlCVSx7h5VsoOxm4zmhIKh8mLj3CVAdF0YJpk91At4Lyt5ZVD nEv5Spest4g9Ye34Z634Ei4rOQdvK0GTJa9e6gIuoQpm9N7ODQAuK8+K8JpwDc0JSk NNytUZUu/YWMww9UUXspnV12A8Ghpze+zy6A6CUw= From: "cvs-commit at gcc dot gnu.org" To: gdb-prs@sourceware.org Subject: [Bug gdb/31259] [gdb] ThreadSanitizer: heap-use-after-free linux-nat.c:2809 in select_event_lwp Date: Mon, 26 Feb 2024 15:28:53 +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: HEAD X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: cvs-commit at gcc dot gnu.org X-Bugzilla-Status: NEW 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 List-Id: https://sourceware.org/bugzilla/show_bug.cgi?id=3D31259 --- Comment #2 from Sourceware Commits --- The master branch has been updated by Pedro Alves : https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D3d2d21728b6d= b4430ff168ee27e12fc6e2627fad commit 3d2d21728b6db4430ff168ee27e12fc6e2627fad Author: Pedro Alves Date: Wed Feb 21 16:23:55 2024 +0000 [gdb] Fix heap-use-after-free in select_event_lwp PR gdb/31259 reveals one scenario where we run into a heap-use-after-free reported by thread sanitizer, while running gdb.base/vfork-follow-parent.exp. The heap-use-after-free happens during the following scenario: - linux_nat_wait_1 is about to return an event for T2. It stops all other threads, and while doing so, stop_wait_callback -> wait_lwp sees T1 exit, and decides to leave the exit event pending. It should have set the lp->stopped flag too, but does not -- this is the bug. - The event for T2 is reported, is processed by infrun, and we're back at linux_nat_wait_1. - linux_nat_wait_1 selects LWP T1 with the pending exit status to report. - it sets variable lp to point to the corresponding lwp_info. - it calls stop_callback and stop_wait_callback for all threads (because !target_is_non_stop_p ()). - it calls select_event_lwp to maybe pick another thread than T1, to prevent starvation. The problem is the following: - while calling stop_wait_callback for all threads, it also does this for T1. While doing so, the corresponding lwp_info is deleted (callstack stop_wait_callback -> wait_lwp -> exit_lwp -> delete_lwp), leaving variable lp as a dangling pointer. - variable lp is passed to select_event_lwp, which derefences it, which causes the heap-use-after-free. Note that the comment here mentions "all other LWP's": ... /* Now stop all other LWP's ... */ iterate_over_lwps (minus_one_ptid, stop_callback); /* ... and wait until all of them have reported back that they're no longer running. */ iterate_over_lwps (minus_one_ptid, stop_wait_callback); ... The reason the comments say "all other LWP's", and doesn't bother filtering out LP is that lp->stopped should be true at this point, and the callbacks (both stop_callback and stop_wait_callback) check that flag, and do nothing if set. I.e., they skip already-stopped threads, so they should skip LP. In this particular scenario, though, we missed setting the stopped flag right in the first step described above, so LP was iterated over incorrectly. The fix is to make wait_lwp set the lp->stopped flag when it decides to leave the exit event pending. However, going a bit further, gdbserver has a mark_lwp_dead function to centralize setting up various lwp flags such that the rest of the code doesn't mishandle them, and it seems like a good idea to do a similar thing in gdb as well. That is what this patch does. PR gdb/31259 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=3D31259 Co-Authored-By: Tom de Vries Change-Id: I4a6169976f89bf714c478cbb2b7d4c32365e62a9 --=20 You are receiving this mail because: You are on the CC list for the bug.=