diff options
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 31 |
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 |
| 1628 | SYSCALL_DEFINE0(fork) | 1640 | SYSCALL_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 | |||
| 1886 | bad_unshare_cleanup_cred: | 1895 | bad_unshare_cleanup_cred: |
| 1887 | if (new_cred) | 1896 | if (new_cred) |
| 1888 | put_cred(new_cred); | 1897 | put_cred(new_cred); |
