Commit 8abf2775dd425ec3c767ea7c5a51b45fc8be76c2
1 parent
8e3028b908
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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
fs/cifs/cifsacl.c
... | ... | @@ -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 */ |
fs/cifs/cifspdu.h
fs/cifs/cifsproto.h
... | ... | @@ -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 *, |
fs/cifs/inode.c
... | ... | @@ -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); |