lkml.org 
[lkml]   [2015]   [Mar]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.16.y-ckt 073/165] eCryptfs: don't pass fs-specific ioctl commands through
    Date
    3.16.7-ckt9 -stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Tyler Hicks <tyhicks@canonical.com>

    commit 6d65261a09adaa374c05de807f73a144d783669e upstream.

    eCryptfs can't be aware of what to expect when after passing an
    arbitrary ioctl command through to the lower filesystem. The ioctl
    command may trigger an action in the lower filesystem that is
    incompatible with eCryptfs.

    One specific example is when one attempts to use the Btrfs clone
    ioctl command when the source file is in the Btrfs filesystem that
    eCryptfs is mounted on top of and the destination fd is from a new file
    created in the eCryptfs mount. The ioctl syscall incorrectly returns
    success because the command is passed down to Btrfs which thinks that it
    was able to do the clone operation. However, the result is an empty
    eCryptfs file.

    This patch allows the trim, {g,s}etflags, and {g,s}etversion ioctl
    commands through and then copies up the inode metadata from the lower
    inode to the eCryptfs inode to catch any changes made to the lower
    inode's metadata. Those five ioctl commands are mostly common across all
    filesystems but the whitelist may need to be further pruned in the
    future.

    https://bugzilla.kernel.org/show_bug.cgi?id=93691
    https://launchpad.net/bugs/1305335

    Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
    Cc: Rocko <rockorequin@hotmail.com>
    Cc: Colin Ian King <colin.king@canonical.com>
    Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
    ---
    fs/ecryptfs/file.c | 34 ++++++++++++++++++++++++++++++----
    1 file changed, 30 insertions(+), 4 deletions(-)

    diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
    index de1111457b5e..0682699519af 100644
    --- a/fs/ecryptfs/file.c
    +++ b/fs/ecryptfs/file.c
    @@ -303,9 +303,22 @@ ecryptfs_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
    struct file *lower_file = ecryptfs_file_to_lower(file);
    long rc = -ENOTTY;

    - if (lower_file->f_op->unlocked_ioctl)
    + if (!lower_file->f_op->unlocked_ioctl)
    + return rc;
    +
    + switch (cmd) {
    + case FITRIM:
    + case FS_IOC_GETFLAGS:
    + case FS_IOC_SETFLAGS:
    + case FS_IOC_GETVERSION:
    + case FS_IOC_SETVERSION:
    rc = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg);
    - return rc;
    + fsstack_copy_attr_all(file_inode(file), file_inode(lower_file));
    +
    + return rc;
    + default:
    + return rc;
    + }
    }

    #ifdef CONFIG_COMPAT
    @@ -315,9 +328,22 @@ ecryptfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
    struct file *lower_file = ecryptfs_file_to_lower(file);
    long rc = -ENOIOCTLCMD;

    - if (lower_file->f_op->compat_ioctl)
    + if (!lower_file->f_op->compat_ioctl)
    + return rc;
    +
    + switch (cmd) {
    + case FITRIM:
    + case FS_IOC32_GETFLAGS:
    + case FS_IOC32_SETFLAGS:
    + case FS_IOC32_GETVERSION:
    + case FS_IOC32_SETVERSION:
    rc = lower_file->f_op->compat_ioctl(lower_file, cmd, arg);
    - return rc;
    + fsstack_copy_attr_all(file_inode(file), file_inode(lower_file));
    +
    + return rc;
    + default:
    + return rc;
    + }
    }
    #endif


    \
     
     \ /
      Last update: 2015-03-25 15:41    [W:2.959 / U:0.132 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site