aboutsummaryrefslogtreecommitdiffstats
path: root/fs/posix_acl.c
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@linbit.com>2014-01-23 18:56:15 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-23 19:37:04 -0500
commit949b9c3d4263c9b7c2448588afce37becd58e1ad (patch)
tree9db6da020bb289372cd001a816768f2ececfffc0 /fs/posix_acl.c
parente376ed7c85fe102ff63db2eb8a0c5595f68151fa (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.c10
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