aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 1d68f1255dd8..6715ebc3761d 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -61,6 +61,7 @@
61#include <linux/proc_fs.h> 61#include <linux/proc_fs.h>
62#include <linux/blkdev.h> 62#include <linux/blkdev.h>
63#include <trace/sched.h> 63#include <trace/sched.h>
64#include <linux/magic.h>
64 65
65#include <asm/pgtable.h> 66#include <asm/pgtable.h>
66#include <asm/pgalloc.h> 67#include <asm/pgalloc.h>
@@ -212,6 +213,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
212{ 213{
213 struct task_struct *tsk; 214 struct task_struct *tsk;
214 struct thread_info *ti; 215 struct thread_info *ti;
216 unsigned long *stackend;
217
215 int err; 218 int err;
216 219
217 prepare_to_copy(orig); 220 prepare_to_copy(orig);
@@ -237,6 +240,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
237 goto out; 240 goto out;
238 241
239 setup_thread_stack(tsk, orig); 242 setup_thread_stack(tsk, orig);
243 stackend = end_of_stack(tsk);
244 *stackend = STACK_END_MAGIC; /* for overflow detection */
240 245
241#ifdef CONFIG_CC_STACKPROTECTOR 246#ifdef CONFIG_CC_STACKPROTECTOR
242 tsk->stack_canary = get_random_int(); 247 tsk->stack_canary = get_random_int();
@@ -817,17 +822,17 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig)
817static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) 822static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
818{ 823{
819 struct signal_struct *sig; 824 struct signal_struct *sig;
820 int ret;
821 825
822 if (clone_flags & CLONE_THREAD) { 826 if (clone_flags & CLONE_THREAD) {
823 ret = thread_group_cputime_clone_thread(current); 827 atomic_inc(&current->signal->count);
824 if (likely(!ret)) { 828 atomic_inc(&current->signal->live);
825 atomic_inc(&current->signal->count); 829 return 0;
826 atomic_inc(&current->signal->live);
827 }
828 return ret;
829 } 830 }
830 sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); 831 sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
832
833 if (sig)
834 posix_cpu_timers_init_group(sig);
835
831 tsk->signal = sig; 836 tsk->signal = sig;
832 if (!sig) 837 if (!sig)
833 return -ENOMEM; 838 return -ENOMEM;
@@ -851,21 +856,20 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
851 sig->tty_old_pgrp = NULL; 856 sig->tty_old_pgrp = NULL;
852 sig->tty = NULL; 857 sig->tty = NULL;
853 858
854 sig->cutime = sig->cstime = cputime_zero; 859 sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero;
855 sig->gtime = cputime_zero; 860 sig->gtime = cputime_zero;
856 sig->cgtime = cputime_zero; 861 sig->cgtime = cputime_zero;
857 sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; 862 sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
858 sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; 863 sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
859 sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; 864 sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0;
860 task_io_accounting_init(&sig->ioac); 865 task_io_accounting_init(&sig->ioac);
866 sig->sum_sched_runtime = 0;
861 taskstats_tgid_init(sig); 867 taskstats_tgid_init(sig);
862 868
863 task_lock(current->group_leader); 869 task_lock(current->group_leader);
864 memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim); 870 memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim);
865 task_unlock(current->group_leader); 871 task_unlock(current->group_leader);
866 872
867 posix_cpu_timers_init_group(sig);
868
869 acct_init_pacct(&sig->pacct); 873 acct_init_pacct(&sig->pacct);
870 874
871 tty_audit_fork(sig); 875 tty_audit_fork(sig);
@@ -901,7 +905,7 @@ static void copy_flags(unsigned long clone_flags, struct task_struct *p)
901 clear_freeze_flag(p); 905 clear_freeze_flag(p);
902} 906}
903 907
904asmlinkage long sys_set_tid_address(int __user *tidptr) 908SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr)
905{ 909{
906 current->clear_child_tid = tidptr; 910 current->clear_child_tid = tidptr;
907 911
@@ -1007,6 +1011,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1007 * triggers too late. This doesn't hurt, the check is only there 1011 * triggers too late. This doesn't hurt, the check is only there
1008 * to stop root fork bombs. 1012 * to stop root fork bombs.
1009 */ 1013 */
1014 retval = -EAGAIN;
1010 if (nr_threads >= max_threads) 1015 if (nr_threads >= max_threads)
1011 goto bad_fork_cleanup_count; 1016 goto bad_fork_cleanup_count;
1012 1017
@@ -1095,7 +1100,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1095#ifdef CONFIG_DEBUG_MUTEXES 1100#ifdef CONFIG_DEBUG_MUTEXES
1096 p->blocked_on = NULL; /* not blocked yet */ 1101 p->blocked_on = NULL; /* not blocked yet */
1097#endif 1102#endif
1098 if (unlikely(ptrace_reparented(current))) 1103 if (unlikely(current->ptrace))
1099 ptrace_fork(p, clone_flags); 1104 ptrace_fork(p, clone_flags);
1100 1105
1101 /* Perform scheduler related setup. Assign this task to a CPU. */ 1106 /* Perform scheduler related setup. Assign this task to a CPU. */
@@ -1179,10 +1184,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1179#endif 1184#endif
1180 clear_all_latency_tracing(p); 1185 clear_all_latency_tracing(p);
1181 1186
1182 /* Our parent execution domain becomes current domain
1183 These must match for thread signalling to apply */
1184 p->parent_exec_id = p->self_exec_id;
1185
1186 /* ok, now we should be set up.. */ 1187 /* ok, now we should be set up.. */
1187 p->exit_signal = (clone_flags & CLONE_THREAD) ? -1 : (clone_flags & CSIGNAL); 1188 p->exit_signal = (clone_flags & CLONE_THREAD) ? -1 : (clone_flags & CSIGNAL);
1188 p->pdeath_signal = 0; 1189 p->pdeath_signal = 0;
@@ -1220,10 +1221,13 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1220 set_task_cpu(p, smp_processor_id()); 1221 set_task_cpu(p, smp_processor_id());
1221 1222
1222 /* CLONE_PARENT re-uses the old parent */ 1223 /* CLONE_PARENT re-uses the old parent */
1223 if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) 1224 if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) {
1224 p->real_parent = current->real_parent; 1225 p->real_parent = current->real_parent;
1225 else 1226 p->parent_exec_id = current->parent_exec_id;
1227 } else {
1226 p->real_parent = current; 1228 p->real_parent = current;
1229 p->parent_exec_id = current->self_exec_id;
1230 }
1227 1231
1228 spin_lock(&current->sighand->siglock); 1232 spin_lock(&current->sighand->siglock);
1229 1233
@@ -1603,7 +1607,7 @@ static int unshare_fd(unsigned long unshare_flags, struct files_struct **new_fdp
1603 * constructed. Here we are modifying the current, active, 1607 * constructed. Here we are modifying the current, active,
1604 * task_struct. 1608 * task_struct.
1605 */ 1609 */
1606asmlinkage long sys_unshare(unsigned long unshare_flags) 1610SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
1607{ 1611{
1608 int err = 0; 1612 int err = 0;
1609 struct fs_struct *fs, *new_fs = NULL; 1613 struct fs_struct *fs, *new_fs = NULL;