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-next>] [day] [month] [year] [list]
Message-Id: <201201172345.15010.rjw@sisk.pl>
Date:	Tue, 17 Jan 2012 23:45:14 +0100
From:	"Rafael J. Wysocki" <rjw@...k.pl>
To:	Linux PM list <linux-pm@...r.kernel.org>
Cc:	"Srivatsa S. Bhat" <srivatsa.bhat@...ux.vnet.ibm.com>,
	LKML <linux-kernel@...r.kernel.org>
Subject: [PATCH] PM / Hibernate: Fix s2disk regression related to unlock_system_sleep()

From: Rafael J. Wysocki <rjw@...k.pl>

Commit bcda53faf5814c0c6025a0bd47108adfcbe9f199, "PM / Sleep: Replace
mutex_[un]lock(&pm_mutex) with [un]lock_system_sleep()", modified
snapshot_read() and snapshot_write() in kernel/power/user.c, among
other things, by making them use lock_system_sleep() and
unlock_system_sleep() instead of just locking and unlocking pm_mutex.
Unfortunately, however, this was a mistake, because these routines
are supposed to be executed after processes have been frozen
(i.e. when system_freezing_cnt is nonzero), so when
unlock_system_sleep() is executed by one of them, this causes the
caller to execute try_to_freeze() and go into the refrigerator as
a result.  This, in turn, deadlocks the suspend process and locks up
the system.

Fix the problem by reverting the part of commit bcda53faf5814c0c6025a
that changed snapshot_read() and snapshot_write().  Additionally,
make these functions check system_freezing_cnt and return error codes
if it is zero to ensure that they won't do anything if tasks have not
been frozen.

Signed-off-by: Rafael J. Wysocki <rjw@...k.pl>
---
 kernel/power/user.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

Index: linux/kernel/power/user.c
===================================================================
--- linux.orig/kernel/power/user.c
+++ linux/kernel/power/user.c
@@ -137,7 +137,10 @@ static ssize_t snapshot_read(struct file
 	ssize_t res;
 	loff_t pg_offp = *offp & ~PAGE_MASK;
 
-	lock_system_sleep();
+	if (!atomic_read(&system_freezing_cnt))
+		return -EBUSY;
+
+	mutex_lock(&pm_mutex);
 
 	data = filp->private_data;
 	if (!data->ready) {
@@ -158,7 +161,7 @@ static ssize_t snapshot_read(struct file
 		*offp += res;
 
  Unlock:
-	unlock_system_sleep();
+	mutex_unlock(&pm_mutex);
 
 	return res;
 }
@@ -170,7 +173,10 @@ static ssize_t snapshot_write(struct fil
 	ssize_t res;
 	loff_t pg_offp = *offp & ~PAGE_MASK;
 
-	lock_system_sleep();
+	if (!atomic_read(&system_freezing_cnt))
+		return -EBUSY;
+
+	mutex_lock(&pm_mutex);
 
 	data = filp->private_data;
 
@@ -187,7 +193,7 @@ static ssize_t snapshot_write(struct fil
 	if (res > 0)
 		*offp += res;
 unlock:
-	unlock_system_sleep();
+	mutex_unlock(&pm_mutex);
 
 	return res;
 }
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ