Bug 20973 - robust mutexes: Lost wake-ups
Summary: robust mutexes: Lost wake-ups
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: nptl (show other bugs)
Version: 2.25
: P2 normal
Target Milestone: 2.25
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-12-15 22:07 UTC by Torvald Riegel
Modified: 2017-10-18 15:51 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Torvald Riegel 2016-12-15 22:07:24 UTC
Assume that Thread 1 waits to acquire a robust mutex using futexes to block (and thus sets the FUTEX_WAITERS flag), and is unblocked when this mutex is released.  If Thread 2 concurrently acquires the lock and is killed, Thread 1 can recover from the died owner but fail to restore the FUTEX_WAITERS flag.  This can lead to a Thread 3 that also blocked using futexes at the same time as Thread 1 to not get woken up because FUTEX_WAITERS is not set anymore.

This has been previously reported here:
https://bugzilla.redhat.com/show_bug.cgi?id=1401665
That BZ also contains a testcase.
Comment 1 cvs-commit@gcc.gnu.org 2016-12-19 19:13:11 UTC
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  353683a22ed8a493a6bd1d78d63e144bc3e85d2f (commit)
      from  da16c9b524908fe0353efc4af8eab6a5ad5ea50b (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=353683a22ed8a493a6bd1d78d63e144bc3e85d2f

commit 353683a22ed8a493a6bd1d78d63e144bc3e85d2f
Author: Torvald Riegel <triegel@redhat.com>
Date:   Thu Dec 15 16:06:28 2016 +0100

    Robust mutexes: Fix lost wake-up.
    
    Assume that Thread 1 waits to acquire a robust mutex using futexes to
    block (and thus sets the FUTEX_WAITERS flag), and is unblocked when this
    mutex is released.  If Thread 2 concurrently acquires the lock and is
    killed, Thread 1 can recover from the died owner but fail to restore the
    FUTEX_WAITERS flag.  This can lead to a Thread 3 that also blocked using
    futexes at the same time as Thread 1 to not get woken up because
    FUTEX_WAITERS is not set anymore.
    
    The fix for this is to ensure that we continue to preserve the
    FUTEX_WAITERS flag whenever we may have set it or shared it with another
    thread.  This is the same requirement as in the algorithm for normal
    mutexes, only that the robust mutexes need additional handling for died
    owners and thus preserving the FUTEX_WAITERS flag cannot be done just in
    the futex slowpath code.
    
    	[BZ #20973]
    	* nptl/pthread_mutex_lock.c (__pthread_mutex_lock_full): Fix lost
    	wake-up in robust mutexes.
    	* nptl/pthread_mutex_timedlock.c (pthread_mutex_timedlock): Likewise.

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                      |    7 +++++++
 nptl/pthread_mutex_lock.c      |   15 +++++++++++++--
 nptl/pthread_mutex_timedlock.c |   14 ++++++++++++--
 3 files changed, 32 insertions(+), 4 deletions(-)
Comment 2 Carlos O'Donell 2016-12-20 00:06:28 UTC
Just noting that even with this fix we still have intermittent hangs in tst-robust8 (bug 19004), but that's to be expected since we haven't fixed all the issues.
Comment 3 Torvald Riegel 2016-12-20 14:04:27 UTC
This particular bug is now fixed upstream, though as Carlos notes, there are more in this space.