chaos / diod

Distributed I/O Daemon - a 9P file server
GNU General Public License v2.0
349 stars 56 forks source link

POSIX ACL support? #39

Open rkjnsn opened 6 years ago

rkjnsn commented 6 years ago

The code seems to suggest that both Diod and the v9fs driver support POSIX ACLs, but I can figure out how to properly get them to work. On the remote machine, ls -l identifies the files in question as having ACLs, and getfacl correctly reports them, but they seem to be completely ignored as far as file accesses are concerned.

On files where the ACL grants access but traditional unix permissions wouldn't, I get Permission denied errors. On files where the ACL should deny access but traditional unix permissions would grant it, I can successfully read the contents of the file. (The latter especially surprised me, as the user definitely cannot read the file in question locally, and I would have expected Diod's use of setfs[ug]id to prevent access even if the client machine were ignoring ACLs.)

I have CONFIG_9P_FS_POSIX_ACL enabled in the client kernel, and I tried adding -o posixacl to my diodmount command without any apparent effect.

Am I missing a step somewhere, or is this not supported?

Thanks.

garlick commented 6 years ago

I will try to get a test set up this weekend, but I think this was working a while back.

Regardless of what's working or not now in 9P/v9fs/diod's handling of the ACL attributes, the diod server should definitely not be able to circumvent local access controls. That the most worrisome part of your issue so I'll look at that first. Could you provide:

Thanks!

rkjnsn commented 6 years ago

Sure! To clarify, I'm mounting the filesystem as root and then accessing it as a different user. I don't think it would be unreasonable for the client to be responsible for access enforcement in this case, it's just not what I was expecting from reading the documentation.

garlick commented 6 years ago

Thanks. Still haven't had time to start on this, but one detail that might be important - are the uid and gid mappings and supplemental group memberships the same on client and server?

As I recall 9p2000.u passes the primary uid and gid over the wire (not the names), so that the diod server would setfsuid/gid to the client's numerical id's whether or not those are valid or consistent on the server.

I need to refresh my memory on how the server deals with supplemental groups, but again it's probably based on group membership on the server starting with the client primary uid, not a list of groups passed in from the client?

rkjnsn commented 6 years ago

Yes. /etc/passwd and /etc/group are identical. (I thought from the diod -d 1 output that the attach message only includes the uid, not even the primary gid, but I just tried temporarily changing my primary group on the client using newgrp and newly created files reflect the change. Perhaps this is more indication that permissions are being solely handled on the client side.)

I did some more Googling and experimentation, this morning, and I discovered that if I pass both access=client and posixacl to mount, things appear to work properly. I can access 2 and 3, and get permission denied for 1 and 4. However, this required modifying doidmount to accept access=client, as the current code will reject it. The odd part is that access=user with or without posixacl is acting like I'd expect access=client without posixacl to behave.

garlick commented 6 years ago

Sorry, taking me a bit to refresh my memory here.

One important point I had forgotten: if the client connection is authenticated as root (and other options are not set such as runas-uid or allsquash), then the server actually does assume that the client will perform the discretionary access control. It is still doing setfsuid so that things like file creation work properly, but it's setting the CAP_DAC_OVERRIDE capability on the server.

As an aside, when you change your primary group and create a file, your gid is actually being passed in the Tcreate operation. The diod server does a setfsgid to this before performing the operation. The server also checks that gid against a list of supplemental groups loaded (from the server groups file) at Tattach time.

With the access=user mode in in the client, multiple users are sharing the same connection (authenticated as root), but each user has gone through a Tattach sequence to get a unique root fid, so the server can tell their operations apart. However, the client still performs the discretionary access control.

I think access=client was added on relatively recently, and I'm not sure I understand exactly the differences from access=user, or why a new mode was required, but it does seem to have gone in when POSIX ACL support was added to the v9fs client.

So, possibly we just need to make the change that you already made to diodmount to allow that mode to be used as an alternative to access=user. But I'd like to understand it a little better before we push that in.

rkjnsn commented 6 years ago

Ah, okay. I didn't realize Diod used CAP_DAC_OVERRIDE. Sounds like the Diod server is working as intended, then, and the weirdness is on the v9fs side. Thanks for digging into it!

garlick commented 6 years ago

No, I appreciate you bringing it up as it sounds like we do need to make accommodations for access=client in diodmount, and probably add some documentation about how this works since it's far from obvious. Let's keep this issue open to track those needs.