aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 85f6d536608d..8d932b1c9056 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -413,7 +413,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
413 tmp->vm_next = tmp->vm_prev = NULL; 413 tmp->vm_next = tmp->vm_prev = NULL;
414 file = tmp->vm_file; 414 file = tmp->vm_file;
415 if (file) { 415 if (file) {
416 struct inode *inode = file->f_path.dentry->d_inode; 416 struct inode *inode = file_inode(file);
417 struct address_space *mapping = file->f_mapping; 417 struct address_space *mapping = file->f_mapping;
418 418
419 get_file(file); 419 get_file(file);
@@ -1166,6 +1166,14 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1166 current->signal->flags & SIGNAL_UNKILLABLE) 1166 current->signal->flags & SIGNAL_UNKILLABLE)
1167 return ERR_PTR(-EINVAL); 1167 return ERR_PTR(-EINVAL);
1168 1168
1169 /*
1170 * If the new process will be in a different pid namespace
1171 * don't allow the creation of threads.
1172 */
1173 if ((clone_flags & (CLONE_VM|CLONE_NEWPID)) &&
1174 (task_active_pid_ns(current) != current->nsproxy->pid_ns))
1175 return ERR_PTR(-EINVAL);
1176
1169 retval = security_task_create(clone_flags); 1177 retval = security_task_create(clone_flags);
1170 if (retval) 1178 if (retval)
1171 goto fork_out; 1179 goto fork_out;
@@ -1225,6 +1233,12 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1225#ifndef CONFIG_VIRT_CPU_ACCOUNTING 1233#ifndef CONFIG_VIRT_CPU_ACCOUNTING
1226 p->prev_cputime.utime = p->prev_cputime.stime = 0; 1234 p->prev_cputime.utime = p->prev_cputime.stime = 0;
1227#endif 1235#endif
1236#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
1237 seqlock_init(&p->vtime_seqlock);
1238 p->vtime_snap = 0;
1239 p->vtime_snap_whence = VTIME_SLEEPING;
1240#endif
1241
1228#if defined(SPLIT_RSS_COUNTING) 1242#if defined(SPLIT_RSS_COUNTING)
1229 memset(&p->rss_stat, 0, sizeof(p->rss_stat)); 1243 memset(&p->rss_stat, 0, sizeof(p->rss_stat));
1230#endif 1244#endif
@@ -1613,7 +1627,6 @@ long do_fork(unsigned long clone_flags,
1613 return nr; 1627 return nr;
1614} 1628}
1615 1629
1616#ifdef CONFIG_GENERIC_KERNEL_THREAD
1617/* 1630/*
1618 * Create a kernel thread. 1631 * Create a kernel thread.
1619 */ 1632 */
@@ -1622,7 +1635,6 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
1622 return do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn, 1635 return do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn,
1623 (unsigned long)arg, NULL, NULL); 1636 (unsigned long)arg, NULL, NULL);
1624} 1637}
1625#endif
1626 1638
1627#ifdef __ARCH_WANT_SYS_FORK 1639#ifdef __ARCH_WANT_SYS_FORK
1628SYSCALL_DEFINE0(fork) 1640SYSCALL_DEFINE0(fork)
@@ -1662,8 +1674,10 @@ SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
1662 int, tls_val) 1674 int, tls_val)
1663#endif 1675#endif
1664{ 1676{
1665 return do_fork(clone_flags, newsp, 0, 1677 long ret = do_fork(clone_flags, newsp, 0, parent_tidptr, child_tidptr);
1666 parent_tidptr, child_tidptr); 1678 asmlinkage_protect(5, ret, clone_flags, newsp,
1679 parent_tidptr, child_tidptr, tls_val);
1680 return ret;
1667} 1681}
1668#endif 1682#endif
1669 1683
@@ -1847,10 +1861,8 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
1847 exit_sem(current); 1861 exit_sem(current);
1848 } 1862 }
1849 1863
1850 if (new_nsproxy) { 1864 if (new_nsproxy)
1851 switch_task_namespaces(current, new_nsproxy); 1865 switch_task_namespaces(current, new_nsproxy);
1852 new_nsproxy = NULL;
1853 }
1854 1866
1855 task_lock(current); 1867 task_lock(current);
1856 1868
@@ -1880,9 +1892,6 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
1880 } 1892 }
1881 } 1893 }
1882 1894
1883 if (new_nsproxy)
1884 put_nsproxy(new_nsproxy);
1885
1886bad_unshare_cleanup_cred: 1895bad_unshare_cleanup_cred:
1887 if (new_cred) 1896 if (new_cred)
1888 put_cred(new_cred); 1897 put_cred(new_cred);