diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sys.c | 23 |
1 files changed, 10 insertions, 13 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index e3c08d4324de..42136dd453d1 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -916,8 +916,8 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) | |||
916 | { | 916 | { |
917 | struct task_struct *p; | 917 | struct task_struct *p; |
918 | struct task_struct *group_leader = current->group_leader; | 918 | struct task_struct *group_leader = current->group_leader; |
919 | int err = -EINVAL; | 919 | struct pid *pgrp; |
920 | struct pid_namespace *ns; | 920 | int err; |
921 | 921 | ||
922 | if (!pid) | 922 | if (!pid) |
923 | pid = task_pid_vnr(group_leader); | 923 | pid = task_pid_vnr(group_leader); |
@@ -929,12 +929,10 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) | |||
929 | /* From this point forward we keep holding onto the tasklist lock | 929 | /* From this point forward we keep holding onto the tasklist lock |
930 | * so that our parent does not change from under us. -DaveM | 930 | * so that our parent does not change from under us. -DaveM |
931 | */ | 931 | */ |
932 | ns = current->nsproxy->pid_ns; | ||
933 | |||
934 | write_lock_irq(&tasklist_lock); | 932 | write_lock_irq(&tasklist_lock); |
935 | 933 | ||
936 | err = -ESRCH; | 934 | err = -ESRCH; |
937 | p = find_task_by_pid_ns(pid, ns); | 935 | p = find_task_by_vpid(pid); |
938 | if (!p) | 936 | if (!p) |
939 | goto out; | 937 | goto out; |
940 | 938 | ||
@@ -942,7 +940,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) | |||
942 | if (!thread_group_leader(p)) | 940 | if (!thread_group_leader(p)) |
943 | goto out; | 941 | goto out; |
944 | 942 | ||
945 | if (p->real_parent->tgid == group_leader->tgid) { | 943 | if (same_thread_group(p->real_parent, group_leader)) { |
946 | err = -EPERM; | 944 | err = -EPERM; |
947 | if (task_session(p) != task_session(group_leader)) | 945 | if (task_session(p) != task_session(group_leader)) |
948 | goto out; | 946 | goto out; |
@@ -959,10 +957,12 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) | |||
959 | if (p->signal->leader) | 957 | if (p->signal->leader) |
960 | goto out; | 958 | goto out; |
961 | 959 | ||
960 | pgrp = task_pid(p); | ||
962 | if (pgid != pid) { | 961 | if (pgid != pid) { |
963 | struct task_struct *g; | 962 | struct task_struct *g; |
964 | 963 | ||
965 | g = find_task_by_pid_type_ns(PIDTYPE_PGID, pgid, ns); | 964 | pgrp = find_vpid(pgid); |
965 | g = pid_task(pgrp, PIDTYPE_PGID); | ||
966 | if (!g || task_session(g) != task_session(group_leader)) | 966 | if (!g || task_session(g) != task_session(group_leader)) |
967 | goto out; | 967 | goto out; |
968 | } | 968 | } |
@@ -971,13 +971,10 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) | |||
971 | if (err) | 971 | if (err) |
972 | goto out; | 972 | goto out; |
973 | 973 | ||
974 | if (task_pgrp_nr_ns(p, ns) != pgid) { | 974 | if (task_pgrp(p) != pgrp) { |
975 | struct pid *pid; | ||
976 | |||
977 | detach_pid(p, PIDTYPE_PGID); | 975 | detach_pid(p, PIDTYPE_PGID); |
978 | pid = find_vpid(pgid); | 976 | attach_pid(p, PIDTYPE_PGID, pgrp); |
979 | attach_pid(p, PIDTYPE_PGID, pid); | 977 | set_task_pgrp(p, pid_nr(pgrp)); |
980 | set_task_pgrp(p, pid_nr(pid)); | ||
981 | } | 978 | } |
982 | 979 | ||
983 | err = 0; | 980 | err = 0; |