FAILED: patch "[PATCH] smb: client: fix fattr leaking on wsl_to_fattr() failure" failed to apply to 6.12-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x e1253a82bb4c0fed6706a5839fc8b6e01be1abe2
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026092250-exploring-whoever-83c0@gregkh' --subject-prefix 'PATCH 6.12.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From e1253a82bb4c0fed6706a5839fc8b6e01be1abe2 Mon Sep 17 00:00:00 2001
From: Paulo Alcantara <[email protected]>
Date: Sun, 13 Sep 2026 21:15:41 -0300
Subject: [PATCH] smb: client: fix fattr leaking on wsl_to_fattr() failure
wsl_to_fattr() mutates fattr fields as it parses each WSL EA. If validation later fails, the function returns false with partially mutated fattr fields that callers do not reset.
Fix this by parsing into local variables and only committing them to fattr on success.
fs/smb/client/reparse.c +19 -15
@@ -1149,29 +1149,30 @@ static bool wsl_to_fattr(struct cifs_open_info_data *data, u32 tag, struct cifs_fattr *fattr) {unsigned int sbflags =cifs_sb_flags (cifs_sb); +kuid_t uid = cifs_sb->ctx->linux_uid; +kgid_t gid = cifs_sb->ctx->linux_gid;struct smb2_file_full_ea_info *ea;bool have_xattr_dev = false; +dev_t rdev =0 ; +umode_t mode;u32 next =0 ; - fattr->cf_uid = cifs_sb->ctx->linux_uid; - fattr->cf_gid = cifs_sb->ctx->linux_gid; - - fattr->cf_mode &= ~S_IFMT ; + mode = fattr->cf_mode & ~S_IFMT ;switch (tag) {case IO_REPARSE_TAG_LX_SYMLINK : - fattr->cf_mode |=S_IFLNK ; + mode |=S_IFLNK ;break ;case IO_REPARSE_TAG_LX_FIFO : - fattr->cf_mode |=S_IFIFO ; + mode |=S_IFIFO ;break ;case IO_REPARSE_TAG_AF_UNIX : - fattr->cf_mode |=S_IFSOCK ; + mode |=S_IFSOCK ;break ;case IO_REPARSE_TAG_LX_CHR : - fattr->cf_mode |=S_IFCHR ; + mode |=S_IFCHR ;break ;case IO_REPARSE_TAG_LX_BLK : - fattr->cf_mode |=S_IFBLK ; + mode |=S_IFBLK ;break ; }
@@ -1195,26 +1196,29 @@ static bool wsl_to_fattr(struct cifs_open_info_data *data,if (!strncmp (name,SMB2_WSL_XATTR_UID , nlen)) {if (!(sbflags &CIFS_MOUNT_OVERR_UID )) - fattr->cf_uid =wsl_make_kuid (cifs_sb, v); + uid =wsl_make_kuid (cifs_sb, v); }else if (!strncmp (name,SMB2_WSL_XATTR_GID , nlen)) {if (!(sbflags &CIFS_MOUNT_OVERR_GID )) - fattr->cf_gid =wsl_make_kgid (cifs_sb, v); + gid =wsl_make_kgid (cifs_sb, v); }else if (!strncmp (name,SMB2_WSL_XATTR_MODE , nlen)) {/* File type in reparse point tag and in xattr mode must match. */ -if (S_DT (fattr->cf_mode) !=S_DT (get_unaligned_le32 (v))) +if (S_DT (mode) !=S_DT (get_unaligned_le32 (v)))return false; - fattr->cf_mode = (umode_t )get_unaligned_le32 (v); + mode =get_unaligned_le32 (v); }else if (!strncmp (name,SMB2_WSL_XATTR_DEV , nlen)) { - fattr->cf_rdev =reparse_mkdev (v); + rdev =reparse_mkdev (v); have_xattr_dev = true; } }while (next); out: -/* Major and minor numbers for char and block devices are mandatory. */ if (!have_xattr_dev && (tag ==IO_REPARSE_TAG_LX_CHR || tag ==IO_REPARSE_TAG_LX_BLK ))return false; + fattr->cf_uid = uid; + fattr->cf_gid = gid; + fattr->cf_mode = mode; + fattr->cf_rdev = rdev;return true; }
Sasha Levin
maintainerPATCH 1/2 smb: client: use atomic_t for mnt_cifs_flags
From: Paulo Alcantara <[email protected]>
[ Upstream commit 4fc3a433c13944ee5766ec5b9bf6f1eb4d29b880 ]
Use atomic_t for cifs_sb_info::mnt_cifs_flags as it's currently accessed locklessly and may be changed concurrently in mount/remount and reconnect paths.
[6.12 dependency adaptation for e1253a82bb4c:
Convert the existing stable mount-flag readers and writers, including SMB1 reconnect and cache macros, without importing newer symlink code or the generic CIFS_SB refactor. Keep all existing function interfaces and locations; provide cifs_sb_flags as a single-evaluation macro so no functions are added. Keep smb3_update_mnt_flags void and publish its computed flags with atomic_set.
Include the WSL uid/gid defaults and forceuid/forcegid guards from cd2b2b57921d, and the unaligned WSL attribute reads from e1aeaf79dea5. These supply the parser context required for the unmodified target e1253a82bb4c to apply cleanly; the target fix itself is not included.]
[ sashal: Reduced backport -- upstream 4fc3a433c1394 touches 27 file(s), this
backport carries 24. Not backported here:
fs/smb/client/cifs_unicode.h
fs/smb/client/fs_context.h
fs/smb/client/smb2file.c
This note is generated from the file lists only; see the resolution record for the reasoning. ]
Stable-dep-of: e1253a82bb4c ("smb: client: fix fattr leaking on wsl_to_fattr() failure")
--- fs/smb/client/cached_dir.c | 2 +- fs/smb/client/cifs_fs_sb.h | 7 ++- fs/smb/client/cifs_ioctl.h | 2 +- fs/smb/client/cifs_unicode.c | 4 +- fs/smb/client/cifsacl.c | 6 +- fs/smb/client/cifsfs.c | 66 ++++++++++----------- fs/smb/client/cifsglob.h | 10 +++- fs/smb/client/connect.c | 43 +++++++------- fs/smb/client/dfs_cache.c | 2 +- fs/smb/client/dir.c | 16 ++--- fs/smb/client/file.c | 32 +++++----- fs/smb/client/fs_context.c | 110 +++++++++++++++++------------------ fs/smb/client/inode.c | 84 +++++++++++++------------- fs/smb/client/ioctl.c | 2 +- fs/smb/client/link.c | 4 +- fs/smb/client/misc.c | 12 ++-- fs/smb/client/readdir.c | 16 ++--- fs/smb/client/reparse.c | 20 ++++--- fs/smb/client/reparse.h | 11 ++-- fs/smb/client/smb1ops.c | 4 +- fs/smb/client/smb2misc.c | 4 +- fs/smb/client/smb2ops.c | 4 +- fs/smb/client/smb2pdu.c | 4 +- fs/smb/client/xattr.c | 6 +- 24 files changed, 244 insertions(+), 227 deletions(-)
fs/smb/client/cached_dir.c +1 -1
@@ -118,7 +118,7 @@ static const char *path_no_prefix(struct cifs_sb_info *cifs_sb,if (!*path)return path; -if ((cifs_sb->mnt_cifs_flags &CIFS_MOUNT_USE_PREFIX_PATH ) && +if ((cifs_sb_flags (cifs_sb) &CIFS_MOUNT_USE_PREFIX_PATH ) && cifs_sb->prepath) { len =strlen (cifs_sb->prepath) +1 ;if (unlikely (len >strlen (path)))
fs/smb/client/cifs_fs_sb.h +6 -1
@@ -10,6 +10,7 @@#ifndef _CIFS_FS_SB_H#define _CIFS_FS_SB_H +#include <linux/atomic.h> #include <linux/backing-dev.h> #define CIFS_MOUNT_NO_PERM 1/* do not do client vfs_perm check */
@@ -54,7 +55,7 @@ struct cifs_sb_info {struct nls_table *local_nls;struct smb3_fs_context *ctx;atomic_t active; -unsigned int mnt_cifs_flags; +atomic_t mnt_cifs_flags;struct delayed_work prune_tlinks;struct rcu_head rcu;
@@ -71,4 +72,8 @@ struct cifs_sb_info {*/ struct dentry *root; }; + +/* Mount flags are accessed locklessly in mount/remount and reconnect paths. */ +#define cifs_sb_flags (cifs_sb) ((unsigned int)atomic_read(&(cifs_sb)->mnt_cifs_flags)) +#endif /* _CIFS_FS_SB_H */
fs/smb/client/cifs_ioctl.h +1 -1
@@ -125,7 +125,7 @@ struct smb3_notify_info {static inline bool cifs_forced_shutdown (struct cifs_sb_info *sbi) { -if (CIFS_MOUNT_SHUTDOWN & sbi->mnt_cifs_flags) +if (CIFS_MOUNT_SHUTDOWN &cifs_sb_flags (sbi))return true;else return false;
fs/smb/client/cifs_unicode.c +2 -2
@@ -16,9 +16,9 @@ int cifs_remap(struct cifs_sb_info *cifs_sb) {int map_type; -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_MAP_SFM_CHR ) +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_MAP_SFM_CHR ) map_type =SFM_MAP_UNI_RSVD ; -else if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_MAP_SPECIAL_CHR ) +else if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_MAP_SPECIAL_CHR ) map_type =SFU_MAP_UNI_RSVD ;else map_type =NO_MAP_UNI_RSVD ;
fs/smb/client/cifsacl.c +3 -3
@@ -374,7 +374,7 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct smb_sid *psid,return -EIO ; } -if ((cifs_sb->mnt_cifs_flags &CIFS_MOUNT_UID_FROM_ACL ) || +if ((cifs_sb_flags (cifs_sb) &CIFS_MOUNT_UID_FROM_ACL ) || (cifs_sb_master_tcon (cifs_sb)->posix_extensions)) {uint32_t unix_id;bool is_group;
@@ -1733,12 +1733,12 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,return rc; } -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_MODE_FROM_SID ) +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_MODE_FROM_SID ) mode_from_sid = true;else mode_from_sid = false; -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_UID_FROM_ACL ) +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_UID_FROM_ACL ) id_from_sid = true;else id_from_sid = false;
fs/smb/client/cifsfs.c +33 -33
148 lines not on this page · raw message
fs/smb/client/cifsglob.h +7 -3
@@ -1500,9 +1500,13 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file);#define CIFS_CACHE_RW_FLG (CIFS_CACHE_READ_FLG | CIFS_CACHE_WRITE_FLG)#define CIFS_CACHE_RHW_FLG (CIFS_CACHE_RW_FLG | CIFS_CACHE_HANDLE_FLG) -#define CIFS_CACHE_READ (cinode) ((cinode->oplock & CIFS_CACHE_READ_FLG) || (CIFS_SB(cinode->netfs.inode.i_sb)->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE)) +#define CIFS_CACHE_READ (cinode) \ + ((cinode->oplock & CIFS_CACHE_READ_FLG) || \ + (cifs_sb_flags(CIFS_SB(cinode->netfs.inode.i_sb)) & CIFS_MOUNT_RO_CACHE))#define CIFS_CACHE_HANDLE (cinode) (cinode->oplock & CIFS_CACHE_HANDLE_FLG) -#define CIFS_CACHE_WRITE (cinode) ((cinode->oplock & CIFS_CACHE_WRITE_FLG) || (CIFS_SB(cinode->netfs.inode.i_sb)->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE)) +#define CIFS_CACHE_WRITE (cinode) \ + ((cinode->oplock & CIFS_CACHE_WRITE_FLG) || \ + (cifs_sb_flags(CIFS_SB(cinode->netfs.inode.i_sb)) & CIFS_MOUNT_RW_CACHE))/* * One of these for each file inode
@@ -1565,7 +1569,7 @@ CIFS_FILE_SB(struct file *file)static inline char CIFS_DIR_SEP (const struct cifs_sb_info *cifs_sb) { -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_POSIX_PATHS ) +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_POSIX_PATHS )return '/' ;else return '\\' ;
fs/smb/client/connect.c +22 -21
133 lines not on this page · raw message
fs/smb/client/dfs_cache.c +1 -1
@@ -1340,7 +1340,7 @@ int dfs_cache_remount_fs(struct cifs_sb_info *cifs_sb)* Force the use of prefix path to support failover on DFS paths that resolve to targets * that have different prefix paths. */ - cifs_sb->mnt_cifs_flags |=CIFS_MOUNT_USE_PREFIX_PATH ; +atomic_or (CIFS_MOUNT_USE_PREFIX_PATH , &cifs_sb->mnt_cifs_flags);refresh_tcon_referral (tcon, true);return 0 ;
fs/smb/client/dir.c +8 -8
@@ -96,7 +96,7 @@ char *__build_path_from_dentry_optional_prefix(struct dentry *direntry, void *paelse dfsplen =0 ; -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_USE_PREFIX_PATH ) +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_USE_PREFIX_PATH ) pplen = cifs_sb->prepath ?strlen (cifs_sb->prepath) +1 :0 ; s =dentry_path_raw (direntry, page,PATH_MAX );
@@ -123,7 +123,7 @@ char *__build_path_from_dentry_optional_prefix(struct dentry *direntry, void *paif (dfsplen) { s -= dfsplen;memcpy (s, tree, dfsplen); -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_POSIX_PATHS ) { +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_POSIX_PATHS ) {int i;for (i =0 ; i < dfsplen; i++) {if (s[i] =='\\' )
@@ -160,7 +160,7 @@ check_name(struct dentry *direntry, struct cifs_tcon *tcon) le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength)))return -ENAMETOOLONG ; -if (!(cifs_sb->mnt_cifs_flags &CIFS_MOUNT_POSIX_PATHS )) { +if (!(cifs_sb_flags (cifs_sb) &CIFS_MOUNT_POSIX_PATHS )) {for (i =0 ; i < direntry->d_name.len; i++) {if (direntry->d_name.name[i] =='\\' ) {cifs_dbg (FYI ,"Invalid file name\n" );
@@ -350,7 +350,7 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned .device = 0, }; -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_SET_UID ) { +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_SET_UID ) { args.uid =current_fsuid ();if (inode->i_mode &S_ISGID ) args.gid = inode->i_gid;
@@ -387,9 +387,9 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsignedif (server->ops->set_lease_key) server->ops->set_lease_key (newinode, fid);if ((*oplock &CIFS_CREATE_ACTION ) &&S_ISREG (newinode->i_mode)) { -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_DYNPERM ) +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_DYNPERM ) newinode->i_mode = mode; -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_SET_UID ) { +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_SET_UID ) { newinode->i_uid =current_fsuid ();if (inode->i_mode &S_ISGID ) newinode->i_gid = inode->i_gid;
@@ -519,8 +519,8 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, }if (file->f_flags &O_DIRECT && -CIFS_SB (inode->i_sb)->mnt_cifs_flags &CIFS_MOUNT_STRICT_IO ) { -if (CIFS_SB (inode->i_sb)->mnt_cifs_flags &CIFS_MOUNT_NO_BRL ) +cifs_sb_flags (CIFS_SB (inode->i_sb)) &CIFS_MOUNT_STRICT_IO ) { +if (cifs_sb_flags (CIFS_SB (inode->i_sb)) &CIFS_MOUNT_NO_BRL ) file->f_op = &cifs_file_direct_nobrl_ops;else file->f_op = &cifs_file_direct_ops;
fs/smb/client/file.c +16 -16
@@ -269,7 +269,7 @@ static int cifs_init_request(struct netfs_io_request *rreq, struct file *file) open_file = file->private_data; rreq->netfs_priv = file->private_data; req->cfile =cifsFileInfo_get (open_file); -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_RWPIDFORWARD ) +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_RWPIDFORWARD ) req->pid = req->cfile->pid; }else if (rreq->origin !=NETFS_WRITEBACK ) {WARN_ON_ONCE (1 );
@@ -883,7 +883,7 @@ void _cifsFileInfo_put(struct cifsFileInfo *cifs_file,* close because it may cause a error when we open this file * again and get at least level II oplock. */ -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_STRICT_IO ) +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_STRICT_IO )set_bit (CIFS_INO_INVALID_MAPPING , &cifsi->flags);cifs_set_oplock_level (cifsi,0 ); }
@@ -974,8 +974,8 @@ int cifs_open(struct inode *inode, struct file *file) inode, file->f_flags, full_path);if (file->f_flags &O_DIRECT && - cifs_sb->mnt_cifs_flags &CIFS_MOUNT_STRICT_IO ) { -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_NO_BRL ) +cifs_sb_flags (cifs_sb) &CIFS_MOUNT_STRICT_IO ) { +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_NO_BRL ) file->f_op = &cifs_file_direct_nobrl_ops;else file->f_op = &cifs_file_direct_ops;
@@ -1123,7 +1123,7 @@ cifs_relock_file(struct cifsFileInfo *cfile)#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY if (cap_unix (tcon->ses) && (CIFS_UNIX_FCNTL_CAP &le64_to_cpu (tcon->fsUnixInfo.Capability)) && - ((cifs_sb->mnt_cifs_flags &CIFS_MOUNT_NOPOSIXBRL ) ==0 )) + ((cifs_sb_flags (cifs_sb) &CIFS_MOUNT_NOPOSIXBRL ) ==0 )) rc =cifs_push_posix_locks (cfile); else#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
@@ -1919,7 +1919,7 @@ cifs_push_locks(struct cifsFileInfo *cfile)#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY if (cap_unix (tcon->ses) && (CIFS_UNIX_FCNTL_CAP &le64_to_cpu (tcon->fsUnixInfo.Capability)) && - ((cifs_sb->mnt_cifs_flags &CIFS_MOUNT_NOPOSIXBRL ) ==0 )) + ((cifs_sb_flags (cifs_sb) &CIFS_MOUNT_NOPOSIXBRL ) ==0 )) rc =cifs_push_posix_locks (cfile); else#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
@@ -2327,7 +2327,7 @@ int cifs_flock(struct file *file, int cmd, struct file_lock *fl)if (cap_unix (tcon->ses) && (CIFS_UNIX_FCNTL_CAP &le64_to_cpu (tcon->fsUnixInfo.Capability)) && - ((cifs_sb->mnt_cifs_flags &CIFS_MOUNT_NOPOSIXBRL ) ==0 )) + ((cifs_sb_flags (cifs_sb) &CIFS_MOUNT_NOPOSIXBRL ) ==0 )) posix_lck = true;if (!lock && !unlock) {
@@ -2377,7 +2377,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *flock)if (cap_unix (tcon->ses) && (CIFS_UNIX_FCNTL_CAP &le64_to_cpu (tcon->fsUnixInfo.Capability)) && - ((cifs_sb->mnt_cifs_flags &CIFS_MOUNT_NOPOSIXBRL ) ==0 )) + ((cifs_sb_flags (cifs_sb) &CIFS_MOUNT_NOPOSIXBRL ) ==0 )) posix_lck = true;/* * BB add code here to normalize offset and length to account for
@@ -2432,7 +2432,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,struct cifs_sb_info *cifs_sb =CIFS_SB (cifs_inode->netfs.inode.i_sb);/* only filter by fsuid on multiuser mounts */ -if (!(cifs_sb->mnt_cifs_flags &CIFS_MOUNT_MULTIUSER )) +if (!(cifs_sb_flags (cifs_sb) &CIFS_MOUNT_MULTIUSER )) fsuid_only = false;spin_lock (&cifs_inode->open_file_lock);
@@ -2488,7 +2488,7 @@ cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, int flags, cifs_sb =CIFS_SB (cifs_inode->netfs.inode.i_sb);/* only filter by fsuid on multiuser mounts */ -if (!(cifs_sb->mnt_cifs_flags &CIFS_MOUNT_MULTIUSER )) +if (!(cifs_sb_flags (cifs_sb) &CIFS_MOUNT_MULTIUSER )) fsuid_only = false;spin_lock (&cifs_inode->open_file_lock);
@@ -2663,7 +2663,7 @@ int cifs_strict_fsync(struct file *file, loff_t start, loff_t end, } tcon =tlink_tcon (smbfile->tlink); -if (!(cifs_sb->mnt_cifs_flags &CIFS_MOUNT_NOSSYNC )) { +if (!(cifs_sb_flags (cifs_sb) &CIFS_MOUNT_NOSSYNC )) { server = tcon->ses->server;if (server->ops->flush ==NULL ) { rc = -ENOSYS ;
@@ -2711,7 +2711,7 @@ int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync) file, datasync); tcon =tlink_tcon (smbfile->tlink); -if (!(cifs_sb->mnt_cifs_flags &CIFS_MOUNT_NOSSYNC )) { +if (!(cifs_sb_flags (cifs_sb) &CIFS_MOUNT_NOSSYNC )) { server = tcon->ses->server;if (server->ops->flush ==NULL ) { rc = -ENOSYS ;
@@ -2780,7 +2780,7 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)if (rc <=0 ) goto out; -if ((cifs_sb->mnt_cifs_flags &CIFS_MOUNT_NOPOSIXBRL ) && +if ((cifs_sb_flags (cifs_sb) &CIFS_MOUNT_NOPOSIXBRL ) && (cifs_find_lock_conflict (cfile, iocb->ki_pos,iov_iter_count (from), server->vals->exclusive_lock_type,0 ,NULL ,CIFS_WRITE_OP ))) {
@@ -2816,7 +2816,7 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from)if (CIFS_CACHE_WRITE (cinode)) {if (cap_unix (tcon->ses) && (CIFS_UNIX_FCNTL_CAP &le64_to_cpu (tcon->fsUnixInfo.Capability)) && - ((cifs_sb->mnt_cifs_flags &CIFS_MOUNT_NOPOSIXBRL ) ==0 )) { + ((cifs_sb_flags (cifs_sb) &CIFS_MOUNT_NOPOSIXBRL ) ==0 )) { written =netfs_file_write_iter (iocb, from); goto out; }
@@ -2921,7 +2921,7 @@ cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to)if (!CIFS_CACHE_READ (cinode))return netfs_unbuffered_read_iter (iocb, to); -if ((cifs_sb->mnt_cifs_flags &CIFS_MOUNT_NOPOSIXBRL ) ==0 ) { +if ((cifs_sb_flags (cifs_sb) &CIFS_MOUNT_NOPOSIXBRL ) ==0 ) {if (iocb->ki_flags &IOCB_DIRECT )return netfs_unbuffered_read_iter (iocb, to);return netfs_buffered_read_iter (iocb, to);
@@ -3043,7 +3043,7 @@ bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file,struct cifs_sb_info *cifs_sb; cifs_sb =CIFS_SB (cifsInode->netfs.inode.i_sb); -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_DIRECT_IO ) { +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_DIRECT_IO ) {/* since no page cache to corrupt on directio we can change size safely */ return true;
fs/smb/client/fs_context.c +55 -55
201 lines not on this page · raw message
fs/smb/client/inode.c +42 -42
284 lines not on this page · raw message
fs/smb/client/ioctl.c +1 -1
@@ -220,7 +220,7 @@ static int cifs_shutdown(struct super_block *sb, unsigned long arg)*/ case CIFS_GOING_FLAGS_LOGFLUSH :case CIFS_GOING_FLAGS_NOLOGFLUSH : - sbi->mnt_cifs_flags |=CIFS_MOUNT_SHUTDOWN ; +atomic_or (CIFS_MOUNT_SHUTDOWN , &sbi->mnt_cifs_flags); goto shutdown_good;default : rc = -EINVAL ;
fs/smb/client/link.c +2 -2
@@ -604,9 +604,9 @@ cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,cifs_dbg (FYI ,"symname is %s\n" , symname);/* BB what if DFS and this volume is on different share? BB */ -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_MF_SYMLINKS ) { +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_MF_SYMLINKS ) { rc =create_mf_symlink (xid, pTcon, cifs_sb, full_path, symname); - }else if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_UNX_EMUL ) { + }else if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_UNX_EMUL ) { rc =__cifs_sfu_make_node (xid, inode, direntry, pTcon, full_path,S_IFLNK ,0 , symname);#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
fs/smb/client/misc.c +6 -6
@@ -562,13 +562,13 @@ dump_smb(void *buf, int smb_buf_length)void cifs_autodisable_serverino (struct cifs_sb_info *cifs_sb) { -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_SERVER_INUM ) { +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_SERVER_INUM ) {struct cifs_tcon *tcon =NULL ;if (cifs_sb->master_tlink) tcon =cifs_sb_master_tcon (cifs_sb); - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM ; +atomic_andnot (CIFS_MOUNT_SERVER_INUM , &cifs_sb->mnt_cifs_flags); cifs_sb->mnt_cifs_serverino_autodisabled = true;cifs_dbg (VFS ,"Autodisabling the use of server inode numbers on %s\n" , tcon ? tcon->tree_name :"new server" );
@@ -670,11 +670,11 @@ void cifs_done_oplock_break(struct cifsInodeInfo *cinode)bool backup_cred (struct cifs_sb_info *cifs_sb) { -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_CIFS_BACKUPUID ) { +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_CIFS_BACKUPUID ) {if (uid_eq (cifs_sb->ctx->backupuid,current_fsuid ()))return true; } -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_CIFS_BACKUPGID ) { +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_CIFS_BACKUPGID ) {if (in_group_p (cifs_sb->ctx->backupgid))return true; }
@@ -1310,7 +1310,7 @@ int cifs_update_super_prepath(struct cifs_sb_info *cifs_sb, char *prefix)convert_delimiter (cifs_sb->prepath,CIFS_DIR_SEP (cifs_sb)); } - cifs_sb->mnt_cifs_flags |=CIFS_MOUNT_USE_PREFIX_PATH ; +atomic_or (CIFS_MOUNT_USE_PREFIX_PATH , &cifs_sb->mnt_cifs_flags);return 0 ; }
@@ -1339,7 +1339,7 @@ int cifs_inval_name_dfs_link_error(const unsigned int xid,* look up or tcon is not DFS. */ if (strlen (full_path) <2 || !cifs_sb || - (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_NO_DFS ) || + (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_NO_DFS ) || !is_tcon_dfs (tcon))return 0 ;
fs/smb/client/readdir.c +8 -8
@@ -121,7 +121,7 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name,* want to clobber the existing one with the one that * the readdir code created. */ -if (!(cifs_sb->mnt_cifs_flags &CIFS_MOUNT_SERVER_INUM )) +if (!(cifs_sb_flags (cifs_sb) &CIFS_MOUNT_SERVER_INUM )) fattr->cf_uniqueid =CIFS_I (inode)->uniqueid;/*
@@ -215,11 +215,11 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)* may look wrong since the inodes may not have timed out by the time * "ls" does a stat() call on them. */ -if ((cifs_sb->mnt_cifs_flags &CIFS_MOUNT_CIFS_ACL ) || - (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_MODE_FROM_SID )) +if ((cifs_sb_flags (cifs_sb) &CIFS_MOUNT_CIFS_ACL ) || + (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_MODE_FROM_SID )) fattr->cf_flags |=CIFS_FATTR_NEED_REVAL ; -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_UNX_EMUL && +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_UNX_EMUL && fattr->cf_cifsattrs &ATTR_SYSTEM ) {if (fattr->cf_eof ==0 ) { fattr->cf_mode &= ~S_IFMT ;
@@ -395,7 +395,7 @@ _initiate_cifs_search(const unsigned int xid, struct file *file,else if ((tcon->ses->capabilities & tcon->ses->server->vals->cap_nt_find) ==0 ) { cifsFile->srch_inf.info_level =SMB_FIND_FILE_INFO_STANDARD ; - }else if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_SERVER_INUM ) { + }else if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_SERVER_INUM ) { cifsFile->srch_inf.info_level =SMB_FIND_FILE_ID_FULL_DIR_INFO ; }else /* not srvinos - BB fixme add check for backlevel? */ { cifsFile->srch_inf.info_level =SMB_FIND_FILE_FULL_DIRECTORY_INFO ;
@@ -412,7 +412,7 @@ _initiate_cifs_search(const unsigned int xid, struct file *file,if (rc ==0 ) { cifsFile->invalidHandle = false; }else if ((rc == -EOPNOTSUPP ) && - (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_SERVER_INUM )) { + (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_SERVER_INUM )) {cifs_autodisable_serverino (cifs_sb); goto ffirst_retry; }
@@ -1010,14 +1010,14 @@ static int cifs_filldir(char *find_entry, struct file *file,break ; } -if (de.ino && (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_SERVER_INUM )) { +if (de.ino && (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_SERVER_INUM )) { fattr.cf_uniqueid = de.ino; }else { fattr.cf_uniqueid =iunique (sb,ROOT_I );cifs_autodisable_serverino (cifs_sb); } -if ((cifs_sb->mnt_cifs_flags &CIFS_MOUNT_MF_SYMLINKS ) && +if ((cifs_sb_flags (cifs_sb) &CIFS_MOUNT_MF_SYMLINKS ) &&couldbe_mf_symlink (&fattr))/* * trying to get the type and mode can be slow,
fs/smb/client/reparse.c +13 -7
@@ -679,10 +679,14 @@ static bool wsl_to_fattr(struct cifs_open_info_data *data,struct cifs_sb_info *cifs_sb, u32 tag, struct cifs_fattr *fattr) { + unsigned int sbflags = cifs_sb_flags(cifs_sb);struct smb2_file_full_ea_info *ea;bool have_xattr_dev = false;u32 next =0 ; + fattr->cf_uid = cifs_sb->ctx->linux_uid; + fattr->cf_gid = cifs_sb->ctx->linux_gid; + fattr->cf_mode &= ~S_IFMT ;switch (tag) {case IO_REPARSE_TAG_LX_SYMLINK :
@@ -720,15 +724,17 @@ static bool wsl_to_fattr(struct cifs_open_info_data *data, nlen = ea->ea_name_length; v = (void *)((u8 *)ea->ea_data + ea->ea_name_length +1 ); -if (!strncmp (name,SMB2_WSL_XATTR_UID , nlen)) - fattr->cf_uid =wsl_make_kuid (cifs_sb, v); -else if (!strncmp (name,SMB2_WSL_XATTR_GID , nlen)) - fattr->cf_gid =wsl_make_kgid (cifs_sb, v); -else if (!strncmp (name,SMB2_WSL_XATTR_MODE , nlen)) { +if (!strncmp (name,SMB2_WSL_XATTR_UID , nlen)) { +if (!(sbflags &CIFS_MOUNT_OVERR_UID )) + fattr->cf_uid =wsl_make_kuid (cifs_sb, v); + }else if (!strncmp (name,SMB2_WSL_XATTR_GID , nlen)) { +if (!(sbflags &CIFS_MOUNT_OVERR_GID )) + fattr->cf_gid =wsl_make_kgid (cifs_sb, v); + }else if (!strncmp (name,SMB2_WSL_XATTR_MODE , nlen)) {/* File type in reparse point tag and in xattr mode must match. */ -if (S_DT (fattr->cf_mode) !=S_DT (le32_to_cpu (*(__le32 *)v))) +if (S_DT (fattr->cf_mode) !=S_DT (get_unaligned_le32 (v)))return false; - fattr->cf_mode = (umode_t )le32_to_cpu (*(__le32 *)v); + fattr->cf_mode = (umode_t )get_unaligned_le32 (v); }else if (!strncmp (name,SMB2_WSL_XATTR_DEV , nlen)) { fattr->cf_rdev =reparse_mkdev (v); have_xattr_dev = true;
fs/smb/client/reparse.h +6 -5
@@ -9,6 +9,7 @@#include <linux/fs.h> #include <linux/stat.h> #include <linux/uidgid.h> +#include <linux/unaligned.h> #include "fs_context.h" #include "cifsglob.h"
@@ -22,7 +23,7 @@static inline dev_t reparse_mkdev (void *ptr) { -u64 v =le64_to_cpu (*(__le64 *)ptr); +u64 v =get_unaligned_le64 (ptr);return MKDEV (v &0xffffffff , v >>32 ); }
@@ -30,9 +31,9 @@ static inline dev_t reparse_mkdev(void *ptr)static inline kuid_t wsl_make_kuid (struct cifs_sb_info *cifs_sb,void *ptr) { -u32 uid =le32_to_cpu (*(__le32 *)ptr); +u32 uid =get_unaligned_le32 (ptr); -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_OVERR_UID ) +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_OVERR_UID )return cifs_sb->ctx->linux_uid;return make_kuid (current_user_ns (), uid); }
@@ -40,9 +41,9 @@ static inline kuid_t wsl_make_kuid(struct cifs_sb_info *cifs_sb,static inline kgid_t wsl_make_kgid (struct cifs_sb_info *cifs_sb,void *ptr) { -u32 gid =le32_to_cpu (*(__le32 *)ptr); +u32 gid =get_unaligned_le32 (ptr); -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_OVERR_GID ) +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_OVERR_GID )return cifs_sb->ctx->linux_gid;return make_kgid (current_user_ns (), gid); }
fs/smb/client/smb1ops.c +2 -2
@@ -1323,7 +1323,7 @@ cifs_make_node(unsigned int xid, struct inode *inode, .mtime = NO_CHANGE_64, .device = dev, }; -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_SET_UID ) { +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_SET_UID ) { args.uid =current_fsuid (); args.gid =current_fsgid (); }else {
@@ -1349,7 +1349,7 @@ cifs_make_node(unsigned int xid, struct inode *inode,* supports block and char device, socket & fifo, * and was used by default in earlier versions of Windows */ -if (!(cifs_sb->mnt_cifs_flags &CIFS_MOUNT_UNX_EMUL )) +if (!(cifs_sb_flags (cifs_sb) &CIFS_MOUNT_UNX_EMUL ))return -EPERM ;return cifs_sfu_make_node (xid, inode, dentry, tcon, full_path, mode, dev);
fs/smb/client/smb2misc.c +2 -2
@@ -495,9 +495,9 @@ cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb)__le16 *to;int map_type; -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_MAP_SFM_CHR ) +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_MAP_SFM_CHR ) map_type =SFM_MAP_UNI_RSVD ; -else if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_MAP_SPECIAL_CHR ) +else if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_MAP_SPECIAL_CHR ) map_type =SFU_MAP_UNI_RSVD ;else map_type =NO_MAP_UNI_RSVD ;
fs/smb/client/smb2ops.c +2 -2
@@ -1011,7 +1011,7 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon, rc = -EREMOTE ; }if (rc == -EREMOTE &&IS_ENABLED (CONFIG_CIFS_DFS_UPCALL ) && cifs_sb && - (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_NO_DFS )) + (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_NO_DFS )) rc = -EOPNOTSUPP ; goto out; }
@@ -5520,7 +5520,7 @@ static int smb2_make_node(unsigned int xid, struct inode *inode,* supports block and char device, socket & fifo, * and was used by default in earlier versions of Windows */ -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_UNX_EMUL ) { +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_UNX_EMUL ) { rc =cifs_sfu_make_node (xid, inode, dentry, tcon, full_path, mode, dev); }else {
fs/smb/client/smb2pdu.c +2 -2
@@ -3127,7 +3127,7 @@ SMB2_open_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,bool set_mode;bool set_owner; -if ((oparms->cifs_sb->mnt_cifs_flags &CIFS_MOUNT_MODE_FROM_SID ) && +if ((cifs_sb_flags (oparms->cifs_sb) &CIFS_MOUNT_MODE_FROM_SID ) && (oparms->mode !=ACL_NO_MODE )) set_mode = true;else {
@@ -3135,7 +3135,7 @@ SMB2_open_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server, oparms->mode =ACL_NO_MODE ; } -if (oparms->cifs_sb->mnt_cifs_flags &CIFS_MOUNT_UID_FROM_ACL ) +if (cifs_sb_flags (oparms->cifs_sb) &CIFS_MOUNT_UID_FROM_ACL ) set_owner = true;else set_owner = false;
fs/smb/client/xattr.c +3 -3
@@ -147,7 +147,7 @@ static int cifs_xattr_set(const struct xattr_handler *handler,break ; } -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_NO_XATTR ) +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_NO_XATTR ) goto out;if (pTcon->ses->server->ops->set_EA) {
@@ -299,7 +299,7 @@ static int cifs_xattr_get(const struct xattr_handler *handler,break ; } -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_NO_XATTR ) +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_NO_XATTR ) goto out;if (pTcon->ses->server->ops->query_all_EAs)
@@ -373,7 +373,7 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)if (unlikely (cifs_forced_shutdown (cifs_sb)))return -EIO ; -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_NO_XATTR ) +if (cifs_sb_flags (cifs_sb) &CIFS_MOUNT_NO_XATTR )return -EOPNOTSUPP ; tlink =cifs_sb_tlink (cifs_sb);
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 smb: client: fix fattr leaking on wsl_to_fattr() failure
From: Paulo Alcantara <[email protected]>
[ Upstream commit e1253a82bb4c0fed6706a5839fc8b6e01be1abe2 ]
wsl_to_fattr() mutates fattr fields as it parses each WSL EA. If validation later fails, the function returns false with partially mutated fattr fields that callers do not reset.
Fix this by parsing into local variables and only committing them to fattr on success.
--- fs/smb/client/reparse.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-)
fs/smb/client/reparse.c +19 -15
@@ -680,29 +680,30 @@ static bool wsl_to_fattr(struct cifs_open_info_data *data, u32 tag, struct cifs_fattr *fattr) {unsigned int sbflags =cifs_sb_flags (cifs_sb); +kuid_t uid = cifs_sb->ctx->linux_uid; +kgid_t gid = cifs_sb->ctx->linux_gid;struct smb2_file_full_ea_info *ea;bool have_xattr_dev = false; +dev_t rdev =0 ; +umode_t mode;u32 next =0 ; - fattr->cf_uid = cifs_sb->ctx->linux_uid; - fattr->cf_gid = cifs_sb->ctx->linux_gid; - - fattr->cf_mode &= ~S_IFMT ; + mode = fattr->cf_mode & ~S_IFMT ;switch (tag) {case IO_REPARSE_TAG_LX_SYMLINK : - fattr->cf_mode |=S_IFLNK ; + mode |=S_IFLNK ;break ;case IO_REPARSE_TAG_LX_FIFO : - fattr->cf_mode |=S_IFIFO ; + mode |=S_IFIFO ;break ;case IO_REPARSE_TAG_AF_UNIX : - fattr->cf_mode |=S_IFSOCK ; + mode |=S_IFSOCK ;break ;case IO_REPARSE_TAG_LX_CHR : - fattr->cf_mode |=S_IFCHR ; + mode |=S_IFCHR ;break ;case IO_REPARSE_TAG_LX_BLK : - fattr->cf_mode |=S_IFBLK ; + mode |=S_IFBLK ;break ; }
@@ -726,26 +727,29 @@ static bool wsl_to_fattr(struct cifs_open_info_data *data,if (!strncmp (name,SMB2_WSL_XATTR_UID , nlen)) {if (!(sbflags &CIFS_MOUNT_OVERR_UID )) - fattr->cf_uid =wsl_make_kuid (cifs_sb, v); + uid =wsl_make_kuid (cifs_sb, v); }else if (!strncmp (name,SMB2_WSL_XATTR_GID , nlen)) {if (!(sbflags &CIFS_MOUNT_OVERR_GID )) - fattr->cf_gid =wsl_make_kgid (cifs_sb, v); + gid =wsl_make_kgid (cifs_sb, v); }else if (!strncmp (name,SMB2_WSL_XATTR_MODE , nlen)) {/* File type in reparse point tag and in xattr mode must match. */ -if (S_DT (fattr->cf_mode) !=S_DT (get_unaligned_le32 (v))) +if (S_DT (mode) !=S_DT (get_unaligned_le32 (v)))return false; - fattr->cf_mode = (umode_t )get_unaligned_le32 (v); + mode =get_unaligned_le32 (v); }else if (!strncmp (name,SMB2_WSL_XATTR_DEV , nlen)) { - fattr->cf_rdev =reparse_mkdev (v); + rdev =reparse_mkdev (v); have_xattr_dev = true; } }while (next); out: -/* Major and minor numbers for char and block devices are mandatory. */ if (!have_xattr_dev && (tag ==IO_REPARSE_TAG_LX_CHR || tag ==IO_REPARSE_TAG_LX_BLK ))return false; + fattr->cf_uid = uid; + fattr->cf_gid = gid; + fattr->cf_mode = mode; + fattr->cf_rdev = rdev;return true; }
Signature · 1 line
2.53.0
Re: [PATCH 6.12.y 2/2] smb: client: fix fattr leaking on wsl_to_fattr() failure
Quoted 111 lines · Sasha Levin
From: Paulo Alcantara <[email protected]>
[ Upstream commit
e1253a82bb4c0fed6706a5839fc8b6e01be1abe2]
wsl_to_fattr()mutates fattr fields as it parses each WSL EA. If validation later fails, the function returns false with partially mutated fattr fields that callers do not reset.Fix this by parsing into local variables and only committing them to fattr on success.
Fixes 78e26bec4d6d ("smb: client: parse uid, gid, mode and dev from WSL reparse points")Reviewed-by Namjae Jeon <[email protected]>Signed-off-by Paulo Alcantara <[email protected]>Cc David Howells <[email protected]>Cc Tom Talpey <[email protected]>Cc Shyam Prasad N <[email protected]>Cc Ronnie Sahlberg <[email protected]>Cc Bharath SM <[email protected]>Cc Namjae Jeon <[email protected]>Signed-off-by Sasha Levin <[email protected]>--- fs/smb/client/reparse.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-)fs/smb/client/reparse.c +19
-15@@ -680,29 +680,30 @@ static bool wsl_to_fattr(struct cifs_open_info_data *data, u32 tag, struct cifs_fattr *fattr) {unsigned int sbflags =cifs_sb_flags (cifs_sb); +kuid_t uid = cifs_sb->ctx->linux_uid; +kgid_t gid = cifs_sb->ctx->linux_gid;struct smb2_file_full_ea_info *ea;bool have_xattr_dev = false; +dev_t rdev =0 ; +umode_t mode;u32 next =0 ; - fattr->cf_uid = cifs_sb->ctx->linux_uid; - fattr->cf_gid = cifs_sb->ctx->linux_gid; - - fattr->cf_mode &= ~S_IFMT ; + mode = fattr->cf_mode & ~S_IFMT ;switch (tag) {case IO_REPARSE_TAG_LX_SYMLINK : - fattr->cf_mode |=S_IFLNK ; + mode |=S_IFLNK ;break ;case IO_REPARSE_TAG_LX_FIFO : - fattr->cf_mode |=S_IFIFO ; + mode |=S_IFIFO ;break ;case IO_REPARSE_TAG_AF_UNIX : - fattr->cf_mode |=S_IFSOCK ; + mode |=S_IFSOCK ;break ;case IO_REPARSE_TAG_LX_CHR : - fattr->cf_mode |=S_IFCHR ; + mode |=S_IFCHR ;break ;case IO_REPARSE_TAG_LX_BLK : - fattr->cf_mode |=S_IFBLK ; + mode |=S_IFBLK ;break ; }@@ -726,26 +727,29 @@ static bool wsl_to_fattr(struct cifs_open_info_data *data,if (!strncmp (name,SMB2_WSL_XATTR_UID , nlen)) {if (!(sbflags &CIFS_MOUNT_OVERR_UID )) - fattr->cf_uid =wsl_make_kuid (cifs_sb, v); + uid =wsl_make_kuid (cifs_sb, v); }else if (!strncmp (name,SMB2_WSL_XATTR_GID , nlen)) {if (!(sbflags &CIFS_MOUNT_OVERR_GID )) - fattr->cf_gid =wsl_make_kgid (cifs_sb, v); + gid =wsl_make_kgid (cifs_sb, v); }else if (!strncmp (name,SMB2_WSL_XATTR_MODE , nlen)) {/* File type in reparse point tag and in xattr mode must match. */ -if (S_DT (fattr->cf_mode) !=S_DT (get_unaligned_le32 (v))) +if (S_DT (mode) !=S_DT (get_unaligned_le32 (v)))return false; - fattr->cf_mode = (umode_t )get_unaligned_le32 (v); + mode =get_unaligned_le32 (v); }else if (!strncmp (name,SMB2_WSL_XATTR_DEV , nlen)) { - fattr->cf_rdev =reparse_mkdev (v); + rdev =reparse_mkdev (v); have_xattr_dev = true; } }while (next); out: -/* Major and minor numbers for char and block devices are mandatory. */ if (!have_xattr_dev && (tag ==IO_REPARSE_TAG_LX_CHR || tag ==IO_REPARSE_TAG_LX_BLK ))return false; + fattr->cf_uid = uid; + fattr->cf_gid = gid; + fattr->cf_mode = mode; + fattr->cf_rdev = rdev;return true; }Signature · 1 line
2.53.0
Did not apply