diff options
Diffstat (limited to 'kernel/sys.c')
-rw-r--r-- | kernel/sys.c | 62 |
1 files changed, 30 insertions, 32 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index eecf84526afe..b6941e06d5d5 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -489,6 +489,12 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user | |||
489 | magic2 != LINUX_REBOOT_MAGIC2C)) | 489 | magic2 != LINUX_REBOOT_MAGIC2C)) |
490 | return -EINVAL; | 490 | return -EINVAL; |
491 | 491 | ||
492 | /* Instead of trying to make the power_off code look like | ||
493 | * halt when pm_power_off is not set do it the easy way. | ||
494 | */ | ||
495 | if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off) | ||
496 | cmd = LINUX_REBOOT_CMD_HALT; | ||
497 | |||
492 | lock_kernel(); | 498 | lock_kernel(); |
493 | switch (cmd) { | 499 | switch (cmd) { |
494 | case LINUX_REBOOT_CMD_RESTART: | 500 | case LINUX_REBOOT_CMD_RESTART: |
@@ -1084,10 +1090,11 @@ asmlinkage long sys_times(struct tms __user * tbuf) | |||
1084 | asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) | 1090 | asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) |
1085 | { | 1091 | { |
1086 | struct task_struct *p; | 1092 | struct task_struct *p; |
1093 | struct task_struct *group_leader = current->group_leader; | ||
1087 | int err = -EINVAL; | 1094 | int err = -EINVAL; |
1088 | 1095 | ||
1089 | if (!pid) | 1096 | if (!pid) |
1090 | pid = current->pid; | 1097 | pid = group_leader->pid; |
1091 | if (!pgid) | 1098 | if (!pgid) |
1092 | pgid = pid; | 1099 | pgid = pid; |
1093 | if (pgid < 0) | 1100 | if (pgid < 0) |
@@ -1107,16 +1114,16 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) | |||
1107 | if (!thread_group_leader(p)) | 1114 | if (!thread_group_leader(p)) |
1108 | goto out; | 1115 | goto out; |
1109 | 1116 | ||
1110 | if (p->parent == current || p->real_parent == current) { | 1117 | if (p->real_parent == group_leader) { |
1111 | err = -EPERM; | 1118 | err = -EPERM; |
1112 | if (p->signal->session != current->signal->session) | 1119 | if (p->signal->session != group_leader->signal->session) |
1113 | goto out; | 1120 | goto out; |
1114 | err = -EACCES; | 1121 | err = -EACCES; |
1115 | if (p->did_exec) | 1122 | if (p->did_exec) |
1116 | goto out; | 1123 | goto out; |
1117 | } else { | 1124 | } else { |
1118 | err = -ESRCH; | 1125 | err = -ESRCH; |
1119 | if (p != current) | 1126 | if (p != group_leader) |
1120 | goto out; | 1127 | goto out; |
1121 | } | 1128 | } |
1122 | 1129 | ||
@@ -1128,7 +1135,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) | |||
1128 | struct task_struct *p; | 1135 | struct task_struct *p; |
1129 | 1136 | ||
1130 | do_each_task_pid(pgid, PIDTYPE_PGID, p) { | 1137 | do_each_task_pid(pgid, PIDTYPE_PGID, p) { |
1131 | if (p->signal->session == current->signal->session) | 1138 | if (p->signal->session == group_leader->signal->session) |
1132 | goto ok_pgid; | 1139 | goto ok_pgid; |
1133 | } while_each_task_pid(pgid, PIDTYPE_PGID, p); | 1140 | } while_each_task_pid(pgid, PIDTYPE_PGID, p); |
1134 | goto out; | 1141 | goto out; |
@@ -1208,24 +1215,22 @@ asmlinkage long sys_getsid(pid_t pid) | |||
1208 | 1215 | ||
1209 | asmlinkage long sys_setsid(void) | 1216 | asmlinkage long sys_setsid(void) |
1210 | { | 1217 | { |
1218 | struct task_struct *group_leader = current->group_leader; | ||
1211 | struct pid *pid; | 1219 | struct pid *pid; |
1212 | int err = -EPERM; | 1220 | int err = -EPERM; |
1213 | 1221 | ||
1214 | if (!thread_group_leader(current)) | ||
1215 | return -EINVAL; | ||
1216 | |||
1217 | down(&tty_sem); | 1222 | down(&tty_sem); |
1218 | write_lock_irq(&tasklist_lock); | 1223 | write_lock_irq(&tasklist_lock); |
1219 | 1224 | ||
1220 | pid = find_pid(PIDTYPE_PGID, current->pid); | 1225 | pid = find_pid(PIDTYPE_PGID, group_leader->pid); |
1221 | if (pid) | 1226 | if (pid) |
1222 | goto out; | 1227 | goto out; |
1223 | 1228 | ||
1224 | current->signal->leader = 1; | 1229 | group_leader->signal->leader = 1; |
1225 | __set_special_pids(current->pid, current->pid); | 1230 | __set_special_pids(group_leader->pid, group_leader->pid); |
1226 | current->signal->tty = NULL; | 1231 | group_leader->signal->tty = NULL; |
1227 | current->signal->tty_old_pgrp = 0; | 1232 | group_leader->signal->tty_old_pgrp = 0; |
1228 | err = process_group(current); | 1233 | err = process_group(group_leader); |
1229 | out: | 1234 | out: |
1230 | write_unlock_irq(&tasklist_lock); | 1235 | write_unlock_irq(&tasklist_lock); |
1231 | up(&tty_sem); | 1236 | up(&tty_sem); |
@@ -1687,7 +1692,10 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r) | |||
1687 | if (unlikely(!p->signal)) | 1692 | if (unlikely(!p->signal)) |
1688 | return; | 1693 | return; |
1689 | 1694 | ||
1695 | utime = stime = cputime_zero; | ||
1696 | |||
1690 | switch (who) { | 1697 | switch (who) { |
1698 | case RUSAGE_BOTH: | ||
1691 | case RUSAGE_CHILDREN: | 1699 | case RUSAGE_CHILDREN: |
1692 | spin_lock_irqsave(&p->sighand->siglock, flags); | 1700 | spin_lock_irqsave(&p->sighand->siglock, flags); |
1693 | utime = p->signal->cutime; | 1701 | utime = p->signal->cutime; |
@@ -1697,22 +1705,11 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r) | |||
1697 | r->ru_minflt = p->signal->cmin_flt; | 1705 | r->ru_minflt = p->signal->cmin_flt; |
1698 | r->ru_majflt = p->signal->cmaj_flt; | 1706 | r->ru_majflt = p->signal->cmaj_flt; |
1699 | spin_unlock_irqrestore(&p->sighand->siglock, flags); | 1707 | spin_unlock_irqrestore(&p->sighand->siglock, flags); |
1700 | cputime_to_timeval(utime, &r->ru_utime); | 1708 | |
1701 | cputime_to_timeval(stime, &r->ru_stime); | 1709 | if (who == RUSAGE_CHILDREN) |
1702 | break; | 1710 | break; |
1711 | |||
1703 | case RUSAGE_SELF: | 1712 | 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); | 1713 | utime = cputime_add(utime, p->signal->utime); |
1717 | stime = cputime_add(stime, p->signal->stime); | 1714 | stime = cputime_add(stime, p->signal->stime); |
1718 | r->ru_nvcsw += p->signal->nvcsw; | 1715 | r->ru_nvcsw += p->signal->nvcsw; |
@@ -1729,13 +1726,14 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r) | |||
1729 | r->ru_majflt += t->maj_flt; | 1726 | r->ru_majflt += t->maj_flt; |
1730 | t = next_thread(t); | 1727 | t = next_thread(t); |
1731 | } while (t != p); | 1728 | } 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; | 1729 | break; |
1730 | |||
1736 | default: | 1731 | default: |
1737 | BUG(); | 1732 | BUG(); |
1738 | } | 1733 | } |
1734 | |||
1735 | cputime_to_timeval(utime, &r->ru_utime); | ||
1736 | cputime_to_timeval(stime, &r->ru_stime); | ||
1739 | } | 1737 | } |
1740 | 1738 | ||
1741 | int getrusage(struct task_struct *p, int who, struct rusage __user *ru) | 1739 | int getrusage(struct task_struct *p, int who, struct rusage __user *ru) |