diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/fork.c | 32 | ||||
-rw-r--r-- | kernel/nsproxy.c | 2 | ||||
-rw-r--r-- | kernel/pid_namespace.c | 2 |
3 files changed, 26 insertions, 10 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 0f2bbce311fc..811ffbad7889 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -1565,9 +1565,11 @@ long do_fork(unsigned long clone_flags, | |||
1565 | * Do some preliminary argument and permissions checking before we | 1565 | * Do some preliminary argument and permissions checking before we |
1566 | * actually start allocating stuff | 1566 | * actually start allocating stuff |
1567 | */ | 1567 | */ |
1568 | if (clone_flags & CLONE_NEWUSER) { | 1568 | if (clone_flags & (CLONE_NEWUSER | CLONE_NEWPID)) { |
1569 | if (clone_flags & CLONE_THREAD) | 1569 | if (clone_flags & (CLONE_THREAD|CLONE_PARENT)) |
1570 | return -EINVAL; | 1570 | return -EINVAL; |
1571 | } | ||
1572 | if (clone_flags & CLONE_NEWUSER) { | ||
1571 | /* hopefully this check will go away when userns support is | 1573 | /* hopefully this check will go away when userns support is |
1572 | * complete | 1574 | * complete |
1573 | */ | 1575 | */ |
@@ -1692,7 +1694,8 @@ static int check_unshare_flags(unsigned long unshare_flags) | |||
1692 | { | 1694 | { |
1693 | if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND| | 1695 | if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND| |
1694 | CLONE_VM|CLONE_FILES|CLONE_SYSVSEM| | 1696 | CLONE_VM|CLONE_FILES|CLONE_SYSVSEM| |
1695 | CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET)) | 1697 | CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET| |
1698 | CLONE_NEWPID)) | ||
1696 | return -EINVAL; | 1699 | return -EINVAL; |
1697 | /* | 1700 | /* |
1698 | * Not implemented, but pretend it works if there is nothing to | 1701 | * Not implemented, but pretend it works if there is nothing to |
@@ -1763,15 +1766,30 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags) | |||
1763 | int do_sysvsem = 0; | 1766 | int do_sysvsem = 0; |
1764 | int err; | 1767 | int err; |
1765 | 1768 | ||
1766 | err = check_unshare_flags(unshare_flags); | 1769 | /* |
1767 | if (err) | 1770 | * If unsharing a pid namespace must also unshare the thread. |
1768 | goto bad_unshare_out; | 1771 | */ |
1769 | 1772 | if (unshare_flags & CLONE_NEWPID) | |
1773 | unshare_flags |= CLONE_THREAD; | ||
1774 | /* | ||
1775 | * If unsharing a thread from a thread group, must also unshare vm. | ||
1776 | */ | ||
1777 | if (unshare_flags & CLONE_THREAD) | ||
1778 | unshare_flags |= CLONE_VM; | ||
1779 | /* | ||
1780 | * If unsharing vm, must also unshare signal handlers. | ||
1781 | */ | ||
1782 | if (unshare_flags & CLONE_VM) | ||
1783 | unshare_flags |= CLONE_SIGHAND; | ||
1770 | /* | 1784 | /* |
1771 | * If unsharing namespace, must also unshare filesystem information. | 1785 | * If unsharing namespace, must also unshare filesystem information. |
1772 | */ | 1786 | */ |
1773 | if (unshare_flags & CLONE_NEWNS) | 1787 | if (unshare_flags & CLONE_NEWNS) |
1774 | unshare_flags |= CLONE_FS; | 1788 | unshare_flags |= CLONE_FS; |
1789 | |||
1790 | err = check_unshare_flags(unshare_flags); | ||
1791 | if (err) | ||
1792 | goto bad_unshare_out; | ||
1775 | /* | 1793 | /* |
1776 | * CLONE_NEWIPC must also detach from the undolist: after switching | 1794 | * CLONE_NEWIPC must also detach from the undolist: after switching |
1777 | * to a new ipc namespace, the semaphore arrays from the old | 1795 | * to a new ipc namespace, the semaphore arrays from the old |
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c index acc92680381a..b8d4d8709d70 100644 --- a/kernel/nsproxy.c +++ b/kernel/nsproxy.c | |||
@@ -188,7 +188,7 @@ int unshare_nsproxy_namespaces(unsigned long unshare_flags, | |||
188 | int err = 0; | 188 | int err = 0; |
189 | 189 | ||
190 | if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | | 190 | if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | |
191 | CLONE_NEWNET))) | 191 | CLONE_NEWNET | CLONE_NEWPID))) |
192 | return 0; | 192 | return 0; |
193 | 193 | ||
194 | if (!capable(CAP_SYS_ADMIN)) | 194 | if (!capable(CAP_SYS_ADMIN)) |
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index f78fc48c86bc..68508d330634 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c | |||
@@ -144,8 +144,6 @@ struct pid_namespace *copy_pid_ns(unsigned long flags, | |||
144 | { | 144 | { |
145 | if (!(flags & CLONE_NEWPID)) | 145 | if (!(flags & CLONE_NEWPID)) |
146 | return get_pid_ns(old_ns); | 146 | return get_pid_ns(old_ns); |
147 | if (flags & (CLONE_THREAD|CLONE_PARENT)) | ||
148 | return ERR_PTR(-EINVAL); | ||
149 | if (task_active_pid_ns(current) != old_ns) | 147 | if (task_active_pid_ns(current) != old_ns) |
150 | return ERR_PTR(-EINVAL); | 148 | return ERR_PTR(-EINVAL); |
151 | return create_pid_namespace(user_ns, old_ns); | 149 | return create_pid_namespace(user_ns, old_ns); |