aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/fork.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 1bfefc6f96a4..d544ae97f999 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1866,13 +1866,21 @@ static int check_unshare_flags(unsigned long unshare_flags)
1866 CLONE_NEWUSER|CLONE_NEWPID)) 1866 CLONE_NEWUSER|CLONE_NEWPID))
1867 return -EINVAL; 1867 return -EINVAL;
1868 /* 1868 /*
1869 * Not implemented, but pretend it works if there is nothing to 1869 * Not implemented, but pretend it works if there is nothing
1870 * unshare. Note that unsharing CLONE_THREAD or CLONE_SIGHAND 1870 * to unshare. Note that unsharing the address space or the
1871 * needs to unshare vm. 1871 * signal handlers also need to unshare the signal queues (aka
1872 * CLONE_THREAD).
1872 */ 1873 */
1873 if (unshare_flags & (CLONE_THREAD | CLONE_SIGHAND | CLONE_VM)) { 1874 if (unshare_flags & (CLONE_THREAD | CLONE_SIGHAND | CLONE_VM)) {
1874 /* FIXME: get_task_mm() increments ->mm_users */ 1875 if (!thread_group_empty(current))
1875 if (atomic_read(&current->mm->mm_users) > 1) 1876 return -EINVAL;
1877 }
1878 if (unshare_flags & (CLONE_SIGHAND | CLONE_VM)) {
1879 if (atomic_read(&current->sighand->count) > 1)
1880 return -EINVAL;
1881 }
1882 if (unshare_flags & CLONE_VM) {
1883 if (!current_is_single_threaded())
1876 return -EINVAL; 1884 return -EINVAL;
1877 } 1885 }
1878 1886
@@ -1941,16 +1949,16 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
1941 if (unshare_flags & CLONE_NEWUSER) 1949 if (unshare_flags & CLONE_NEWUSER)
1942 unshare_flags |= CLONE_THREAD | CLONE_FS; 1950 unshare_flags |= CLONE_THREAD | CLONE_FS;
1943 /* 1951 /*
1944 * If unsharing a thread from a thread group, must also unshare vm.
1945 */
1946 if (unshare_flags & CLONE_THREAD)
1947 unshare_flags |= CLONE_VM;
1948 /*
1949 * If unsharing vm, must also unshare signal handlers. 1952 * If unsharing vm, must also unshare signal handlers.
1950 */ 1953 */
1951 if (unshare_flags & CLONE_VM) 1954 if (unshare_flags & CLONE_VM)
1952 unshare_flags |= CLONE_SIGHAND; 1955 unshare_flags |= CLONE_SIGHAND;
1953 /* 1956 /*
1957 * If unsharing a signal handlers, must also unshare the signal queues.
1958 */
1959 if (unshare_flags & CLONE_SIGHAND)
1960 unshare_flags |= CLONE_THREAD;
1961 /*
1954 * If unsharing namespace, must also unshare filesystem information. 1962 * If unsharing namespace, must also unshare filesystem information.
1955 */ 1963 */
1956 if (unshare_flags & CLONE_NEWNS) 1964 if (unshare_flags & CLONE_NEWNS)