]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.19.2/ecryptfs-don-t-pass-fs-specific-ioctl-commands-through.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.19.2 / ecryptfs-don-t-pass-fs-specific-ioctl-commands-through.patch
1 From 6d65261a09adaa374c05de807f73a144d783669e Mon Sep 17 00:00:00 2001
2 From: Tyler Hicks <tyhicks@canonical.com>
3 Date: Tue, 24 Feb 2015 19:28:10 -0600
4 Subject: eCryptfs: don't pass fs-specific ioctl commands through
5
6 From: Tyler Hicks <tyhicks@canonical.com>
7
8 commit 6d65261a09adaa374c05de807f73a144d783669e upstream.
9
10 eCryptfs can't be aware of what to expect when after passing an
11 arbitrary ioctl command through to the lower filesystem. The ioctl
12 command may trigger an action in the lower filesystem that is
13 incompatible with eCryptfs.
14
15 One specific example is when one attempts to use the Btrfs clone
16 ioctl command when the source file is in the Btrfs filesystem that
17 eCryptfs is mounted on top of and the destination fd is from a new file
18 created in the eCryptfs mount. The ioctl syscall incorrectly returns
19 success because the command is passed down to Btrfs which thinks that it
20 was able to do the clone operation. However, the result is an empty
21 eCryptfs file.
22
23 This patch allows the trim, {g,s}etflags, and {g,s}etversion ioctl
24 commands through and then copies up the inode metadata from the lower
25 inode to the eCryptfs inode to catch any changes made to the lower
26 inode's metadata. Those five ioctl commands are mostly common across all
27 filesystems but the whitelist may need to be further pruned in the
28 future.
29
30 https://bugzilla.kernel.org/show_bug.cgi?id=93691
31 https://launchpad.net/bugs/1305335
32
33 Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
34 Cc: Rocko <rockorequin@hotmail.com>
35 Cc: Colin Ian King <colin.king@canonical.com>
36 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
37
38 ---
39 fs/ecryptfs/file.c | 34 ++++++++++++++++++++++++++++++----
40 1 file changed, 30 insertions(+), 4 deletions(-)
41
42 --- a/fs/ecryptfs/file.c
43 +++ b/fs/ecryptfs/file.c
44 @@ -303,9 +303,22 @@ ecryptfs_unlocked_ioctl(struct file *fil
45 struct file *lower_file = ecryptfs_file_to_lower(file);
46 long rc = -ENOTTY;
47
48 - if (lower_file->f_op->unlocked_ioctl)
49 + if (!lower_file->f_op->unlocked_ioctl)
50 + return rc;
51 +
52 + switch (cmd) {
53 + case FITRIM:
54 + case FS_IOC_GETFLAGS:
55 + case FS_IOC_SETFLAGS:
56 + case FS_IOC_GETVERSION:
57 + case FS_IOC_SETVERSION:
58 rc = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg);
59 - return rc;
60 + fsstack_copy_attr_all(file_inode(file), file_inode(lower_file));
61 +
62 + return rc;
63 + default:
64 + return rc;
65 + }
66 }
67
68 #ifdef CONFIG_COMPAT
69 @@ -315,9 +328,22 @@ ecryptfs_compat_ioctl(struct file *file,
70 struct file *lower_file = ecryptfs_file_to_lower(file);
71 long rc = -ENOIOCTLCMD;
72
73 - if (lower_file->f_op->compat_ioctl)
74 + if (!lower_file->f_op->compat_ioctl)
75 + return rc;
76 +
77 + switch (cmd) {
78 + case FITRIM:
79 + case FS_IOC32_GETFLAGS:
80 + case FS_IOC32_SETFLAGS:
81 + case FS_IOC32_GETVERSION:
82 + case FS_IOC32_SETVERSION:
83 rc = lower_file->f_op->compat_ioctl(lower_file, cmd, arg);
84 - return rc;
85 + fsstack_copy_attr_all(file_inode(file), file_inode(lower_file));
86 +
87 + return rc;
88 + default:
89 + return rc;
90 + }
91 }
92 #endif
93