diff options
author | Andreas Gruenbacher <agruen@linbit.com> | 2014-01-23 18:56:15 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-23 19:37:04 -0500 |
commit | 949b9c3d4263c9b7c2448588afce37becd58e1ad (patch) | |
tree | 9db6da020bb289372cd001a816768f2ececfffc0 /fs/posix_acl.c | |
parent | e376ed7c85fe102ff63db2eb8a0c5595f68151fa (diff) |
userns: relax the posix_acl_valid() checks
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>
Diffstat (limited to 'fs/posix_acl.c')
-rw-r--r-- | fs/posix_acl.c | 10 |
1 files changed, 0 insertions, 10 deletions
diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 021e7c069b86..551e61ba15b6 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c | |||
@@ -149,8 +149,6 @@ posix_acl_valid(const struct posix_acl *acl) | |||
149 | { | 149 | { |
150 | const struct posix_acl_entry *pa, *pe; | 150 | const struct posix_acl_entry *pa, *pe; |
151 | int state = ACL_USER_OBJ; | 151 | int state = ACL_USER_OBJ; |
152 | kuid_t prev_uid = INVALID_UID; | ||
153 | kgid_t prev_gid = INVALID_GID; | ||
154 | int needs_mask = 0; | 152 | int needs_mask = 0; |
155 | 153 | ||
156 | FOREACH_ACL_ENTRY(pa, acl, pe) { | 154 | FOREACH_ACL_ENTRY(pa, acl, pe) { |
@@ -169,10 +167,6 @@ posix_acl_valid(const struct posix_acl *acl) | |||
169 | return -EINVAL; | 167 | return -EINVAL; |
170 | if (!uid_valid(pa->e_uid)) | 168 | if (!uid_valid(pa->e_uid)) |
171 | return -EINVAL; | 169 | return -EINVAL; |
172 | if (uid_valid(prev_uid) && | ||
173 | uid_lte(pa->e_uid, prev_uid)) | ||
174 | return -EINVAL; | ||
175 | prev_uid = pa->e_uid; | ||
176 | needs_mask = 1; | 170 | needs_mask = 1; |
177 | break; | 171 | break; |
178 | 172 | ||
@@ -188,10 +182,6 @@ posix_acl_valid(const struct posix_acl *acl) | |||
188 | return -EINVAL; | 182 | return -EINVAL; |
189 | if (!gid_valid(pa->e_gid)) | 183 | if (!gid_valid(pa->e_gid)) |
190 | return -EINVAL; | 184 | return -EINVAL; |
191 | if (gid_valid(prev_gid) && | ||
192 | gid_lte(pa->e_gid, prev_gid)) | ||
193 | return -EINVAL; | ||
194 | prev_gid = pa->e_gid; | ||
195 | needs_mask = 1; | 185 | needs_mask = 1; |
196 | break; | 186 | break; |
197 | 187 | ||