aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c86
1 files changed, 56 insertions, 30 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index 18da702ec813..e4128b278f23 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -37,6 +37,7 @@
37#include <linux/ptrace.h> 37#include <linux/ptrace.h>
38#include <linux/fs_struct.h> 38#include <linux/fs_struct.h>
39#include <linux/gfp.h> 39#include <linux/gfp.h>
40#include <linux/syscore_ops.h>
40 41
41#include <linux/compat.h> 42#include <linux/compat.h>
42#include <linux/syscalls.h> 43#include <linux/syscalls.h>
@@ -119,16 +120,33 @@ EXPORT_SYMBOL(cad_pid);
119void (*pm_power_off_prepare)(void); 120void (*pm_power_off_prepare)(void);
120 121
121/* 122/*
123 * Returns true if current's euid is same as p's uid or euid,
124 * or has CAP_SYS_NICE to p's user_ns.
125 *
126 * Called with rcu_read_lock, creds are safe
127 */
128static bool set_one_prio_perm(struct task_struct *p)
129{
130 const struct cred *cred = current_cred(), *pcred = __task_cred(p);
131
132 if (pcred->user->user_ns == cred->user->user_ns &&
133 (pcred->uid == cred->euid ||
134 pcred->euid == cred->euid))
135 return true;
136 if (ns_capable(pcred->user->user_ns, CAP_SYS_NICE))
137 return true;
138 return false;
139}
140
141/*
122 * set the priority of a task 142 * set the priority of a task
123 * - the caller must hold the RCU read lock 143 * - the caller must hold the RCU read lock
124 */ 144 */
125static int set_one_prio(struct task_struct *p, int niceval, int error) 145static int set_one_prio(struct task_struct *p, int niceval, int error)
126{ 146{
127 const struct cred *cred = current_cred(), *pcred = __task_cred(p);
128 int no_nice; 147 int no_nice;
129 148
130 if (pcred->uid != cred->euid && 149 if (!set_one_prio_perm(p)) {
131 pcred->euid != cred->euid && !capable(CAP_SYS_NICE)) {
132 error = -EPERM; 150 error = -EPERM;
133 goto out; 151 goto out;
134 } 152 }
@@ -296,8 +314,9 @@ void kernel_restart_prepare(char *cmd)
296{ 314{
297 blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); 315 blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd);
298 system_state = SYSTEM_RESTART; 316 system_state = SYSTEM_RESTART;
317 usermodehelper_disable();
299 device_shutdown(); 318 device_shutdown();
300 sysdev_shutdown(); 319 syscore_shutdown();
301} 320}
302 321
303/** 322/**
@@ -325,6 +344,7 @@ static void kernel_shutdown_prepare(enum system_states state)
325 blocking_notifier_call_chain(&reboot_notifier_list, 344 blocking_notifier_call_chain(&reboot_notifier_list,
326 (state == SYSTEM_HALT)?SYS_HALT:SYS_POWER_OFF, NULL); 345 (state == SYSTEM_HALT)?SYS_HALT:SYS_POWER_OFF, NULL);
327 system_state = state; 346 system_state = state;
347 usermodehelper_disable();
328 device_shutdown(); 348 device_shutdown();
329} 349}
330/** 350/**
@@ -335,7 +355,7 @@ static void kernel_shutdown_prepare(enum system_states state)
335void kernel_halt(void) 355void kernel_halt(void)
336{ 356{
337 kernel_shutdown_prepare(SYSTEM_HALT); 357 kernel_shutdown_prepare(SYSTEM_HALT);
338 sysdev_shutdown(); 358 syscore_shutdown();
339 printk(KERN_EMERG "System halted.\n"); 359 printk(KERN_EMERG "System halted.\n");
340 kmsg_dump(KMSG_DUMP_HALT); 360 kmsg_dump(KMSG_DUMP_HALT);
341 machine_halt(); 361 machine_halt();
@@ -354,7 +374,7 @@ void kernel_power_off(void)
354 if (pm_power_off_prepare) 374 if (pm_power_off_prepare)
355 pm_power_off_prepare(); 375 pm_power_off_prepare();
356 disable_nonboot_cpus(); 376 disable_nonboot_cpus();
357 sysdev_shutdown(); 377 syscore_shutdown();
358 printk(KERN_EMERG "Power down.\n"); 378 printk(KERN_EMERG "Power down.\n");
359 kmsg_dump(KMSG_DUMP_POWEROFF); 379 kmsg_dump(KMSG_DUMP_POWEROFF);
360 machine_power_off(); 380 machine_power_off();
@@ -502,7 +522,7 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
502 if (rgid != (gid_t) -1) { 522 if (rgid != (gid_t) -1) {
503 if (old->gid == rgid || 523 if (old->gid == rgid ||
504 old->egid == rgid || 524 old->egid == rgid ||
505 capable(CAP_SETGID)) 525 nsown_capable(CAP_SETGID))
506 new->gid = rgid; 526 new->gid = rgid;
507 else 527 else
508 goto error; 528 goto error;
@@ -511,7 +531,7 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
511 if (old->gid == egid || 531 if (old->gid == egid ||
512 old->egid == egid || 532 old->egid == egid ||
513 old->sgid == egid || 533 old->sgid == egid ||
514 capable(CAP_SETGID)) 534 nsown_capable(CAP_SETGID))
515 new->egid = egid; 535 new->egid = egid;
516 else 536 else
517 goto error; 537 goto error;
@@ -546,7 +566,7 @@ SYSCALL_DEFINE1(setgid, gid_t, gid)
546 old = current_cred(); 566 old = current_cred();
547 567
548 retval = -EPERM; 568 retval = -EPERM;
549 if (capable(CAP_SETGID)) 569 if (nsown_capable(CAP_SETGID))
550 new->gid = new->egid = new->sgid = new->fsgid = gid; 570 new->gid = new->egid = new->sgid = new->fsgid = gid;
551 else if (gid == old->gid || gid == old->sgid) 571 else if (gid == old->gid || gid == old->sgid)
552 new->egid = new->fsgid = gid; 572 new->egid = new->fsgid = gid;
@@ -613,7 +633,7 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
613 new->uid = ruid; 633 new->uid = ruid;
614 if (old->uid != ruid && 634 if (old->uid != ruid &&
615 old->euid != ruid && 635 old->euid != ruid &&
616 !capable(CAP_SETUID)) 636 !nsown_capable(CAP_SETUID))
617 goto error; 637 goto error;
618 } 638 }
619 639
@@ -622,7 +642,7 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
622 if (old->uid != euid && 642 if (old->uid != euid &&
623 old->euid != euid && 643 old->euid != euid &&
624 old->suid != euid && 644 old->suid != euid &&
625 !capable(CAP_SETUID)) 645 !nsown_capable(CAP_SETUID))
626 goto error; 646 goto error;
627 } 647 }
628 648
@@ -670,7 +690,7 @@ SYSCALL_DEFINE1(setuid, uid_t, uid)
670 old = current_cred(); 690 old = current_cred();
671 691
672 retval = -EPERM; 692 retval = -EPERM;
673 if (capable(CAP_SETUID)) { 693 if (nsown_capable(CAP_SETUID)) {
674 new->suid = new->uid = uid; 694 new->suid = new->uid = uid;
675 if (uid != old->uid) { 695 if (uid != old->uid) {
676 retval = set_user(new); 696 retval = set_user(new);
@@ -712,7 +732,7 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
712 old = current_cred(); 732 old = current_cred();
713 733
714 retval = -EPERM; 734 retval = -EPERM;
715 if (!capable(CAP_SETUID)) { 735 if (!nsown_capable(CAP_SETUID)) {
716 if (ruid != (uid_t) -1 && ruid != old->uid && 736 if (ruid != (uid_t) -1 && ruid != old->uid &&
717 ruid != old->euid && ruid != old->suid) 737 ruid != old->euid && ruid != old->suid)
718 goto error; 738 goto error;
@@ -776,7 +796,7 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
776 old = current_cred(); 796 old = current_cred();
777 797
778 retval = -EPERM; 798 retval = -EPERM;
779 if (!capable(CAP_SETGID)) { 799 if (!nsown_capable(CAP_SETGID)) {
780 if (rgid != (gid_t) -1 && rgid != old->gid && 800 if (rgid != (gid_t) -1 && rgid != old->gid &&
781 rgid != old->egid && rgid != old->sgid) 801 rgid != old->egid && rgid != old->sgid)
782 goto error; 802 goto error;
@@ -836,7 +856,7 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
836 856
837 if (uid == old->uid || uid == old->euid || 857 if (uid == old->uid || uid == old->euid ||
838 uid == old->suid || uid == old->fsuid || 858 uid == old->suid || uid == old->fsuid ||
839 capable(CAP_SETUID)) { 859 nsown_capable(CAP_SETUID)) {
840 if (uid != old_fsuid) { 860 if (uid != old_fsuid) {
841 new->fsuid = uid; 861 new->fsuid = uid;
842 if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0) 862 if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0)
@@ -869,7 +889,7 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
869 889
870 if (gid == old->gid || gid == old->egid || 890 if (gid == old->gid || gid == old->egid ||
871 gid == old->sgid || gid == old->fsgid || 891 gid == old->sgid || gid == old->fsgid ||
872 capable(CAP_SETGID)) { 892 nsown_capable(CAP_SETGID)) {
873 if (gid != old_fsgid) { 893 if (gid != old_fsgid) {
874 new->fsgid = gid; 894 new->fsgid = gid;
875 goto change_okay; 895 goto change_okay;
@@ -1177,8 +1197,9 @@ SYSCALL_DEFINE2(sethostname, char __user *, name, int, len)
1177 int errno; 1197 int errno;
1178 char tmp[__NEW_UTS_LEN]; 1198 char tmp[__NEW_UTS_LEN];
1179 1199
1180 if (!capable(CAP_SYS_ADMIN)) 1200 if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
1181 return -EPERM; 1201 return -EPERM;
1202
1182 if (len < 0 || len > __NEW_UTS_LEN) 1203 if (len < 0 || len > __NEW_UTS_LEN)
1183 return -EINVAL; 1204 return -EINVAL;
1184 down_write(&uts_sem); 1205 down_write(&uts_sem);
@@ -1226,7 +1247,7 @@ SYSCALL_DEFINE2(setdomainname, char __user *, name, int, len)
1226 int errno; 1247 int errno;
1227 char tmp[__NEW_UTS_LEN]; 1248 char tmp[__NEW_UTS_LEN];
1228 1249
1229 if (!capable(CAP_SYS_ADMIN)) 1250 if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
1230 return -EPERM; 1251 return -EPERM;
1231 if (len < 0 || len > __NEW_UTS_LEN) 1252 if (len < 0 || len > __NEW_UTS_LEN)
1232 return -EINVAL; 1253 return -EINVAL;
@@ -1341,6 +1362,8 @@ int do_prlimit(struct task_struct *tsk, unsigned int resource,
1341 rlim = tsk->signal->rlim + resource; 1362 rlim = tsk->signal->rlim + resource;
1342 task_lock(tsk->group_leader); 1363 task_lock(tsk->group_leader);
1343 if (new_rlim) { 1364 if (new_rlim) {
1365 /* Keep the capable check against init_user_ns until
1366 cgroups can contain all limits */
1344 if (new_rlim->rlim_max > rlim->rlim_max && 1367 if (new_rlim->rlim_max > rlim->rlim_max &&
1345 !capable(CAP_SYS_RESOURCE)) 1368 !capable(CAP_SYS_RESOURCE))
1346 retval = -EPERM; 1369 retval = -EPERM;
@@ -1384,19 +1407,22 @@ static int check_prlimit_permission(struct task_struct *task)
1384{ 1407{
1385 const struct cred *cred = current_cred(), *tcred; 1408 const struct cred *cred = current_cred(), *tcred;
1386 1409
1387 tcred = __task_cred(task); 1410 if (current == task)
1388 if (current != task && 1411 return 0;
1389 (cred->uid != tcred->euid ||
1390 cred->uid != tcred->suid ||
1391 cred->uid != tcred->uid ||
1392 cred->gid != tcred->egid ||
1393 cred->gid != tcred->sgid ||
1394 cred->gid != tcred->gid) &&
1395 !capable(CAP_SYS_RESOURCE)) {
1396 return -EPERM;
1397 }
1398 1412
1399 return 0; 1413 tcred = __task_cred(task);
1414 if (cred->user->user_ns == tcred->user->user_ns &&
1415 (cred->uid == tcred->euid &&
1416 cred->uid == tcred->suid &&
1417 cred->uid == tcred->uid &&
1418 cred->gid == tcred->egid &&
1419 cred->gid == tcred->sgid &&
1420 cred->gid == tcred->gid))
1421 return 0;
1422 if (ns_capable(tcred->user->user_ns, CAP_SYS_RESOURCE))
1423 return 0;
1424
1425 return -EPERM;
1400} 1426}
1401 1427
1402SYSCALL_DEFINE4(prlimit64, pid_t, pid, unsigned int, resource, 1428SYSCALL_DEFINE4(prlimit64, pid_t, pid, unsigned int, resource,