aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c62
1 files changed, 28 insertions, 34 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 65ce60adc8e8..6144b36cd897 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -151,9 +151,8 @@ void __put_task_struct(struct task_struct *tsk)
151 WARN_ON(atomic_read(&tsk->usage)); 151 WARN_ON(atomic_read(&tsk->usage));
152 WARN_ON(tsk == current); 152 WARN_ON(tsk == current);
153 153
154 security_task_free(tsk); 154 put_cred(tsk->real_cred);
155 free_uid(tsk->user); 155 put_cred(tsk->cred);
156 put_group_info(tsk->group_info);
157 delayacct_tsk_free(tsk); 156 delayacct_tsk_free(tsk);
158 157
159 if (!profile_handoff_task(tsk)) 158 if (!profile_handoff_task(tsk))
@@ -822,12 +821,6 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
822 if (!sig) 821 if (!sig)
823 return -ENOMEM; 822 return -ENOMEM;
824 823
825 ret = copy_thread_group_keys(tsk);
826 if (ret < 0) {
827 kmem_cache_free(signal_cachep, sig);
828 return ret;
829 }
830
831 atomic_set(&sig->count, 1); 824 atomic_set(&sig->count, 1);
832 atomic_set(&sig->live, 1); 825 atomic_set(&sig->live, 1);
833 init_waitqueue_head(&sig->wait_chldexit); 826 init_waitqueue_head(&sig->wait_chldexit);
@@ -872,7 +865,6 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
872void __cleanup_signal(struct signal_struct *sig) 865void __cleanup_signal(struct signal_struct *sig)
873{ 866{
874 thread_group_cputime_free(sig); 867 thread_group_cputime_free(sig);
875 exit_thread_group_keys(sig);
876 tty_kref_put(sig->tty); 868 tty_kref_put(sig->tty);
877 kmem_cache_free(signal_cachep, sig); 869 kmem_cache_free(signal_cachep, sig);
878} 870}
@@ -988,16 +980,16 @@ static struct task_struct *copy_process(unsigned long clone_flags,
988 DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled); 980 DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
989#endif 981#endif
990 retval = -EAGAIN; 982 retval = -EAGAIN;
991 if (atomic_read(&p->user->processes) >= 983 if (atomic_read(&p->real_cred->user->processes) >=
992 p->signal->rlim[RLIMIT_NPROC].rlim_cur) { 984 p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
993 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) && 985 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
994 p->user != current->nsproxy->user_ns->root_user) 986 p->real_cred->user != INIT_USER)
995 goto bad_fork_free; 987 goto bad_fork_free;
996 } 988 }
997 989
998 atomic_inc(&p->user->__count); 990 retval = copy_creds(p, clone_flags);
999 atomic_inc(&p->user->processes); 991 if (retval < 0)
1000 get_group_info(p->group_info); 992 goto bad_fork_free;
1001 993
1002 /* 994 /*
1003 * If multiple threads are within copy_process(), then this check 995 * If multiple threads are within copy_process(), then this check
@@ -1052,10 +1044,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1052 do_posix_clock_monotonic_gettime(&p->start_time); 1044 do_posix_clock_monotonic_gettime(&p->start_time);
1053 p->real_start_time = p->start_time; 1045 p->real_start_time = p->start_time;
1054 monotonic_to_bootbased(&p->real_start_time); 1046 monotonic_to_bootbased(&p->real_start_time);
1055#ifdef CONFIG_SECURITY
1056 p->security = NULL;
1057#endif
1058 p->cap_bset = current->cap_bset;
1059 p->io_context = NULL; 1047 p->io_context = NULL;
1060 p->audit_context = NULL; 1048 p->audit_context = NULL;
1061 cgroup_fork(p); 1049 cgroup_fork(p);
@@ -1102,10 +1090,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1102 /* Perform scheduler related setup. Assign this task to a CPU. */ 1090 /* Perform scheduler related setup. Assign this task to a CPU. */
1103 sched_fork(p, clone_flags); 1091 sched_fork(p, clone_flags);
1104 1092
1105 if ((retval = security_task_alloc(p)))
1106 goto bad_fork_cleanup_policy;
1107 if ((retval = audit_alloc(p))) 1093 if ((retval = audit_alloc(p)))
1108 goto bad_fork_cleanup_security; 1094 goto bad_fork_cleanup_policy;
1109 /* copy all the process information */ 1095 /* copy all the process information */
1110 if ((retval = copy_semundo(clone_flags, p))) 1096 if ((retval = copy_semundo(clone_flags, p)))
1111 goto bad_fork_cleanup_audit; 1097 goto bad_fork_cleanup_audit;
@@ -1119,10 +1105,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1119 goto bad_fork_cleanup_sighand; 1105 goto bad_fork_cleanup_sighand;
1120 if ((retval = copy_mm(clone_flags, p))) 1106 if ((retval = copy_mm(clone_flags, p)))
1121 goto bad_fork_cleanup_signal; 1107 goto bad_fork_cleanup_signal;
1122 if ((retval = copy_keys(clone_flags, p)))
1123 goto bad_fork_cleanup_mm;
1124 if ((retval = copy_namespaces(clone_flags, p))) 1108 if ((retval = copy_namespaces(clone_flags, p)))
1125 goto bad_fork_cleanup_keys; 1109 goto bad_fork_cleanup_mm;
1126 if ((retval = copy_io(clone_flags, p))) 1110 if ((retval = copy_io(clone_flags, p)))
1127 goto bad_fork_cleanup_namespaces; 1111 goto bad_fork_cleanup_namespaces;
1128 retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs); 1112 retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
@@ -1291,8 +1275,6 @@ bad_fork_cleanup_io:
1291 put_io_context(p->io_context); 1275 put_io_context(p->io_context);
1292bad_fork_cleanup_namespaces: 1276bad_fork_cleanup_namespaces:
1293 exit_task_namespaces(p); 1277 exit_task_namespaces(p);
1294bad_fork_cleanup_keys:
1295 exit_keys(p);
1296bad_fork_cleanup_mm: 1278bad_fork_cleanup_mm:
1297 if (p->mm) 1279 if (p->mm)
1298 mmput(p->mm); 1280 mmput(p->mm);
@@ -1308,8 +1290,6 @@ bad_fork_cleanup_semundo:
1308 exit_sem(p); 1290 exit_sem(p);
1309bad_fork_cleanup_audit: 1291bad_fork_cleanup_audit:
1310 audit_free(p); 1292 audit_free(p);
1311bad_fork_cleanup_security:
1312 security_task_free(p);
1313bad_fork_cleanup_policy: 1293bad_fork_cleanup_policy:
1314#ifdef CONFIG_NUMA 1294#ifdef CONFIG_NUMA
1315 mpol_put(p->mempolicy); 1295 mpol_put(p->mempolicy);
@@ -1322,9 +1302,9 @@ bad_fork_cleanup_cgroup:
1322bad_fork_cleanup_put_domain: 1302bad_fork_cleanup_put_domain:
1323 module_put(task_thread_info(p)->exec_domain->module); 1303 module_put(task_thread_info(p)->exec_domain->module);
1324bad_fork_cleanup_count: 1304bad_fork_cleanup_count:
1325 put_group_info(p->group_info); 1305 atomic_dec(&p->cred->user->processes);
1326 atomic_dec(&p->user->processes); 1306 put_cred(p->real_cred);
1327 free_uid(p->user); 1307 put_cred(p->cred);
1328bad_fork_free: 1308bad_fork_free:
1329 free_task(p); 1309 free_task(p);
1330fork_out: 1310fork_out:
@@ -1368,6 +1348,21 @@ long do_fork(unsigned long clone_flags,
1368 long nr; 1348 long nr;
1369 1349
1370 /* 1350 /*
1351 * Do some preliminary argument and permissions checking before we
1352 * actually start allocating stuff
1353 */
1354 if (clone_flags & CLONE_NEWUSER) {
1355 if (clone_flags & CLONE_THREAD)
1356 return -EINVAL;
1357 /* hopefully this check will go away when userns support is
1358 * complete
1359 */
1360 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SETUID) ||
1361 !capable(CAP_SETGID))
1362 return -EPERM;
1363 }
1364
1365 /*
1371 * We hope to recycle these flags after 2.6.26 1366 * We hope to recycle these flags after 2.6.26
1372 */ 1367 */
1373 if (unlikely(clone_flags & CLONE_STOPPED)) { 1368 if (unlikely(clone_flags & CLONE_STOPPED)) {
@@ -1615,8 +1610,7 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
1615 err = -EINVAL; 1610 err = -EINVAL;
1616 if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND| 1611 if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
1617 CLONE_VM|CLONE_FILES|CLONE_SYSVSEM| 1612 CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
1618 CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWUSER| 1613 CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET))
1619 CLONE_NEWNET))
1620 goto bad_unshare_out; 1614 goto bad_unshare_out;
1621 1615
1622 /* 1616 /*