diff options
Diffstat (limited to 'kernel/sys.c')
-rw-r--r-- | kernel/sys.c | 57 |
1 files changed, 21 insertions, 36 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index e3c08d4324de..a626116af5db 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; |
@@ -994,17 +991,14 @@ asmlinkage long sys_getpgid(pid_t pid) | |||
994 | else { | 991 | else { |
995 | int retval; | 992 | int retval; |
996 | struct task_struct *p; | 993 | struct task_struct *p; |
997 | struct pid_namespace *ns; | ||
998 | |||
999 | ns = current->nsproxy->pid_ns; | ||
1000 | 994 | ||
1001 | read_lock(&tasklist_lock); | 995 | read_lock(&tasklist_lock); |
1002 | p = find_task_by_pid_ns(pid, ns); | 996 | p = find_task_by_vpid(pid); |
1003 | retval = -ESRCH; | 997 | retval = -ESRCH; |
1004 | if (p) { | 998 | if (p) { |
1005 | retval = security_task_getpgid(p); | 999 | retval = security_task_getpgid(p); |
1006 | if (!retval) | 1000 | if (!retval) |
1007 | retval = task_pgrp_nr_ns(p, ns); | 1001 | retval = task_pgrp_vnr(p); |
1008 | } | 1002 | } |
1009 | read_unlock(&tasklist_lock); | 1003 | read_unlock(&tasklist_lock); |
1010 | return retval; | 1004 | return retval; |
@@ -1028,19 +1022,16 @@ asmlinkage long sys_getsid(pid_t pid) | |||
1028 | else { | 1022 | else { |
1029 | int retval; | 1023 | int retval; |
1030 | struct task_struct *p; | 1024 | struct task_struct *p; |
1031 | struct pid_namespace *ns; | ||
1032 | |||
1033 | ns = current->nsproxy->pid_ns; | ||
1034 | 1025 | ||
1035 | read_lock(&tasklist_lock); | 1026 | rcu_read_lock(); |
1036 | p = find_task_by_pid_ns(pid, ns); | 1027 | p = find_task_by_vpid(pid); |
1037 | retval = -ESRCH; | 1028 | retval = -ESRCH; |
1038 | if (p) { | 1029 | if (p) { |
1039 | retval = security_task_getsid(p); | 1030 | retval = security_task_getsid(p); |
1040 | if (!retval) | 1031 | if (!retval) |
1041 | retval = task_session_nr_ns(p, ns); | 1032 | retval = task_session_vnr(p); |
1042 | } | 1033 | } |
1043 | read_unlock(&tasklist_lock); | 1034 | rcu_read_unlock(); |
1044 | return retval; | 1035 | return retval; |
1045 | } | 1036 | } |
1046 | } | 1037 | } |
@@ -1048,35 +1039,29 @@ asmlinkage long sys_getsid(pid_t pid) | |||
1048 | asmlinkage long sys_setsid(void) | 1039 | asmlinkage long sys_setsid(void) |
1049 | { | 1040 | { |
1050 | struct task_struct *group_leader = current->group_leader; | 1041 | struct task_struct *group_leader = current->group_leader; |
1051 | pid_t session; | 1042 | struct pid *sid = task_pid(group_leader); |
1043 | pid_t session = pid_vnr(sid); | ||
1052 | int err = -EPERM; | 1044 | int err = -EPERM; |
1053 | 1045 | ||
1054 | write_lock_irq(&tasklist_lock); | 1046 | write_lock_irq(&tasklist_lock); |
1055 | |||
1056 | /* Fail if I am already a session leader */ | 1047 | /* Fail if I am already a session leader */ |
1057 | if (group_leader->signal->leader) | 1048 | if (group_leader->signal->leader) |
1058 | goto out; | 1049 | goto out; |
1059 | 1050 | ||
1060 | session = group_leader->pid; | ||
1061 | /* Fail if a process group id already exists that equals the | 1051 | /* Fail if a process group id already exists that equals the |
1062 | * proposed session id. | 1052 | * proposed session id. |
1063 | * | ||
1064 | * Don't check if session id == 1 because kernel threads use this | ||
1065 | * session id and so the check will always fail and make it so | ||
1066 | * init cannot successfully call setsid. | ||
1067 | */ | 1053 | */ |
1068 | if (session > 1 && find_task_by_pid_type_ns(PIDTYPE_PGID, | 1054 | if (pid_task(sid, PIDTYPE_PGID)) |
1069 | session, &init_pid_ns)) | ||
1070 | goto out; | 1055 | goto out; |
1071 | 1056 | ||
1072 | group_leader->signal->leader = 1; | 1057 | group_leader->signal->leader = 1; |
1073 | __set_special_pids(session, session); | 1058 | __set_special_pids(sid); |
1074 | 1059 | ||
1075 | spin_lock(&group_leader->sighand->siglock); | 1060 | spin_lock(&group_leader->sighand->siglock); |
1076 | group_leader->signal->tty = NULL; | 1061 | group_leader->signal->tty = NULL; |
1077 | spin_unlock(&group_leader->sighand->siglock); | 1062 | spin_unlock(&group_leader->sighand->siglock); |
1078 | 1063 | ||
1079 | err = task_pgrp_vnr(group_leader); | 1064 | err = session; |
1080 | out: | 1065 | out: |
1081 | write_unlock_irq(&tasklist_lock); | 1066 | write_unlock_irq(&tasklist_lock); |
1082 | return err; | 1067 | return err; |