diff options
| author | Robbie Ko <robbieko@synology.com> | 2018-08-21 04:17:40 -0400 |
|---|---|---|
| committer | Tyler Hicks <tyhicks@canonical.com> | 2019-02-16 18:18:57 -0500 |
| commit | d43388dea04b18f516bd7c837d9222fe7309b12d (patch) | |
| tree | 49ecee9a2b01849ef2cd7d8bb340a6311969f54a | |
| parent | 4b47a8b51e7bc0bcd1fa8e546a6333a04ab760d8 (diff) | |
eCryptfs: fix permission denied with ecryptfs_xattr mount option when create readonly file
When the ecryptfs_xattr mount option is turned on, the ecryptfs
metadata will be written to xattr via vfs_setxattr, which will
check the WRITE permissions.
However, this will cause denial of permission when creating a
file withoug write permission.
So fix this by calling __vfs_setxattr directly to skip permission
check.
Signed-off-by: Robbie Ko <robbieko@synology.com>
[tyhicks: Copy up lower inode attributes when successful]
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
| -rw-r--r-- | fs/ecryptfs/crypto.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 708f931c36f1..bc2376726090 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
| 38 | #include <asm/unaligned.h> | 38 | #include <asm/unaligned.h> |
| 39 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
| 40 | #include <linux/xattr.h> | ||
| 40 | #include "ecryptfs_kernel.h" | 41 | #include "ecryptfs_kernel.h" |
| 41 | 42 | ||
| 42 | #define DECRYPT 0 | 43 | #define DECRYPT 0 |
| @@ -1131,9 +1132,21 @@ ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry, | |||
| 1131 | char *page_virt, size_t size) | 1132 | char *page_virt, size_t size) |
| 1132 | { | 1133 | { |
| 1133 | int rc; | 1134 | int rc; |
| 1135 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); | ||
| 1136 | struct inode *lower_inode = d_inode(lower_dentry); | ||
| 1134 | 1137 | ||
| 1135 | rc = ecryptfs_setxattr(ecryptfs_dentry, ecryptfs_inode, | 1138 | if (!(lower_inode->i_opflags & IOP_XATTR)) { |
| 1136 | ECRYPTFS_XATTR_NAME, page_virt, size, 0); | 1139 | rc = -EOPNOTSUPP; |
| 1140 | goto out; | ||
| 1141 | } | ||
| 1142 | |||
| 1143 | inode_lock(lower_inode); | ||
| 1144 | rc = __vfs_setxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME, | ||
| 1145 | page_virt, size, 0); | ||
| 1146 | if (!rc && ecryptfs_inode) | ||
| 1147 | fsstack_copy_attr_all(ecryptfs_inode, lower_inode); | ||
| 1148 | inode_unlock(lower_inode); | ||
| 1149 | out: | ||
| 1137 | return rc; | 1150 | return rc; |
| 1138 | } | 1151 | } |
| 1139 | 1152 | ||
