From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16206 invoked by alias); 25 Jun 2014 15:47:15 -0000 Mailing-List: contact glibc-bugs-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: glibc-bugs-owner@sourceware.org Received: (qmail 16123 invoked by uid 48); 25 Jun 2014 15:47:05 -0000 From: "bugdal at aerifal dot cx" To: glibc-bugs@sourceware.org Subject: [Bug nptl/14485] File corruption race condition in robust mutex unlocking Date: Wed, 25 Jun 2014 15:47:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: glibc X-Bugzilla-Component: nptl X-Bugzilla-Version: unspecified X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: bugdal at aerifal dot cx X-Bugzilla-Status: NEW X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned at sourceware dot org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: security- X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://sourceware.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2014-06/txt/msg01576.txt.bz2 https://sourceware.org/bugzilla/show_bug.cgi?id=14485 --- Comment #3 from Rich Felker --- The corruption is performed by the kernel when it walks the robust list. The basic situation is the same as in PR #13690, except that here there's actually a potential write to the memory rather than just a read. The sequence of events leading to corruption goes like this: 1. Thread A unlocks the process-shared, robust mutex and is preempted after the mutex is removed from the robust list and atomically unlocked, but before it's removed from the list_op_pending field of the robust list header. 2. Thread B locks the mutex, and, knowing by program logic that it's the last user of the mutex, unlocks and unmaps it, allocates/maps something else that gets assigned the same address as the shared mutex mapping, and then exits. 3. The kernel destroys the process, which involves walking each thread's robust list and processing each thread's list_op_pending field of the robust list header. Since thread A has a list_op_pending pointing at the address previously occupied by the mutex, the kernel obliviously "unlocks the mutex" by writing a 0 to the address and futex-waking it. However, the kernel has instead overwritten part of whatever mapping thread A created. If this is private memory it (probably) doesn't matter since the process is ending anyway (but are there race conditions where this can be seen?). If this is shared memory or a shared file mapping, however, the kernel corrupts it. I suspect the race is difficult to hit since thread A has to get preempted at exactly the wrong time AND thread B has to do a fair amount of work without thread A getting scheduled again. So I'm not sure how much luck we'd have getting a test case. -- You are receiving this mail because: You are on the CC list for the bug.