I'm generally in favor of considering this a bug and fixing it. Thanks!
On Mon, Mar 20, 2023 at 04:21:12PM -0400, Jeffrey E Altman wrote: > On 7 March Andrew Deason submitted a patch to OpenAFS documenting the > existing behavior of the OpenAFS fileserver when computing Anonymous and > Caller Access Rights if the IPv4 address from which the RXAFS RPC was > received matches a PTS host entry and that PTS entry matches an Access > Control Entry (ACE). > > https://gerrit.openafs.org/#/c/15340/ > > Quoting Andrew's submission to the fs_setacl man page: > > "Combining _Negative rights_ granted from machine entries (IP > addresses) and _Normal rights_ granted from non-machine entries (or > vice versa) will generally not work as expected. Permissions granted > by machine entries and by non-machine entries are calculated > separately, and both sets of permissions are given to an accessing > user. For example, if permissions are granted to an authenticated > user or group (or _system:anyuser_), you cannot remove those > permissions from specific hosts by adding machine entries to a group > in an ACL in the _Negative rights_> section." > > The IBM AFS Administrator's Guide "Protecting Data in AFS" section states: > > "When determining what type of access to grant to a user, theFile > Server first compiles a set of permissions by examiningall of the > entries in the Normal rights section of the ACL. Itthen subtracts > any permissions associated with the user (orwith groups to which the > user belongs) on the Negative rightssection of the ACL. Therefore, > negative permissions alwayscancel out normal permissions." > > IBM/Transarc AFS 3.2 introduced the granting of permissions based upon the > host's IPv4 address in addition to those granted to the caller. The > implementation evaluates the caller's rights independently of the host's > rights and then ORs the results. This approach violates the statement that > negative permissions always cancel out normal (aka positive) permissions. If > a caller is granted "read" but there is a matching negative "read" ACE (aka > permission) for the host, the negative "read" ACE is ignored. Likewise if > "lookup" is granted to the host but the caller matches a negative "lookup" > ACE, then the caller's negative "lookup" ACE is ignored. > > The problem can be demonstrated with a couple of examples. First, lets > define some PTS entities and membership relations: > > * user: jane = 1000 > o member: system:authusers > o member: system:anyuser > o member: no-admin > * user: 128.66.0.130 = 2000 > o member: local-hosts > * group: no-admin = -100 > o member: jane > * group: local-hosts = -500 > o member: 128.66.0.130 > > Example 1: RXAFS RPC received from a host that is not a member of > local-hosts > > ACL > > * system:anyuser: l; -none > * system:authuser: lrk; -none > * jane: none; -r > * local-hosts: r; -none > > Rights: > > * system:anyuser: lookup > * system:authuser: lookup, read, lock > * jane: lookup, lock > > When "jane" accesses a file with this ACL the granted rights will be "lk" > because the negative read permission cancels the positive read permission > granted by the membership in the system:authuser group. > > > Example 2: RXAFS RPC received from a host that is a member of local-hosts > > ACL > > * system:anyuser: l; -none > * system:authuser: lrk; -none > * jane: none; -r > * local-hosts: r; -none > > Rights: > > * system:anyuser: lookup, read > * system:authuser: lookup, read, lock > * jane: lookup, read, lock > > In this case, even though "jane" is denied the "read" permission granted to > members of "system:authuser" because of the negative "read" in the "jane" > ACE she is granted the permission because of the positive read permission > granted to "local-hosts" members. The granting of "read" permission to > "jane" is an unexpected result! > > > Example 3: RXAFS RPC received from a host that is not a member of > local-hosts > > ACL > > * system:anyuser: l; -none > * system:authuser: lrk; -none > * jane: lrkwid; -none > * local-hosts: none; -wida > > Rights: > > * system:anyuser: lookup > * system:authuser: lookup, read, lock > * jane: lookup, read, lock, write, insert, delete > > In this case, "jane" is granted all of the permissions other than "admin". > > > Example 4: RXAFS RPC received from a host that is a member of local-hosts > > ACL > > * system:anyuser: l; -none > * system:authuser: lrk; -none > * jane: lrkwid; -none > * local-hosts: none; -wida > > Rights: > > * system:anyuser: lookup > * system:authuser: lookup, read, lock > * jane: lookup, read, lock, write, insert, delete > > In this case, "jane" is granted all of the permissions other than "admin". > However, because the RPC was issued from a host that is a member of > "local-hosts" the expected result would be "jane" receiving only the > "lookup, read, lock" rights. The granting of "write, insert and delete" > permission is an unexpected outcome! > > > In examples 2 and 4 rights are granted to the caller that would appear to be > contrary to the explicit use of negative rights in the access control > entries. The example 4 use case might represent client systems which are > intended to be read-only consumers of the /afs content but which might be > vulnerable to exploitation. Example 2 is intended to always deny read > privileges to "jane" but if she can gain access to the host with IPv4 > address 128.66.0.130 she can bypass those restrictions. > > This behavior feels like a bug to me. A bug that has been present since the > release of AFS 3.2 more than thirty years ago but a bug nevertheless. I > propose that OpenAFS fix the broken behavior so that ACL interpretation is > consistent with the documentation inherited from IBM. > > Two commits submitted to Gerrit will enforce negative access rights. > > https://gerrit.openafs.org/#/c/15344/ > https://gerrit.openafs.org/#/c/15345/ > > > History: > > AFS 3.1 and earlier did not have a concept of IP or Host ACLs. That > functionality was introduced in AFS 3.2. However, the implementation that > is present in the release version of AFS 3.2 and in use to this day might > not have been the original implementation. Today's fileserver issues > separate calls to the protection service to obtain the caller's Current > Protection Set (CPS) and the host's CPS. The fileserver then computes the > caller rights by comparing the caller's CPS to the object's ACL; and it > computes the host's rights by comparing the host's CPS to the object's > ACL. The fileserver then grants the caller all rights granted to both the > caller and the host. > > The host's CPS is obtained by the fileserver by issuing the PR_GetHostCPS > RPC. PR_GetHostCPS differs from PR_GetCPS in that it matches the host's > IPv4 address using wildcard pattern matching when searching for a matching > PTS ID. It also does not treat the PTS entity as a member of the > system:anyuser group. > > Before PR_GetHostCPS was added to the protection service another RPC was > introduced, PR_GetCPS2 which obtained the CPS for the combination of a > caller and a host. An implementation of IP ACLs that used PR_GetCPS2 would > have behaved as expected because the all of the positive rights would have > been computed and from those all of the negative rights would have been > removed. I do not have access to the source code for a version of the > fileserver that used the PR_GetCPS2 RPC but I can imagine that a likely > implementation would have issued a PR_GetCPS2 call for (anonymous, host) and > (caller, host). The additional load these RPCs placed on the protection > service might have been deemed too expensive. As a result, the alternative > approach using the PR_GetHostCPS was introduced. > > Whatever the motivation for PR_GetHostCPS in preference to PR_GetCPS2, the > existing implementation does not interpret ACLs in a manner that permits > negative rights to be superior to positive rights. Perhaps it didn't occur > to the implementer that there was a problem; and it didn't occur to anyone > that a simple change to acl_checkRights() and the fileserver GetRights() > function would permit computing the expected results. > > > Proposal: > > I propose that OpenAFS treat the current behavior as a bug. The use of > negative rights is discouraged because they are hard to analyze. It is > hoped that their use is rare. If negative rights are not in use, then > changing the behavior when IP ACLs exist will not alter the computed > outcome. However, if negative rights are in use, they are likely being used > because it wasn't easy to limit the access any other way. In which case, > granting more access then was specified is problematic. A CVE can be > published to document the existing behavior and the behavior as it will > appear beginning with a specific version of the fileserver. > > If required, a configuration option can be provided to enable the AFS 3.2 > behavior until all of the fileservers within a cell have been updated. I > discourage using a configuration option to enable the stricter > interpretation of ACLs as that will result in some sites being vulnerable > when they did not intend to be. > > > Jeffrey Altman > > P.S. I am writing this letter publicly as opposed to sending it to the > openafs-security queue because the behavior in question is public and > Andrew's proposed patch to the OpenAFS man pages is public. > -- ******************************** David William Botsch Programmer/Analyst @CornellCNF [email protected] ******************************** _______________________________________________ OpenAFS-info mailing list [email protected] https://lists.openafs.org/mailman/listinfo/openafs-info
