aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 208dd99f13bc..d6cc56558507 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1608,13 +1608,15 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
1608 struct sem_undo_list *new_ulist = NULL; 1608 struct sem_undo_list *new_ulist = NULL;
1609 struct nsproxy *new_nsproxy = NULL, *old_nsproxy = NULL; 1609 struct nsproxy *new_nsproxy = NULL, *old_nsproxy = NULL;
1610 struct uts_namespace *uts, *new_uts = NULL; 1610 struct uts_namespace *uts, *new_uts = NULL;
1611 struct ipc_namespace *ipc, *new_ipc = NULL;
1611 1612
1612 check_unshare_flags(&unshare_flags); 1613 check_unshare_flags(&unshare_flags);
1613 1614
1614 /* Return -EINVAL for all unsupported flags */ 1615 /* Return -EINVAL for all unsupported flags */
1615 err = -EINVAL; 1616 err = -EINVAL;
1616 if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND| 1617 if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
1617 CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|CLONE_NEWUTS)) 1618 CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
1619 CLONE_NEWUTS|CLONE_NEWIPC))
1618 goto bad_unshare_out; 1620 goto bad_unshare_out;
1619 1621
1620 if ((err = unshare_thread(unshare_flags))) 1622 if ((err = unshare_thread(unshare_flags)))
@@ -1633,18 +1635,20 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
1633 goto bad_unshare_cleanup_fd; 1635 goto bad_unshare_cleanup_fd;
1634 if ((err = unshare_utsname(unshare_flags, &new_uts))) 1636 if ((err = unshare_utsname(unshare_flags, &new_uts)))
1635 goto bad_unshare_cleanup_semundo; 1637 goto bad_unshare_cleanup_semundo;
1638 if ((err = unshare_ipcs(unshare_flags, &new_ipc)))
1639 goto bad_unshare_cleanup_uts;
1636 1640
1637 if (new_ns || new_uts) { 1641 if (new_ns || new_uts || new_ipc) {
1638 old_nsproxy = current->nsproxy; 1642 old_nsproxy = current->nsproxy;
1639 new_nsproxy = dup_namespaces(old_nsproxy); 1643 new_nsproxy = dup_namespaces(old_nsproxy);
1640 if (!new_nsproxy) { 1644 if (!new_nsproxy) {
1641 err = -ENOMEM; 1645 err = -ENOMEM;
1642 goto bad_unshare_cleanup_uts; 1646 goto bad_unshare_cleanup_ipc;
1643 } 1647 }
1644 } 1648 }
1645 1649
1646 if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist || 1650 if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist ||
1647 new_uts) { 1651 new_uts || new_ipc) {
1648 1652
1649 task_lock(current); 1653 task_lock(current);
1650 1654
@@ -1692,12 +1696,22 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
1692 new_uts = uts; 1696 new_uts = uts;
1693 } 1697 }
1694 1698
1699 if (new_ipc) {
1700 ipc = current->nsproxy->ipc_ns;
1701 current->nsproxy->ipc_ns = new_ipc;
1702 new_ipc = ipc;
1703 }
1704
1695 task_unlock(current); 1705 task_unlock(current);
1696 } 1706 }
1697 1707
1698 if (new_nsproxy) 1708 if (new_nsproxy)
1699 put_nsproxy(new_nsproxy); 1709 put_nsproxy(new_nsproxy);
1700 1710
1711bad_unshare_cleanup_ipc:
1712 if (new_ipc)
1713 put_ipc_ns(new_ipc);
1714
1701bad_unshare_cleanup_uts: 1715bad_unshare_cleanup_uts:
1702 if (new_uts) 1716 if (new_uts)
1703 put_uts_ns(new_uts); 1717 put_uts_ns(new_uts);