mds/client: check the cephx mds auth access in client side#48027
mds/client: check the cephx mds auth access in client side#48027rishabh-d-dave merged 21 commits intoceph:mainfrom
Conversation
mchangir
left a comment
There was a problem hiding this comment.
nit: please rephrase commit message
mds: add ceph_subsys_mds_auth subsys for MDSAuthCaps.cc
In client side we also need to debug it without debug_mds being enabled.
Circling back to my comment in #47506 (comment) . Why are we issuing Fw caps for a client with root_squash? Also, any fix should begin with a test case. |
Once a permissions access check passed for a non-root user and the MDS will successfully open the inode in MDS and the The root-user's access could come in any time so we couldn't predict it here. I am thinking maybe we should always set the cap update request's
Sure. Will do it. Thanks! |
8e486e9 to
2d479a6
Compare
Do we know why the kclient always uses 0/0 for uid/gid rather than using caller uid/gid? (I understand we do not track uid/gid for per cap (flushes)). |
This was introduced by Sage's commit in userspace client 7 years ago: Before this it would also set it to There also have some other cases, which fixes are in kclient but not in userspace client, just like this. I have fixed many of them already. |
I presume this is related to the issue with root squash. Is there any other benefit of passing the auth caps back to the client than just having the mds hint the client that it has root squash and then client then uses this bit of information to deny write/update operations from 0/0?
|
Yeah. While in kclient the async dirops could benefit from this, which is irrelevant to the Currently it will issue Frw caps to kclient for
The The above will enable Then how could we handle this case ? Maybe we could add one map for each CInode and then pass it back to clients, but for different client id may have different keyring and different mds caps, then we need to record all of them in the CInode, it will be like: Such as for the This will make it more complicated than the fix in this PR currently and hard to maintain in MDS side ?
|
That's a valid point @lxbsz, however, passing mds auth caps to the client is making me feel a bit uncomfortable, although, its nothing to do with security aspects as such.
|
|
...
Not only for The simple graph: And then, for example, for all the subdirs' inode in clients side of This should simplify it. But still not sure whether is there any potential issue for this approach we haven't foresee yet ? @vshankar Any idea ? |
Which issue?
Are you talking about a different approach than #48027 (comment)? |
|
...
The async dirops in kclient allows users to cache creating files or directories locally without getting a change to do the cephx check in MDS side before it. That means users will see the files/directories were created successfully but later it will see a We can use to check access before caching the creating. [...]
Yeah. Just a little different but mostly are the same. There is no need to record the following info in each CInode: But this will make the client side code more complicated than this PR than as expected. Currently this PR is still the easiest and simplest to fix this bug. |
Oh yeh - I recall we discussing this.
Fair enough. I'll go through it in detail. |
@lxbsz I want to make sure that we're on the same page . The cephx MDS auth caps are ORed. Since cephx ID test_b has MDS auth caps Similarly, a client using test_b ID and mounting path I think a more useful path based restriction of MDS caps for a cephx ID would look like, Anyways, I think your current approach of passing all of the cephx MDS caps to the userspace FS client makes sense to me.
|
Okay, thanks for this. I never tested this yet. Just for a example and yours below is the correct one.
Yeah, this is the simplest approach too. Still waiting @vshankar 's reply on it. And after that I will fix your comments. Thanks! |
If couldn't get the absolute path string we need to force it to do the sync setattr. Fixes: https://tracker.ceph.com/issues/57154 Signed-off-by: Xiubo Li <xiubli@redhat.com>
This feature bit could be used to distinguish old and new clients. Fixes: https://tracker.ceph.com/issues/57154 Signed-off-by: Xiubo Li <xiubli@redhat.com>
Since the setattr will check the cephx mds auth access before buffering the changes, so it makes no sense any more to let the cap update to check the access in MDS again. Fixes: https://tracker.ceph.com/issues/57154 Signed-off-by: Xiubo Li <xiubli@redhat.com>
Before opening the file locally we need to check the cephx access. Fixes: https://tracker.ceph.com/issues/57154 Signed-off-by: Xiubo Li <xiubli@redhat.com>
as it's too late. Session access authorization already happens before new caps are issued. Fixes: https://tracker.ceph.com/issues/56067 Signed-off-by: Ramana Raja <rraja@redhat.com>
... MDS auth caps but don't have CEPHFS_FEATURE_MDS_AUTH_CAPS_CHECK feature bit (i.e., can't check the auth caps sent back to it by the MDS) from establishing a session. Do this in Server::handle_client_session(), and Server::handle_client_reconnect(), where old clients try to reconnect to MDS servers after an upgrade. If the client doesn't have the ability to authorize session access based on the MDS auth caps send back to it by the MDS, then the client may buffer changes locally during open and setattr operations when it's not supposed to, e.g., when enforcing root_squash MDS auth caps. Fixes: https://tracker.ceph.com/issues/56067 Signed-off-by: Ramana Raja <rraja@redhat.com>
The test.cc will be included in ceph_test_libcephfs, no need to include it to access. Fixes: https://tracker.ceph.com/issues/57154 Signed-off-by: Xiubo Li <xiubli@redhat.com>
Fixes: https://tracker.ceph.com/issues/57154 Signed-off-by: Xiubo Li <xiubli@redhat.com>
Test the 'chown' and 'truncate', which will call the setattr and 'cat' will open the files. Before each testing will open the file by non-root user and keep it to make sure the Fxw caps are issued, and then user the 'sudo' do to the tests, which will set the uid/gid to 0/0. Fixes: https://tracker.ceph.com/issues/57154 Signed-off-by: Xiubo Li <xiubli@redhat.com>
…6067 A kernel CephFS client with MDS root_squash caps is able to write to a file as non-root user. However, the data written is lost after clearing the kernel client cache, or re-mounting the client. This issue is not observed with a FUSE CephFS client. Signed-off-by: Ramana Raja <rraja@redhat.com>
kclient doesn't have CEPHFS_FEATURE_MDS_AUTH_CAPS required to enforce root_squash. Run root_squash tests only for FUSE client. Signed-off-by: Ramana Raja <rraja@redhat.com>
Rebased it and resolve the conflicts with #41779. |
@rishabh-d-dave Please run this through tests on prio. |
|
jenkins test api |
or let me know if you are tied up this week - I can plan to get this run through fs suite. |
rishabh-d-dave
left a comment
There was a problem hiding this comment.
Testing was successful - https://tracker.ceph.com/projects/cephfs/wiki/Main#22-Sep-2023
|
Venky is also okay merging this PR, so I am proceeding. |
|
I'm looking at a small part of this code for unrelated reasons (checking paths live within a share on a shared Ganesha Client), and I don't think that the make_path_string() path-checking logic works right. In particular:
But this root ino is not the full CephFS filesystem root, it's the mount point of this particular Client. So if the client mounts at /volumes/foo, and there is a file at /volumes/foo/bar/baz, this function will actually return "/bar/baz". And that means none of the path checking will work. Am I missing something about this? I see some tests for pieces of the PR, but not for this functionality — is there some that I'm missing? @vshankar @batrick @lxbsz |
|
I also see that if the dentry doesn't have a parent, it's happy to just stick "???" into the directory, which...maybe works? |
Yeah, this is buggy. BTW, is just passing the mountpoint's full path to client safe ? If so we can pass it to clients and then make the full path from fs' root. |
The
In this case we should issue a lookup first. I will fix it. |
Okay, we have already recorded the mount position in client side in |
I think I have already handled this, please see https://github.com/ceph/ceph/blob/main/src/client/Client.cc#L8041. It will try to do sync setattr/open if |
Currently for the
setattrit could buffer the changes locally if the requiredcapsare issued and just succeeds thesetattrrequest. But later whenflushing the changes back to MDS via the cap update request the MDS
may fail it when checking the cephx mds auth access. This will cause to
lose the memtadata/data when the mountpoint remounted or something
else. It's bad!!!
And also the same for the
open, which may just open the inode locallyby sending a check_caps() to MDS.
This PR will pass the parsed the mds auth caps back to clients when
opening sessions. And the client could do the same access checking
if clients want to buffer the changes or without sending a sync request
to MDS.
After this I will make this change in kernel client, which need much more
work than this, because we couldn't reuse the mds auth related code
there.
Fixes: https://tracker.ceph.com/issues/57154
Signed-off-by: Xiubo Li xiubli@redhat.com
Contribution Guidelines
To sign and title your commits, please refer to Submitting Patches to Ceph.
If you are submitting a fix for a stable branch (e.g. "pacific"), please refer to Submitting Patches to Ceph - Backports for the proper workflow.
Checklist
Show available Jenkins commands
jenkins retest this pleasejenkins test classic perfjenkins test crimson perfjenkins test signedjenkins test make checkjenkins test make check arm64jenkins test submodulesjenkins test dashboardjenkins test dashboard cephadmjenkins test apijenkins test docsjenkins render docsjenkins test ceph-volume alljenkins test ceph-volume toxjenkins test windows