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] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 28 Jun 2017 18:36:13 +0300
From:   Kirill Tkhai <ktkhai@...tuozzo.com>
To:     Niklas Cassel <niklas.cassel@...s.com>
Cc:     peterz@...radead.org, linux-kernel@...r.kernel.org,
        mingo@...nel.org, stable@...nel.org
Subject: Re: [PATCH] rwsem-spinlock: Fix EINTR branch in __down_write_common()

On Wed, Jun 28, 2017 at 15:20, Niklas Cassel wrote:
> Good catch!
> 
> This should go to -stable as well.
> 
> 
> Perhaps
> 
> if (!list_empty(&sem->wait_list) && sem->count > 0)
> 	__rwsem_do_wake(sem, 0);
> 
> Rather than
> 
> if (!list_empty(&sem->wait_list) && sem->count >= 0)
> 	__rwsem_do_wake(sem, 0);
> 
> Since we have the spinlock, and since we just checked
> if sem->count == 0, we still know that it can't be 0.
> 
> Either way:
> 
> Acked-by: Niklas Cassel <niklas.cassel@...s.com>
> 

[PATCH]rwsem-spinlock: Fix EINTR branch in __down_write_common()

If a writer could been woken up, the above branch

    if (sem->count == 0)
	    break;

would have moved us to taking the sem. So, it's
not the time to wake a writer now, and only readers
are allowed now. Thus, 0 must be passed to __rwsem_do_wake().

Next, __rwsem_do_wake() wakes readers unconditionally.
But we mustn't do that if the sem is owned by writer
in the moment. Otherwise, writer and reader own the sem
the same time, which leads to memory corruption in
callers.

rwsem-xadd.c does not need that, as:
1)the similar check is made lockless there,
2)in __rwsem_mark_wake::try_reader_grant we test,
that sem is not owned by writer.

Fixes: 17fcbd590d0c "locking/rwsem: Fix down_write_killable() for CONFIG_RWSEM_GENERIC_SPINLOCK=y"
Signed-off-by: Kirill Tkhai <ktkhai@...tuozzo.com>
Acked-by: Niklas Cassel <niklas.cassel@...s.com>
CC: Peter Zijlstra (Intel) <peterz@...radead.org>
CC: Ingo Molnar <mingo@...nel.org>
---
 kernel/locking/rwsem-spinlock.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/locking/rwsem-spinlock.c b/kernel/locking/rwsem-spinlock.c
index c65f7989f850..3e6feccb8b56 100644
--- a/kernel/locking/rwsem-spinlock.c
+++ b/kernel/locking/rwsem-spinlock.c
@@ -231,8 +231,8 @@ int __sched __down_write_common(struct rw_semaphore *sem, int state)
 
 out_nolock:
 	list_del(&waiter.list);
-	if (!list_empty(&sem->wait_list))
-		__rwsem_do_wake(sem, 1);
+	if (!list_empty(&sem->wait_list) && sem->count > 0)
+		__rwsem_do_wake(sem, 0);
 	raw_spin_unlock_irqrestore(&sem->wait_lock, flags);
 
 	return -EINTR;

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ