aboutsummaryrefslogtreecommitdiffstats
path: root/include/sound
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2014-06-11 18:44:04 +0000
committerBen Hutchings <ben@decadent.org.uk>2014-07-11 13:33:51 +0100
commitb5177f732041aa39e3bfd6bb2e5f43e04e76a4a5 (patch)
tree75890e898eeb6400e0cbff115e014ea406d85fdf /include/sound
parentfaeac1e13e52a0d44c5cb32bf69ad3fe47070560 (diff)
downloadkernel_samsung_smdk4412-b5177f732041aa39e3bfd6bb2e5f43e04e76a4a5.zip
kernel_samsung_smdk4412-b5177f732041aa39e3bfd6bb2e5f43e04e76a4a5.tar.gz
kernel_samsung_smdk4412-b5177f732041aa39e3bfd6bb2e5f43e04e76a4a5.tar.bz2
rtmutex: Plug slow unlock race
commit 27e35715df54cbc4f2d044f681802ae30479e7fb upstream. When the rtmutex fast path is enabled the slow unlock function can create the following situation: spin_lock(foo->m->wait_lock); foo->m->owner = NULL; rt_mutex_lock(foo->m); <-- fast path free = atomic_dec_and_test(foo->refcnt); rt_mutex_unlock(foo->m); <-- fast path if (free) kfree(foo); spin_unlock(foo->m->wait_lock); <--- Use after free. Plug the race by changing the slow unlock to the following scheme: while (!rt_mutex_has_waiters(m)) { /* Clear the waiters bit in m->owner */ clear_rt_mutex_waiters(m); owner = rt_mutex_owner(m); spin_unlock(m->wait_lock); if (cmpxchg(m->owner, owner, 0) == owner) return; spin_lock(m->wait_lock); } So in case of a new waiter incoming while the owner tries the slow path unlock we have two situations: unlock(wait_lock); lock(wait_lock); cmpxchg(p, owner, 0) == owner mark_rt_mutex_waiters(lock); acquire(lock); Or: unlock(wait_lock); lock(wait_lock); mark_rt_mutex_waiters(lock); cmpxchg(p, owner, 0) != owner enqueue_waiter(); unlock(wait_lock); lock(wait_lock); wakeup_next waiter(); unlock(wait_lock); lock(wait_lock); acquire(lock); If the fast path is disabled, then the simple m->owner = NULL; unlock(m->wait_lock); is sufficient as all access to m->owner is serialized via m->wait_lock; Also document and clarify the wakeup_next_waiter function as suggested by Oleg Nesterov. Reported-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Steven Rostedt <rostedt@goodmis.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/20140611183852.937945560@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de> [bwh: Backported to 3.2: adjust filename] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'include/sound')
0 files changed, 0 insertions, 0 deletions