FAILED: patch "[PATCH] smb: client: fix fattr leaking on wsl_to_fattr() failure" failed to apply to 6.18-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.18-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.18.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 '2026092249-multitude-amigo-b729@gregkh' --subject-prefix 'PATCH 6.18.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/3 smb: client: fix WSL reparse point uid/gid override
From: Paulo Alcantara <[email protected]>
[ Upstream commit cd2b2b57921d4caa7875e83198bb2aa71254328b ]
wsl_to_fattr() unconditionally overwrites cf_uid/cf_gid with values from WSL extended attributes ($LXUID/$LXGID), ignoring the forceuid and forcegid mount options.
Fix this by initializing cf_uid/cf_gid to the mount defaults and gating the $LXUID/$LXGID EA parsing on forceuid/forcegid.
Backport adaptation for Linux 6.18:
Keep the existing S_IFMT clearing from 99daf7535445 when adding the mount-default UID/GID initialization. The stable branch already has that file-type fix, which followed this dependency upstream.
Also include the two wsl_to_fattr() mode-read conversions from e1aeaf79dea5 and include linux/unaligned.h directly. These are the remaining context changes needed for e1253a82bb4c to apply unchanged; the other helper conversions are outside this target's context.
Stable-dep-of: e1253a82bb4c ("smb: client: fix fattr leaking on wsl_to_fattr() failure")
--- fs/smb/client/reparse.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
fs/smb/client/reparse.c +14 -7
@@ -6,6 +6,7 @@#include <linux/fs.h> #include <linux/stat.h> #include <linux/slab.h> +#include <linux/unaligned.h> #include "cifsglob.h" #include "smb2proto.h" #include "cifsproto.h"
@@ -1109,10 +1110,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 :
@@ -1150,15 +1155,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;
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/3 smb: client: fix unaligned access in WSL reparse point parser
From: Paulo Alcantara <[email protected]>
[ Upstream commit e1aeaf79dea51e6065da56924bc07e22d59012ac ]
When wsl_to_fattr() parses WSL extended attributes, it computes a payload pointer from ea->ea_data + ea_name_length + 1. Since the smb2_file_full_ea_info struct is __packed and all WSL xattr names are 6 bytes long, the value pointer always lands at an odd byte offset, never satisfying __le32 or __le64 alignment requirements.
The code then casts this pointer to __le32 * or __le64 * and dereferences it directly, which may cause alignment faults on some architectures.
Replace all such casts with get_unaligned_le32() and get_unaligned_le64() in reparse_mkdev(), wsl_make_kuid(), wsl_make_kgid() and wsl_to_fattr().
Stable-dep-of: e1253a82bb4c ("smb: client: fix fattr leaking on wsl_to_fattr() failure")
--- fs/smb/client/reparse.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
fs/smb/client/reparse.h +4 -3
@@ -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,7 +31,7 @@ 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_flags (cifs_sb) &CIFS_MOUNT_OVERR_UID )return cifs_sb->ctx->linux_uid;
@@ -40,7 +41,7 @@ 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_flags (cifs_sb) &CIFS_MOUNT_OVERR_GID )return cifs_sb->ctx->linux_gid;
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 3/3 smb: client: fix fattr leaking on wsl_to_fattr() failure
In reply to Sasha LevinFrom: 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
@@ -1111,29 +1111,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 ; }
@@ -1157,26 +1158,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.18.y 1/3] smb: client: fix WSL reparse point uid/gid override
In reply to Sasha LevinQuoted 92 lines · Sasha Levin
From: Paulo Alcantara <[email protected]>
[ Upstream commit
cd2b2b57921d4caa7875e83198bb2aa71254328b]
wsl_to_fattr()unconditionally overwrites cf_uid/cf_gid with values from WSL extended attributes ($LXUID/$LXGID), ignoring the forceuid and forcegid mount options.Fix this by initializing cf_uid/cf_gid to the mount defaults and gating the $LXUID/$LXGID EA parsing on forceuid/forcegid.
Reviewed-by Namjae Jeon <[email protected]>Signed-off-by Paulo Alcantara <[email protected]>Cc Ronnie Sahlberg <[email protected]>Cc Shyam Prasad N <[email protected]>Cc Tom Talpey <[email protected]>Cc Bharath SM <[email protected]>Backport adaptation for Linux 6.18:
Keep the existingS_IFMTclearing from99daf7535445when adding the mount-default UID/GID initialization. The stable branch already has that file-type fix, which followed this dependency upstream.Also include the two
wsl_to_fattr()mode-read conversions frome1aeaf79dea5and includelinux/unaligned.hdirectly. These are the remaining context changes needed fore1253a82bb4cto apply unchanged; the other helper conversions are outside this target's context.Stable-dep-of:
e1253a82bb4c("smb: client: fix fattr leaking onwsl_to_fattr()failure")Signed-off-by Sasha Levin <[email protected]>--- fs/smb/client/reparse.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)fs/smb/client/reparse.c +14
-7@@ -6,6 +6,7 @@#include <linux/fs.h> #include <linux/stat.h> #include <linux/slab.h> +#include <linux/unaligned.h> #include "cifsglob.h" #include "smb2proto.h" #include "cifsproto.h" @@ -1109,10 +1110,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 :@@ -1150,15 +1155,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;Signature · 1 line
2.53.0
Does not apply :(