From: tip-bot for Brian Silverman <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: bsilver16384@gmail.com, hpa@zytor.com,
linux-kernel@vger.kernel.org, tglx@linutronix.de,
mingo@kernel.org
Subject: [tip:locking/urgent] futex: Fix a race condition between REQUEUE_PI and task death
Date: Sun, 26 Oct 2014 08:22:46 -0700 [thread overview]
Message-ID: <tip-30a6b8031fe14031ab27c1fa3483cb9780e7f63c@git.kernel.org> (raw)
In-Reply-To: <1414282837-23092-1-git-send-email-bsilver16384@gmail.com>
Commit-ID: 30a6b8031fe14031ab27c1fa3483cb9780e7f63c
Gitweb: http://git.kernel.org/tip/30a6b8031fe14031ab27c1fa3483cb9780e7f63c
Author: Brian Silverman <bsilver16384@gmail.com>
AuthorDate: Sat, 25 Oct 2014 20:20:37 -0400
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 26 Oct 2014 16:16:18 +0100
futex: Fix a race condition between REQUEUE_PI and task death
free_pi_state and exit_pi_state_list both clean up futex_pi_state's.
exit_pi_state_list takes the hb lock first, and most callers of
free_pi_state do too. requeue_pi doesn't, which means free_pi_state
can free the pi_state out from under exit_pi_state_list. For example:
task A | task B
exit_pi_state_list |
pi_state = |
curr->pi_state_list->next |
| futex_requeue(requeue_pi=1)
| // pi_state is the same as
| // the one in task A
| free_pi_state(pi_state)
| list_del_init(&pi_state->list)
| kfree(pi_state)
list_del_init(&pi_state->list) |
Move the free_pi_state calls in requeue_pi to before it drops the hb
locks which it's already holding.
[ tglx: Removed a pointless free_pi_state() call and the hb->lock held
debugging. The latter comes via a seperate patch ]
Signed-off-by: Brian Silverman <bsilver16384@gmail.com>
Cc: austin.linux@gmail.com
Cc: darren@dvhart.com
Cc: peterz@infradead.org
Cc: stable@vger.kernel.org
Link: http://lkml.kernel.org/r/1414282837-23092-1-git-send-email-bsilver16384@gmail.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/futex.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/kernel/futex.c b/kernel/futex.c
index bbf071f..63678b5 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -647,8 +647,14 @@ static struct futex_pi_state * alloc_pi_state(void)
return pi_state;
}
+/*
+ * Must be called with the hb lock held.
+ */
static void free_pi_state(struct futex_pi_state *pi_state)
{
+ if (!pi_state)
+ return;
+
if (!atomic_dec_and_test(&pi_state->refcount))
return;
@@ -1527,15 +1533,6 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags,
}
retry:
- if (pi_state != NULL) {
- /*
- * We will have to lookup the pi_state again, so free this one
- * to keep the accounting correct.
- */
- free_pi_state(pi_state);
- pi_state = NULL;
- }
-
ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1, VERIFY_READ);
if (unlikely(ret != 0))
goto out;
@@ -1625,6 +1622,8 @@ retry_private:
case 0:
break;
case -EFAULT:
+ free_pi_state(pi_state);
+ pi_state = NULL;
double_unlock_hb(hb1, hb2);
hb_waiters_dec(hb2);
put_futex_key(&key2);
@@ -1640,6 +1639,8 @@ retry_private:
* exit to complete.
* - The user space value changed.
*/
+ free_pi_state(pi_state);
+ pi_state = NULL;
double_unlock_hb(hb1, hb2);
hb_waiters_dec(hb2);
put_futex_key(&key2);
@@ -1716,6 +1717,7 @@ retry_private:
}
out_unlock:
+ free_pi_state(pi_state);
double_unlock_hb(hb1, hb2);
hb_waiters_dec(hb2);
@@ -1733,8 +1735,6 @@ out_put_keys:
out_put_key1:
put_futex_key(&key1);
out:
- if (pi_state != NULL)
- free_pi_state(pi_state);
return ret ? ret : task_count;
}
prev parent reply other threads:[~2014-10-26 15:23 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-23 19:22 [PATCH] futex: fix a race condition between REQUEUE_PI and task death Brian Silverman
2014-10-23 19:28 ` Brian Silverman
2014-10-24 5:25 ` Mike Galbraith
2014-10-30 4:28 ` Darren Hart
2014-10-30 5:18 ` Mike Galbraith
2014-10-25 19:29 ` Thomas Gleixner
2014-10-26 0:19 ` Brian Silverman
2014-10-26 14:29 ` Thomas Gleixner
2014-10-26 0:20 ` [PATCH v2] " Brian Silverman
2014-10-26 6:22 ` Mike Galbraith
2014-10-26 14:45 ` Thomas Gleixner
2014-10-26 15:04 ` Thomas Gleixner
2014-10-26 15:22 ` tip-bot for Brian Silverman [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=tip-30a6b8031fe14031ab27c1fa3483cb9780e7f63c@git.kernel.org \
--to=tipbot@zytor.com \
--cc=bsilver16384@gmail.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.