Commit 8abf2775dd425ec3c767ea7c5a51b45fc8be76c2

Authored by Eric W. Biederman
1 parent 8e3028b908

cifs: Use kuids and kgids SID to uid/gid mapping

Update id_mode_to_cifs_acl to take a kuid_t and a kgid_t.

Replace NO_CHANGE_32 with INVALID_UID and INVALID_GID, and tests for
NO_CHANGE_32 with uid_valid and gid_valid.

Carefully unpack the value returned from request_key.  memcpy the
value into the expected type.  The convert the uid/gid into a
kuid/kgid.  And then only if the result is a valid kuid or kgid update
fuid/fgid.

Cc: Steve French <smfrench@gmail.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>

Showing 4 changed files with 34 additions and 20 deletions Side-by-side Diff

... ... @@ -266,8 +266,8 @@
266 266 struct key *sidkey;
267 267 char *sidstr;
268 268 const struct cred *saved_cred;
269   - uid_t fuid = cifs_sb->mnt_uid;
270   - gid_t fgid = cifs_sb->mnt_gid;
  269 + kuid_t fuid = cifs_sb->mnt_uid;
  270 + kgid_t fgid = cifs_sb->mnt_gid;
271 271  
272 272 /*
273 273 * If we have too many subauthorities, then something is really wrong.
... ... @@ -306,10 +306,21 @@
306 306 goto out_key_put;
307 307 }
308 308  
309   - if (sidtype == SIDOWNER)
310   - memcpy(&fuid, &sidkey->payload.value, sizeof(uid_t));
311   - else
312   - memcpy(&fgid, &sidkey->payload.value, sizeof(gid_t));
  309 + if (sidtype == SIDOWNER) {
  310 + kuid_t uid;
  311 + uid_t id;
  312 + memcpy(&id, &sidkey->payload.value, sizeof(uid_t));
  313 + uid = make_kuid(&init_user_ns, id);
  314 + if (uid_valid(uid))
  315 + fuid = uid;
  316 + } else {
  317 + kgid_t gid;
  318 + gid_t id;
  319 + memcpy(&id, &sidkey->payload.value, sizeof(gid_t));
  320 + gid = make_kgid(&init_user_ns, id);
  321 + if (gid_valid(gid))
  322 + fgid = gid;
  323 + }
313 324  
314 325 out_key_put:
315 326 key_put(sidkey);
... ... @@ -776,7 +787,7 @@
776 787  
777 788 /* Convert permission bits from mode to equivalent CIFS ACL */
778 789 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
779   - __u32 secdesclen, __u64 nmode, uid_t uid, gid_t gid, int *aclflag)
  790 + __u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, int *aclflag)
780 791 {
781 792 int rc = 0;
782 793 __u32 dacloffset;
783 794  
784 795  
... ... @@ -808,17 +819,19 @@
808 819 *aclflag = CIFS_ACL_DACL;
809 820 } else {
810 821 memcpy(pnntsd, pntsd, secdesclen);
811   - if (uid != NO_CHANGE_32) { /* chown */
  822 + if (uid_valid(uid)) { /* chown */
  823 + uid_t id;
812 824 owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
813 825 le32_to_cpu(pnntsd->osidoffset));
814 826 nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
815 827 GFP_KERNEL);
816 828 if (!nowner_sid_ptr)
817 829 return -ENOMEM;
818   - rc = id_to_sid(uid, SIDOWNER, nowner_sid_ptr);
  830 + id = from_kuid(&init_user_ns, uid);
  831 + rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
819 832 if (rc) {
820 833 cFYI(1, "%s: Mapping error %d for owner id %d",
821   - __func__, rc, uid);
  834 + __func__, rc, id);
822 835 kfree(nowner_sid_ptr);
823 836 return rc;
824 837 }
825 838  
826 839  
... ... @@ -826,17 +839,19 @@
826 839 kfree(nowner_sid_ptr);
827 840 *aclflag = CIFS_ACL_OWNER;
828 841 }
829   - if (gid != NO_CHANGE_32) { /* chgrp */
  842 + if (gid_valid(gid)) { /* chgrp */
  843 + gid_t id;
830 844 group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
831 845 le32_to_cpu(pnntsd->gsidoffset));
832 846 ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
833 847 GFP_KERNEL);
834 848 if (!ngroup_sid_ptr)
835 849 return -ENOMEM;
836   - rc = id_to_sid(gid, SIDGROUP, ngroup_sid_ptr);
  850 + id = from_kgid(&init_user_ns, gid);
  851 + rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
837 852 if (rc) {
838 853 cFYI(1, "%s: Mapping error %d for group id %d",
839   - __func__, rc, gid);
  854 + __func__, rc, id);
840 855 kfree(ngroup_sid_ptr);
841 856 return rc;
842 857 }
... ... @@ -1004,7 +1019,7 @@
1004 1019 /* Convert mode bits to an ACL so we can update the ACL on the server */
1005 1020 int
1006 1021 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1007   - uid_t uid, gid_t gid)
  1022 + kuid_t uid, kgid_t gid)
1008 1023 {
1009 1024 int rc = 0;
1010 1025 int aclflag = CIFS_ACL_DACL; /* default flag to set */
... ... @@ -277,7 +277,6 @@
277 277 #define CIFS_NO_HANDLE 0xFFFF
278 278  
279 279 #define NO_CHANGE_64 0xFFFFFFFFFFFFFFFFULL
280   -#define NO_CHANGE_32 0xFFFFFFFFUL
281 280  
282 281 /* IPC$ in ASCII */
283 282 #define CIFS_IPC_RESOURCE "\x49\x50\x43\x24"
... ... @@ -161,7 +161,7 @@
161 161 struct cifs_fattr *fattr, struct inode *inode,
162 162 const char *path, const __u16 *pfid);
163 163 extern int id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64,
164   - uid_t, gid_t);
  164 + kuid_t, kgid_t);
165 165 extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *,
166 166 const char *, u32 *);
167 167 extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *,
... ... @@ -2090,8 +2090,8 @@
2090 2090 cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
2091 2091 {
2092 2092 unsigned int xid;
2093   - uid_t uid = NO_CHANGE_32;
2094   - gid_t gid = NO_CHANGE_32;
  2093 + kuid_t uid = INVALID_UID;
  2094 + kgid_t gid = INVALID_GID;
2095 2095 struct inode *inode = direntry->d_inode;
2096 2096 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
2097 2097 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
... ... @@ -2150,7 +2150,7 @@
2150 2150  
2151 2151 #ifdef CONFIG_CIFS_ACL
2152 2152 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
2153   - if (uid != NO_CHANGE_32 || gid != NO_CHANGE_32) {
  2153 + if (uid_valid(uid) || gid_valid(gid)) {
2154 2154 rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64,
2155 2155 uid, gid);
2156 2156 if (rc) {
... ... @@ -2174,7 +2174,7 @@
2174 2174 #ifdef CONFIG_CIFS_ACL
2175 2175 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
2176 2176 rc = id_mode_to_cifs_acl(inode, full_path, mode,
2177   - NO_CHANGE_32, NO_CHANGE_32);
  2177 + INVALID_UID, INVALID_GID);
2178 2178 if (rc) {
2179 2179 cFYI(1, "%s: Setting ACL failed with error: %d",
2180 2180 __func__, rc);