aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c75
1 files changed, 43 insertions, 32 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index eecf84526afe..d09cac23fdfd 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -19,6 +19,7 @@
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/kexec.h> 20#include <linux/kexec.h>
21#include <linux/workqueue.h> 21#include <linux/workqueue.h>
22#include <linux/capability.h>
22#include <linux/device.h> 23#include <linux/device.h>
23#include <linux/key.h> 24#include <linux/key.h>
24#include <linux/times.h> 25#include <linux/times.h>
@@ -223,6 +224,18 @@ int unregister_reboot_notifier(struct notifier_block * nb)
223 224
224EXPORT_SYMBOL(unregister_reboot_notifier); 225EXPORT_SYMBOL(unregister_reboot_notifier);
225 226
227#ifndef CONFIG_SECURITY
228int capable(int cap)
229{
230 if (cap_raised(current->cap_effective, cap)) {
231 current->flags |= PF_SUPERPRIV;
232 return 1;
233 }
234 return 0;
235}
236EXPORT_SYMBOL(capable);
237#endif
238
226static int set_one_prio(struct task_struct *p, int niceval, int error) 239static int set_one_prio(struct task_struct *p, int niceval, int error)
227{ 240{
228 int no_nice; 241 int no_nice;
@@ -489,6 +502,12 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
489 magic2 != LINUX_REBOOT_MAGIC2C)) 502 magic2 != LINUX_REBOOT_MAGIC2C))
490 return -EINVAL; 503 return -EINVAL;
491 504
505 /* Instead of trying to make the power_off code look like
506 * halt when pm_power_off is not set do it the easy way.
507 */
508 if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
509 cmd = LINUX_REBOOT_CMD_HALT;
510
492 lock_kernel(); 511 lock_kernel();
493 switch (cmd) { 512 switch (cmd) {
494 case LINUX_REBOOT_CMD_RESTART: 513 case LINUX_REBOOT_CMD_RESTART:
@@ -1084,10 +1103,11 @@ asmlinkage long sys_times(struct tms __user * tbuf)
1084asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) 1103asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
1085{ 1104{
1086 struct task_struct *p; 1105 struct task_struct *p;
1106 struct task_struct *group_leader = current->group_leader;
1087 int err = -EINVAL; 1107 int err = -EINVAL;
1088 1108
1089 if (!pid) 1109 if (!pid)
1090 pid = current->pid; 1110 pid = group_leader->pid;
1091 if (!pgid) 1111 if (!pgid)
1092 pgid = pid; 1112 pgid = pid;
1093 if (pgid < 0) 1113 if (pgid < 0)
@@ -1107,16 +1127,16 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
1107 if (!thread_group_leader(p)) 1127 if (!thread_group_leader(p))
1108 goto out; 1128 goto out;
1109 1129
1110 if (p->parent == current || p->real_parent == current) { 1130 if (p->real_parent == group_leader) {
1111 err = -EPERM; 1131 err = -EPERM;
1112 if (p->signal->session != current->signal->session) 1132 if (p->signal->session != group_leader->signal->session)
1113 goto out; 1133 goto out;
1114 err = -EACCES; 1134 err = -EACCES;
1115 if (p->did_exec) 1135 if (p->did_exec)
1116 goto out; 1136 goto out;
1117 } else { 1137 } else {
1118 err = -ESRCH; 1138 err = -ESRCH;
1119 if (p != current) 1139 if (p != group_leader)
1120 goto out; 1140 goto out;
1121 } 1141 }
1122 1142
@@ -1128,7 +1148,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
1128 struct task_struct *p; 1148 struct task_struct *p;
1129 1149
1130 do_each_task_pid(pgid, PIDTYPE_PGID, p) { 1150 do_each_task_pid(pgid, PIDTYPE_PGID, p) {
1131 if (p->signal->session == current->signal->session) 1151 if (p->signal->session == group_leader->signal->session)
1132 goto ok_pgid; 1152 goto ok_pgid;
1133 } while_each_task_pid(pgid, PIDTYPE_PGID, p); 1153 } while_each_task_pid(pgid, PIDTYPE_PGID, p);
1134 goto out; 1154 goto out;
@@ -1208,24 +1228,22 @@ asmlinkage long sys_getsid(pid_t pid)
1208 1228
1209asmlinkage long sys_setsid(void) 1229asmlinkage long sys_setsid(void)
1210{ 1230{
1231 struct task_struct *group_leader = current->group_leader;
1211 struct pid *pid; 1232 struct pid *pid;
1212 int err = -EPERM; 1233 int err = -EPERM;
1213 1234
1214 if (!thread_group_leader(current))
1215 return -EINVAL;
1216
1217 down(&tty_sem); 1235 down(&tty_sem);
1218 write_lock_irq(&tasklist_lock); 1236 write_lock_irq(&tasklist_lock);
1219 1237
1220 pid = find_pid(PIDTYPE_PGID, current->pid); 1238 pid = find_pid(PIDTYPE_PGID, group_leader->pid);
1221 if (pid) 1239 if (pid)
1222 goto out; 1240 goto out;
1223 1241
1224 current->signal->leader = 1; 1242 group_leader->signal->leader = 1;
1225 __set_special_pids(current->pid, current->pid); 1243 __set_special_pids(group_leader->pid, group_leader->pid);
1226 current->signal->tty = NULL; 1244 group_leader->signal->tty = NULL;
1227 current->signal->tty_old_pgrp = 0; 1245 group_leader->signal->tty_old_pgrp = 0;
1228 err = process_group(current); 1246 err = process_group(group_leader);
1229out: 1247out:
1230 write_unlock_irq(&tasklist_lock); 1248 write_unlock_irq(&tasklist_lock);
1231 up(&tty_sem); 1249 up(&tty_sem);
@@ -1687,7 +1705,10 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1687 if (unlikely(!p->signal)) 1705 if (unlikely(!p->signal))
1688 return; 1706 return;
1689 1707
1708 utime = stime = cputime_zero;
1709
1690 switch (who) { 1710 switch (who) {
1711 case RUSAGE_BOTH:
1691 case RUSAGE_CHILDREN: 1712 case RUSAGE_CHILDREN:
1692 spin_lock_irqsave(&p->sighand->siglock, flags); 1713 spin_lock_irqsave(&p->sighand->siglock, flags);
1693 utime = p->signal->cutime; 1714 utime = p->signal->cutime;
@@ -1697,22 +1718,11 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1697 r->ru_minflt = p->signal->cmin_flt; 1718 r->ru_minflt = p->signal->cmin_flt;
1698 r->ru_majflt = p->signal->cmaj_flt; 1719 r->ru_majflt = p->signal->cmaj_flt;
1699 spin_unlock_irqrestore(&p->sighand->siglock, flags); 1720 spin_unlock_irqrestore(&p->sighand->siglock, flags);
1700 cputime_to_timeval(utime, &r->ru_utime); 1721
1701 cputime_to_timeval(stime, &r->ru_stime); 1722 if (who == RUSAGE_CHILDREN)
1702 break; 1723 break;
1724
1703 case RUSAGE_SELF: 1725 case RUSAGE_SELF:
1704 spin_lock_irqsave(&p->sighand->siglock, flags);
1705 utime = stime = cputime_zero;
1706 goto sum_group;
1707 case RUSAGE_BOTH:
1708 spin_lock_irqsave(&p->sighand->siglock, flags);
1709 utime = p->signal->cutime;
1710 stime = p->signal->cstime;
1711 r->ru_nvcsw = p->signal->cnvcsw;
1712 r->ru_nivcsw = p->signal->cnivcsw;
1713 r->ru_minflt = p->signal->cmin_flt;
1714 r->ru_majflt = p->signal->cmaj_flt;
1715 sum_group:
1716 utime = cputime_add(utime, p->signal->utime); 1726 utime = cputime_add(utime, p->signal->utime);
1717 stime = cputime_add(stime, p->signal->stime); 1727 stime = cputime_add(stime, p->signal->stime);
1718 r->ru_nvcsw += p->signal->nvcsw; 1728 r->ru_nvcsw += p->signal->nvcsw;
@@ -1729,13 +1739,14 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1729 r->ru_majflt += t->maj_flt; 1739 r->ru_majflt += t->maj_flt;
1730 t = next_thread(t); 1740 t = next_thread(t);
1731 } while (t != p); 1741 } while (t != p);
1732 spin_unlock_irqrestore(&p->sighand->siglock, flags);
1733 cputime_to_timeval(utime, &r->ru_utime);
1734 cputime_to_timeval(stime, &r->ru_stime);
1735 break; 1742 break;
1743
1736 default: 1744 default:
1737 BUG(); 1745 BUG();
1738 } 1746 }
1747
1748 cputime_to_timeval(utime, &r->ru_utime);
1749 cputime_to_timeval(stime, &r->ru_stime);
1739} 1750}
1740 1751
1741int getrusage(struct task_struct *p, int who, struct rusage __user *ru) 1752int getrusage(struct task_struct *p, int who, struct rusage __user *ru)