diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-12-31 02:31:57 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-12-31 02:31:57 -0500 |
commit | a9de18eb761f7c1c860964b2e5addc1a35c7e861 (patch) | |
tree | 886e75fdfd09690cd262ca69cb7f5d1d42b48602 /kernel/fork.c | |
parent | b2aaf8f74cdc84a9182f6cabf198b7763bcb9d40 (diff) | |
parent | 6a94cb73064c952255336cc57731904174b2c58f (diff) |
Merge branch 'linus' into stackprotector
Conflicts:
arch/x86/include/asm/pda.h
kernel/fork.c
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 204 |
1 files changed, 118 insertions, 86 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 99c5c655b098..913284e3db14 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -40,12 +40,14 @@ | |||
40 | #include <linux/jiffies.h> | 40 | #include <linux/jiffies.h> |
41 | #include <linux/tracehook.h> | 41 | #include <linux/tracehook.h> |
42 | #include <linux/futex.h> | 42 | #include <linux/futex.h> |
43 | #include <linux/compat.h> | ||
43 | #include <linux/task_io_accounting_ops.h> | 44 | #include <linux/task_io_accounting_ops.h> |
44 | #include <linux/rcupdate.h> | 45 | #include <linux/rcupdate.h> |
45 | #include <linux/ptrace.h> | 46 | #include <linux/ptrace.h> |
46 | #include <linux/mount.h> | 47 | #include <linux/mount.h> |
47 | #include <linux/audit.h> | 48 | #include <linux/audit.h> |
48 | #include <linux/memcontrol.h> | 49 | #include <linux/memcontrol.h> |
50 | #include <linux/ftrace.h> | ||
49 | #include <linux/profile.h> | 51 | #include <linux/profile.h> |
50 | #include <linux/rmap.h> | 52 | #include <linux/rmap.h> |
51 | #include <linux/acct.h> | 53 | #include <linux/acct.h> |
@@ -58,6 +60,7 @@ | |||
58 | #include <linux/tty.h> | 60 | #include <linux/tty.h> |
59 | #include <linux/proc_fs.h> | 61 | #include <linux/proc_fs.h> |
60 | #include <linux/blkdev.h> | 62 | #include <linux/blkdev.h> |
63 | #include <trace/sched.h> | ||
61 | #include <linux/magic.h> | 64 | #include <linux/magic.h> |
62 | 65 | ||
63 | #include <asm/pgtable.h> | 66 | #include <asm/pgtable.h> |
@@ -79,6 +82,8 @@ DEFINE_PER_CPU(unsigned long, process_counts) = 0; | |||
79 | 82 | ||
80 | __cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */ | 83 | __cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */ |
81 | 84 | ||
85 | DEFINE_TRACE(sched_process_fork); | ||
86 | |||
82 | int nr_processes(void) | 87 | int nr_processes(void) |
83 | { | 88 | { |
84 | int cpu; | 89 | int cpu; |
@@ -136,6 +141,7 @@ void free_task(struct task_struct *tsk) | |||
136 | prop_local_destroy_single(&tsk->dirties); | 141 | prop_local_destroy_single(&tsk->dirties); |
137 | free_thread_info(tsk->stack); | 142 | free_thread_info(tsk->stack); |
138 | rt_mutex_debug_task_free(tsk); | 143 | rt_mutex_debug_task_free(tsk); |
144 | ftrace_graph_exit_task(tsk); | ||
139 | free_task_struct(tsk); | 145 | free_task_struct(tsk); |
140 | } | 146 | } |
141 | EXPORT_SYMBOL(free_task); | 147 | EXPORT_SYMBOL(free_task); |
@@ -146,9 +152,8 @@ void __put_task_struct(struct task_struct *tsk) | |||
146 | WARN_ON(atomic_read(&tsk->usage)); | 152 | WARN_ON(atomic_read(&tsk->usage)); |
147 | WARN_ON(tsk == current); | 153 | WARN_ON(tsk == current); |
148 | 154 | ||
149 | security_task_free(tsk); | 155 | put_cred(tsk->real_cred); |
150 | free_uid(tsk->user); | 156 | put_cred(tsk->cred); |
151 | put_group_info(tsk->group_info); | ||
152 | delayacct_tsk_free(tsk); | 157 | delayacct_tsk_free(tsk); |
153 | 158 | ||
154 | if (!profile_handoff_task(tsk)) | 159 | if (!profile_handoff_task(tsk)) |
@@ -318,17 +323,20 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | |||
318 | file = tmp->vm_file; | 323 | file = tmp->vm_file; |
319 | if (file) { | 324 | if (file) { |
320 | struct inode *inode = file->f_path.dentry->d_inode; | 325 | struct inode *inode = file->f_path.dentry->d_inode; |
326 | struct address_space *mapping = file->f_mapping; | ||
327 | |||
321 | get_file(file); | 328 | get_file(file); |
322 | if (tmp->vm_flags & VM_DENYWRITE) | 329 | if (tmp->vm_flags & VM_DENYWRITE) |
323 | atomic_dec(&inode->i_writecount); | 330 | atomic_dec(&inode->i_writecount); |
324 | 331 | spin_lock(&mapping->i_mmap_lock); | |
325 | /* insert tmp into the share list, just after mpnt */ | 332 | if (tmp->vm_flags & VM_SHARED) |
326 | spin_lock(&file->f_mapping->i_mmap_lock); | 333 | mapping->i_mmap_writable++; |
327 | tmp->vm_truncate_count = mpnt->vm_truncate_count; | 334 | tmp->vm_truncate_count = mpnt->vm_truncate_count; |
328 | flush_dcache_mmap_lock(file->f_mapping); | 335 | flush_dcache_mmap_lock(mapping); |
336 | /* insert tmp into the share list, just after mpnt */ | ||
329 | vma_prio_tree_add(tmp, mpnt); | 337 | vma_prio_tree_add(tmp, mpnt); |
330 | flush_dcache_mmap_unlock(file->f_mapping); | 338 | flush_dcache_mmap_unlock(mapping); |
331 | spin_unlock(&file->f_mapping->i_mmap_lock); | 339 | spin_unlock(&mapping->i_mmap_lock); |
332 | } | 340 | } |
333 | 341 | ||
334 | /* | 342 | /* |
@@ -412,8 +420,8 @@ static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) | |||
412 | set_mm_counter(mm, file_rss, 0); | 420 | set_mm_counter(mm, file_rss, 0); |
413 | set_mm_counter(mm, anon_rss, 0); | 421 | set_mm_counter(mm, anon_rss, 0); |
414 | spin_lock_init(&mm->page_table_lock); | 422 | spin_lock_init(&mm->page_table_lock); |
415 | rwlock_init(&mm->ioctx_list_lock); | 423 | spin_lock_init(&mm->ioctx_lock); |
416 | mm->ioctx_list = NULL; | 424 | INIT_HLIST_HEAD(&mm->ioctx_list); |
417 | mm->free_area_cache = TASK_UNMAPPED_BASE; | 425 | mm->free_area_cache = TASK_UNMAPPED_BASE; |
418 | mm->cached_hole_size = ~0UL; | 426 | mm->cached_hole_size = ~0UL; |
419 | mm_init_owner(mm, p); | 427 | mm_init_owner(mm, p); |
@@ -523,6 +531,16 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm) | |||
523 | { | 531 | { |
524 | struct completion *vfork_done = tsk->vfork_done; | 532 | struct completion *vfork_done = tsk->vfork_done; |
525 | 533 | ||
534 | /* Get rid of any futexes when releasing the mm */ | ||
535 | #ifdef CONFIG_FUTEX | ||
536 | if (unlikely(tsk->robust_list)) | ||
537 | exit_robust_list(tsk); | ||
538 | #ifdef CONFIG_COMPAT | ||
539 | if (unlikely(tsk->compat_robust_list)) | ||
540 | compat_exit_robust_list(tsk); | ||
541 | #endif | ||
542 | #endif | ||
543 | |||
526 | /* Get rid of any cached register state */ | 544 | /* Get rid of any cached register state */ |
527 | deactivate_mm(tsk, mm); | 545 | deactivate_mm(tsk, mm); |
528 | 546 | ||
@@ -764,27 +782,50 @@ void __cleanup_sighand(struct sighand_struct *sighand) | |||
764 | kmem_cache_free(sighand_cachep, sighand); | 782 | kmem_cache_free(sighand_cachep, sighand); |
765 | } | 783 | } |
766 | 784 | ||
785 | |||
786 | /* | ||
787 | * Initialize POSIX timer handling for a thread group. | ||
788 | */ | ||
789 | static void posix_cpu_timers_init_group(struct signal_struct *sig) | ||
790 | { | ||
791 | /* Thread group counters. */ | ||
792 | thread_group_cputime_init(sig); | ||
793 | |||
794 | /* Expiration times and increments. */ | ||
795 | sig->it_virt_expires = cputime_zero; | ||
796 | sig->it_virt_incr = cputime_zero; | ||
797 | sig->it_prof_expires = cputime_zero; | ||
798 | sig->it_prof_incr = cputime_zero; | ||
799 | |||
800 | /* Cached expiration times. */ | ||
801 | sig->cputime_expires.prof_exp = cputime_zero; | ||
802 | sig->cputime_expires.virt_exp = cputime_zero; | ||
803 | sig->cputime_expires.sched_exp = 0; | ||
804 | |||
805 | /* The timer lists. */ | ||
806 | INIT_LIST_HEAD(&sig->cpu_timers[0]); | ||
807 | INIT_LIST_HEAD(&sig->cpu_timers[1]); | ||
808 | INIT_LIST_HEAD(&sig->cpu_timers[2]); | ||
809 | } | ||
810 | |||
767 | static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | 811 | static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) |
768 | { | 812 | { |
769 | struct signal_struct *sig; | 813 | struct signal_struct *sig; |
770 | int ret; | 814 | int ret; |
771 | 815 | ||
772 | if (clone_flags & CLONE_THREAD) { | 816 | if (clone_flags & CLONE_THREAD) { |
773 | atomic_inc(¤t->signal->count); | 817 | ret = thread_group_cputime_clone_thread(current); |
774 | atomic_inc(¤t->signal->live); | 818 | if (likely(!ret)) { |
775 | return 0; | 819 | atomic_inc(¤t->signal->count); |
820 | atomic_inc(¤t->signal->live); | ||
821 | } | ||
822 | return ret; | ||
776 | } | 823 | } |
777 | sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); | 824 | sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); |
778 | tsk->signal = sig; | 825 | tsk->signal = sig; |
779 | if (!sig) | 826 | if (!sig) |
780 | return -ENOMEM; | 827 | return -ENOMEM; |
781 | 828 | ||
782 | ret = copy_thread_group_keys(tsk); | ||
783 | if (ret < 0) { | ||
784 | kmem_cache_free(signal_cachep, sig); | ||
785 | return ret; | ||
786 | } | ||
787 | |||
788 | atomic_set(&sig->count, 1); | 829 | atomic_set(&sig->count, 1); |
789 | atomic_set(&sig->live, 1); | 830 | atomic_set(&sig->live, 1); |
790 | init_waitqueue_head(&sig->wait_chldexit); | 831 | init_waitqueue_head(&sig->wait_chldexit); |
@@ -800,40 +841,25 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
800 | sig->it_real_incr.tv64 = 0; | 841 | sig->it_real_incr.tv64 = 0; |
801 | sig->real_timer.function = it_real_fn; | 842 | sig->real_timer.function = it_real_fn; |
802 | 843 | ||
803 | sig->it_virt_expires = cputime_zero; | ||
804 | sig->it_virt_incr = cputime_zero; | ||
805 | sig->it_prof_expires = cputime_zero; | ||
806 | sig->it_prof_incr = cputime_zero; | ||
807 | |||
808 | sig->leader = 0; /* session leadership doesn't inherit */ | 844 | sig->leader = 0; /* session leadership doesn't inherit */ |
809 | sig->tty_old_pgrp = NULL; | 845 | sig->tty_old_pgrp = NULL; |
810 | sig->tty = NULL; | 846 | sig->tty = NULL; |
811 | 847 | ||
812 | sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero; | 848 | sig->cutime = sig->cstime = cputime_zero; |
813 | sig->gtime = cputime_zero; | 849 | sig->gtime = cputime_zero; |
814 | sig->cgtime = cputime_zero; | 850 | sig->cgtime = cputime_zero; |
815 | sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; | 851 | sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; |
816 | sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; | 852 | sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; |
817 | sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; | 853 | sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; |
818 | task_io_accounting_init(&sig->ioac); | 854 | task_io_accounting_init(&sig->ioac); |
819 | sig->sum_sched_runtime = 0; | ||
820 | INIT_LIST_HEAD(&sig->cpu_timers[0]); | ||
821 | INIT_LIST_HEAD(&sig->cpu_timers[1]); | ||
822 | INIT_LIST_HEAD(&sig->cpu_timers[2]); | ||
823 | taskstats_tgid_init(sig); | 855 | taskstats_tgid_init(sig); |
824 | 856 | ||
825 | task_lock(current->group_leader); | 857 | task_lock(current->group_leader); |
826 | memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim); | 858 | memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim); |
827 | task_unlock(current->group_leader); | 859 | task_unlock(current->group_leader); |
828 | 860 | ||
829 | if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) { | 861 | posix_cpu_timers_init_group(sig); |
830 | /* | 862 | |
831 | * New sole thread in the process gets an expiry time | ||
832 | * of the whole CPU time limit. | ||
833 | */ | ||
834 | tsk->it_prof_expires = | ||
835 | secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur); | ||
836 | } | ||
837 | acct_init_pacct(&sig->pacct); | 863 | acct_init_pacct(&sig->pacct); |
838 | 864 | ||
839 | tty_audit_fork(sig); | 865 | tty_audit_fork(sig); |
@@ -843,7 +869,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
843 | 869 | ||
844 | void __cleanup_signal(struct signal_struct *sig) | 870 | void __cleanup_signal(struct signal_struct *sig) |
845 | { | 871 | { |
846 | exit_thread_group_keys(sig); | 872 | thread_group_cputime_free(sig); |
847 | tty_kref_put(sig->tty); | 873 | tty_kref_put(sig->tty); |
848 | kmem_cache_free(signal_cachep, sig); | 874 | kmem_cache_free(signal_cachep, sig); |
849 | } | 875 | } |
@@ -893,6 +919,19 @@ void mm_init_owner(struct mm_struct *mm, struct task_struct *p) | |||
893 | #endif /* CONFIG_MM_OWNER */ | 919 | #endif /* CONFIG_MM_OWNER */ |
894 | 920 | ||
895 | /* | 921 | /* |
922 | * Initialize POSIX timer handling for a single task. | ||
923 | */ | ||
924 | static void posix_cpu_timers_init(struct task_struct *tsk) | ||
925 | { | ||
926 | tsk->cputime_expires.prof_exp = cputime_zero; | ||
927 | tsk->cputime_expires.virt_exp = cputime_zero; | ||
928 | tsk->cputime_expires.sched_exp = 0; | ||
929 | INIT_LIST_HEAD(&tsk->cpu_timers[0]); | ||
930 | INIT_LIST_HEAD(&tsk->cpu_timers[1]); | ||
931 | INIT_LIST_HEAD(&tsk->cpu_timers[2]); | ||
932 | } | ||
933 | |||
934 | /* | ||
896 | * This creates a new process as a copy of the old one, | 935 | * This creates a new process as a copy of the old one, |
897 | * but does not actually start it yet. | 936 | * but does not actually start it yet. |
898 | * | 937 | * |
@@ -946,16 +985,16 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
946 | DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled); | 985 | DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled); |
947 | #endif | 986 | #endif |
948 | retval = -EAGAIN; | 987 | retval = -EAGAIN; |
949 | if (atomic_read(&p->user->processes) >= | 988 | if (atomic_read(&p->real_cred->user->processes) >= |
950 | p->signal->rlim[RLIMIT_NPROC].rlim_cur) { | 989 | p->signal->rlim[RLIMIT_NPROC].rlim_cur) { |
951 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) && | 990 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) && |
952 | p->user != current->nsproxy->user_ns->root_user) | 991 | p->real_cred->user != INIT_USER) |
953 | goto bad_fork_free; | 992 | goto bad_fork_free; |
954 | } | 993 | } |
955 | 994 | ||
956 | atomic_inc(&p->user->__count); | 995 | retval = copy_creds(p, clone_flags); |
957 | atomic_inc(&p->user->processes); | 996 | if (retval < 0) |
958 | get_group_info(p->group_info); | 997 | goto bad_fork_free; |
959 | 998 | ||
960 | /* | 999 | /* |
961 | * If multiple threads are within copy_process(), then this check | 1000 | * If multiple threads are within copy_process(), then this check |
@@ -994,6 +1033,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
994 | p->prev_utime = cputime_zero; | 1033 | p->prev_utime = cputime_zero; |
995 | p->prev_stime = cputime_zero; | 1034 | p->prev_stime = cputime_zero; |
996 | 1035 | ||
1036 | p->default_timer_slack_ns = current->timer_slack_ns; | ||
1037 | |||
997 | #ifdef CONFIG_DETECT_SOFTLOCKUP | 1038 | #ifdef CONFIG_DETECT_SOFTLOCKUP |
998 | p->last_switch_count = 0; | 1039 | p->last_switch_count = 0; |
999 | p->last_switch_timestamp = 0; | 1040 | p->last_switch_timestamp = 0; |
@@ -1002,21 +1043,12 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1002 | task_io_accounting_init(&p->ioac); | 1043 | task_io_accounting_init(&p->ioac); |
1003 | acct_clear_integrals(p); | 1044 | acct_clear_integrals(p); |
1004 | 1045 | ||
1005 | p->it_virt_expires = cputime_zero; | 1046 | posix_cpu_timers_init(p); |
1006 | p->it_prof_expires = cputime_zero; | ||
1007 | p->it_sched_expires = 0; | ||
1008 | INIT_LIST_HEAD(&p->cpu_timers[0]); | ||
1009 | INIT_LIST_HEAD(&p->cpu_timers[1]); | ||
1010 | INIT_LIST_HEAD(&p->cpu_timers[2]); | ||
1011 | 1047 | ||
1012 | p->lock_depth = -1; /* -1 = no lock */ | 1048 | p->lock_depth = -1; /* -1 = no lock */ |
1013 | do_posix_clock_monotonic_gettime(&p->start_time); | 1049 | do_posix_clock_monotonic_gettime(&p->start_time); |
1014 | p->real_start_time = p->start_time; | 1050 | p->real_start_time = p->start_time; |
1015 | monotonic_to_bootbased(&p->real_start_time); | 1051 | monotonic_to_bootbased(&p->real_start_time); |
1016 | #ifdef CONFIG_SECURITY | ||
1017 | p->security = NULL; | ||
1018 | #endif | ||
1019 | p->cap_bset = current->cap_bset; | ||
1020 | p->io_context = NULL; | 1052 | p->io_context = NULL; |
1021 | p->audit_context = NULL; | 1053 | p->audit_context = NULL; |
1022 | cgroup_fork(p); | 1054 | cgroup_fork(p); |
@@ -1057,14 +1089,14 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1057 | #ifdef CONFIG_DEBUG_MUTEXES | 1089 | #ifdef CONFIG_DEBUG_MUTEXES |
1058 | p->blocked_on = NULL; /* not blocked yet */ | 1090 | p->blocked_on = NULL; /* not blocked yet */ |
1059 | #endif | 1091 | #endif |
1092 | if (unlikely(ptrace_reparented(current))) | ||
1093 | ptrace_fork(p, clone_flags); | ||
1060 | 1094 | ||
1061 | /* Perform scheduler related setup. Assign this task to a CPU. */ | 1095 | /* Perform scheduler related setup. Assign this task to a CPU. */ |
1062 | sched_fork(p, clone_flags); | 1096 | sched_fork(p, clone_flags); |
1063 | 1097 | ||
1064 | if ((retval = security_task_alloc(p))) | ||
1065 | goto bad_fork_cleanup_policy; | ||
1066 | if ((retval = audit_alloc(p))) | 1098 | if ((retval = audit_alloc(p))) |
1067 | goto bad_fork_cleanup_security; | 1099 | goto bad_fork_cleanup_policy; |
1068 | /* copy all the process information */ | 1100 | /* copy all the process information */ |
1069 | if ((retval = copy_semundo(clone_flags, p))) | 1101 | if ((retval = copy_semundo(clone_flags, p))) |
1070 | goto bad_fork_cleanup_audit; | 1102 | goto bad_fork_cleanup_audit; |
@@ -1078,10 +1110,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1078 | goto bad_fork_cleanup_sighand; | 1110 | goto bad_fork_cleanup_sighand; |
1079 | if ((retval = copy_mm(clone_flags, p))) | 1111 | if ((retval = copy_mm(clone_flags, p))) |
1080 | goto bad_fork_cleanup_signal; | 1112 | goto bad_fork_cleanup_signal; |
1081 | if ((retval = copy_keys(clone_flags, p))) | ||
1082 | goto bad_fork_cleanup_mm; | ||
1083 | if ((retval = copy_namespaces(clone_flags, p))) | 1113 | if ((retval = copy_namespaces(clone_flags, p))) |
1084 | goto bad_fork_cleanup_keys; | 1114 | goto bad_fork_cleanup_mm; |
1085 | if ((retval = copy_io(clone_flags, p))) | 1115 | if ((retval = copy_io(clone_flags, p))) |
1086 | goto bad_fork_cleanup_namespaces; | 1116 | goto bad_fork_cleanup_namespaces; |
1087 | retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs); | 1117 | retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs); |
@@ -1101,6 +1131,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1101 | } | 1131 | } |
1102 | } | 1132 | } |
1103 | 1133 | ||
1134 | ftrace_graph_init_task(p); | ||
1135 | |||
1104 | p->pid = pid_nr(pid); | 1136 | p->pid = pid_nr(pid); |
1105 | p->tgid = p->pid; | 1137 | p->tgid = p->pid; |
1106 | if (clone_flags & CLONE_THREAD) | 1138 | if (clone_flags & CLONE_THREAD) |
@@ -1109,7 +1141,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1109 | if (current->nsproxy != p->nsproxy) { | 1141 | if (current->nsproxy != p->nsproxy) { |
1110 | retval = ns_cgroup_clone(p, pid); | 1142 | retval = ns_cgroup_clone(p, pid); |
1111 | if (retval) | 1143 | if (retval) |
1112 | goto bad_fork_free_pid; | 1144 | goto bad_fork_free_graph; |
1113 | } | 1145 | } |
1114 | 1146 | ||
1115 | p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL; | 1147 | p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL; |
@@ -1202,27 +1234,12 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1202 | spin_unlock(¤t->sighand->siglock); | 1234 | spin_unlock(¤t->sighand->siglock); |
1203 | write_unlock_irq(&tasklist_lock); | 1235 | write_unlock_irq(&tasklist_lock); |
1204 | retval = -ERESTARTNOINTR; | 1236 | retval = -ERESTARTNOINTR; |
1205 | goto bad_fork_free_pid; | 1237 | goto bad_fork_free_graph; |
1206 | } | 1238 | } |
1207 | 1239 | ||
1208 | if (clone_flags & CLONE_THREAD) { | 1240 | if (clone_flags & CLONE_THREAD) { |
1209 | p->group_leader = current->group_leader; | 1241 | p->group_leader = current->group_leader; |
1210 | list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group); | 1242 | list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group); |
1211 | |||
1212 | if (!cputime_eq(current->signal->it_virt_expires, | ||
1213 | cputime_zero) || | ||
1214 | !cputime_eq(current->signal->it_prof_expires, | ||
1215 | cputime_zero) || | ||
1216 | current->signal->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY || | ||
1217 | !list_empty(¤t->signal->cpu_timers[0]) || | ||
1218 | !list_empty(¤t->signal->cpu_timers[1]) || | ||
1219 | !list_empty(¤t->signal->cpu_timers[2])) { | ||
1220 | /* | ||
1221 | * Have child wake up on its first tick to check | ||
1222 | * for process CPU timers. | ||
1223 | */ | ||
1224 | p->it_prof_expires = jiffies_to_cputime(1); | ||
1225 | } | ||
1226 | } | 1243 | } |
1227 | 1244 | ||
1228 | if (likely(p->pid)) { | 1245 | if (likely(p->pid)) { |
@@ -1254,6 +1271,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1254 | cgroup_post_fork(p); | 1271 | cgroup_post_fork(p); |
1255 | return p; | 1272 | return p; |
1256 | 1273 | ||
1274 | bad_fork_free_graph: | ||
1275 | ftrace_graph_exit_task(p); | ||
1257 | bad_fork_free_pid: | 1276 | bad_fork_free_pid: |
1258 | if (pid != &init_struct_pid) | 1277 | if (pid != &init_struct_pid) |
1259 | free_pid(pid); | 1278 | free_pid(pid); |
@@ -1261,8 +1280,6 @@ bad_fork_cleanup_io: | |||
1261 | put_io_context(p->io_context); | 1280 | put_io_context(p->io_context); |
1262 | bad_fork_cleanup_namespaces: | 1281 | bad_fork_cleanup_namespaces: |
1263 | exit_task_namespaces(p); | 1282 | exit_task_namespaces(p); |
1264 | bad_fork_cleanup_keys: | ||
1265 | exit_keys(p); | ||
1266 | bad_fork_cleanup_mm: | 1283 | bad_fork_cleanup_mm: |
1267 | if (p->mm) | 1284 | if (p->mm) |
1268 | mmput(p->mm); | 1285 | mmput(p->mm); |
@@ -1278,8 +1295,6 @@ bad_fork_cleanup_semundo: | |||
1278 | exit_sem(p); | 1295 | exit_sem(p); |
1279 | bad_fork_cleanup_audit: | 1296 | bad_fork_cleanup_audit: |
1280 | audit_free(p); | 1297 | audit_free(p); |
1281 | bad_fork_cleanup_security: | ||
1282 | security_task_free(p); | ||
1283 | bad_fork_cleanup_policy: | 1298 | bad_fork_cleanup_policy: |
1284 | #ifdef CONFIG_NUMA | 1299 | #ifdef CONFIG_NUMA |
1285 | mpol_put(p->mempolicy); | 1300 | mpol_put(p->mempolicy); |
@@ -1292,9 +1307,9 @@ bad_fork_cleanup_cgroup: | |||
1292 | bad_fork_cleanup_put_domain: | 1307 | bad_fork_cleanup_put_domain: |
1293 | module_put(task_thread_info(p)->exec_domain->module); | 1308 | module_put(task_thread_info(p)->exec_domain->module); |
1294 | bad_fork_cleanup_count: | 1309 | bad_fork_cleanup_count: |
1295 | put_group_info(p->group_info); | 1310 | atomic_dec(&p->cred->user->processes); |
1296 | atomic_dec(&p->user->processes); | 1311 | put_cred(p->real_cred); |
1297 | free_uid(p->user); | 1312 | put_cred(p->cred); |
1298 | bad_fork_free: | 1313 | bad_fork_free: |
1299 | free_task(p); | 1314 | free_task(p); |
1300 | fork_out: | 1315 | fork_out: |
@@ -1338,6 +1353,21 @@ long do_fork(unsigned long clone_flags, | |||
1338 | long nr; | 1353 | long nr; |
1339 | 1354 | ||
1340 | /* | 1355 | /* |
1356 | * Do some preliminary argument and permissions checking before we | ||
1357 | * actually start allocating stuff | ||
1358 | */ | ||
1359 | if (clone_flags & CLONE_NEWUSER) { | ||
1360 | if (clone_flags & CLONE_THREAD) | ||
1361 | return -EINVAL; | ||
1362 | /* hopefully this check will go away when userns support is | ||
1363 | * complete | ||
1364 | */ | ||
1365 | if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SETUID) || | ||
1366 | !capable(CAP_SETGID)) | ||
1367 | return -EPERM; | ||
1368 | } | ||
1369 | |||
1370 | /* | ||
1341 | * We hope to recycle these flags after 2.6.26 | 1371 | * We hope to recycle these flags after 2.6.26 |
1342 | */ | 1372 | */ |
1343 | if (unlikely(clone_flags & CLONE_STOPPED)) { | 1373 | if (unlikely(clone_flags & CLONE_STOPPED)) { |
@@ -1369,6 +1399,8 @@ long do_fork(unsigned long clone_flags, | |||
1369 | if (!IS_ERR(p)) { | 1399 | if (!IS_ERR(p)) { |
1370 | struct completion vfork; | 1400 | struct completion vfork; |
1371 | 1401 | ||
1402 | trace_sched_process_fork(current, p); | ||
1403 | |||
1372 | nr = task_pid_vnr(p); | 1404 | nr = task_pid_vnr(p); |
1373 | 1405 | ||
1374 | if (clone_flags & CLONE_PARENT_SETTID) | 1406 | if (clone_flags & CLONE_PARENT_SETTID) |
@@ -1379,6 +1411,7 @@ long do_fork(unsigned long clone_flags, | |||
1379 | init_completion(&vfork); | 1411 | init_completion(&vfork); |
1380 | } | 1412 | } |
1381 | 1413 | ||
1414 | audit_finish_fork(p); | ||
1382 | tracehook_report_clone(trace, regs, clone_flags, nr, p); | 1415 | tracehook_report_clone(trace, regs, clone_flags, nr, p); |
1383 | 1416 | ||
1384 | /* | 1417 | /* |
@@ -1582,8 +1615,7 @@ asmlinkage long sys_unshare(unsigned long unshare_flags) | |||
1582 | err = -EINVAL; | 1615 | err = -EINVAL; |
1583 | if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND| | 1616 | if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND| |
1584 | CLONE_VM|CLONE_FILES|CLONE_SYSVSEM| | 1617 | CLONE_VM|CLONE_FILES|CLONE_SYSVSEM| |
1585 | CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWUSER| | 1618 | CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET)) |
1586 | CLONE_NEWNET)) | ||
1587 | goto bad_unshare_out; | 1619 | goto bad_unshare_out; |
1588 | 1620 | ||
1589 | /* | 1621 | /* |