aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c48
1 files changed, 27 insertions, 21 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 6067e429f281..068ffe007529 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -381,14 +381,13 @@ static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p)
381 mm->ioctx_list = NULL; 381 mm->ioctx_list = NULL;
382 mm->free_area_cache = TASK_UNMAPPED_BASE; 382 mm->free_area_cache = TASK_UNMAPPED_BASE;
383 mm->cached_hole_size = ~0UL; 383 mm->cached_hole_size = ~0UL;
384 mm_init_cgroup(mm, p); 384 mm_init_owner(mm, p);
385 385
386 if (likely(!mm_alloc_pgd(mm))) { 386 if (likely(!mm_alloc_pgd(mm))) {
387 mm->def_flags = 0; 387 mm->def_flags = 0;
388 return mm; 388 return mm;
389 } 389 }
390 390
391 mm_free_cgroup(mm);
392 free_mm(mm); 391 free_mm(mm);
393 return NULL; 392 return NULL;
394} 393}
@@ -432,13 +431,13 @@ void mmput(struct mm_struct *mm)
432 if (atomic_dec_and_test(&mm->mm_users)) { 431 if (atomic_dec_and_test(&mm->mm_users)) {
433 exit_aio(mm); 432 exit_aio(mm);
434 exit_mmap(mm); 433 exit_mmap(mm);
434 set_mm_exe_file(mm, NULL);
435 if (!list_empty(&mm->mmlist)) { 435 if (!list_empty(&mm->mmlist)) {
436 spin_lock(&mmlist_lock); 436 spin_lock(&mmlist_lock);
437 list_del(&mm->mmlist); 437 list_del(&mm->mmlist);
438 spin_unlock(&mmlist_lock); 438 spin_unlock(&mmlist_lock);
439 } 439 }
440 put_swap_token(mm); 440 put_swap_token(mm);
441 mm_free_cgroup(mm);
442 mmdrop(mm); 441 mmdrop(mm);
443 } 442 }
444} 443}
@@ -545,6 +544,8 @@ struct mm_struct *dup_mm(struct task_struct *tsk)
545 if (init_new_context(tsk, mm)) 544 if (init_new_context(tsk, mm))
546 goto fail_nocontext; 545 goto fail_nocontext;
547 546
547 dup_mm_exe_file(oldmm, mm);
548
548 err = dup_mmap(mm, oldmm); 549 err = dup_mmap(mm, oldmm);
549 if (err) 550 if (err)
550 goto free_pt; 551 goto free_pt;
@@ -982,6 +983,13 @@ static void rt_mutex_init_task(struct task_struct *p)
982#endif 983#endif
983} 984}
984 985
986#ifdef CONFIG_MM_OWNER
987void mm_init_owner(struct mm_struct *mm, struct task_struct *p)
988{
989 mm->owner = p;
990}
991#endif /* CONFIG_MM_OWNER */
992
985/* 993/*
986 * This creates a new process as a copy of the old one, 994 * This creates a new process as a copy of the old one,
987 * but does not actually start it yet. 995 * but does not actually start it yet.
@@ -1664,18 +1672,6 @@ static int unshare_fd(unsigned long unshare_flags, struct files_struct **new_fdp
1664} 1672}
1665 1673
1666/* 1674/*
1667 * Unsharing of semundo for tasks created with CLONE_SYSVSEM is not
1668 * supported yet
1669 */
1670static int unshare_semundo(unsigned long unshare_flags, struct sem_undo_list **new_ulistp)
1671{
1672 if (unshare_flags & CLONE_SYSVSEM)
1673 return -EINVAL;
1674
1675 return 0;
1676}
1677
1678/*
1679 * unshare allows a process to 'unshare' part of the process 1675 * unshare allows a process to 'unshare' part of the process
1680 * context which was originally shared using clone. copy_* 1676 * context which was originally shared using clone. copy_*
1681 * functions used by do_fork() cannot be used here directly 1677 * functions used by do_fork() cannot be used here directly
@@ -1690,8 +1686,8 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
1690 struct sighand_struct *new_sigh = NULL; 1686 struct sighand_struct *new_sigh = NULL;
1691 struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL; 1687 struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL;
1692 struct files_struct *fd, *new_fd = NULL; 1688 struct files_struct *fd, *new_fd = NULL;
1693 struct sem_undo_list *new_ulist = NULL;
1694 struct nsproxy *new_nsproxy = NULL; 1689 struct nsproxy *new_nsproxy = NULL;
1690 int do_sysvsem = 0;
1695 1691
1696 check_unshare_flags(&unshare_flags); 1692 check_unshare_flags(&unshare_flags);
1697 1693
@@ -1703,6 +1699,13 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
1703 CLONE_NEWNET)) 1699 CLONE_NEWNET))
1704 goto bad_unshare_out; 1700 goto bad_unshare_out;
1705 1701
1702 /*
1703 * CLONE_NEWIPC must also detach from the undolist: after switching
1704 * to a new ipc namespace, the semaphore arrays from the old
1705 * namespace are unreachable.
1706 */
1707 if (unshare_flags & (CLONE_NEWIPC|CLONE_SYSVSEM))
1708 do_sysvsem = 1;
1706 if ((err = unshare_thread(unshare_flags))) 1709 if ((err = unshare_thread(unshare_flags)))
1707 goto bad_unshare_out; 1710 goto bad_unshare_out;
1708 if ((err = unshare_fs(unshare_flags, &new_fs))) 1711 if ((err = unshare_fs(unshare_flags, &new_fs)))
@@ -1713,13 +1716,17 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
1713 goto bad_unshare_cleanup_sigh; 1716 goto bad_unshare_cleanup_sigh;
1714 if ((err = unshare_fd(unshare_flags, &new_fd))) 1717 if ((err = unshare_fd(unshare_flags, &new_fd)))
1715 goto bad_unshare_cleanup_vm; 1718 goto bad_unshare_cleanup_vm;
1716 if ((err = unshare_semundo(unshare_flags, &new_ulist)))
1717 goto bad_unshare_cleanup_fd;
1718 if ((err = unshare_nsproxy_namespaces(unshare_flags, &new_nsproxy, 1719 if ((err = unshare_nsproxy_namespaces(unshare_flags, &new_nsproxy,
1719 new_fs))) 1720 new_fs)))
1720 goto bad_unshare_cleanup_semundo; 1721 goto bad_unshare_cleanup_fd;
1721 1722
1722 if (new_fs || new_mm || new_fd || new_ulist || new_nsproxy) { 1723 if (new_fs || new_mm || new_fd || do_sysvsem || new_nsproxy) {
1724 if (do_sysvsem) {
1725 /*
1726 * CLONE_SYSVSEM is equivalent to sys_exit().
1727 */
1728 exit_sem(current);
1729 }
1723 1730
1724 if (new_nsproxy) { 1731 if (new_nsproxy) {
1725 switch_task_namespaces(current, new_nsproxy); 1732 switch_task_namespaces(current, new_nsproxy);
@@ -1755,7 +1762,6 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
1755 if (new_nsproxy) 1762 if (new_nsproxy)
1756 put_nsproxy(new_nsproxy); 1763 put_nsproxy(new_nsproxy);
1757 1764
1758bad_unshare_cleanup_semundo:
1759bad_unshare_cleanup_fd: 1765bad_unshare_cleanup_fd:
1760 if (new_fd) 1766 if (new_fd)
1761 put_files_struct(new_fd); 1767 put_files_struct(new_fd);