aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
authorJames Morris <jmorris@namei.org>2008-12-24 19:40:09 -0500
committerJames Morris <jmorris@namei.org>2008-12-24 19:40:09 -0500
commitcbacc2c7f066a1e01b33b0e27ae5efbf534bc2db (patch)
tree90d1093131d2a3543a8b3b1f3364e7c6f4081a93 /kernel/fork.c
parent4a6908a3a050aacc9c3a2f36b276b46c0629ad91 (diff)
parent74192246910ff4fb95309ba1a683215644beeb62 (diff)
Merge branch 'next' into for-linus
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 495da2e9a8b4..4e8ca23c0ede 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -147,9 +147,8 @@ void __put_task_struct(struct task_struct *tsk)
147 WARN_ON(atomic_read(&tsk->usage)); 147 WARN_ON(atomic_read(&tsk->usage));
148 WARN_ON(tsk == current); 148 WARN_ON(tsk == current);
149 149
150 security_task_free(tsk); 150 put_cred(tsk->real_cred);
151 free_uid(tsk->user); 151 put_cred(tsk->cred);
152 put_group_info(tsk->group_info);
153 delayacct_tsk_free(tsk); 152 delayacct_tsk_free(tsk);
154 153
155 if (!profile_handoff_task(tsk)) 154 if (!profile_handoff_task(tsk))
@@ -818,12 +817,6 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
818 if (!sig) 817 if (!sig)
819 return -ENOMEM; 818 return -ENOMEM;
820 819
821 ret = copy_thread_group_keys(tsk);
822 if (ret < 0) {
823 kmem_cache_free(signal_cachep, sig);
824 return ret;
825 }
826
827 atomic_set(&sig->count, 1); 820 atomic_set(&sig->count, 1);
828 atomic_set(&sig->live, 1); 821 atomic_set(&sig->live, 1);
829 init_waitqueue_head(&sig->wait_chldexit); 822 init_waitqueue_head(&sig->wait_chldexit);
@@ -868,7 +861,6 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
868void __cleanup_signal(struct signal_struct *sig) 861void __cleanup_signal(struct signal_struct *sig)
869{ 862{
870 thread_group_cputime_free(sig); 863 thread_group_cputime_free(sig);
871 exit_thread_group_keys(sig);
872 tty_kref_put(sig->tty); 864 tty_kref_put(sig->tty);
873 kmem_cache_free(signal_cachep, sig); 865 kmem_cache_free(signal_cachep, sig);
874} 866}
@@ -984,16 +976,16 @@ static struct task_struct *copy_process(unsigned long clone_flags,
984 DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled); 976 DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
985#endif 977#endif
986 retval = -EAGAIN; 978 retval = -EAGAIN;
987 if (atomic_read(&p->user->processes) >= 979 if (atomic_read(&p->real_cred->user->processes) >=
988 p->signal->rlim[RLIMIT_NPROC].rlim_cur) { 980 p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
989 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) && 981 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
990 p->user != current->nsproxy->user_ns->root_user) 982 p->real_cred->user != INIT_USER)
991 goto bad_fork_free; 983 goto bad_fork_free;
992 } 984 }
993 985
994 atomic_inc(&p->user->__count); 986 retval = copy_creds(p, clone_flags);
995 atomic_inc(&p->user->processes); 987 if (retval < 0)
996 get_group_info(p->group_info); 988 goto bad_fork_free;
997 989
998 /* 990 /*
999 * If multiple threads are within copy_process(), then this check 991 * If multiple threads are within copy_process(), then this check
@@ -1048,10 +1040,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1048 do_posix_clock_monotonic_gettime(&p->start_time); 1040 do_posix_clock_monotonic_gettime(&p->start_time);
1049 p->real_start_time = p->start_time; 1041 p->real_start_time = p->start_time;
1050 monotonic_to_bootbased(&p->real_start_time); 1042 monotonic_to_bootbased(&p->real_start_time);
1051#ifdef CONFIG_SECURITY
1052 p->security = NULL;
1053#endif
1054 p->cap_bset = current->cap_bset;
1055 p->io_context = NULL; 1043 p->io_context = NULL;
1056 p->audit_context = NULL; 1044 p->audit_context = NULL;
1057 cgroup_fork(p); 1045 cgroup_fork(p);
@@ -1096,10 +1084,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1096 /* Perform scheduler related setup. Assign this task to a CPU. */ 1084 /* Perform scheduler related setup. Assign this task to a CPU. */
1097 sched_fork(p, clone_flags); 1085 sched_fork(p, clone_flags);
1098 1086
1099 if ((retval = security_task_alloc(p)))
1100 goto bad_fork_cleanup_policy;
1101 if ((retval = audit_alloc(p))) 1087 if ((retval = audit_alloc(p)))
1102 goto bad_fork_cleanup_security; 1088 goto bad_fork_cleanup_policy;
1103 /* copy all the process information */ 1089 /* copy all the process information */
1104 if ((retval = copy_semundo(clone_flags, p))) 1090 if ((retval = copy_semundo(clone_flags, p)))
1105 goto bad_fork_cleanup_audit; 1091 goto bad_fork_cleanup_audit;
@@ -1113,10 +1099,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1113 goto bad_fork_cleanup_sighand; 1099 goto bad_fork_cleanup_sighand;
1114 if ((retval = copy_mm(clone_flags, p))) 1100 if ((retval = copy_mm(clone_flags, p)))
1115 goto bad_fork_cleanup_signal; 1101 goto bad_fork_cleanup_signal;
1116 if ((retval = copy_keys(clone_flags, p)))
1117 goto bad_fork_cleanup_mm;
1118 if ((retval = copy_namespaces(clone_flags, p))) 1102 if ((retval = copy_namespaces(clone_flags, p)))
1119 goto bad_fork_cleanup_keys; 1103 goto bad_fork_cleanup_mm;
1120 if ((retval = copy_io(clone_flags, p))) 1104 if ((retval = copy_io(clone_flags, p)))
1121 goto bad_fork_cleanup_namespaces; 1105 goto bad_fork_cleanup_namespaces;
1122 retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs); 1106 retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
@@ -1281,8 +1265,6 @@ bad_fork_cleanup_io:
1281 put_io_context(p->io_context); 1265 put_io_context(p->io_context);
1282bad_fork_cleanup_namespaces: 1266bad_fork_cleanup_namespaces:
1283 exit_task_namespaces(p); 1267 exit_task_namespaces(p);
1284bad_fork_cleanup_keys:
1285 exit_keys(p);
1286bad_fork_cleanup_mm: 1268bad_fork_cleanup_mm:
1287 if (p->mm) 1269 if (p->mm)
1288 mmput(p->mm); 1270 mmput(p->mm);
@@ -1298,8 +1280,6 @@ bad_fork_cleanup_semundo:
1298 exit_sem(p); 1280 exit_sem(p);
1299bad_fork_cleanup_audit: 1281bad_fork_cleanup_audit:
1300 audit_free(p); 1282 audit_free(p);
1301bad_fork_cleanup_security:
1302 security_task_free(p);
1303bad_fork_cleanup_policy: 1283bad_fork_cleanup_policy:
1304#ifdef CONFIG_NUMA 1284#ifdef CONFIG_NUMA
1305 mpol_put(p->mempolicy); 1285 mpol_put(p->mempolicy);
@@ -1312,9 +1292,9 @@ bad_fork_cleanup_cgroup:
1312bad_fork_cleanup_put_domain: 1292bad_fork_cleanup_put_domain:
1313 module_put(task_thread_info(p)->exec_domain->module); 1293 module_put(task_thread_info(p)->exec_domain->module);
1314bad_fork_cleanup_count: 1294bad_fork_cleanup_count:
1315 put_group_info(p->group_info); 1295 atomic_dec(&p->cred->user->processes);
1316 atomic_dec(&p->user->processes); 1296 put_cred(p->real_cred);
1317 free_uid(p->user); 1297 put_cred(p->cred);
1318bad_fork_free: 1298bad_fork_free:
1319 free_task(p); 1299 free_task(p);
1320fork_out: 1300fork_out:
@@ -1358,6 +1338,21 @@ long do_fork(unsigned long clone_flags,
1358 long nr; 1338 long nr;
1359 1339
1360 /* 1340 /*
1341 * Do some preliminary argument and permissions checking before we
1342 * actually start allocating stuff
1343 */
1344 if (clone_flags & CLONE_NEWUSER) {
1345 if (clone_flags & CLONE_THREAD)
1346 return -EINVAL;
1347 /* hopefully this check will go away when userns support is
1348 * complete
1349 */
1350 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SETUID) ||
1351 !capable(CAP_SETGID))
1352 return -EPERM;
1353 }
1354
1355 /*
1361 * We hope to recycle these flags after 2.6.26 1356 * We hope to recycle these flags after 2.6.26
1362 */ 1357 */
1363 if (unlikely(clone_flags & CLONE_STOPPED)) { 1358 if (unlikely(clone_flags & CLONE_STOPPED)) {
@@ -1605,8 +1600,7 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
1605 err = -EINVAL; 1600 err = -EINVAL;
1606 if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND| 1601 if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
1607 CLONE_VM|CLONE_FILES|CLONE_SYSVSEM| 1602 CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
1608 CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWUSER| 1603 CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET))
1609 CLONE_NEWNET))
1610 goto bad_unshare_out; 1604 goto bad_unshare_out;
1611 1605
1612 /* 1606 /*