aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c80
1 files changed, 54 insertions, 26 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index 31b71a276b40..af468edf096a 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 }
@@ -298,6 +316,7 @@ void kernel_restart_prepare(char *cmd)
298 system_state = SYSTEM_RESTART; 316 system_state = SYSTEM_RESTART;
299 device_shutdown(); 317 device_shutdown();
300 sysdev_shutdown(); 318 sysdev_shutdown();
319 syscore_shutdown();
301} 320}
302 321
303/** 322/**
@@ -336,6 +355,7 @@ void kernel_halt(void)
336{ 355{
337 kernel_shutdown_prepare(SYSTEM_HALT); 356 kernel_shutdown_prepare(SYSTEM_HALT);
338 sysdev_shutdown(); 357 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();
@@ -355,6 +375,7 @@ void kernel_power_off(void)
355 pm_power_off_prepare(); 375 pm_power_off_prepare();
356 disable_nonboot_cpus(); 376 disable_nonboot_cpus();
357 sysdev_shutdown(); 377 sysdev_shutdown();
378 syscore_shutdown();
358 printk(KERN_EMERG "Power down.\n"); 379 printk(KERN_EMERG "Power down.\n");
359 kmsg_dump(KMSG_DUMP_POWEROFF); 380 kmsg_dump(KMSG_DUMP_POWEROFF);
360 machine_power_off(); 381 machine_power_off();
@@ -502,7 +523,7 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
502 if (rgid != (gid_t) -1) { 523 if (rgid != (gid_t) -1) {
503 if (old->gid == rgid || 524 if (old->gid == rgid ||
504 old->egid == rgid || 525 old->egid == rgid ||
505 capable(CAP_SETGID)) 526 nsown_capable(CAP_SETGID))
506 new->gid = rgid; 527 new->gid = rgid;
507 else 528 else
508 goto error; 529 goto error;
@@ -511,7 +532,7 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
511 if (old->gid == egid || 532 if (old->gid == egid ||
512 old->egid == egid || 533 old->egid == egid ||
513 old->sgid == egid || 534 old->sgid == egid ||
514 capable(CAP_SETGID)) 535 nsown_capable(CAP_SETGID))
515 new->egid = egid; 536 new->egid = egid;
516 else 537 else
517 goto error; 538 goto error;
@@ -546,7 +567,7 @@ SYSCALL_DEFINE1(setgid, gid_t, gid)
546 old = current_cred(); 567 old = current_cred();
547 568
548 retval = -EPERM; 569 retval = -EPERM;
549 if (capable(CAP_SETGID)) 570 if (nsown_capable(CAP_SETGID))
550 new->gid = new->egid = new->sgid = new->fsgid = gid; 571 new->gid = new->egid = new->sgid = new->fsgid = gid;
551 else if (gid == old->gid || gid == old->sgid) 572 else if (gid == old->gid || gid == old->sgid)
552 new->egid = new->fsgid = gid; 573 new->egid = new->fsgid = gid;
@@ -613,7 +634,7 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
613 new->uid = ruid; 634 new->uid = ruid;
614 if (old->uid != ruid && 635 if (old->uid != ruid &&
615 old->euid != ruid && 636 old->euid != ruid &&
616 !capable(CAP_SETUID)) 637 !nsown_capable(CAP_SETUID))
617 goto error; 638 goto error;
618 } 639 }
619 640
@@ -622,7 +643,7 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
622 if (old->uid != euid && 643 if (old->uid != euid &&
623 old->euid != euid && 644 old->euid != euid &&
624 old->suid != euid && 645 old->suid != euid &&
625 !capable(CAP_SETUID)) 646 !nsown_capable(CAP_SETUID))
626 goto error; 647 goto error;
627 } 648 }
628 649
@@ -670,7 +691,7 @@ SYSCALL_DEFINE1(setuid, uid_t, uid)
670 old = current_cred(); 691 old = current_cred();
671 692
672 retval = -EPERM; 693 retval = -EPERM;
673 if (capable(CAP_SETUID)) { 694 if (nsown_capable(CAP_SETUID)) {
674 new->suid = new->uid = uid; 695 new->suid = new->uid = uid;
675 if (uid != old->uid) { 696 if (uid != old->uid) {
676 retval = set_user(new); 697 retval = set_user(new);
@@ -712,7 +733,7 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
712 old = current_cred(); 733 old = current_cred();
713 734
714 retval = -EPERM; 735 retval = -EPERM;
715 if (!capable(CAP_SETUID)) { 736 if (!nsown_capable(CAP_SETUID)) {
716 if (ruid != (uid_t) -1 && ruid != old->uid && 737 if (ruid != (uid_t) -1 && ruid != old->uid &&
717 ruid != old->euid && ruid != old->suid) 738 ruid != old->euid && ruid != old->suid)
718 goto error; 739 goto error;
@@ -776,7 +797,7 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
776 old = current_cred(); 797 old = current_cred();
777 798
778 retval = -EPERM; 799 retval = -EPERM;
779 if (!capable(CAP_SETGID)) { 800 if (!nsown_capable(CAP_SETGID)) {
780 if (rgid != (gid_t) -1 && rgid != old->gid && 801 if (rgid != (gid_t) -1 && rgid != old->gid &&
781 rgid != old->egid && rgid != old->sgid) 802 rgid != old->egid && rgid != old->sgid)
782 goto error; 803 goto error;
@@ -836,7 +857,7 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
836 857
837 if (uid == old->uid || uid == old->euid || 858 if (uid == old->uid || uid == old->euid ||
838 uid == old->suid || uid == old->fsuid || 859 uid == old->suid || uid == old->fsuid ||
839 capable(CAP_SETUID)) { 860 nsown_capable(CAP_SETUID)) {
840 if (uid != old_fsuid) { 861 if (uid != old_fsuid) {
841 new->fsuid = uid; 862 new->fsuid = uid;
842 if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0) 863 if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0)
@@ -869,7 +890,7 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
869 890
870 if (gid == old->gid || gid == old->egid || 891 if (gid == old->gid || gid == old->egid ||
871 gid == old->sgid || gid == old->fsgid || 892 gid == old->sgid || gid == old->fsgid ||
872 capable(CAP_SETGID)) { 893 nsown_capable(CAP_SETGID)) {
873 if (gid != old_fsgid) { 894 if (gid != old_fsgid) {
874 new->fsgid = gid; 895 new->fsgid = gid;
875 goto change_okay; 896 goto change_okay;
@@ -1177,8 +1198,9 @@ SYSCALL_DEFINE2(sethostname, char __user *, name, int, len)
1177 int errno; 1198 int errno;
1178 char tmp[__NEW_UTS_LEN]; 1199 char tmp[__NEW_UTS_LEN];
1179 1200
1180 if (!capable(CAP_SYS_ADMIN)) 1201 if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
1181 return -EPERM; 1202 return -EPERM;
1203
1182 if (len < 0 || len > __NEW_UTS_LEN) 1204 if (len < 0 || len > __NEW_UTS_LEN)
1183 return -EINVAL; 1205 return -EINVAL;
1184 down_write(&uts_sem); 1206 down_write(&uts_sem);
@@ -1226,7 +1248,7 @@ SYSCALL_DEFINE2(setdomainname, char __user *, name, int, len)
1226 int errno; 1248 int errno;
1227 char tmp[__NEW_UTS_LEN]; 1249 char tmp[__NEW_UTS_LEN];
1228 1250
1229 if (!capable(CAP_SYS_ADMIN)) 1251 if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
1230 return -EPERM; 1252 return -EPERM;
1231 if (len < 0 || len > __NEW_UTS_LEN) 1253 if (len < 0 || len > __NEW_UTS_LEN)
1232 return -EINVAL; 1254 return -EINVAL;
@@ -1341,6 +1363,8 @@ int do_prlimit(struct task_struct *tsk, unsigned int resource,
1341 rlim = tsk->signal->rlim + resource; 1363 rlim = tsk->signal->rlim + resource;
1342 task_lock(tsk->group_leader); 1364 task_lock(tsk->group_leader);
1343 if (new_rlim) { 1365 if (new_rlim) {
1366 /* Keep the capable check against init_user_ns until
1367 cgroups can contain all limits */
1344 if (new_rlim->rlim_max > rlim->rlim_max && 1368 if (new_rlim->rlim_max > rlim->rlim_max &&
1345 !capable(CAP_SYS_RESOURCE)) 1369 !capable(CAP_SYS_RESOURCE))
1346 retval = -EPERM; 1370 retval = -EPERM;
@@ -1384,18 +1408,22 @@ static int check_prlimit_permission(struct task_struct *task)
1384{ 1408{
1385 const struct cred *cred = current_cred(), *tcred; 1409 const struct cred *cred = current_cred(), *tcred;
1386 1410
1387 tcred = __task_cred(task); 1411 if (current == task)
1388 if ((cred->uid != tcred->euid || 1412 return 0;
1389 cred->uid != tcred->suid ||
1390 cred->uid != tcred->uid ||
1391 cred->gid != tcred->egid ||
1392 cred->gid != tcred->sgid ||
1393 cred->gid != tcred->gid) &&
1394 !capable(CAP_SYS_RESOURCE)) {
1395 return -EPERM;
1396 }
1397 1413
1398 return 0; 1414 tcred = __task_cred(task);
1415 if (cred->user->user_ns == tcred->user->user_ns &&
1416 (cred->uid == tcred->euid &&
1417 cred->uid == tcred->suid &&
1418 cred->uid == tcred->uid &&
1419 cred->gid == tcred->egid &&
1420 cred->gid == tcred->sgid &&
1421 cred->gid == tcred->gid))
1422 return 0;
1423 if (ns_capable(tcred->user->user_ns, CAP_SYS_RESOURCE))
1424 return 0;
1425
1426 return -EPERM;
1399} 1427}
1400 1428
1401SYSCALL_DEFINE4(prlimit64, pid_t, pid, unsigned int, resource, 1429SYSCALL_DEFINE4(prlimit64, pid_t, pid, unsigned int, resource,