lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:	Sun, 15 May 2016 13:57:40 -0700
From:	tip-bot for Peter Zijlstra <tipbot@...or.com>
To:	linux-tip-commits@...r.kernel.org
Cc:	jcmvbkbc@...il.com, linux-kernel@...r.kernel.org,
	penguin-kernel@...ove.SAKURA.ne.jp, acme@...hat.com,
	Waiman.Long@....com, eranian@...gle.com, mingo@...nel.org,
	tony.luck@...el.com, torvalds@...ux-foundation.org,
	mhocko@...nel.org, tglx@...utronix.de, vincent.weaver@...ne.edu,
	dave@...olabs.net, jolsa@...hat.com, peterz@...radead.org,
	davem@...emloft.net, alexander.shishkin@...ux.intel.com,
	hpa@...or.com, chris@...kel.net, akpm@...ux-foundation.org
Subject: [tip:locking/rwsem] locking/rwsem: Fix down_write_killable()

Commit-ID:  04cafed7fc19a8010771c788708ac97c405fc3de
Gitweb:     http://git.kernel.org/tip/04cafed7fc19a8010771c788708ac97c405fc3de
Author:     Peter Zijlstra <peterz@...radead.org>
AuthorDate: Thu, 12 May 2016 13:57:45 +0200
Committer:  Ingo Molnar <mingo@...nel.org>
CommitDate: Sun, 15 May 2016 22:55:00 +0200

locking/rwsem: Fix down_write_killable()

The new signal_pending exit path in __rwsem_down_write_failed_common()
was fingered as breaking his kernel by Tetsuo Handa.

Upon inspection it was found that there are two things wrong with it;

 - it forgets to remove WAITING_BIAS if it leaves the list empty, or
 - it forgets to wake further waiters that were blocked on the now
   removed waiter.

Especially the first issue causes new lock attempts to block and stall
indefinitely, as the code assumes that pending waiters mean there is
an owner that will wake when it releases the lock.

Reported-by: Tetsuo Handa <penguin-kernel@...ove.SAKURA.ne.jp>
Tested-by: Tetsuo Handa <penguin-kernel@...ove.SAKURA.ne.jp>
Tested-by: Michal Hocko <mhocko@...nel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@...radead.org>
Cc: Alexander Shishkin <alexander.shishkin@...ux.intel.com>
Cc: Andrew Morton <akpm@...ux-foundation.org>
Cc: Arnaldo Carvalho de Melo <acme@...hat.com>
Cc: Chris Zankel <chris@...kel.net>
Cc: David S. Miller <davem@...emloft.net>
Cc: Davidlohr Bueso <dave@...olabs.net>
Cc: H. Peter Anvin <hpa@...or.com>
Cc: Jiri Olsa <jolsa@...hat.com>
Cc: Linus Torvalds <torvalds@...ux-foundation.org>
Cc: Max Filippov <jcmvbkbc@...il.com>
Cc: Peter Zijlstra <peterz@...radead.org>
Cc: Stephane Eranian <eranian@...gle.com>
Cc: Thomas Gleixner <tglx@...utronix.de>
Cc: Tony Luck <tony.luck@...el.com>
Cc: Vince Weaver <vincent.weaver@...ne.edu>
Cc: Waiman Long <Waiman.Long@....com>
Link: http://lkml.kernel.org/r/20160512115745.GP3192@twins.programming.kicks-ass.net
Signed-off-by: Ingo Molnar <mingo@...nel.org>
---
 kernel/locking/rwsem-xadd.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/kernel/locking/rwsem-xadd.c b/kernel/locking/rwsem-xadd.c
index df4dcb8..09e30c6 100644
--- a/kernel/locking/rwsem-xadd.c
+++ b/kernel/locking/rwsem-xadd.c
@@ -487,23 +487,32 @@ __rwsem_down_write_failed_common(struct rw_semaphore *sem, int state)
 
 		/* Block until there are no active lockers. */
 		do {
-			if (signal_pending_state(state, current)) {
-				raw_spin_lock_irq(&sem->wait_lock);
-				ret = ERR_PTR(-EINTR);
-				goto out;
-			}
+			if (signal_pending_state(state, current))
+				goto out_nolock;
+
 			schedule();
 			set_current_state(state);
 		} while ((count = sem->count) & RWSEM_ACTIVE_MASK);
 
 		raw_spin_lock_irq(&sem->wait_lock);
 	}
-out:
 	__set_current_state(TASK_RUNNING);
 	list_del(&waiter.list);
 	raw_spin_unlock_irq(&sem->wait_lock);
 
 	return ret;
+
+out_nolock:
+	__set_current_state(TASK_RUNNING);
+	raw_spin_lock_irq(&sem->wait_lock);
+	list_del(&waiter.list);
+	if (list_empty(&sem->wait_list))
+		rwsem_atomic_update(-RWSEM_WAITING_BIAS, sem);
+	else
+		__rwsem_do_wake(sem, RWSEM_WAKE_ANY);
+	raw_spin_unlock_irq(&sem->wait_lock);
+
+	return ERR_PTR(-EINTR);
 }
 
 __visible struct rw_semaphore * __sched

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ