diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/exit.c | 1 | ||||
-rw-r--r-- | kernel/module.c | 7 | ||||
-rw-r--r-- | kernel/signal.c | 11 | ||||
-rw-r--r-- | kernel/sysctl.c | 12 |
4 files changed, 26 insertions, 5 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index abf9cf3b95c..036e8d74016 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -1476,6 +1476,7 @@ static int wait_consider_task(struct task_struct *parent, int ptrace, | |||
1476 | */ | 1476 | */ |
1477 | if (*notask_error) | 1477 | if (*notask_error) |
1478 | *notask_error = ret; | 1478 | *notask_error = ret; |
1479 | return 0; | ||
1479 | } | 1480 | } |
1480 | 1481 | ||
1481 | if (likely(!ptrace) && unlikely(p->ptrace)) { | 1482 | if (likely(!ptrace) && unlikely(p->ptrace)) { |
diff --git a/kernel/module.c b/kernel/module.c index e797812a4d9..cb3887e770e 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -72,6 +72,9 @@ DEFINE_MUTEX(module_mutex); | |||
72 | EXPORT_SYMBOL_GPL(module_mutex); | 72 | EXPORT_SYMBOL_GPL(module_mutex); |
73 | static LIST_HEAD(modules); | 73 | static LIST_HEAD(modules); |
74 | 74 | ||
75 | /* Block module loading/unloading? */ | ||
76 | int modules_disabled = 0; | ||
77 | |||
75 | /* Waiting for a module to finish initializing? */ | 78 | /* Waiting for a module to finish initializing? */ |
76 | static DECLARE_WAIT_QUEUE_HEAD(module_wq); | 79 | static DECLARE_WAIT_QUEUE_HEAD(module_wq); |
77 | 80 | ||
@@ -777,7 +780,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user, | |||
777 | char name[MODULE_NAME_LEN]; | 780 | char name[MODULE_NAME_LEN]; |
778 | int ret, forced = 0; | 781 | int ret, forced = 0; |
779 | 782 | ||
780 | if (!capable(CAP_SYS_MODULE)) | 783 | if (!capable(CAP_SYS_MODULE) || modules_disabled) |
781 | return -EPERM; | 784 | return -EPERM; |
782 | 785 | ||
783 | if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0) | 786 | if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0) |
@@ -2336,7 +2339,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, | |||
2336 | int ret = 0; | 2339 | int ret = 0; |
2337 | 2340 | ||
2338 | /* Must have permission */ | 2341 | /* Must have permission */ |
2339 | if (!capable(CAP_SYS_MODULE)) | 2342 | if (!capable(CAP_SYS_MODULE) || modules_disabled) |
2340 | return -EPERM; | 2343 | return -EPERM; |
2341 | 2344 | ||
2342 | /* Only one module load at a time, please */ | 2345 | /* Only one module load at a time, please */ |
diff --git a/kernel/signal.c b/kernel/signal.c index d8034737db4..d2dd9cf5dcc 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -249,14 +249,19 @@ void flush_sigqueue(struct sigpending *queue) | |||
249 | /* | 249 | /* |
250 | * Flush all pending signals for a task. | 250 | * Flush all pending signals for a task. |
251 | */ | 251 | */ |
252 | void __flush_signals(struct task_struct *t) | ||
253 | { | ||
254 | clear_tsk_thread_flag(t, TIF_SIGPENDING); | ||
255 | flush_sigqueue(&t->pending); | ||
256 | flush_sigqueue(&t->signal->shared_pending); | ||
257 | } | ||
258 | |||
252 | void flush_signals(struct task_struct *t) | 259 | void flush_signals(struct task_struct *t) |
253 | { | 260 | { |
254 | unsigned long flags; | 261 | unsigned long flags; |
255 | 262 | ||
256 | spin_lock_irqsave(&t->sighand->siglock, flags); | 263 | spin_lock_irqsave(&t->sighand->siglock, flags); |
257 | clear_tsk_thread_flag(t, TIF_SIGPENDING); | 264 | __flush_signals(t); |
258 | flush_sigqueue(&t->pending); | ||
259 | flush_sigqueue(&t->signal->shared_pending); | ||
260 | spin_unlock_irqrestore(&t->sighand->siglock, flags); | 265 | spin_unlock_irqrestore(&t->sighand->siglock, flags); |
261 | } | 266 | } |
262 | 267 | ||
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index ea78fa101ad..98ecf35d5bf 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -115,6 +115,7 @@ static int ngroups_max = NGROUPS_MAX; | |||
115 | 115 | ||
116 | #ifdef CONFIG_MODULES | 116 | #ifdef CONFIG_MODULES |
117 | extern char modprobe_path[]; | 117 | extern char modprobe_path[]; |
118 | extern int modules_disabled; | ||
118 | #endif | 119 | #endif |
119 | #ifdef CONFIG_CHR_DEV_SG | 120 | #ifdef CONFIG_CHR_DEV_SG |
120 | extern int sg_big_buff; | 121 | extern int sg_big_buff; |
@@ -535,6 +536,17 @@ static struct ctl_table kern_table[] = { | |||
535 | .proc_handler = &proc_dostring, | 536 | .proc_handler = &proc_dostring, |
536 | .strategy = &sysctl_string, | 537 | .strategy = &sysctl_string, |
537 | }, | 538 | }, |
539 | { | ||
540 | .ctl_name = CTL_UNNUMBERED, | ||
541 | .procname = "modules_disabled", | ||
542 | .data = &modules_disabled, | ||
543 | .maxlen = sizeof(int), | ||
544 | .mode = 0644, | ||
545 | /* only handle a transition from default "0" to "1" */ | ||
546 | .proc_handler = &proc_dointvec_minmax, | ||
547 | .extra1 = &one, | ||
548 | .extra2 = &one, | ||
549 | }, | ||
538 | #endif | 550 | #endif |
539 | #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) | 551 | #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) |
540 | { | 552 | { |