aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobbie Ko <robbieko@synology.com>2018-08-21 04:17:40 -0400
committerTyler Hicks <tyhicks@canonical.com>2019-02-16 18:18:57 -0500
commitd43388dea04b18f516bd7c837d9222fe7309b12d (patch)
tree49ecee9a2b01849ef2cd7d8bb340a6311969f54a
parent4b47a8b51e7bc0bcd1fa8e546a6333a04ab760d8 (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.c17
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);
1149out:
1137 return rc; 1150 return rc;
1138} 1151}
1139 1152