aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c31
1 files changed, 15 insertions, 16 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index 9968c5fb55b9..877fe4f8e05e 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -8,7 +8,6 @@
8#include <linux/mm.h> 8#include <linux/mm.h>
9#include <linux/utsname.h> 9#include <linux/utsname.h>
10#include <linux/mman.h> 10#include <linux/mman.h>
11#include <linux/smp_lock.h>
12#include <linux/notifier.h> 11#include <linux/notifier.h>
13#include <linux/reboot.h> 12#include <linux/reboot.h>
14#include <linux/prctl.h> 13#include <linux/prctl.h>
@@ -163,6 +162,7 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)
163 if (niceval > 19) 162 if (niceval > 19)
164 niceval = 19; 163 niceval = 19;
165 164
165 rcu_read_lock();
166 read_lock(&tasklist_lock); 166 read_lock(&tasklist_lock);
167 switch (which) { 167 switch (which) {
168 case PRIO_PROCESS: 168 case PRIO_PROCESS:
@@ -190,16 +190,17 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)
190 !(user = find_user(who))) 190 !(user = find_user(who)))
191 goto out_unlock; /* No processes for this user */ 191 goto out_unlock; /* No processes for this user */
192 192
193 do_each_thread(g, p) 193 do_each_thread(g, p) {
194 if (__task_cred(p)->uid == who) 194 if (__task_cred(p)->uid == who)
195 error = set_one_prio(p, niceval, error); 195 error = set_one_prio(p, niceval, error);
196 while_each_thread(g, p); 196 } while_each_thread(g, p);
197 if (who != cred->uid) 197 if (who != cred->uid)
198 free_uid(user); /* For find_user() */ 198 free_uid(user); /* For find_user() */
199 break; 199 break;
200 } 200 }
201out_unlock: 201out_unlock:
202 read_unlock(&tasklist_lock); 202 read_unlock(&tasklist_lock);
203 rcu_read_unlock();
203out: 204out:
204 return error; 205 return error;
205} 206}
@@ -221,6 +222,7 @@ SYSCALL_DEFINE2(getpriority, int, which, int, who)
221 if (which > PRIO_USER || which < PRIO_PROCESS) 222 if (which > PRIO_USER || which < PRIO_PROCESS)
222 return -EINVAL; 223 return -EINVAL;
223 224
225 rcu_read_lock();
224 read_lock(&tasklist_lock); 226 read_lock(&tasklist_lock);
225 switch (which) { 227 switch (which) {
226 case PRIO_PROCESS: 228 case PRIO_PROCESS:
@@ -253,19 +255,20 @@ SYSCALL_DEFINE2(getpriority, int, which, int, who)
253 !(user = find_user(who))) 255 !(user = find_user(who)))
254 goto out_unlock; /* No processes for this user */ 256 goto out_unlock; /* No processes for this user */
255 257
256 do_each_thread(g, p) 258 do_each_thread(g, p) {
257 if (__task_cred(p)->uid == who) { 259 if (__task_cred(p)->uid == who) {
258 niceval = 20 - task_nice(p); 260 niceval = 20 - task_nice(p);
259 if (niceval > retval) 261 if (niceval > retval)
260 retval = niceval; 262 retval = niceval;
261 } 263 }
262 while_each_thread(g, p); 264 } while_each_thread(g, p);
263 if (who != cred->uid) 265 if (who != cred->uid)
264 free_uid(user); /* for find_user() */ 266 free_uid(user); /* for find_user() */
265 break; 267 break;
266 } 268 }
267out_unlock: 269out_unlock:
268 read_unlock(&tasklist_lock); 270 read_unlock(&tasklist_lock);
271 rcu_read_unlock();
269 272
270 return retval; 273 return retval;
271} 274}
@@ -349,6 +352,9 @@ void kernel_power_off(void)
349 machine_power_off(); 352 machine_power_off();
350} 353}
351EXPORT_SYMBOL_GPL(kernel_power_off); 354EXPORT_SYMBOL_GPL(kernel_power_off);
355
356static DEFINE_MUTEX(reboot_mutex);
357
352/* 358/*
353 * Reboot system call: for obvious reasons only root may call it, 359 * Reboot system call: for obvious reasons only root may call it,
354 * and even root needs to set up some magic numbers in the registers 360 * and even root needs to set up some magic numbers in the registers
@@ -381,7 +387,7 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
381 if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off) 387 if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
382 cmd = LINUX_REBOOT_CMD_HALT; 388 cmd = LINUX_REBOOT_CMD_HALT;
383 389
384 lock_kernel(); 390 mutex_lock(&reboot_mutex);
385 switch (cmd) { 391 switch (cmd) {
386 case LINUX_REBOOT_CMD_RESTART: 392 case LINUX_REBOOT_CMD_RESTART:
387 kernel_restart(NULL); 393 kernel_restart(NULL);
@@ -397,20 +403,18 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
397 403
398 case LINUX_REBOOT_CMD_HALT: 404 case LINUX_REBOOT_CMD_HALT:
399 kernel_halt(); 405 kernel_halt();
400 unlock_kernel();
401 do_exit(0); 406 do_exit(0);
402 panic("cannot halt"); 407 panic("cannot halt");
403 408
404 case LINUX_REBOOT_CMD_POWER_OFF: 409 case LINUX_REBOOT_CMD_POWER_OFF:
405 kernel_power_off(); 410 kernel_power_off();
406 unlock_kernel();
407 do_exit(0); 411 do_exit(0);
408 break; 412 break;
409 413
410 case LINUX_REBOOT_CMD_RESTART2: 414 case LINUX_REBOOT_CMD_RESTART2:
411 if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) { 415 if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) {
412 unlock_kernel(); 416 ret = -EFAULT;
413 return -EFAULT; 417 break;
414 } 418 }
415 buffer[sizeof(buffer) - 1] = '\0'; 419 buffer[sizeof(buffer) - 1] = '\0';
416 420
@@ -433,7 +437,7 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
433 ret = -EINVAL; 437 ret = -EINVAL;
434 break; 438 break;
435 } 439 }
436 unlock_kernel(); 440 mutex_unlock(&reboot_mutex);
437 return ret; 441 return ret;
438} 442}
439 443
@@ -567,11 +571,6 @@ static int set_user(struct cred *new)
567 if (!new_user) 571 if (!new_user)
568 return -EAGAIN; 572 return -EAGAIN;
569 573
570 if (!task_can_switch_user(new_user, current)) {
571 free_uid(new_user);
572 return -EINVAL;
573 }
574
575 if (atomic_read(&new_user->processes) >= 574 if (atomic_read(&new_user->processes) >=
576 current->signal->rlim[RLIMIT_NPROC].rlim_cur && 575 current->signal->rlim[RLIMIT_NPROC].rlim_cur &&
577 new_user != INIT_USER) { 576 new_user != INIT_USER) {