mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
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.
Closes: https://sashiko.dev/#/patchset/20260906200517.725015-1-pc%40manguebit.org
Fixes: 78e26bec4d ("smb: client: parse uid, gid, mode and dev from WSL reparse points")
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: stable@vger.kernel.org
This commit is contained in:
parent
e1aeaf79de
commit
e1253a82bb
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user