|
@@ -36,6 +36,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>
|
|
@@ -50,6 +51,7 @@ static struct workqueue_struct *khelper_wq;
|
|
|
static kernel_cap_t usermodehelper_bset = CAP_FULL_SET;
|
|
|
static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET;
|
|
|
static DEFINE_SPINLOCK(umh_sysctl_lock);
|
|
|
+static DECLARE_RWSEM(umhelper_sem);
|
|
|
|
|
|
#ifdef CONFIG_MODULES
|
|
|
|
|
@@ -275,6 +277,7 @@ static void __call_usermodehelper(struct work_struct *work)
|
|
|
* 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 = 1;
|
|
|
|
|
@@ -293,6 +296,18 @@ static DECLARE_WAIT_QUEUE_HEAD(running_helpers_waitq);
|
|
|
*/
|
|
|
#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
|
|
|
*/
|
|
@@ -300,8 +315,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
|
|
@@ -314,7 +331,9 @@ int usermodehelper_disable(void)
|
|
|
if (retval)
|
|
|
return 0;
|
|
|
|
|
|
+ down_write(&umhelper_sem);
|
|
|
usermodehelper_disabled = 0;
|
|
|
+ up_write(&umhelper_sem);
|
|
|
return -EAGAIN;
|
|
|
}
|
|
|
|
|
@@ -323,7 +342,9 @@ int usermodehelper_disable(void)
|
|
|
*/
|
|
|
void usermodehelper_enable(void)
|
|
|
{
|
|
|
+ down_write(&umhelper_sem);
|
|
|
usermodehelper_disabled = 0;
|
|
|
+ up_write(&umhelper_sem);
|
|
|
}
|
|
|
|
|
|
/**
|