Commit 51982ff9 authored by Jann Horn's avatar Jann Horn Committed by Andy Whitcroft

UBUNTU: SAUCE: ecryptfs: forbid opening files without mmap handler

BugLink: http://bugs.launchpad.net/bugs/1588871

This prevents users from triggering an exploitable stack overflow
through a recursive invocation of pagefault handling on systems that
allow unprivileged users to mount ecryptfs. More precisely:

When a file in ecryptfs is mmap()ed, ecryptfs only uses the VFS read
and write methods of the lower filesystem (using kernel_read() and
kernel_write()) to interact with the lower file. This means that
it is possible to mmap() the decrypted view of a lower file that
normally couldn't be mmap()ed.

One such file is /proc/$pid/environ. If an encrypted ecryptfs file
is placed in the environment area of a process with PID $pid and
/proc/$pid is mounted to /tmp/foo, /tmp/foo/environ can then be
opened and mmap()ed. A pagefault in the memory area to which
/tmp/foo/environ is mapped will cause a kernel_read() on
/proc/$pid/environ, which in turn will cause a pagefault in the
context of the process with PID $pid.

By using a chain of processes in which each process has the
decrypted view of the next process' environment mapped into its
environment area, where the environment of the last process in the
chain is an "ecryptfs matroska" (the result of encrypting some data
using ecryptfs, then encrypting the result of that and so on), and
then triggering a pagefault in the environment of the first process
in the chain, it is possible to cause a recursive pagefault that
ends up overflowing the stack.

Fix it by disallowing opening anything without an mmap handler
through ecryptfs.

CVE-2016-1583
Signed-off-by: default avatarJann Horn <jannh@google.com>
Cc: stable@vger.kernel.org
Acked-by: default avatarTyler Hicks <tyhicks@canonical.com>
Acked-by: default avatarLuis Henriques <luis.henriques@canonical.com>
Signed-off-by: default avatarKamal Mostafa <kamal@canonical.com>
parent b5b2e27c
......@@ -25,6 +25,7 @@
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/mount.h>
#include <linux/file.h>
#include "ecryptfs_kernel.h"
struct ecryptfs_open_req {
......@@ -147,7 +148,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
flags |= IS_RDONLY(d_inode(lower_dentry)) ? O_RDONLY : O_RDWR;
(*lower_file) = dentry_open(&req.path, flags, cred);
if (!IS_ERR(*lower_file))
goto out;
goto have_file;
if ((flags & O_ACCMODE) == O_RDONLY) {
rc = PTR_ERR((*lower_file));
goto out;
......@@ -165,8 +166,16 @@ int ecryptfs_privileged_open(struct file **lower_file,
mutex_unlock(&ecryptfs_kthread_ctl.mux);
wake_up(&ecryptfs_kthread_ctl.wait);
wait_for_completion(&req.done);
if (IS_ERR(*lower_file))
if (IS_ERR(*lower_file)) {
rc = PTR_ERR(*lower_file);
goto out;
}
have_file:
if ((*lower_file)->f_op->mmap == NULL) {
fput(*lower_file);
*lower_file = NULL;
rc = -EMEDIUMTYPE;
}
out:
return rc;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment