From 65d5dbdc089be42fc48a6f77bc6b648307f34b17 Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Sun, 6 Sep 2026 16:01:16 -0300 Subject: [PATCH] smb: client: fix file type corruption in posix_reparse_to_fattr() Setting the file type in cf_mode without clearing the existing S_IFMT bits first is wrong as it corrupts the file type when cf_mode already has type bits set (e.g. S_IFREG | S_IFCHR == S_IFLNK). Use a local ftype variable to collect the new file type and apply it after validation succeeds, clearing S_IFMT and setting the new type in a single assignment. This avoids stripping cf_mode on malformed reparse points where the function returns false early. Closes: https://sashiko.dev/#/patchset/20260906172005.627163-1-pc%40manguebit.org Reviewed-by: Namjae Jeon Signed-off-by: Paulo Alcantara Cc: Ronnie Sahlberg Cc: Shyam Prasad N Cc: Tom Talpey Cc: Bharath SM Cc: stable@vger.kernel.org --- fs/smb/client/reparse.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c index 8a19dee564b8..616ca2dbfac4 100644 --- a/fs/smb/client/reparse.c +++ b/fs/smb/client/reparse.c @@ -1212,6 +1212,7 @@ static bool posix_reparse_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_open_info_data *data) { struct reparse_nfs_data_buffer *buf = (struct reparse_nfs_data_buffer *)data->reparse.buf; + umode_t ftype; if (buf == NULL) return true; @@ -1227,7 +1228,7 @@ static bool posix_reparse_to_fattr(struct cifs_sb_info *cifs_sb, WARN_ON_ONCE(1); return false; } - fattr->cf_mode |= S_IFCHR; + ftype = S_IFCHR; fattr->cf_rdev = reparse_mkdev(buf->DataBuffer); break; case NFS_SPECFILE_BLK: @@ -1235,22 +1236,23 @@ static bool posix_reparse_to_fattr(struct cifs_sb_info *cifs_sb, WARN_ON_ONCE(1); return false; } - fattr->cf_mode |= S_IFBLK; + ftype = S_IFBLK; fattr->cf_rdev = reparse_mkdev(buf->DataBuffer); break; case NFS_SPECFILE_FIFO: - fattr->cf_mode |= S_IFIFO; + ftype = S_IFIFO; break; case NFS_SPECFILE_SOCK: - fattr->cf_mode |= S_IFSOCK; + ftype = S_IFSOCK; break; case NFS_SPECFILE_LNK: - fattr->cf_mode |= S_IFLNK; + ftype = S_IFLNK; break; default: WARN_ON_ONCE(1); return false; } + fattr->cf_mode = (fattr->cf_mode & ~S_IFMT) | ftype; return true; }