userns: relax the posix_acl_valid() checks
authorAndreas Gruenbacher <agruen@linbit.com>
Thu, 23 Jan 2014 23:56:15 +0000 (15:56 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 24 Jan 2014 00:37:04 +0000 (16:37 -0800)
So far, POSIX ACLs are using a canonical representation that keeps all ACL
entries in a strict order; the ACL_USER and ACL_GROUP entries for specific
users and groups are ordered by user and group identifier, respectively.
The user-space code provides ACL entries in this order; the kernel
verifies that the ACL entry order is correct in posix_acl_valid().

User namespaces allow to arbitrary map user and group identifiers which
can cause the ACL_USER and ACL_GROUP entry order to differ between user
space and the kernel; posix_acl_valid() would then fail.

Work around this by allowing ACL_USER and ACL_GROUP entries to be in any
order in the kernel.  The effect is only minor: file permission checks
will pick the first matching ACL_USER entry, and check all matching
ACL_GROUP entries.

(The libacl user-space library and getfacl / setfacl tools will not create
ACLs with duplicate user or group idenfifiers; they will handle ACLs with
entries in an arbitrary order correctly.)

Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Theodore Tso <tytso@mit.edu>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Andreas Dilger <adilger.kernel@dilger.ca>
Cc: Jan Kara <jack@suse.cz>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/posix_acl.c

index 021e7c069b8677bc5bea7da08fe99e9ace41fdc6..551e61ba15b6047c909594968163eaf26c8cb605 100644 (file)
@@ -149,8 +149,6 @@ posix_acl_valid(const struct posix_acl *acl)
 {
        const struct posix_acl_entry *pa, *pe;
        int state = ACL_USER_OBJ;
-       kuid_t prev_uid = INVALID_UID;
-       kgid_t prev_gid = INVALID_GID;
        int needs_mask = 0;
 
        FOREACH_ACL_ENTRY(pa, acl, pe) {
@@ -169,10 +167,6 @@ posix_acl_valid(const struct posix_acl *acl)
                                        return -EINVAL;
                                if (!uid_valid(pa->e_uid))
                                        return -EINVAL;
-                               if (uid_valid(prev_uid) &&
-                                   uid_lte(pa->e_uid, prev_uid))
-                                       return -EINVAL;
-                               prev_uid = pa->e_uid;
                                needs_mask = 1;
                                break;
 
@@ -188,10 +182,6 @@ posix_acl_valid(const struct posix_acl *acl)
                                        return -EINVAL;
                                if (!gid_valid(pa->e_gid))
                                        return -EINVAL;
-                               if (gid_valid(prev_gid) &&
-                                   gid_lte(pa->e_gid, prev_gid))
-                                       return -EINVAL;
-                               prev_gid = pa->e_gid;
                                needs_mask = 1;
                                break;