stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg KH <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: torvalds@linux-foundation.org, akpm@linux-foundation.org,
	alan@lxorguk.ukuu.org.uk, rjw@sisk.pl, valdis.kletnieks@vt.edu,
	cloos@hjcloos.com, riesebie@lxtec.de,
	penguin-kernel@i-love.sakura.ne.jp,
	srivatsa.bhat@linux.vnet.ibm.com
Subject: [ 33/34] PM / Sleep: Fix freezer failures due to racy usermodehelper_is_disabled()
Date: Thu, 01 Mar 2012 13:39:55 -0800	[thread overview]
Message-ID: <20120301213927.606796177@linuxfoundation.org> (raw)
In-Reply-To: <20120301214654.GA13231@kroah.com>

2.6.32-longterm review patch.  If anyone has any objections, please let me know.

------------------


From: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>

[ Upstream commit b298d289c79211508f11cb50749b0d1d54eb244a ]

Commit a144c6a (PM: Print a warning if firmware is requested when tasks
are frozen) introduced usermodehelper_is_disabled() to warn and exit
immediately if firmware is requested when usermodehelpers are disabled.

However, it is racy. Consider the following scenario, currently used in
drivers/base/firmware_class.c:

...
if (usermodehelper_is_disabled())
        goto out;

/* Do actual work */
...

out:
        return err;

Nothing prevents someone from disabling usermodehelpers just after the check
in the 'if' condition, which means that it is quite possible to try doing the
"actual work" with usermodehelpers disabled, leading to undesirable
consequences.

In particular, this race condition in _request_firmware() causes task freezing
failures whenever suspend/hibernation is in progress because, it wrongly waits
to get the firmware/microcode image from userspace when actually the
usermodehelpers are disabled or userspace has been frozen.
Some of the example scenarios that cause freezing failures due to this race
are those that depend on userspace via request_firmware(), such as x86
microcode module initialization and microcode image reload.

Previous discussions about this issue can be found at:
http://thread.gmane.org/gmane.linux.kernel/1198291/focus=1200591

This patch adds proper synchronization to fix this issue.

It is to be noted that this patchset fixes the freezing failures but doesn't
remove the warnings. IOW, it does not attempt to add explicit synchronization
to x86 microcode driver to avoid requesting microcode image at inopportune
moments. Because, the warnings were introduced to highlight such cases, in the
first place. And we need not silence the warnings, since we take care of the
*real* problem (freezing failure) and hence, after that, the warnings are
pretty harmless anyway.

Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---

 drivers/base/firmware_class.c |    3 +++
 include/linux/kmod.h          |    4 ++++
 kernel/kmod.c                 |   24 +++++++++++++++++++++++-
 3 files changed, 30 insertions(+), 1 deletion(-)

--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -508,6 +508,8 @@ _request_firmware(const struct firmware
 		return 0;
 	}
 
+	read_lock_usermodehelper();
+
 	if (WARN_ON(usermodehelper_is_disabled())) {
 		dev_err(device, "firmware: %s will not be loaded\n", name);
 		retval = -EBUSY;
@@ -551,6 +553,7 @@ error_kfree_fw:
 	kfree(firmware);
 	*firmware_p = NULL;
 out:
+	read_unlock_usermodehelper();
 	return retval;
 }
 
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -108,8 +108,12 @@ extern int call_usermodehelper_pipe(char
 extern int usermodehelper_disable(void);
 extern void usermodehelper_enable(void);
 extern bool usermodehelper_is_disabled(void);
+extern void read_lock_usermodehelper(void);
+extern void read_unlock_usermodehelper(void);
 #else
 static inline bool usermodehelper_is_disabled(void) { return false; }
+static inline void read_lock_usermodehelper(void) {}
+static inline void read_unlock_usermodehelper(void) {}
 #endif
 
 #endif /* __LINUX_KMOD_H__ */
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -35,6 +35,7 @@
 #include <linux/resource.h>
 #include <linux/notifier.h>
 #include <linux/suspend.h>
+#include <linux/rwsem.h>
 #include <asm/uaccess.h>
 
 #include <trace/events/module.h>
@@ -43,6 +44,8 @@ extern int max_threads;
 
 static struct workqueue_struct *khelper_wq;
 
+static DECLARE_RWSEM(umhelper_sem);
+
 #ifdef CONFIG_MODULES
 
 /*
@@ -286,6 +289,7 @@ static void __call_usermodehelper(struct
  * If set, call_usermodehelper_exec() will exit immediately returning -EBUSY
  * (used for preventing user land processes from being created after the user
  * land has been frozen during a system-wide hibernation or suspend operation).
+ * Should always be manipulated under umhelper_sem acquired for write.
  */
 static int usermodehelper_disabled;
 
@@ -304,6 +308,18 @@ static DECLARE_WAIT_QUEUE_HEAD(running_h
  */
 #define RUNNING_HELPERS_TIMEOUT	(5 * HZ)
 
+void read_lock_usermodehelper(void)
+{
+	down_read(&umhelper_sem);
+}
+EXPORT_SYMBOL_GPL(read_lock_usermodehelper);
+
+void read_unlock_usermodehelper(void)
+{
+	up_read(&umhelper_sem);
+}
+EXPORT_SYMBOL_GPL(read_unlock_usermodehelper);
+
 /**
  * usermodehelper_disable - prevent new helpers from being started
  */
@@ -311,8 +327,10 @@ int usermodehelper_disable(void)
 {
 	long retval;
 
+	down_write(&umhelper_sem);
 	usermodehelper_disabled = 1;
-	smp_mb();
+	up_write(&umhelper_sem);
+
 	/*
 	 * From now on call_usermodehelper_exec() won't start any new
 	 * helpers, so it is sufficient if running_helpers turns out to
@@ -325,7 +343,9 @@ int usermodehelper_disable(void)
 	if (retval)
 		return 0;
 
+	down_write(&umhelper_sem);
 	usermodehelper_disabled = 0;
+	up_write(&umhelper_sem);
 	return -EAGAIN;
 }
 
@@ -334,7 +354,9 @@ int usermodehelper_disable(void)
  */
 void usermodehelper_enable(void)
 {
+	down_write(&umhelper_sem);
 	usermodehelper_disabled = 0;
+	up_write(&umhelper_sem);
 }
 
 /**



  parent reply	other threads:[~2012-03-01 21:39 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-01 21:46 [ 00/34] 2.6.32.58-longterm review Greg KH
2012-03-01 21:39 ` [ 01/34] drm/i915: no lvds quirk for AOpen MP45 Greg KH
2012-03-01 21:39 ` [ 02/34] hwmon: (f75375s) Fix bit shifting in f75375_write16 Greg KH
2012-03-01 21:39 ` [ 03/34] lib: proportion: lower PROP_MAX_SHIFT to 32 on 64-bit kernel Greg KH
2012-03-05 15:06   ` Jan Kara
2012-03-05 21:31     ` Fengguang Wu
2012-03-06 20:35       ` Jan Kara
2012-03-07  5:14         ` Fengguang Wu
2012-03-01 21:39 ` [ 04/34] relay: prevent integer overflow in relay_open() Greg KH
2012-03-01 21:39 ` [ 05/34] mac80211: timeout a single frame in the rx reorder buffer Greg KH
2012-03-01 21:39 ` [ 06/34] kernel.h: fix wrong usage of __ratelimit() Greg KH
2012-03-01 21:39 ` [ 07/34] printk_ratelimited(): fix uninitialized spinlock Greg KH
2012-03-01 21:39 ` [ 08/34] hwmon: (f75375s) Fix automatic pwm mode setting for F75373 & F75375 Greg KH
2012-03-01 21:39 ` [ 09/34] crypto: sha512 - Use binary and instead of modulus Greg KH
2012-03-01 21:39 ` [ 10/34] crypto: sha512 - Avoid stack bloat on i386 Greg KH
2012-03-01 21:39 ` [ 11/34] eCryptfs: Remove mmap from directory operations Greg KH
2012-03-01 21:39 ` [ 12/34] Ban ecryptfs over ecryptfs Greg KH
2012-03-01 21:39 ` [ 13/34] Add mount option to check uid of device being mounted = expect uid, CVE-2011-1833 Greg KH
2012-03-01 21:39 ` [ 14/34] crypto: sha512 - use standard ror64() Greg KH
2012-03-01 21:39 ` [ 15/34] drm/radeon/kms: fix MSI re-arm on rv370+ Greg KH
2012-03-01 21:39 ` [ 16/34] ecryptfs: read on a directory should return EISDIR if not supported Greg KH
2012-03-01 21:39 ` [ 17/34] SCSI: 3w-9xxx fix bug in sgl loading Greg KH
2012-03-01 21:39 ` [ 18/34] ARM: 7321/1: cache-v7: Disable preemption when reading CCSIDR Greg KH
2012-03-01 21:39 ` [ 19/34] ARM: 7325/1: fix v7 boot with lockdep enabled Greg KH
2012-03-01 21:39 ` [ 20/34] USB: Added Kamstrup VID/PIDs to cp210x serial driver Greg KH
2012-03-01 21:39 ` [ 21/34] USB: Fix handoff when BIOS disables host PCI device Greg KH
2012-03-01 21:39 ` [ 22/34] xhci: Fix encoding for HS bulk/control NAK rate Greg KH
2012-03-01 21:39 ` [ 23/34] [media] hdpvr: fix race conditon during start of streaming Greg KH
2012-03-01 21:39 ` [ 24/34] eCryptfs: Use notify_change for truncating lower inodes Greg KH
2012-03-01 21:39 ` [ 25/34] eCryptfs: Remove extra d_delete in ecryptfs_rmdir Greg KH
2012-03-01 21:39 ` [ 26/34] eCryptfs: Clear i_nlink in rmdir Greg KH
2012-03-01 21:39 ` [ 27/34] cdrom: use copy_to_user() without the underscores Greg KH
2012-03-01 21:39 ` [ 28/34] autofs: work around unhappy compat problem on x86-64 Greg KH
2012-03-01 21:39 ` [ 29/34] Fix autofs compile without CONFIG_COMPAT Greg KH
2012-03-01 21:39 ` [ 30/34] compat: fix compile breakage on s390 Greg KH
2012-03-01 21:39 ` [ 31/34] PM: Print a warning if firmware is requested when tasks are frozen Greg KH
2012-03-01 21:39 ` [ 32/34] firmware loader: allow builtin firmware load even if usermodehelper is disabled Greg KH
2012-03-01 21:39 ` Greg KH [this message]
2012-03-01 21:39 ` [ 34/34] PM / Sleep: Fix read_unlock_usermodehelper() call Greg KH
2012-03-02  7:19 ` [ 00/34] 2.6.32.58-longterm review Willy Tarreau
2012-03-02 13:51   ` Stefan Bader
2012-03-02 15:37   ` Greg KH

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=20120301213927.606796177@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=akpm@linux-foundation.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=cloos@hjcloos.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=penguin-kernel@i-love.sakura.ne.jp \
    --cc=riesebie@lxtec.de \
    --cc=rjw@sisk.pl \
    --cc=srivatsa.bhat@linux.vnet.ibm.com \
    --cc=stable@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    --cc=valdis.kletnieks@vt.edu \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).