Will discard this patch.
We are planing to make the clients to check the mds auth caps before
buffering the changes instead of this workaround and will blocklist or
forbid old clients to mount if root_squash enabled, because it's hard to
fix this bug for the old clients properly.
Thanks!
Xiubo
On 02/09/2022 09:55, xiubli@xxxxxxxxxx wrote:
From: Xiubo Li <xiubli@xxxxxxxxxx>
With the root_squash MDS caps enabled and for a root user it should
fail to write the file. But currently the kclient will just skip
sending a open request and check_caps() instead even with the root
user. This will skip checking the MDS caps in MDS server.
We should force sending a open request to MDS for root user if the
cephx is enabled.
URL: https://tracker.ceph.com/issues/56067
URL: https://tracker.ceph.com/issues/57154
Signed-off-by: Xiubo Li <xiubli@xxxxxxxxxx>
---
fs/ceph/file.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 86265713a743..d51c98412a30 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -360,6 +360,7 @@ int ceph_open(struct inode *inode, struct file *file)
struct ceph_mds_client *mdsc = fsc->mdsc;
struct ceph_mds_request *req;
struct ceph_file_info *fi = file->private_data;
+ uid_t uid = from_kuid(&init_user_ns, get_current_cred()->fsuid);
int err;
int flags, fmode, wanted;
@@ -393,13 +394,19 @@ int ceph_open(struct inode *inode, struct file *file)
}
/*
- * No need to block if we have caps on the auth MDS (for
- * write) or any MDS (for read). Update wanted set
- * asynchronously.
+ * If the caller is root user and the Fw caps is required
+ * it will force sending a open request to MDS to let
+ * the MDS do the root_squash MDS caps check.
+ *
+ * Otherwise no need to block if we have caps on the auth
+ * MDS (for write) or any MDS (for read). Update wanted
+ * set asynchronously.
*/
spin_lock(&ci->i_ceph_lock);
- if (__ceph_is_any_real_caps(ci) &&
- (((fmode & CEPH_FILE_MODE_WR) == 0) || ci->i_auth_cap)) {
+ if (!((fmode & CEPH_FILE_MODE_WR) && !uid) &&
+ (__ceph_is_any_real_caps(ci) &&
+ (((fmode & CEPH_FILE_MODE_WR) == 0) || ci->i_auth_cap))) {
+
int mds_wanted = __ceph_caps_mds_wanted(ci, true);
int issued = __ceph_caps_issued(ci, NULL);