aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c95
1 files changed, 65 insertions, 30 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index 7f5a0cd296a9..e4128b278f23 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -37,12 +37,15 @@
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>
43#include <linux/kprobes.h> 44#include <linux/kprobes.h>
44#include <linux/user_namespace.h> 45#include <linux/user_namespace.h>
45 46
47#include <linux/kmsg_dump.h>
48
46#include <asm/uaccess.h> 49#include <asm/uaccess.h>
47#include <asm/io.h> 50#include <asm/io.h>
48#include <asm/unistd.h> 51#include <asm/unistd.h>
@@ -117,16 +120,33 @@ EXPORT_SYMBOL(cad_pid);
117void (*pm_power_off_prepare)(void); 120void (*pm_power_off_prepare)(void);
118 121
119/* 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/*
120 * set the priority of a task 142 * set the priority of a task
121 * - the caller must hold the RCU read lock 143 * - the caller must hold the RCU read lock
122 */ 144 */
123static 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)
124{ 146{
125 const struct cred *cred = current_cred(), *pcred = __task_cred(p);
126 int no_nice; 147 int no_nice;
127 148
128 if (pcred->uid != cred->euid && 149 if (!set_one_prio_perm(p)) {
129 pcred->euid != cred->euid && !capable(CAP_SYS_NICE)) {
130 error = -EPERM; 150 error = -EPERM;
131 goto out; 151 goto out;
132 } 152 }
@@ -285,6 +305,7 @@ out_unlock:
285 */ 305 */
286void emergency_restart(void) 306void emergency_restart(void)
287{ 307{
308 kmsg_dump(KMSG_DUMP_EMERG);
288 machine_emergency_restart(); 309 machine_emergency_restart();
289} 310}
290EXPORT_SYMBOL_GPL(emergency_restart); 311EXPORT_SYMBOL_GPL(emergency_restart);
@@ -293,8 +314,9 @@ void kernel_restart_prepare(char *cmd)
293{ 314{
294 blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); 315 blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd);
295 system_state = SYSTEM_RESTART; 316 system_state = SYSTEM_RESTART;
317 usermodehelper_disable();
296 device_shutdown(); 318 device_shutdown();
297 sysdev_shutdown(); 319 syscore_shutdown();
298} 320}
299 321
300/** 322/**
@@ -312,6 +334,7 @@ void kernel_restart(char *cmd)
312 printk(KERN_EMERG "Restarting system.\n"); 334 printk(KERN_EMERG "Restarting system.\n");
313 else 335 else
314 printk(KERN_EMERG "Restarting system with command '%s'.\n", cmd); 336 printk(KERN_EMERG "Restarting system with command '%s'.\n", cmd);
337 kmsg_dump(KMSG_DUMP_RESTART);
315 machine_restart(cmd); 338 machine_restart(cmd);
316} 339}
317EXPORT_SYMBOL_GPL(kernel_restart); 340EXPORT_SYMBOL_GPL(kernel_restart);
@@ -321,6 +344,7 @@ static void kernel_shutdown_prepare(enum system_states state)
321 blocking_notifier_call_chain(&reboot_notifier_list, 344 blocking_notifier_call_chain(&reboot_notifier_list,
322 (state == SYSTEM_HALT)?SYS_HALT:SYS_POWER_OFF, NULL); 345 (state == SYSTEM_HALT)?SYS_HALT:SYS_POWER_OFF, NULL);
323 system_state = state; 346 system_state = state;
347 usermodehelper_disable();
324 device_shutdown(); 348 device_shutdown();
325} 349}
326/** 350/**
@@ -331,8 +355,9 @@ static void kernel_shutdown_prepare(enum system_states state)
331void kernel_halt(void) 355void kernel_halt(void)
332{ 356{
333 kernel_shutdown_prepare(SYSTEM_HALT); 357 kernel_shutdown_prepare(SYSTEM_HALT);
334 sysdev_shutdown(); 358 syscore_shutdown();
335 printk(KERN_EMERG "System halted.\n"); 359 printk(KERN_EMERG "System halted.\n");
360 kmsg_dump(KMSG_DUMP_HALT);
336 machine_halt(); 361 machine_halt();
337} 362}
338 363
@@ -349,8 +374,9 @@ void kernel_power_off(void)
349 if (pm_power_off_prepare) 374 if (pm_power_off_prepare)
350 pm_power_off_prepare(); 375 pm_power_off_prepare();
351 disable_nonboot_cpus(); 376 disable_nonboot_cpus();
352 sysdev_shutdown(); 377 syscore_shutdown();
353 printk(KERN_EMERG "Power down.\n"); 378 printk(KERN_EMERG "Power down.\n");
379 kmsg_dump(KMSG_DUMP_POWEROFF);
354 machine_power_off(); 380 machine_power_off();
355} 381}
356EXPORT_SYMBOL_GPL(kernel_power_off); 382EXPORT_SYMBOL_GPL(kernel_power_off);
@@ -496,7 +522,7 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
496 if (rgid != (gid_t) -1) { 522 if (rgid != (gid_t) -1) {
497 if (old->gid == rgid || 523 if (old->gid == rgid ||
498 old->egid == rgid || 524 old->egid == rgid ||
499 capable(CAP_SETGID)) 525 nsown_capable(CAP_SETGID))
500 new->gid = rgid; 526 new->gid = rgid;
501 else 527 else
502 goto error; 528 goto error;
@@ -505,7 +531,7 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
505 if (old->gid == egid || 531 if (old->gid == egid ||
506 old->egid == egid || 532 old->egid == egid ||
507 old->sgid == egid || 533 old->sgid == egid ||
508 capable(CAP_SETGID)) 534 nsown_capable(CAP_SETGID))
509 new->egid = egid; 535 new->egid = egid;
510 else 536 else
511 goto error; 537 goto error;
@@ -540,7 +566,7 @@ SYSCALL_DEFINE1(setgid, gid_t, gid)
540 old = current_cred(); 566 old = current_cred();
541 567
542 retval = -EPERM; 568 retval = -EPERM;
543 if (capable(CAP_SETGID)) 569 if (nsown_capable(CAP_SETGID))
544 new->gid = new->egid = new->sgid = new->fsgid = gid; 570 new->gid = new->egid = new->sgid = new->fsgid = gid;
545 else if (gid == old->gid || gid == old->sgid) 571 else if (gid == old->gid || gid == old->sgid)
546 new->egid = new->fsgid = gid; 572 new->egid = new->fsgid = gid;
@@ -607,7 +633,7 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
607 new->uid = ruid; 633 new->uid = ruid;
608 if (old->uid != ruid && 634 if (old->uid != ruid &&
609 old->euid != ruid && 635 old->euid != ruid &&
610 !capable(CAP_SETUID)) 636 !nsown_capable(CAP_SETUID))
611 goto error; 637 goto error;
612 } 638 }
613 639
@@ -616,7 +642,7 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
616 if (old->uid != euid && 642 if (old->uid != euid &&
617 old->euid != euid && 643 old->euid != euid &&
618 old->suid != euid && 644 old->suid != euid &&
619 !capable(CAP_SETUID)) 645 !nsown_capable(CAP_SETUID))
620 goto error; 646 goto error;
621 } 647 }
622 648
@@ -664,7 +690,7 @@ SYSCALL_DEFINE1(setuid, uid_t, uid)
664 old = current_cred(); 690 old = current_cred();
665 691
666 retval = -EPERM; 692 retval = -EPERM;
667 if (capable(CAP_SETUID)) { 693 if (nsown_capable(CAP_SETUID)) {
668 new->suid = new->uid = uid; 694 new->suid = new->uid = uid;
669 if (uid != old->uid) { 695 if (uid != old->uid) {
670 retval = set_user(new); 696 retval = set_user(new);
@@ -706,7 +732,7 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
706 old = current_cred(); 732 old = current_cred();
707 733
708 retval = -EPERM; 734 retval = -EPERM;
709 if (!capable(CAP_SETUID)) { 735 if (!nsown_capable(CAP_SETUID)) {
710 if (ruid != (uid_t) -1 && ruid != old->uid && 736 if (ruid != (uid_t) -1 && ruid != old->uid &&
711 ruid != old->euid && ruid != old->suid) 737 ruid != old->euid && ruid != old->suid)
712 goto error; 738 goto error;
@@ -770,7 +796,7 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
770 old = current_cred(); 796 old = current_cred();
771 797
772 retval = -EPERM; 798 retval = -EPERM;
773 if (!capable(CAP_SETGID)) { 799 if (!nsown_capable(CAP_SETGID)) {
774 if (rgid != (gid_t) -1 && rgid != old->gid && 800 if (rgid != (gid_t) -1 && rgid != old->gid &&
775 rgid != old->egid && rgid != old->sgid) 801 rgid != old->egid && rgid != old->sgid)
776 goto error; 802 goto error;
@@ -830,7 +856,7 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
830 856
831 if (uid == old->uid || uid == old->euid || 857 if (uid == old->uid || uid == old->euid ||
832 uid == old->suid || uid == old->fsuid || 858 uid == old->suid || uid == old->fsuid ||
833 capable(CAP_SETUID)) { 859 nsown_capable(CAP_SETUID)) {
834 if (uid != old_fsuid) { 860 if (uid != old_fsuid) {
835 new->fsuid = uid; 861 new->fsuid = uid;
836 if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0) 862 if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0)
@@ -863,7 +889,7 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
863 889
864 if (gid == old->gid || gid == old->egid || 890 if (gid == old->gid || gid == old->egid ||
865 gid == old->sgid || gid == old->fsgid || 891 gid == old->sgid || gid == old->fsgid ||
866 capable(CAP_SETGID)) { 892 nsown_capable(CAP_SETGID)) {
867 if (gid != old_fsgid) { 893 if (gid != old_fsgid) {
868 new->fsgid = gid; 894 new->fsgid = gid;
869 goto change_okay; 895 goto change_okay;
@@ -1080,8 +1106,10 @@ SYSCALL_DEFINE0(setsid)
1080 err = session; 1106 err = session;
1081out: 1107out:
1082 write_unlock_irq(&tasklist_lock); 1108 write_unlock_irq(&tasklist_lock);
1083 if (err > 0) 1109 if (err > 0) {
1084 proc_sid_connector(group_leader); 1110 proc_sid_connector(group_leader);
1111 sched_autogroup_create_attach(group_leader);
1112 }
1085 return err; 1113 return err;
1086} 1114}
1087 1115
@@ -1169,8 +1197,9 @@ SYSCALL_DEFINE2(sethostname, char __user *, name, int, len)
1169 int errno; 1197 int errno;
1170 char tmp[__NEW_UTS_LEN]; 1198 char tmp[__NEW_UTS_LEN];
1171 1199
1172 if (!capable(CAP_SYS_ADMIN)) 1200 if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
1173 return -EPERM; 1201 return -EPERM;
1202
1174 if (len < 0 || len > __NEW_UTS_LEN) 1203 if (len < 0 || len > __NEW_UTS_LEN)
1175 return -EINVAL; 1204 return -EINVAL;
1176 down_write(&uts_sem); 1205 down_write(&uts_sem);
@@ -1218,7 +1247,7 @@ SYSCALL_DEFINE2(setdomainname, char __user *, name, int, len)
1218 int errno; 1247 int errno;
1219 char tmp[__NEW_UTS_LEN]; 1248 char tmp[__NEW_UTS_LEN];
1220 1249
1221 if (!capable(CAP_SYS_ADMIN)) 1250 if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
1222 return -EPERM; 1251 return -EPERM;
1223 if (len < 0 || len > __NEW_UTS_LEN) 1252 if (len < 0 || len > __NEW_UTS_LEN)
1224 return -EINVAL; 1253 return -EINVAL;
@@ -1333,6 +1362,8 @@ int do_prlimit(struct task_struct *tsk, unsigned int resource,
1333 rlim = tsk->signal->rlim + resource; 1362 rlim = tsk->signal->rlim + resource;
1334 task_lock(tsk->group_leader); 1363 task_lock(tsk->group_leader);
1335 if (new_rlim) { 1364 if (new_rlim) {
1365 /* Keep the capable check against init_user_ns until
1366 cgroups can contain all limits */
1336 if (new_rlim->rlim_max > rlim->rlim_max && 1367 if (new_rlim->rlim_max > rlim->rlim_max &&
1337 !capable(CAP_SYS_RESOURCE)) 1368 !capable(CAP_SYS_RESOURCE))
1338 retval = -EPERM; 1369 retval = -EPERM;
@@ -1376,18 +1407,22 @@ static int check_prlimit_permission(struct task_struct *task)
1376{ 1407{
1377 const struct cred *cred = current_cred(), *tcred; 1408 const struct cred *cred = current_cred(), *tcred;
1378 1409
1379 tcred = __task_cred(task); 1410 if (current == task)
1380 if ((cred->uid != tcred->euid || 1411 return 0;
1381 cred->uid != tcred->suid ||
1382 cred->uid != tcred->uid ||
1383 cred->gid != tcred->egid ||
1384 cred->gid != tcred->sgid ||
1385 cred->gid != tcred->gid) &&
1386 !capable(CAP_SYS_RESOURCE)) {
1387 return -EPERM;
1388 }
1389 1412
1390 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;
1391} 1426}
1392 1427
1393SYSCALL_DEFINE4(prlimit64, pid_t, pid, unsigned int, resource, 1428SYSCALL_DEFINE4(prlimit64, pid_t, pid, unsigned int, resource,