diff options
Diffstat (limited to 'kernel/kmod.c')
-rw-r--r-- | kernel/kmod.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/kernel/kmod.c b/kernel/kmod.c index 2142687094d3..a0a88543934e 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c | |||
@@ -34,6 +34,9 @@ | |||
34 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/resource.h> | 36 | #include <linux/resource.h> |
37 | #include <linux/notifier.h> | ||
38 | #include <linux/suspend.h> | ||
39 | #include <linux/rwsem.h> | ||
37 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
38 | 41 | ||
39 | #include <trace/events/module.h> | 42 | #include <trace/events/module.h> |
@@ -48,6 +51,7 @@ static struct workqueue_struct *khelper_wq; | |||
48 | static kernel_cap_t usermodehelper_bset = CAP_FULL_SET; | 51 | static kernel_cap_t usermodehelper_bset = CAP_FULL_SET; |
49 | static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET; | 52 | static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET; |
50 | static DEFINE_SPINLOCK(umh_sysctl_lock); | 53 | static DEFINE_SPINLOCK(umh_sysctl_lock); |
54 | static DECLARE_RWSEM(umhelper_sem); | ||
51 | 55 | ||
52 | #ifdef CONFIG_MODULES | 56 | #ifdef CONFIG_MODULES |
53 | 57 | ||
@@ -273,6 +277,7 @@ static void __call_usermodehelper(struct work_struct *work) | |||
273 | * If set, call_usermodehelper_exec() will exit immediately returning -EBUSY | 277 | * If set, call_usermodehelper_exec() will exit immediately returning -EBUSY |
274 | * (used for preventing user land processes from being created after the user | 278 | * (used for preventing user land processes from being created after the user |
275 | * land has been frozen during a system-wide hibernation or suspend operation). | 279 | * land has been frozen during a system-wide hibernation or suspend operation). |
280 | * Should always be manipulated under umhelper_sem acquired for write. | ||
276 | */ | 281 | */ |
277 | static int usermodehelper_disabled = 1; | 282 | static int usermodehelper_disabled = 1; |
278 | 283 | ||
@@ -291,6 +296,18 @@ static DECLARE_WAIT_QUEUE_HEAD(running_helpers_waitq); | |||
291 | */ | 296 | */ |
292 | #define RUNNING_HELPERS_TIMEOUT (5 * HZ) | 297 | #define RUNNING_HELPERS_TIMEOUT (5 * HZ) |
293 | 298 | ||
299 | void read_lock_usermodehelper(void) | ||
300 | { | ||
301 | down_read(&umhelper_sem); | ||
302 | } | ||
303 | EXPORT_SYMBOL_GPL(read_lock_usermodehelper); | ||
304 | |||
305 | void read_unlock_usermodehelper(void) | ||
306 | { | ||
307 | up_read(&umhelper_sem); | ||
308 | } | ||
309 | EXPORT_SYMBOL_GPL(read_unlock_usermodehelper); | ||
310 | |||
294 | /** | 311 | /** |
295 | * usermodehelper_disable - prevent new helpers from being started | 312 | * usermodehelper_disable - prevent new helpers from being started |
296 | */ | 313 | */ |
@@ -298,8 +315,10 @@ int usermodehelper_disable(void) | |||
298 | { | 315 | { |
299 | long retval; | 316 | long retval; |
300 | 317 | ||
318 | down_write(&umhelper_sem); | ||
301 | usermodehelper_disabled = 1; | 319 | usermodehelper_disabled = 1; |
302 | smp_mb(); | 320 | up_write(&umhelper_sem); |
321 | |||
303 | /* | 322 | /* |
304 | * From now on call_usermodehelper_exec() won't start any new | 323 | * From now on call_usermodehelper_exec() won't start any new |
305 | * helpers, so it is sufficient if running_helpers turns out to | 324 | * helpers, so it is sufficient if running_helpers turns out to |
@@ -312,7 +331,9 @@ int usermodehelper_disable(void) | |||
312 | if (retval) | 331 | if (retval) |
313 | return 0; | 332 | return 0; |
314 | 333 | ||
334 | down_write(&umhelper_sem); | ||
315 | usermodehelper_disabled = 0; | 335 | usermodehelper_disabled = 0; |
336 | up_write(&umhelper_sem); | ||
316 | return -EAGAIN; | 337 | return -EAGAIN; |
317 | } | 338 | } |
318 | 339 | ||
@@ -321,7 +342,9 @@ int usermodehelper_disable(void) | |||
321 | */ | 342 | */ |
322 | void usermodehelper_enable(void) | 343 | void usermodehelper_enable(void) |
323 | { | 344 | { |
345 | down_write(&umhelper_sem); | ||
324 | usermodehelper_disabled = 0; | 346 | usermodehelper_disabled = 0; |
347 | up_write(&umhelper_sem); | ||
325 | } | 348 | } |
326 | 349 | ||
327 | /** | 350 | /** |