Blame SOURCES/0004-eCryptfs-fix-permission-denied-with-ecryptfs_xattr-m.patch

Kmods SIG 1bd144
From d43388dea04b18f516bd7c837d9222fe7309b12d Mon Sep 17 00:00:00 2001
Kmods SIG 1bd144
From: Robbie Ko <robbieko@synology.com>
Kmods SIG 1bd144
Date: Tue, 21 Aug 2018 16:17:40 +0800
Kmods SIG 1bd144
Subject: [Backport d43388dea04b] eCryptfs: fix permission denied with
Kmods SIG 1bd144
 ecryptfs_xattr mount option when create readonly file
Kmods SIG 1bd144
Kmods SIG 1bd144
When the ecryptfs_xattr mount option is turned on, the ecryptfs
Kmods SIG 1bd144
metadata will be written to xattr via vfs_setxattr, which will
Kmods SIG 1bd144
check the WRITE permissions.
Kmods SIG 1bd144
Kmods SIG 1bd144
However, this will cause denial of permission when creating a
Kmods SIG 1bd144
file withoug write permission.
Kmods SIG 1bd144
Kmods SIG 1bd144
So fix this by calling __vfs_setxattr directly to skip permission
Kmods SIG 1bd144
check.
Kmods SIG 1bd144
Kmods SIG 1bd144
Signed-off-by: Robbie Ko <robbieko@synology.com>
Kmods SIG 1bd144
[tyhicks: Copy up lower inode attributes when successful]
Kmods SIG 1bd144
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Kmods SIG 1bd144
---
Kmods SIG 1bd144
 src/crypto.c | 17 +++++++++++++++--
Kmods SIG 1bd144
 1 file changed, 15 insertions(+), 2 deletions(-)
Kmods SIG 1bd144
Kmods SIG 1bd144
diff --git a/src/crypto.c b/src/crypto.c
Kmods SIG 1bd144
index 708f931c36f14adace91af82229a6043386c9baf..bc2376726090b403ed3fa8d043efa07c6b45c23a 100644
Kmods SIG 1bd144
--- a/src/crypto.c
Kmods SIG 1bd144
+++ b/src/crypto.c
Kmods SIG 1bd144
@@ -37,6 +37,7 @@
Kmods SIG 1bd144
 #include <linux/slab.h>
Kmods SIG 1bd144
 #include <asm/unaligned.h>
Kmods SIG 1bd144
 #include <linux/kernel.h>
Kmods SIG 1bd144
+#include <linux/xattr.h>
Kmods SIG 1bd144
 #include "ecryptfs_kernel.h"
Kmods SIG 1bd144
 
Kmods SIG 1bd144
 #define DECRYPT		0
Kmods SIG 1bd144
@@ -1131,9 +1132,21 @@ ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry,
Kmods SIG 1bd144
 				 char *page_virt, size_t size)
Kmods SIG 1bd144
 {
Kmods SIG 1bd144
 	int rc;
Kmods SIG 1bd144
+	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
Kmods SIG 1bd144
+	struct inode *lower_inode = d_inode(lower_dentry);
Kmods SIG 1bd144
 
Kmods SIG 1bd144
-	rc = ecryptfs_setxattr(ecryptfs_dentry, ecryptfs_inode,
Kmods SIG 1bd144
-			       ECRYPTFS_XATTR_NAME, page_virt, size, 0);
Kmods SIG 1bd144
+	if (!(lower_inode->i_opflags & IOP_XATTR)) {
Kmods SIG 1bd144
+		rc = -EOPNOTSUPP;
Kmods SIG 1bd144
+		goto out;
Kmods SIG 1bd144
+	}
Kmods SIG 1bd144
+
Kmods SIG 1bd144
+	inode_lock(lower_inode);
Kmods SIG 1bd144
+	rc = __vfs_setxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME,
Kmods SIG 1bd144
+			    page_virt, size, 0);
Kmods SIG 1bd144
+	if (!rc && ecryptfs_inode)
Kmods SIG 1bd144
+		fsstack_copy_attr_all(ecryptfs_inode, lower_inode);
Kmods SIG 1bd144
+	inode_unlock(lower_inode);
Kmods SIG 1bd144
+out:
Kmods SIG 1bd144
 	return rc;
Kmods SIG 1bd144
 }
Kmods SIG 1bd144
 
Kmods SIG 1bd144
-- 
Kmods SIG 1bd144
2.31.1
Kmods SIG 1bd144