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 c3b1874661fa..0929c698affc 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;
@@ -484,6 +497,12 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
484 magic2 != LINUX_REBOOT_MAGIC2C)) 497 magic2 != LINUX_REBOOT_MAGIC2C))
485 return -EINVAL; 498 return -EINVAL;
486 499
500 /* Instead of trying to make the power_off code look like
501 * halt when pm_power_off is not set do it the easy way.
502 */
503 if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
504 cmd = LINUX_REBOOT_CMD_HALT;
505
487 lock_kernel(); 506 lock_kernel();
488 switch (cmd) { 507 switch (cmd) {
489 case LINUX_REBOOT_CMD_RESTART: 508 case LINUX_REBOOT_CMD_RESTART:
@@ -1079,10 +1098,11 @@ asmlinkage long sys_times(struct tms __user * tbuf)
1079asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) 1098asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
1080{ 1099{
1081 struct task_struct *p; 1100 struct task_struct *p;
1101 struct task_struct *group_leader = current->group_leader;
1082 int err = -EINVAL; 1102 int err = -EINVAL;
1083 1103
1084 if (!pid) 1104 if (!pid)
1085 pid = current->pid; 1105 pid = group_leader->pid;
1086 if (!pgid) 1106 if (!pgid)
1087 pgid = pid; 1107 pgid = pid;
1088 if (pgid < 0) 1108 if (pgid < 0)
@@ -1102,16 +1122,16 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
1102 if (!thread_group_leader(p)) 1122 if (!thread_group_leader(p))
1103 goto out; 1123 goto out;
1104 1124
1105 if (p->parent == current || p->real_parent == current) { 1125 if (p->real_parent == group_leader) {
1106 err = -EPERM; 1126 err = -EPERM;
1107 if (p->signal->session != current->signal->session) 1127 if (p->signal->session != group_leader->signal->session)
1108 goto out; 1128 goto out;
1109 err = -EACCES; 1129 err = -EACCES;
1110 if (p->did_exec) 1130 if (p->did_exec)
1111 goto out; 1131 goto out;
1112 } else { 1132 } else {
1113 err = -ESRCH; 1133 err = -ESRCH;
1114 if (p != current) 1134 if (p != group_leader)
1115 goto out; 1135 goto out;
1116 } 1136 }
1117 1137
@@ -1123,7 +1143,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
1123 struct task_struct *p; 1143 struct task_struct *p;
1124 1144
1125 do_each_task_pid(pgid, PIDTYPE_PGID, p) { 1145 do_each_task_pid(pgid, PIDTYPE_PGID, p) {
1126 if (p->signal->session == current->signal->session) 1146 if (p->signal->session == group_leader->signal->session)
1127 goto ok_pgid; 1147 goto ok_pgid;
1128 } while_each_task_pid(pgid, PIDTYPE_PGID, p); 1148 } while_each_task_pid(pgid, PIDTYPE_PGID, p);
1129 goto out; 1149 goto out;
@@ -1203,24 +1223,22 @@ asmlinkage long sys_getsid(pid_t pid)
1203 1223
1204asmlinkage long sys_setsid(void) 1224asmlinkage long sys_setsid(void)
1205{ 1225{
1226 struct task_struct *group_leader = current->group_leader;
1206 struct pid *pid; 1227 struct pid *pid;
1207 int err = -EPERM; 1228 int err = -EPERM;
1208 1229
1209 if (!thread_group_leader(current))
1210 return -EINVAL;
1211
1212 down(&tty_sem); 1230 down(&tty_sem);
1213 write_lock_irq(&tasklist_lock); 1231 write_lock_irq(&tasklist_lock);
1214 1232
1215 pid = find_pid(PIDTYPE_PGID, current->pid); 1233 pid = find_pid(PIDTYPE_PGID, group_leader->pid);
1216 if (pid) 1234 if (pid)
1217 goto out; 1235 goto out;
1218 1236
1219 current->signal->leader = 1; 1237 group_leader->signal->leader = 1;
1220 __set_special_pids(current->pid, current->pid); 1238 __set_special_pids(group_leader->pid, group_leader->pid);
1221 current->signal->tty = NULL; 1239 group_leader->signal->tty = NULL;
1222 current->signal->tty_old_pgrp = 0; 1240 group_leader->signal->tty_old_pgrp = 0;
1223 err = process_group(current); 1241 err = process_group(group_leader);
1224out: 1242out:
1225 write_unlock_irq(&tasklist_lock); 1243 write_unlock_irq(&tasklist_lock);
1226 up(&tty_sem); 1244 up(&tty_sem);
@@ -1682,7 +1700,10 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1682 if (unlikely(!p->signal)) 1700 if (unlikely(!p->signal))
1683 return; 1701 return;
1684 1702
1703 utime = stime = cputime_zero;
1704
1685 switch (who) { 1705 switch (who) {
1706 case RUSAGE_BOTH:
1686 case RUSAGE_CHILDREN: 1707 case RUSAGE_CHILDREN:
1687 spin_lock_irqsave(&p->sighand->siglock, flags); 1708 spin_lock_irqsave(&p->sighand->siglock, flags);
1688 utime = p->signal->cutime; 1709 utime = p->signal->cutime;
@@ -1692,22 +1713,11 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1692 r->ru_minflt = p->signal->cmin_flt; 1713 r->ru_minflt = p->signal->cmin_flt;
1693 r->ru_majflt = p->signal->cmaj_flt; 1714 r->ru_majflt = p->signal->cmaj_flt;
1694 spin_unlock_irqrestore(&p->sighand->siglock, flags); 1715 spin_unlock_irqrestore(&p->sighand->siglock, flags);
1695 cputime_to_timeval(utime, &r->ru_utime); 1716
1696 cputime_to_timeval(stime, &r->ru_stime); 1717 if (who == RUSAGE_CHILDREN)
1697 break; 1718 break;
1719
1698 case RUSAGE_SELF: 1720 case RUSAGE_SELF:
1699 spin_lock_irqsave(&p->sighand->siglock, flags);
1700 utime = stime = cputime_zero;
1701 goto sum_group;
1702 case RUSAGE_BOTH:
1703 spin_lock_irqsave(&p->sighand->siglock, flags);
1704 utime = p->signal->cutime;
1705 stime = p->signal->cstime;
1706 r->ru_nvcsw = p->signal->cnvcsw;
1707 r->ru_nivcsw = p->signal->cnivcsw;
1708 r->ru_minflt = p->signal->cmin_flt;
1709 r->ru_majflt = p->signal->cmaj_flt;
1710 sum_group:
1711 utime = cputime_add(utime, p->signal->utime); 1721 utime = cputime_add(utime, p->signal->utime);
1712 stime = cputime_add(stime, p->signal->stime); 1722 stime = cputime_add(stime, p->signal->stime);
1713 r->ru_nvcsw += p->signal->nvcsw; 1723 r->ru_nvcsw += p->signal->nvcsw;
@@ -1724,13 +1734,14 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1724 r->ru_majflt += t->maj_flt; 1734 r->ru_majflt += t->maj_flt;
1725 t = next_thread(t); 1735 t = next_thread(t);
1726 } while (t != p); 1736 } while (t != p);
1727 spin_unlock_irqrestore(&p->sighand->siglock, flags);
1728 cputime_to_timeval(utime, &r->ru_utime);
1729 cputime_to_timeval(stime, &r->ru_stime);
1730 break; 1737 break;
1738
1731 default: 1739 default:
1732 BUG(); 1740 BUG();
1733 } 1741 }
1742
1743 cputime_to_timeval(utime, &r->ru_utime);
1744 cputime_to_timeval(stime, &r->ru_stime);
1734} 1745}
1735 1746
1736int getrusage(struct task_struct *p, int who, struct rusage __user *ru) 1747int getrusage(struct task_struct *p, int who, struct rusage __user *ru)