diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-25 19:00:49 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-25 19:00:49 -0500 |
commit | 94f2f14234178f118545a0be60a6371ddeb229b7 (patch) | |
tree | 313af6e9e255e9060fc24c836cd71ce712502b17 /fs/cifs | |
parent | 8d168f71551ec2a6528d01d0389b7a73c091e3e7 (diff) | |
parent | 139321c65c0584cd65c4c87a5eb3fdb4fdbd0e19 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace
Pull user namespace and namespace infrastructure changes from Eric W Biederman:
"This set of changes starts with a few small enhnacements to the user
namespace. reboot support, allowing more arbitrary mappings, and
support for mounting devpts, ramfs, tmpfs, and mqueuefs as just the
user namespace root.
I do my best to document that if you care about limiting your
unprivileged users that when you have the user namespace support
enabled you will need to enable memory control groups.
There is a minor bug fix to prevent overflowing the stack if someone
creates way too many user namespaces.
The bulk of the changes are a continuation of the kuid/kgid push down
work through the filesystems. These changes make using uids and gids
typesafe which ensures that these filesystems are safe to use when
multiple user namespaces are in use. The filesystems converted for
3.9 are ceph, 9p, afs, ocfs2, gfs2, ncpfs, nfs, nfsd, and cifs. The
changes for these filesystems were a little more involved so I split
the changes into smaller hopefully obviously correct changes.
XFS is the only filesystem that remains. I was hoping I could get
that in this release so that user namespace support would be enabled
with an allyesconfig or an allmodconfig but it looks like the xfs
changes need another couple of days before it they are ready."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: (93 commits)
cifs: Enable building with user namespaces enabled.
cifs: Convert struct cifs_ses to use a kuid_t and a kgid_t
cifs: Convert struct cifs_sb_info to use kuids and kgids
cifs: Modify struct smb_vol to use kuids and kgids
cifs: Convert struct cifsFileInfo to use a kuid
cifs: Convert struct cifs_fattr to use kuid and kgids
cifs: Convert struct tcon_link to use a kuid.
cifs: Modify struct cifs_unix_set_info_args to hold a kuid_t and a kgid_t
cifs: Convert from a kuid before printing current_fsuid
cifs: Use kuids and kgids SID to uid/gid mapping
cifs: Pass GLOBAL_ROOT_UID and GLOBAL_ROOT_GID to keyring_alloc
cifs: Use BUILD_BUG_ON to validate uids and gids are the same size
cifs: Override unmappable incoming uids and gids
nfsd: Enable building with user namespaces enabled.
nfsd: Properly compare and initialize kuids and kgids
nfsd: Store ex_anon_uid and ex_anon_gid as kuids and kgids
nfsd: Modify nfsd4_cb_sec to use kuids and kgids
nfsd: Handle kuids and kgids in the nfs4acl to posix_acl conversion
nfsd: Convert nfsxdr to use kuids and kgids
nfsd: Convert nfs3xdr to use kuids and kgids
...
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/cifs_fs_sb.h | 8 | ||||
-rw-r--r-- | fs/cifs/cifs_spnego.c | 6 | ||||
-rw-r--r-- | fs/cifs/cifsacl.c | 47 | ||||
-rw-r--r-- | fs/cifs/cifsfs.c | 14 | ||||
-rw-r--r-- | fs/cifs/cifsglob.h | 22 | ||||
-rw-r--r-- | fs/cifs/cifspdu.h | 1 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 9 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 10 | ||||
-rw-r--r-- | fs/cifs/connect.c | 66 | ||||
-rw-r--r-- | fs/cifs/dir.c | 18 | ||||
-rw-r--r-- | fs/cifs/file.c | 8 | ||||
-rw-r--r-- | fs/cifs/inode.c | 50 | ||||
-rw-r--r-- | fs/cifs/misc.c | 2 |
13 files changed, 166 insertions, 95 deletions
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index c865bfdfe819..37e4a72a7d1c 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h | |||
@@ -55,10 +55,10 @@ struct cifs_sb_info { | |||
55 | unsigned int wsize; | 55 | unsigned int wsize; |
56 | unsigned long actimeo; /* attribute cache timeout (jiffies) */ | 56 | unsigned long actimeo; /* attribute cache timeout (jiffies) */ |
57 | atomic_t active; | 57 | atomic_t active; |
58 | uid_t mnt_uid; | 58 | kuid_t mnt_uid; |
59 | gid_t mnt_gid; | 59 | kgid_t mnt_gid; |
60 | uid_t mnt_backupuid; | 60 | kuid_t mnt_backupuid; |
61 | gid_t mnt_backupgid; | 61 | kgid_t mnt_backupgid; |
62 | umode_t mnt_file_mode; | 62 | umode_t mnt_file_mode; |
63 | umode_t mnt_dir_mode; | 63 | umode_t mnt_dir_mode; |
64 | unsigned int mnt_cifs_flags; | 64 | unsigned int mnt_cifs_flags; |
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c index 086f381d6489..10e774761299 100644 --- a/fs/cifs/cifs_spnego.c +++ b/fs/cifs/cifs_spnego.c | |||
@@ -149,10 +149,12 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo) | |||
149 | goto out; | 149 | goto out; |
150 | 150 | ||
151 | dp = description + strlen(description); | 151 | dp = description + strlen(description); |
152 | sprintf(dp, ";uid=0x%x", sesInfo->linux_uid); | 152 | sprintf(dp, ";uid=0x%x", |
153 | from_kuid_munged(&init_user_ns, sesInfo->linux_uid)); | ||
153 | 154 | ||
154 | dp = description + strlen(description); | 155 | dp = description + strlen(description); |
155 | sprintf(dp, ";creduid=0x%x", sesInfo->cred_uid); | 156 | sprintf(dp, ";creduid=0x%x", |
157 | from_kuid_munged(&init_user_ns, sesInfo->cred_uid)); | ||
156 | 158 | ||
157 | if (sesInfo->user_name) { | 159 | if (sesInfo->user_name) { |
158 | dp = description + strlen(description); | 160 | dp = description + strlen(description); |
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 5cbd00e74067..f1e3f25fe004 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
@@ -266,8 +266,8 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid, | |||
266 | struct key *sidkey; | 266 | struct key *sidkey; |
267 | char *sidstr; | 267 | char *sidstr; |
268 | const struct cred *saved_cred; | 268 | const struct cred *saved_cred; |
269 | uid_t fuid = cifs_sb->mnt_uid; | 269 | kuid_t fuid = cifs_sb->mnt_uid; |
270 | gid_t fgid = cifs_sb->mnt_gid; | 270 | kgid_t fgid = cifs_sb->mnt_gid; |
271 | 271 | ||
272 | /* | 272 | /* |
273 | * If we have too many subauthorities, then something is really wrong. | 273 | * If we have too many subauthorities, then something is really wrong. |
@@ -297,6 +297,7 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid, | |||
297 | * probably a safe assumption but might be better to check based on | 297 | * probably a safe assumption but might be better to check based on |
298 | * sidtype. | 298 | * sidtype. |
299 | */ | 299 | */ |
300 | BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t)); | ||
300 | if (sidkey->datalen != sizeof(uid_t)) { | 301 | if (sidkey->datalen != sizeof(uid_t)) { |
301 | rc = -EIO; | 302 | rc = -EIO; |
302 | cFYI(1, "%s: Downcall contained malformed key " | 303 | cFYI(1, "%s: Downcall contained malformed key " |
@@ -305,10 +306,21 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid, | |||
305 | goto out_key_put; | 306 | goto out_key_put; |
306 | } | 307 | } |
307 | 308 | ||
308 | if (sidtype == SIDOWNER) | 309 | if (sidtype == SIDOWNER) { |
309 | memcpy(&fuid, &sidkey->payload.value, sizeof(uid_t)); | 310 | kuid_t uid; |
310 | else | 311 | uid_t id; |
311 | memcpy(&fgid, &sidkey->payload.value, sizeof(gid_t)); | 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 | } | ||
312 | 324 | ||
313 | out_key_put: | 325 | out_key_put: |
314 | key_put(sidkey); | 326 | key_put(sidkey); |
@@ -346,7 +358,8 @@ init_cifs_idmap(void) | |||
346 | if (!cred) | 358 | if (!cred) |
347 | return -ENOMEM; | 359 | return -ENOMEM; |
348 | 360 | ||
349 | keyring = keyring_alloc(".cifs_idmap", 0, 0, cred, | 361 | keyring = keyring_alloc(".cifs_idmap", |
362 | GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, | ||
350 | (KEY_POS_ALL & ~KEY_POS_SETATTR) | | 363 | (KEY_POS_ALL & ~KEY_POS_SETATTR) | |
351 | KEY_USR_VIEW | KEY_USR_READ, | 364 | KEY_USR_VIEW | KEY_USR_READ, |
352 | KEY_ALLOC_NOT_IN_QUOTA, NULL); | 365 | KEY_ALLOC_NOT_IN_QUOTA, NULL); |
@@ -774,7 +787,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb, | |||
774 | 787 | ||
775 | /* Convert permission bits from mode to equivalent CIFS ACL */ | 788 | /* Convert permission bits from mode to equivalent CIFS ACL */ |
776 | static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, | 789 | static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, |
777 | __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) |
778 | { | 791 | { |
779 | int rc = 0; | 792 | int rc = 0; |
780 | __u32 dacloffset; | 793 | __u32 dacloffset; |
@@ -806,17 +819,19 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, | |||
806 | *aclflag = CIFS_ACL_DACL; | 819 | *aclflag = CIFS_ACL_DACL; |
807 | } else { | 820 | } else { |
808 | memcpy(pnntsd, pntsd, secdesclen); | 821 | memcpy(pnntsd, pntsd, secdesclen); |
809 | if (uid != NO_CHANGE_32) { /* chown */ | 822 | if (uid_valid(uid)) { /* chown */ |
823 | uid_t id; | ||
810 | owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + | 824 | owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + |
811 | le32_to_cpu(pnntsd->osidoffset)); | 825 | le32_to_cpu(pnntsd->osidoffset)); |
812 | nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid), | 826 | nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid), |
813 | GFP_KERNEL); | 827 | GFP_KERNEL); |
814 | if (!nowner_sid_ptr) | 828 | if (!nowner_sid_ptr) |
815 | return -ENOMEM; | 829 | return -ENOMEM; |
816 | 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); | ||
817 | if (rc) { | 832 | if (rc) { |
818 | cFYI(1, "%s: Mapping error %d for owner id %d", | 833 | cFYI(1, "%s: Mapping error %d for owner id %d", |
819 | __func__, rc, uid); | 834 | __func__, rc, id); |
820 | kfree(nowner_sid_ptr); | 835 | kfree(nowner_sid_ptr); |
821 | return rc; | 836 | return rc; |
822 | } | 837 | } |
@@ -824,17 +839,19 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, | |||
824 | kfree(nowner_sid_ptr); | 839 | kfree(nowner_sid_ptr); |
825 | *aclflag = CIFS_ACL_OWNER; | 840 | *aclflag = CIFS_ACL_OWNER; |
826 | } | 841 | } |
827 | if (gid != NO_CHANGE_32) { /* chgrp */ | 842 | if (gid_valid(gid)) { /* chgrp */ |
843 | gid_t id; | ||
828 | group_sid_ptr = (struct cifs_sid *)((char *)pnntsd + | 844 | group_sid_ptr = (struct cifs_sid *)((char *)pnntsd + |
829 | le32_to_cpu(pnntsd->gsidoffset)); | 845 | le32_to_cpu(pnntsd->gsidoffset)); |
830 | ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid), | 846 | ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid), |
831 | GFP_KERNEL); | 847 | GFP_KERNEL); |
832 | if (!ngroup_sid_ptr) | 848 | if (!ngroup_sid_ptr) |
833 | return -ENOMEM; | 849 | return -ENOMEM; |
834 | 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); | ||
835 | if (rc) { | 852 | if (rc) { |
836 | cFYI(1, "%s: Mapping error %d for group id %d", | 853 | cFYI(1, "%s: Mapping error %d for group id %d", |
837 | __func__, rc, gid); | 854 | __func__, rc, id); |
838 | kfree(ngroup_sid_ptr); | 855 | kfree(ngroup_sid_ptr); |
839 | return rc; | 856 | return rc; |
840 | } | 857 | } |
@@ -1002,7 +1019,7 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, | |||
1002 | /* Convert mode bits to an ACL so we can update the ACL on the server */ | 1019 | /* Convert mode bits to an ACL so we can update the ACL on the server */ |
1003 | int | 1020 | int |
1004 | id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, | 1021 | id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, |
1005 | uid_t uid, gid_t gid) | 1022 | kuid_t uid, kgid_t gid) |
1006 | { | 1023 | { |
1007 | int rc = 0; | 1024 | int rc = 0; |
1008 | int aclflag = CIFS_ACL_DACL; /* default flag to set */ | 1025 | int aclflag = CIFS_ACL_DACL; /* default flag to set */ |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index de7f9168a118..9be09b21b4e0 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -375,13 +375,15 @@ cifs_show_options(struct seq_file *s, struct dentry *root) | |||
375 | (int)(srcaddr->sa_family)); | 375 | (int)(srcaddr->sa_family)); |
376 | } | 376 | } |
377 | 377 | ||
378 | seq_printf(s, ",uid=%u", cifs_sb->mnt_uid); | 378 | seq_printf(s, ",uid=%u", |
379 | from_kuid_munged(&init_user_ns, cifs_sb->mnt_uid)); | ||
379 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) | 380 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) |
380 | seq_printf(s, ",forceuid"); | 381 | seq_printf(s, ",forceuid"); |
381 | else | 382 | else |
382 | seq_printf(s, ",noforceuid"); | 383 | seq_printf(s, ",noforceuid"); |
383 | 384 | ||
384 | seq_printf(s, ",gid=%u", cifs_sb->mnt_gid); | 385 | seq_printf(s, ",gid=%u", |
386 | from_kgid_munged(&init_user_ns, cifs_sb->mnt_gid)); | ||
385 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) | 387 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) |
386 | seq_printf(s, ",forcegid"); | 388 | seq_printf(s, ",forcegid"); |
387 | else | 389 | else |
@@ -436,9 +438,13 @@ cifs_show_options(struct seq_file *s, struct dentry *root) | |||
436 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) | 438 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) |
437 | seq_printf(s, ",noperm"); | 439 | seq_printf(s, ",noperm"); |
438 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) | 440 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) |
439 | seq_printf(s, ",backupuid=%u", cifs_sb->mnt_backupuid); | 441 | seq_printf(s, ",backupuid=%u", |
442 | from_kuid_munged(&init_user_ns, | ||
443 | cifs_sb->mnt_backupuid)); | ||
440 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) | 444 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) |
441 | seq_printf(s, ",backupgid=%u", cifs_sb->mnt_backupgid); | 445 | seq_printf(s, ",backupgid=%u", |
446 | from_kgid_munged(&init_user_ns, | ||
447 | cifs_sb->mnt_backupgid)); | ||
442 | 448 | ||
443 | seq_printf(s, ",rsize=%u", cifs_sb->rsize); | 449 | seq_printf(s, ",rsize=%u", cifs_sb->rsize); |
444 | seq_printf(s, ",wsize=%u", cifs_sb->wsize); | 450 | seq_printf(s, ",wsize=%u", cifs_sb->wsize); |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index e6899cea1c35..4f07f6fbe494 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -400,11 +400,11 @@ struct smb_vol { | |||
400 | char *iocharset; /* local code page for mapping to and from Unicode */ | 400 | char *iocharset; /* local code page for mapping to and from Unicode */ |
401 | char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */ | 401 | char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */ |
402 | char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */ | 402 | char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */ |
403 | uid_t cred_uid; | 403 | kuid_t cred_uid; |
404 | uid_t linux_uid; | 404 | kuid_t linux_uid; |
405 | gid_t linux_gid; | 405 | kgid_t linux_gid; |
406 | uid_t backupuid; | 406 | kuid_t backupuid; |
407 | gid_t backupgid; | 407 | kgid_t backupgid; |
408 | umode_t file_mode; | 408 | umode_t file_mode; |
409 | umode_t dir_mode; | 409 | umode_t dir_mode; |
410 | unsigned secFlg; | 410 | unsigned secFlg; |
@@ -703,8 +703,8 @@ struct cifs_ses { | |||
703 | char *serverNOS; /* name of network operating system of server */ | 703 | char *serverNOS; /* name of network operating system of server */ |
704 | char *serverDomain; /* security realm of server */ | 704 | char *serverDomain; /* security realm of server */ |
705 | __u64 Suid; /* remote smb uid */ | 705 | __u64 Suid; /* remote smb uid */ |
706 | uid_t linux_uid; /* overriding owner of files on the mount */ | 706 | kuid_t linux_uid; /* overriding owner of files on the mount */ |
707 | uid_t cred_uid; /* owner of credentials */ | 707 | kuid_t cred_uid; /* owner of credentials */ |
708 | unsigned int capabilities; | 708 | unsigned int capabilities; |
709 | char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for | 709 | char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for |
710 | TCP names - will ipv6 and sctp addresses fit? */ | 710 | TCP names - will ipv6 and sctp addresses fit? */ |
@@ -838,7 +838,7 @@ struct cifs_tcon { | |||
838 | */ | 838 | */ |
839 | struct tcon_link { | 839 | struct tcon_link { |
840 | struct rb_node tl_rbnode; | 840 | struct rb_node tl_rbnode; |
841 | uid_t tl_uid; | 841 | kuid_t tl_uid; |
842 | unsigned long tl_flags; | 842 | unsigned long tl_flags; |
843 | #define TCON_LINK_MASTER 0 | 843 | #define TCON_LINK_MASTER 0 |
844 | #define TCON_LINK_PENDING 1 | 844 | #define TCON_LINK_PENDING 1 |
@@ -931,7 +931,7 @@ struct cifsFileInfo { | |||
931 | struct list_head tlist; /* pointer to next fid owned by tcon */ | 931 | struct list_head tlist; /* pointer to next fid owned by tcon */ |
932 | struct list_head flist; /* next fid (file instance) for this inode */ | 932 | struct list_head flist; /* next fid (file instance) for this inode */ |
933 | struct cifs_fid_locks *llist; /* brlocks held by this fid */ | 933 | struct cifs_fid_locks *llist; /* brlocks held by this fid */ |
934 | unsigned int uid; /* allows finding which FileInfo structure */ | 934 | kuid_t uid; /* allows finding which FileInfo structure */ |
935 | __u32 pid; /* process id who opened file */ | 935 | __u32 pid; /* process id who opened file */ |
936 | struct cifs_fid fid; /* file id from remote */ | 936 | struct cifs_fid fid; /* file id from remote */ |
937 | /* BB add lock scope info here if needed */ ; | 937 | /* BB add lock scope info here if needed */ ; |
@@ -1245,8 +1245,8 @@ struct cifs_fattr { | |||
1245 | u64 cf_eof; | 1245 | u64 cf_eof; |
1246 | u64 cf_bytes; | 1246 | u64 cf_bytes; |
1247 | u64 cf_createtime; | 1247 | u64 cf_createtime; |
1248 | uid_t cf_uid; | 1248 | kuid_t cf_uid; |
1249 | gid_t cf_gid; | 1249 | kgid_t cf_gid; |
1250 | umode_t cf_mode; | 1250 | umode_t cf_mode; |
1251 | dev_t cf_rdev; | 1251 | dev_t cf_rdev; |
1252 | unsigned int cf_nlink; | 1252 | unsigned int cf_nlink; |
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index b9d59a948a2c..e996ff6b26d1 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
@@ -277,7 +277,6 @@ | |||
277 | #define CIFS_NO_HANDLE 0xFFFF | 277 | #define CIFS_NO_HANDLE 0xFFFF |
278 | 278 | ||
279 | #define NO_CHANGE_64 0xFFFFFFFFFFFFFFFFULL | 279 | #define NO_CHANGE_64 0xFFFFFFFFFFFFFFFFULL |
280 | #define NO_CHANGE_32 0xFFFFFFFFUL | ||
281 | 280 | ||
282 | /* IPC$ in ASCII */ | 281 | /* IPC$ in ASCII */ |
283 | #define CIFS_IPC_RESOURCE "\x49\x50\x43\x24" | 282 | #define CIFS_IPC_RESOURCE "\x49\x50\x43\x24" |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 1988c1baa224..f450f0683ddd 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -46,7 +46,8 @@ extern void _free_xid(unsigned int); | |||
46 | ({ \ | 46 | ({ \ |
47 | unsigned int __xid = _get_xid(); \ | 47 | unsigned int __xid = _get_xid(); \ |
48 | cFYI(1, "CIFS VFS: in %s as Xid: %u with uid: %d", \ | 48 | cFYI(1, "CIFS VFS: in %s as Xid: %u with uid: %d", \ |
49 | __func__, __xid, current_fsuid()); \ | 49 | __func__, __xid, \ |
50 | from_kuid(&init_user_ns, current_fsuid())); \ | ||
50 | __xid; \ | 51 | __xid; \ |
51 | }) | 52 | }) |
52 | 53 | ||
@@ -161,7 +162,7 @@ extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, | |||
161 | struct cifs_fattr *fattr, struct inode *inode, | 162 | struct cifs_fattr *fattr, struct inode *inode, |
162 | const char *path, const __u16 *pfid); | 163 | const char *path, const __u16 *pfid); |
163 | extern int id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64, | 164 | extern int id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64, |
164 | uid_t, gid_t); | 165 | kuid_t, kgid_t); |
165 | extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *, | 166 | extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *, |
166 | const char *, u32 *); | 167 | const char *, u32 *); |
167 | extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *, | 168 | extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *, |
@@ -304,8 +305,8 @@ struct cifs_unix_set_info_args { | |||
304 | __u64 atime; | 305 | __u64 atime; |
305 | __u64 mtime; | 306 | __u64 mtime; |
306 | __u64 mode; | 307 | __u64 mode; |
307 | __u64 uid; | 308 | kuid_t uid; |
308 | __u64 gid; | 309 | kgid_t gid; |
309 | dev_t device; | 310 | dev_t device; |
310 | }; | 311 | }; |
311 | 312 | ||
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 76d0d2998850..00e12f2d626b 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -5819,8 +5819,14 @@ static void | |||
5819 | cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset, | 5819 | cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset, |
5820 | const struct cifs_unix_set_info_args *args) | 5820 | const struct cifs_unix_set_info_args *args) |
5821 | { | 5821 | { |
5822 | u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64; | ||
5822 | u64 mode = args->mode; | 5823 | u64 mode = args->mode; |
5823 | 5824 | ||
5825 | if (uid_valid(args->uid)) | ||
5826 | uid = from_kuid(&init_user_ns, args->uid); | ||
5827 | if (gid_valid(args->gid)) | ||
5828 | gid = from_kgid(&init_user_ns, args->gid); | ||
5829 | |||
5824 | /* | 5830 | /* |
5825 | * Samba server ignores set of file size to zero due to bugs in some | 5831 | * Samba server ignores set of file size to zero due to bugs in some |
5826 | * older clients, but we should be precise - we use SetFileSize to | 5832 | * older clients, but we should be precise - we use SetFileSize to |
@@ -5833,8 +5839,8 @@ cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset, | |||
5833 | data_offset->LastStatusChange = cpu_to_le64(args->ctime); | 5839 | data_offset->LastStatusChange = cpu_to_le64(args->ctime); |
5834 | data_offset->LastAccessTime = cpu_to_le64(args->atime); | 5840 | data_offset->LastAccessTime = cpu_to_le64(args->atime); |
5835 | data_offset->LastModificationTime = cpu_to_le64(args->mtime); | 5841 | data_offset->LastModificationTime = cpu_to_le64(args->mtime); |
5836 | data_offset->Uid = cpu_to_le64(args->uid); | 5842 | data_offset->Uid = cpu_to_le64(uid); |
5837 | data_offset->Gid = cpu_to_le64(args->gid); | 5843 | data_offset->Gid = cpu_to_le64(gid); |
5838 | /* better to leave device as zero when it is */ | 5844 | /* better to leave device as zero when it is */ |
5839 | data_offset->DevMajor = cpu_to_le64(MAJOR(args->device)); | 5845 | data_offset->DevMajor = cpu_to_le64(MAJOR(args->device)); |
5840 | data_offset->DevMinor = cpu_to_le64(MINOR(args->device)); | 5846 | data_offset->DevMinor = cpu_to_le64(MINOR(args->device)); |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 12b3da39733b..4474a57f30ab 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -987,6 +987,41 @@ static int get_option_ul(substring_t args[], unsigned long *option) | |||
987 | return rc; | 987 | return rc; |
988 | } | 988 | } |
989 | 989 | ||
990 | static int get_option_uid(substring_t args[], kuid_t *result) | ||
991 | { | ||
992 | unsigned long value; | ||
993 | kuid_t uid; | ||
994 | int rc; | ||
995 | |||
996 | rc = get_option_ul(args, &value); | ||
997 | if (rc) | ||
998 | return rc; | ||
999 | |||
1000 | uid = make_kuid(current_user_ns(), value); | ||
1001 | if (!uid_valid(uid)) | ||
1002 | return -EINVAL; | ||
1003 | |||
1004 | *result = uid; | ||
1005 | return 0; | ||
1006 | } | ||
1007 | |||
1008 | static int get_option_gid(substring_t args[], kgid_t *result) | ||
1009 | { | ||
1010 | unsigned long value; | ||
1011 | kgid_t gid; | ||
1012 | int rc; | ||
1013 | |||
1014 | rc = get_option_ul(args, &value); | ||
1015 | if (rc) | ||
1016 | return rc; | ||
1017 | |||
1018 | gid = make_kgid(current_user_ns(), value); | ||
1019 | if (!gid_valid(gid)) | ||
1020 | return -EINVAL; | ||
1021 | |||
1022 | *result = gid; | ||
1023 | return 0; | ||
1024 | } | ||
990 | 1025 | ||
991 | static int cifs_parse_security_flavors(char *value, | 1026 | static int cifs_parse_security_flavors(char *value, |
992 | struct smb_vol *vol) | 1027 | struct smb_vol *vol) |
@@ -1424,47 +1459,42 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
1424 | 1459 | ||
1425 | /* Numeric Values */ | 1460 | /* Numeric Values */ |
1426 | case Opt_backupuid: | 1461 | case Opt_backupuid: |
1427 | if (get_option_ul(args, &option)) { | 1462 | if (get_option_uid(args, &vol->backupuid)) { |
1428 | cERROR(1, "%s: Invalid backupuid value", | 1463 | cERROR(1, "%s: Invalid backupuid value", |
1429 | __func__); | 1464 | __func__); |
1430 | goto cifs_parse_mount_err; | 1465 | goto cifs_parse_mount_err; |
1431 | } | 1466 | } |
1432 | vol->backupuid = option; | ||
1433 | vol->backupuid_specified = true; | 1467 | vol->backupuid_specified = true; |
1434 | break; | 1468 | break; |
1435 | case Opt_backupgid: | 1469 | case Opt_backupgid: |
1436 | if (get_option_ul(args, &option)) { | 1470 | if (get_option_gid(args, &vol->backupgid)) { |
1437 | cERROR(1, "%s: Invalid backupgid value", | 1471 | cERROR(1, "%s: Invalid backupgid value", |
1438 | __func__); | 1472 | __func__); |
1439 | goto cifs_parse_mount_err; | 1473 | goto cifs_parse_mount_err; |
1440 | } | 1474 | } |
1441 | vol->backupgid = option; | ||
1442 | vol->backupgid_specified = true; | 1475 | vol->backupgid_specified = true; |
1443 | break; | 1476 | break; |
1444 | case Opt_uid: | 1477 | case Opt_uid: |
1445 | if (get_option_ul(args, &option)) { | 1478 | if (get_option_uid(args, &vol->linux_uid)) { |
1446 | cERROR(1, "%s: Invalid uid value", | 1479 | cERROR(1, "%s: Invalid uid value", |
1447 | __func__); | 1480 | __func__); |
1448 | goto cifs_parse_mount_err; | 1481 | goto cifs_parse_mount_err; |
1449 | } | 1482 | } |
1450 | vol->linux_uid = option; | ||
1451 | uid_specified = true; | 1483 | uid_specified = true; |
1452 | break; | 1484 | break; |
1453 | case Opt_cruid: | 1485 | case Opt_cruid: |
1454 | if (get_option_ul(args, &option)) { | 1486 | if (get_option_uid(args, &vol->cred_uid)) { |
1455 | cERROR(1, "%s: Invalid cruid value", | 1487 | cERROR(1, "%s: Invalid cruid value", |
1456 | __func__); | 1488 | __func__); |
1457 | goto cifs_parse_mount_err; | 1489 | goto cifs_parse_mount_err; |
1458 | } | 1490 | } |
1459 | vol->cred_uid = option; | ||
1460 | break; | 1491 | break; |
1461 | case Opt_gid: | 1492 | case Opt_gid: |
1462 | if (get_option_ul(args, &option)) { | 1493 | if (get_option_gid(args, &vol->linux_gid)) { |
1463 | cERROR(1, "%s: Invalid gid value", | 1494 | cERROR(1, "%s: Invalid gid value", |
1464 | __func__); | 1495 | __func__); |
1465 | goto cifs_parse_mount_err; | 1496 | goto cifs_parse_mount_err; |
1466 | } | 1497 | } |
1467 | vol->linux_gid = option; | ||
1468 | gid_specified = true; | 1498 | gid_specified = true; |
1469 | break; | 1499 | break; |
1470 | case Opt_file_mode: | 1500 | case Opt_file_mode: |
@@ -2241,7 +2271,7 @@ static int match_session(struct cifs_ses *ses, struct smb_vol *vol) | |||
2241 | { | 2271 | { |
2242 | switch (ses->server->secType) { | 2272 | switch (ses->server->secType) { |
2243 | case Kerberos: | 2273 | case Kerberos: |
2244 | if (vol->cred_uid != ses->cred_uid) | 2274 | if (!uid_eq(vol->cred_uid, ses->cred_uid)) |
2245 | return 0; | 2275 | return 0; |
2246 | break; | 2276 | break; |
2247 | default: | 2277 | default: |
@@ -2713,7 +2743,7 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data) | |||
2713 | if (new->rsize && new->rsize < old->rsize) | 2743 | if (new->rsize && new->rsize < old->rsize) |
2714 | return 0; | 2744 | return 0; |
2715 | 2745 | ||
2716 | if (old->mnt_uid != new->mnt_uid || old->mnt_gid != new->mnt_gid) | 2746 | if (!uid_eq(old->mnt_uid, new->mnt_uid) || !gid_eq(old->mnt_gid, new->mnt_gid)) |
2717 | return 0; | 2747 | return 0; |
2718 | 2748 | ||
2719 | if (old->mnt_file_mode != new->mnt_file_mode || | 2749 | if (old->mnt_file_mode != new->mnt_file_mode || |
@@ -3919,7 +3949,7 @@ cifs_set_vol_auth(struct smb_vol *vol, struct cifs_ses *ses) | |||
3919 | } | 3949 | } |
3920 | 3950 | ||
3921 | static struct cifs_tcon * | 3951 | static struct cifs_tcon * |
3922 | cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid) | 3952 | cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid) |
3923 | { | 3953 | { |
3924 | int rc; | 3954 | int rc; |
3925 | struct cifs_tcon *master_tcon = cifs_sb_master_tcon(cifs_sb); | 3955 | struct cifs_tcon *master_tcon = cifs_sb_master_tcon(cifs_sb); |
@@ -3989,7 +4019,7 @@ cifs_sb_tcon_pending_wait(void *unused) | |||
3989 | 4019 | ||
3990 | /* find and return a tlink with given uid */ | 4020 | /* find and return a tlink with given uid */ |
3991 | static struct tcon_link * | 4021 | static struct tcon_link * |
3992 | tlink_rb_search(struct rb_root *root, uid_t uid) | 4022 | tlink_rb_search(struct rb_root *root, kuid_t uid) |
3993 | { | 4023 | { |
3994 | struct rb_node *node = root->rb_node; | 4024 | struct rb_node *node = root->rb_node; |
3995 | struct tcon_link *tlink; | 4025 | struct tcon_link *tlink; |
@@ -3997,9 +4027,9 @@ tlink_rb_search(struct rb_root *root, uid_t uid) | |||
3997 | while (node) { | 4027 | while (node) { |
3998 | tlink = rb_entry(node, struct tcon_link, tl_rbnode); | 4028 | tlink = rb_entry(node, struct tcon_link, tl_rbnode); |
3999 | 4029 | ||
4000 | if (tlink->tl_uid > uid) | 4030 | if (uid_gt(tlink->tl_uid, uid)) |
4001 | node = node->rb_left; | 4031 | node = node->rb_left; |
4002 | else if (tlink->tl_uid < uid) | 4032 | else if (uid_lt(tlink->tl_uid, uid)) |
4003 | node = node->rb_right; | 4033 | node = node->rb_right; |
4004 | else | 4034 | else |
4005 | return tlink; | 4035 | return tlink; |
@@ -4018,7 +4048,7 @@ tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink) | |||
4018 | tlink = rb_entry(*new, struct tcon_link, tl_rbnode); | 4048 | tlink = rb_entry(*new, struct tcon_link, tl_rbnode); |
4019 | parent = *new; | 4049 | parent = *new; |
4020 | 4050 | ||
4021 | if (tlink->tl_uid > new_tlink->tl_uid) | 4051 | if (uid_gt(tlink->tl_uid, new_tlink->tl_uid)) |
4022 | new = &((*new)->rb_left); | 4052 | new = &((*new)->rb_left); |
4023 | else | 4053 | else |
4024 | new = &((*new)->rb_right); | 4054 | new = &((*new)->rb_right); |
@@ -4048,7 +4078,7 @@ struct tcon_link * | |||
4048 | cifs_sb_tlink(struct cifs_sb_info *cifs_sb) | 4078 | cifs_sb_tlink(struct cifs_sb_info *cifs_sb) |
4049 | { | 4079 | { |
4050 | int ret; | 4080 | int ret; |
4051 | uid_t fsuid = current_fsuid(); | 4081 | kuid_t fsuid = current_fsuid(); |
4052 | struct tcon_link *tlink, *newtlink; | 4082 | struct tcon_link *tlink, *newtlink; |
4053 | 4083 | ||
4054 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) | 4084 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 8719bbe0dcc3..1cd016217448 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -342,14 +342,14 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, | |||
342 | 342 | ||
343 | *created |= FILE_CREATED; | 343 | *created |= FILE_CREATED; |
344 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 344 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
345 | args.uid = (__u64) current_fsuid(); | 345 | args.uid = current_fsuid(); |
346 | if (inode->i_mode & S_ISGID) | 346 | if (inode->i_mode & S_ISGID) |
347 | args.gid = (__u64) inode->i_gid; | 347 | args.gid = inode->i_gid; |
348 | else | 348 | else |
349 | args.gid = (__u64) current_fsgid(); | 349 | args.gid = current_fsgid(); |
350 | } else { | 350 | } else { |
351 | args.uid = NO_CHANGE_64; | 351 | args.uid = INVALID_UID; /* no change */ |
352 | args.gid = NO_CHANGE_64; | 352 | args.gid = INVALID_GID; /* no change */ |
353 | } | 353 | } |
354 | CIFSSMBUnixSetFileInfo(xid, tcon, &args, fid->netfid, | 354 | CIFSSMBUnixSetFileInfo(xid, tcon, &args, fid->netfid, |
355 | current->tgid); | 355 | current->tgid); |
@@ -588,11 +588,11 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode, | |||
588 | .device = device_number, | 588 | .device = device_number, |
589 | }; | 589 | }; |
590 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 590 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
591 | args.uid = (__u64) current_fsuid(); | 591 | args.uid = current_fsuid(); |
592 | args.gid = (__u64) current_fsgid(); | 592 | args.gid = current_fsgid(); |
593 | } else { | 593 | } else { |
594 | args.uid = NO_CHANGE_64; | 594 | args.uid = INVALID_UID; /* no change */ |
595 | args.gid = NO_CHANGE_64; | 595 | args.gid = INVALID_GID; /* no change */ |
596 | } | 596 | } |
597 | rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args, | 597 | rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args, |
598 | cifs_sb->local_nls, | 598 | cifs_sb->local_nls, |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 8ea6ca50a665..a8d8b589ee0e 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -515,8 +515,8 @@ int cifs_open(struct inode *inode, struct file *file) | |||
515 | */ | 515 | */ |
516 | struct cifs_unix_set_info_args args = { | 516 | struct cifs_unix_set_info_args args = { |
517 | .mode = inode->i_mode, | 517 | .mode = inode->i_mode, |
518 | .uid = NO_CHANGE_64, | 518 | .uid = INVALID_UID, /* no change */ |
519 | .gid = NO_CHANGE_64, | 519 | .gid = INVALID_GID, /* no change */ |
520 | .ctime = NO_CHANGE_64, | 520 | .ctime = NO_CHANGE_64, |
521 | .atime = NO_CHANGE_64, | 521 | .atime = NO_CHANGE_64, |
522 | .mtime = NO_CHANGE_64, | 522 | .mtime = NO_CHANGE_64, |
@@ -1693,7 +1693,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, | |||
1693 | are always at the end of the list but since the first entry might | 1693 | are always at the end of the list but since the first entry might |
1694 | have a close pending, we go through the whole list */ | 1694 | have a close pending, we go through the whole list */ |
1695 | list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { | 1695 | list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { |
1696 | if (fsuid_only && open_file->uid != current_fsuid()) | 1696 | if (fsuid_only && !uid_eq(open_file->uid, current_fsuid())) |
1697 | continue; | 1697 | continue; |
1698 | if (OPEN_FMODE(open_file->f_flags) & FMODE_READ) { | 1698 | if (OPEN_FMODE(open_file->f_flags) & FMODE_READ) { |
1699 | if (!open_file->invalidHandle) { | 1699 | if (!open_file->invalidHandle) { |
@@ -1746,7 +1746,7 @@ refind_writable: | |||
1746 | list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { | 1746 | list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { |
1747 | if (!any_available && open_file->pid != current->tgid) | 1747 | if (!any_available && open_file->pid != current->tgid) |
1748 | continue; | 1748 | continue; |
1749 | if (fsuid_only && open_file->uid != current_fsuid()) | 1749 | if (fsuid_only && !uid_eq(open_file->uid, current_fsuid())) |
1750 | continue; | 1750 | continue; |
1751 | if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) { | 1751 | if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) { |
1752 | if (!open_file->invalidHandle) { | 1752 | if (!open_file->invalidHandle) { |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index ed6208ff85a7..9638233964fc 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -244,15 +244,25 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info, | |||
244 | break; | 244 | break; |
245 | } | 245 | } |
246 | 246 | ||
247 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) | 247 | fattr->cf_uid = cifs_sb->mnt_uid; |
248 | fattr->cf_uid = cifs_sb->mnt_uid; | 248 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) { |
249 | else | 249 | u64 id = le64_to_cpu(info->Uid); |
250 | fattr->cf_uid = le64_to_cpu(info->Uid); | 250 | if (id < ((uid_t)-1)) { |
251 | 251 | kuid_t uid = make_kuid(&init_user_ns, id); | |
252 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) | 252 | if (uid_valid(uid)) |
253 | fattr->cf_gid = cifs_sb->mnt_gid; | 253 | fattr->cf_uid = uid; |
254 | else | 254 | } |
255 | fattr->cf_gid = le64_to_cpu(info->Gid); | 255 | } |
256 | |||
257 | fattr->cf_gid = cifs_sb->mnt_gid; | ||
258 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) { | ||
259 | u64 id = le64_to_cpu(info->Gid); | ||
260 | if (id < ((gid_t)-1)) { | ||
261 | kgid_t gid = make_kgid(&init_user_ns, id); | ||
262 | if (gid_valid(gid)) | ||
263 | fattr->cf_gid = gid; | ||
264 | } | ||
265 | } | ||
256 | 266 | ||
257 | fattr->cf_nlink = le64_to_cpu(info->Nlinks); | 267 | fattr->cf_nlink = le64_to_cpu(info->Nlinks); |
258 | } | 268 | } |
@@ -1245,14 +1255,14 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode, | |||
1245 | .device = 0, | 1255 | .device = 0, |
1246 | }; | 1256 | }; |
1247 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 1257 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
1248 | args.uid = (__u64)current_fsuid(); | 1258 | args.uid = current_fsuid(); |
1249 | if (parent->i_mode & S_ISGID) | 1259 | if (parent->i_mode & S_ISGID) |
1250 | args.gid = (__u64)parent->i_gid; | 1260 | args.gid = parent->i_gid; |
1251 | else | 1261 | else |
1252 | args.gid = (__u64)current_fsgid(); | 1262 | args.gid = current_fsgid(); |
1253 | } else { | 1263 | } else { |
1254 | args.uid = NO_CHANGE_64; | 1264 | args.uid = INVALID_UID; /* no change */ |
1255 | args.gid = NO_CHANGE_64; | 1265 | args.gid = INVALID_GID; /* no change */ |
1256 | } | 1266 | } |
1257 | CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args, | 1267 | CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args, |
1258 | cifs_sb->local_nls, | 1268 | cifs_sb->local_nls, |
@@ -2013,12 +2023,12 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) | |||
2013 | if (attrs->ia_valid & ATTR_UID) | 2023 | if (attrs->ia_valid & ATTR_UID) |
2014 | args->uid = attrs->ia_uid; | 2024 | args->uid = attrs->ia_uid; |
2015 | else | 2025 | else |
2016 | args->uid = NO_CHANGE_64; | 2026 | args->uid = INVALID_UID; /* no change */ |
2017 | 2027 | ||
2018 | if (attrs->ia_valid & ATTR_GID) | 2028 | if (attrs->ia_valid & ATTR_GID) |
2019 | args->gid = attrs->ia_gid; | 2029 | args->gid = attrs->ia_gid; |
2020 | else | 2030 | else |
2021 | args->gid = NO_CHANGE_64; | 2031 | args->gid = INVALID_GID; /* no change */ |
2022 | 2032 | ||
2023 | if (attrs->ia_valid & ATTR_ATIME) | 2033 | if (attrs->ia_valid & ATTR_ATIME) |
2024 | args->atime = cifs_UnixTimeToNT(attrs->ia_atime); | 2034 | args->atime = cifs_UnixTimeToNT(attrs->ia_atime); |
@@ -2086,8 +2096,8 @@ static int | |||
2086 | cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | 2096 | cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) |
2087 | { | 2097 | { |
2088 | unsigned int xid; | 2098 | unsigned int xid; |
2089 | uid_t uid = NO_CHANGE_32; | 2099 | kuid_t uid = INVALID_UID; |
2090 | gid_t gid = NO_CHANGE_32; | 2100 | kgid_t gid = INVALID_GID; |
2091 | struct inode *inode = direntry->d_inode; | 2101 | struct inode *inode = direntry->d_inode; |
2092 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | 2102 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
2093 | struct cifsInodeInfo *cifsInode = CIFS_I(inode); | 2103 | struct cifsInodeInfo *cifsInode = CIFS_I(inode); |
@@ -2146,7 +2156,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
2146 | 2156 | ||
2147 | #ifdef CONFIG_CIFS_ACL | 2157 | #ifdef CONFIG_CIFS_ACL |
2148 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 2158 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
2149 | if (uid != NO_CHANGE_32 || gid != NO_CHANGE_32) { | 2159 | if (uid_valid(uid) || gid_valid(gid)) { |
2150 | rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64, | 2160 | rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64, |
2151 | uid, gid); | 2161 | uid, gid); |
2152 | if (rc) { | 2162 | if (rc) { |
@@ -2170,7 +2180,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
2170 | #ifdef CONFIG_CIFS_ACL | 2180 | #ifdef CONFIG_CIFS_ACL |
2171 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 2181 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
2172 | rc = id_mode_to_cifs_acl(inode, full_path, mode, | 2182 | rc = id_mode_to_cifs_acl(inode, full_path, mode, |
2173 | NO_CHANGE_32, NO_CHANGE_32); | 2183 | INVALID_UID, INVALID_GID); |
2174 | if (rc) { | 2184 | if (rc) { |
2175 | cFYI(1, "%s: Setting ACL failed with error: %d", | 2185 | cFYI(1, "%s: Setting ACL failed with error: %d", |
2176 | __func__, rc); | 2186 | __func__, rc); |
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 3a00c0d0cead..1b15bf839f37 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -569,7 +569,7 @@ bool | |||
569 | backup_cred(struct cifs_sb_info *cifs_sb) | 569 | backup_cred(struct cifs_sb_info *cifs_sb) |
570 | { | 570 | { |
571 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) { | 571 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) { |
572 | if (cifs_sb->mnt_backupuid == current_fsuid()) | 572 | if (uid_eq(cifs_sb->mnt_backupuid, current_fsuid())) |
573 | return true; | 573 | return true; |
574 | } | 574 | } |
575 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) { | 575 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) { |