summaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-09-01 19:13:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-01 19:13:25 -0400
commit73b6fa8e49c2d13e04d20186261e5f7855c6d0bf (patch)
tree75c972b9f5284d84db83c6eae63611e96c827c57 /kernel/fork.c
parente713c80a4e49d4bed5324d24755e42bf01c87556 (diff)
parent4b75de8615050c1b0dd8d7794838c42f74ed36ba (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace
Pull user namespace updates from Eric Biederman: "This finishes up the changes to ensure proc and sysfs do not start implementing executable files, as the there are application today that are only secure because such files do not exist. It akso fixes a long standing misfeature of /proc/<pid>/mountinfo that did not show the proper source for files bind mounted from /proc/<pid>/ns/*. It also straightens out the handling of clone flags related to user namespaces, fixing an unnecessary failure of unshare(CLONE_NEWUSER) when files such as /proc/<pid>/environ are read while <pid> is calling unshare. This winds up fixing a minor bug in unshare flag handling that dates back to the first version of unshare in the kernel. Finally, this fixes a minor regression caused by the introduction of sysfs_create_mount_point, which broke someone's in house application, by restoring the size of /sys/fs/cgroup to 0 bytes. Apparently that application uses the directory size to determine if a tmpfs is mounted on /sys/fs/cgroup. The bind mount escape fixes are present in Al Viros for-next branch. and I expect them to come from there. The bind mount escape is the last of the user namespace related security bugs that I am aware of" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: fs: Set the size of empty dirs to 0. userns,pidns: Force thread group sharing, not signal handler sharing. unshare: Unsharing a thread does not require unsharing a vm nsfs: Add a show_path method to fix mountinfo mnt: fs_fully_visible enforce noexec and nosuid if !SB_I_NOEXEC vfs: Commit to never having exectuables on proc and sysfs.
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 0d93b4d0617b..2b1a61cddc19 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1280,10 +1280,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1280 1280
1281 /* 1281 /*
1282 * If the new process will be in a different pid or user namespace 1282 * If the new process will be in a different pid or user namespace
1283 * do not allow it to share a thread group or signal handlers or 1283 * do not allow it to share a thread group with the forking task.
1284 * parent with the forking task.
1285 */ 1284 */
1286 if (clone_flags & CLONE_SIGHAND) { 1285 if (clone_flags & CLONE_THREAD) {
1287 if ((clone_flags & (CLONE_NEWUSER | CLONE_NEWPID)) || 1286 if ((clone_flags & (CLONE_NEWUSER | CLONE_NEWPID)) ||
1288 (task_active_pid_ns(current) != 1287 (task_active_pid_ns(current) !=
1289 current->nsproxy->pid_ns_for_children)) 1288 current->nsproxy->pid_ns_for_children))
@@ -1872,13 +1871,21 @@ static int check_unshare_flags(unsigned long unshare_flags)
1872 CLONE_NEWUSER|CLONE_NEWPID)) 1871 CLONE_NEWUSER|CLONE_NEWPID))
1873 return -EINVAL; 1872 return -EINVAL;
1874 /* 1873 /*
1875 * Not implemented, but pretend it works if there is nothing to 1874 * Not implemented, but pretend it works if there is nothing
1876 * unshare. Note that unsharing CLONE_THREAD or CLONE_SIGHAND 1875 * to unshare. Note that unsharing the address space or the
1877 * needs to unshare vm. 1876 * signal handlers also need to unshare the signal queues (aka
1877 * CLONE_THREAD).
1878 */ 1878 */
1879 if (unshare_flags & (CLONE_THREAD | CLONE_SIGHAND | CLONE_VM)) { 1879 if (unshare_flags & (CLONE_THREAD | CLONE_SIGHAND | CLONE_VM)) {
1880 /* FIXME: get_task_mm() increments ->mm_users */ 1880 if (!thread_group_empty(current))
1881 if (atomic_read(&current->mm->mm_users) > 1) 1881 return -EINVAL;
1882 }
1883 if (unshare_flags & (CLONE_SIGHAND | CLONE_VM)) {
1884 if (atomic_read(&current->sighand->count) > 1)
1885 return -EINVAL;
1886 }
1887 if (unshare_flags & CLONE_VM) {
1888 if (!current_is_single_threaded())
1882 return -EINVAL; 1889 return -EINVAL;
1883 } 1890 }
1884 1891
@@ -1942,21 +1949,22 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
1942 int err; 1949 int err;
1943 1950
1944 /* 1951 /*
1945 * If unsharing a user namespace must also unshare the thread. 1952 * If unsharing a user namespace must also unshare the thread group
1953 * and unshare the filesystem root and working directories.
1946 */ 1954 */
1947 if (unshare_flags & CLONE_NEWUSER) 1955 if (unshare_flags & CLONE_NEWUSER)
1948 unshare_flags |= CLONE_THREAD | CLONE_FS; 1956 unshare_flags |= CLONE_THREAD | CLONE_FS;
1949 /* 1957 /*
1950 * If unsharing a thread from a thread group, must also unshare vm.
1951 */
1952 if (unshare_flags & CLONE_THREAD)
1953 unshare_flags |= CLONE_VM;
1954 /*
1955 * If unsharing vm, must also unshare signal handlers. 1958 * If unsharing vm, must also unshare signal handlers.
1956 */ 1959 */
1957 if (unshare_flags & CLONE_VM) 1960 if (unshare_flags & CLONE_VM)
1958 unshare_flags |= CLONE_SIGHAND; 1961 unshare_flags |= CLONE_SIGHAND;
1959 /* 1962 /*
1963 * If unsharing a signal handlers, must also unshare the signal queues.
1964 */
1965 if (unshare_flags & CLONE_SIGHAND)
1966 unshare_flags |= CLONE_THREAD;
1967 /*
1960 * If unsharing namespace, must also unshare filesystem information. 1968 * If unsharing namespace, must also unshare filesystem information.
1961 */ 1969 */
1962 if (unshare_flags & CLONE_NEWNS) 1970 if (unshare_flags & CLONE_NEWNS)