aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 33fcf0733ca6..c08cf05dd59b 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1607,13 +1607,14 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
1607 struct files_struct *fd, *new_fd = NULL; 1607 struct files_struct *fd, *new_fd = NULL;
1608 struct sem_undo_list *new_ulist = NULL; 1608 struct sem_undo_list *new_ulist = NULL;
1609 struct nsproxy *new_nsproxy, *old_nsproxy; 1609 struct nsproxy *new_nsproxy, *old_nsproxy;
1610 struct uts_namespace *uts, *new_uts = NULL;
1610 1611
1611 check_unshare_flags(&unshare_flags); 1612 check_unshare_flags(&unshare_flags);
1612 1613
1613 /* Return -EINVAL for all unsupported flags */ 1614 /* Return -EINVAL for all unsupported flags */
1614 err = -EINVAL; 1615 err = -EINVAL;
1615 if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND| 1616 if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
1616 CLONE_VM|CLONE_FILES|CLONE_SYSVSEM)) 1617 CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|CLONE_NEWUTS))
1617 goto bad_unshare_out; 1618 goto bad_unshare_out;
1618 1619
1619 if ((err = unshare_thread(unshare_flags))) 1620 if ((err = unshare_thread(unshare_flags)))
@@ -1630,14 +1631,17 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
1630 goto bad_unshare_cleanup_vm; 1631 goto bad_unshare_cleanup_vm;
1631 if ((err = unshare_semundo(unshare_flags, &new_ulist))) 1632 if ((err = unshare_semundo(unshare_flags, &new_ulist)))
1632 goto bad_unshare_cleanup_fd; 1633 goto bad_unshare_cleanup_fd;
1634 if ((err = unshare_utsname(unshare_flags, &new_uts)))
1635 goto bad_unshare_cleanup_semundo;
1633 1636
1634 if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist) { 1637 if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist ||
1638 new_uts) {
1635 1639
1636 old_nsproxy = current->nsproxy; 1640 old_nsproxy = current->nsproxy;
1637 new_nsproxy = dup_namespaces(old_nsproxy); 1641 new_nsproxy = dup_namespaces(old_nsproxy);
1638 if (!new_nsproxy) { 1642 if (!new_nsproxy) {
1639 err = -ENOMEM; 1643 err = -ENOMEM;
1640 goto bad_unshare_cleanup_semundo; 1644 goto bad_unshare_cleanup_uts;
1641 } 1645 }
1642 1646
1643 task_lock(current); 1647 task_lock(current);
@@ -1676,10 +1680,20 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
1676 new_fd = fd; 1680 new_fd = fd;
1677 } 1681 }
1678 1682
1683 if (new_uts) {
1684 uts = current->nsproxy->uts_ns;
1685 current->nsproxy->uts_ns = new_uts;
1686 new_uts = uts;
1687 }
1688
1679 task_unlock(current); 1689 task_unlock(current);
1680 put_nsproxy(old_nsproxy); 1690 put_nsproxy(old_nsproxy);
1681 } 1691 }
1682 1692
1693bad_unshare_cleanup_uts:
1694 if (new_uts)
1695 put_uts_ns(new_uts);
1696
1683bad_unshare_cleanup_semundo: 1697bad_unshare_cleanup_semundo:
1684bad_unshare_cleanup_fd: 1698bad_unshare_cleanup_fd:
1685 if (new_fd) 1699 if (new_fd)