Commit ddca4e1730cf1b72044ae76ddf17b29d790b4dbc

Authored by Eric W. Biederman
1 parent 1ac7fd8190

nfs_common: Update the translation between nfsv3 acls linux posix acls

- Use kuid_t and kgit in struct nfsacl_encode_desc.
- Convert from kuids and kgids when generating on the wire values.
- Convert on the wire values to kuids and kgids when read.
- Modify cmp_acl_entry to be type safe comparison on posix acls.
  Only acls with type ACL_USER and ACL_GROUP can appear more
  than once and as such need to compare more than their tag.
- The e_id field is being removed from posix acls so don't initialize it.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>

Showing 1 changed file with 26 additions and 15 deletions Side-by-side Diff

fs/nfs_common/nfsacl.c
... ... @@ -38,8 +38,8 @@
38 38 unsigned int count;
39 39 struct posix_acl *acl;
40 40 int typeflag;
41   - uid_t uid;
42   - gid_t gid;
  41 + kuid_t uid;
  42 + kgid_t gid;
43 43 };
44 44  
45 45 struct nfsacl_simple_acl {
46 46  
47 47  
48 48  
... ... @@ -60,14 +60,16 @@
60 60 *p++ = htonl(entry->e_tag | nfsacl_desc->typeflag);
61 61 switch(entry->e_tag) {
62 62 case ACL_USER_OBJ:
63   - *p++ = htonl(nfsacl_desc->uid);
  63 + *p++ = htonl(from_kuid(&init_user_ns, nfsacl_desc->uid));
64 64 break;
65 65 case ACL_GROUP_OBJ:
66   - *p++ = htonl(nfsacl_desc->gid);
  66 + *p++ = htonl(from_kgid(&init_user_ns, nfsacl_desc->gid));
67 67 break;
68 68 case ACL_USER:
  69 + *p++ = htonl(from_kuid(&init_user_ns, entry->e_uid));
  70 + break;
69 71 case ACL_GROUP:
70   - *p++ = htonl(entry->e_id);
  72 + *p++ = htonl(from_kgid(&init_user_ns, entry->e_gid));
71 73 break;
72 74 default: /* Solaris depends on that! */
73 75 *p++ = 0;
... ... @@ -148,6 +150,7 @@
148 150 (struct nfsacl_decode_desc *) desc;
149 151 __be32 *p = elem;
150 152 struct posix_acl_entry *entry;
  153 + unsigned int id;
151 154  
152 155 if (!nfsacl_desc->acl) {
153 156 if (desc->array_len > NFS_ACL_MAX_ENTRIES)
154 157  
155 158  
156 159  
... ... @@ -160,14 +163,22 @@
160 163  
161 164 entry = &nfsacl_desc->acl->a_entries[nfsacl_desc->count++];
162 165 entry->e_tag = ntohl(*p++) & ~NFS_ACL_DEFAULT;
163   - entry->e_id = ntohl(*p++);
  166 + id = ntohl(*p++);
164 167 entry->e_perm = ntohl(*p++);
165 168  
166 169 switch(entry->e_tag) {
167   - case ACL_USER_OBJ:
168 170 case ACL_USER:
169   - case ACL_GROUP_OBJ:
  171 + entry->e_uid = make_kuid(&init_user_ns, id);
  172 + if (!uid_valid(entry->e_uid))
  173 + return -EINVAL;
  174 + break;
170 175 case ACL_GROUP:
  176 + entry->e_gid = make_kgid(&init_user_ns, id);
  177 + if (!gid_valid(entry->e_gid))
  178 + return -EINVAL;
  179 + break;
  180 + case ACL_USER_OBJ:
  181 + case ACL_GROUP_OBJ:
171 182 case ACL_OTHER:
172 183 if (entry->e_perm & ~S_IRWXO)
173 184 return -EINVAL;
174 185  
175 186  
... ... @@ -190,10 +201,14 @@
190 201  
191 202 if (a->e_tag != b->e_tag)
192 203 return a->e_tag - b->e_tag;
193   - else if (a->e_id > b->e_id)
  204 + else if ((a->e_tag == ACL_USER) && uid_gt(a->e_uid, b->e_uid))
194 205 return 1;
195   - else if (a->e_id < b->e_id)
  206 + else if ((a->e_tag == ACL_USER) && uid_lt(a->e_uid, b->e_uid))
196 207 return -1;
  208 + else if ((a->e_tag == ACL_GROUP) && gid_gt(a->e_gid, b->e_gid))
  209 + return 1;
  210 + else if ((a->e_tag == ACL_GROUP) && gid_lt(a->e_gid, b->e_gid))
  211 + return -1;
197 212 else
198 213 return 0;
199 214 }
200 215  
201 216  
202 217  
... ... @@ -213,22 +228,18 @@
213 228 sort(acl->a_entries, acl->a_count, sizeof(struct posix_acl_entry),
214 229 cmp_acl_entry, NULL);
215 230  
216   - /* Clear undefined identifier fields and find the ACL_GROUP_OBJ
217   - and ACL_MASK entries. */
  231 + /* Find the ACL_GROUP_OBJ and ACL_MASK entries. */
218 232 FOREACH_ACL_ENTRY(pa, acl, pe) {
219 233 switch(pa->e_tag) {
220 234 case ACL_USER_OBJ:
221   - pa->e_id = ACL_UNDEFINED_ID;
222 235 break;
223 236 case ACL_GROUP_OBJ:
224   - pa->e_id = ACL_UNDEFINED_ID;
225 237 group_obj = pa;
226 238 break;
227 239 case ACL_MASK:
228 240 mask = pa;
229 241 /* fall through */
230 242 case ACL_OTHER:
231   - pa->e_id = ACL_UNDEFINED_ID;
232 243 break;
233 244 }
234 245 }