From: Sasha Levin Date: Sat, 8 Mar 2025 14:08:41 +0000 (-0500) Subject: Fixes for 6.13 X-Git-Tag: v6.6.82~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=39e59dc0ad9929899e0d0d78228a065030786f15;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.13 Signed-off-by: Sasha Levin --- diff --git a/queue-6.13/cifs-remove-symlink-member-from-cifs_open_info_data-.patch b/queue-6.13/cifs-remove-symlink-member-from-cifs_open_info_data-.patch new file mode 100644 index 0000000000..3b809791b9 --- /dev/null +++ b/queue-6.13/cifs-remove-symlink-member-from-cifs_open_info_data-.patch @@ -0,0 +1,82 @@ +From 7db09b0bddf57b0194eb3226abf04e08ee222b5a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Dec 2024 14:50:38 +0100 +Subject: cifs: Remove symlink member from cifs_open_info_data union +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +[ Upstream commit 65c49767dd4fc058673f9259fda1772fd398eaa7 ] + +Member 'symlink' is part of the union in struct cifs_open_info_data. Its +value is assigned on few places, but is always read through another union +member 'reparse_point'. So to make code more readable, always use only +'reparse_point' member and drop whole union structure. No function change. + +Signed-off-by: Pali Rohár +Acked-by: Paulo Alcantara (Red Hat) +Signed-off-by: Steve French +Stable-dep-of: 9df23801c83d ("smb311: failure to open files of length 1040 when mounting with SMB3.1.1 POSIX extensions") +Signed-off-by: Sasha Levin +--- + fs/smb/client/cifsglob.h | 5 +---- + fs/smb/client/inode.c | 2 +- + fs/smb/client/smb1ops.c | 4 ++-- + 3 files changed, 4 insertions(+), 7 deletions(-) + +diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h +index 1e6085f2f78ee..3877b861529ea 100644 +--- a/fs/smb/client/cifsglob.h ++++ b/fs/smb/client/cifsglob.h +@@ -215,10 +215,7 @@ struct cifs_cred { + + struct cifs_open_info_data { + bool adjust_tz; +- union { +- bool reparse_point; +- bool symlink; +- }; ++ bool reparse_point; + struct { + /* ioctl response buffer */ + struct { +diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c +index 0d149b315a832..4d8effe78be57 100644 +--- a/fs/smb/client/inode.c ++++ b/fs/smb/client/inode.c +@@ -990,7 +990,7 @@ cifs_get_file_info(struct file *filp) + /* TODO: add support to query reparse tag */ + data.adjust_tz = false; + if (data.symlink_target) { +- data.symlink = true; ++ data.reparse_point = true; + data.reparse.tag = IO_REPARSE_TAG_SYMLINK; + } + path = build_path_from_dentry(dentry, page); +diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c +index c70f4961c4eb7..bd791aa54681f 100644 +--- a/fs/smb/client/smb1ops.c ++++ b/fs/smb/client/smb1ops.c +@@ -551,7 +551,7 @@ static int cifs_query_path_info(const unsigned int xid, + int rc; + FILE_ALL_INFO fi = {}; + +- data->symlink = false; ++ data->reparse_point = false; + data->adjust_tz = false; + + /* could do find first instead but this returns more info */ +@@ -592,7 +592,7 @@ static int cifs_query_path_info(const unsigned int xid, + /* Need to check if this is a symbolic link or not */ + tmprc = CIFS_open(xid, &oparms, &oplock, NULL); + if (tmprc == -EOPNOTSUPP) +- data->symlink = true; ++ data->reparse_point = true; + else if (tmprc == 0) + CIFSSMBClose(xid, tcon, fid.netfid); + } +-- +2.39.5 + diff --git a/queue-6.13/series b/queue-6.13/series index b65c7ec462..3fad2bed04 100644 --- a/queue-6.13/series +++ b/queue-6.13/series @@ -1 +1,3 @@ rust-block-fix-formatting-in-gendisk-doc.patch +cifs-remove-symlink-member-from-cifs_open_info_data-.patch +smb311-failure-to-open-files-of-length-1040-when-mou.patch diff --git a/queue-6.13/smb311-failure-to-open-files-of-length-1040-when-mou.patch b/queue-6.13/smb311-failure-to-open-files-of-length-1040-when-mou.patch new file mode 100644 index 0000000000..83d2f9d765 --- /dev/null +++ b/queue-6.13/smb311-failure-to-open-files-of-length-1040-when-mou.patch @@ -0,0 +1,147 @@ +From 8ce8e1b13fa4b829a13245289c3a4c329597e763 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 16 Feb 2025 22:17:54 -0600 +Subject: smb311: failure to open files of length 1040 when mounting with + SMB3.1.1 POSIX extensions + +From: Steve French + +[ Upstream commit 9df23801c83d3e12b4c09be39d37d2be385e52f9 ] + +If a file size has bits 0x410 = ATTR_DIRECTORY | ATTR_REPARSE set +then during queryinfo (stat) the file is regarded as a directory +and subsequent opens can fail. A simple test example is trying +to open any file 1040 bytes long when mounting with "posix" +(SMB3.1.1 POSIX/Linux Extensions). + +The cause of this bug is that Attributes field in smb2_file_all_info +struct occupies the same place that EndOfFile field in +smb311_posix_qinfo, and sometimes the latter struct is incorrectly +processed as if it was the first one. + +Reported-by: Oleh Nykyforchyn +Tested-by: Oleh Nykyforchyn +Acked-by: Paulo Alcantara (Red Hat) +Cc: stable@vger.kernel.org +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/cifsglob.h | 1 + + fs/smb/client/reparse.h | 28 ++++++++++++++++++++++------ + fs/smb/client/smb2inode.c | 4 ++++ + fs/smb/client/smb2ops.c | 3 ++- + 4 files changed, 29 insertions(+), 7 deletions(-) + +diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h +index 3877b861529ea..37b7d84e26913 100644 +--- a/fs/smb/client/cifsglob.h ++++ b/fs/smb/client/cifsglob.h +@@ -216,6 +216,7 @@ struct cifs_cred { + struct cifs_open_info_data { + bool adjust_tz; + bool reparse_point; ++ bool contains_posix_file_info; + struct { + /* ioctl response buffer */ + struct { +diff --git a/fs/smb/client/reparse.h b/fs/smb/client/reparse.h +index ff05b0e75c928..f080f92cb1e74 100644 +--- a/fs/smb/client/reparse.h ++++ b/fs/smb/client/reparse.h +@@ -97,14 +97,30 @@ static inline bool reparse_inode_match(struct inode *inode, + + static inline bool cifs_open_data_reparse(struct cifs_open_info_data *data) + { +- struct smb2_file_all_info *fi = &data->fi; +- u32 attrs = le32_to_cpu(fi->Attributes); ++ u32 attrs; + bool ret; + +- ret = data->reparse_point || (attrs & ATTR_REPARSE); +- if (ret) +- attrs |= ATTR_REPARSE; +- fi->Attributes = cpu_to_le32(attrs); ++ if (data->contains_posix_file_info) { ++ struct smb311_posix_qinfo *fi = &data->posix_fi; ++ ++ attrs = le32_to_cpu(fi->DosAttributes); ++ if (data->reparse_point) { ++ attrs |= ATTR_REPARSE; ++ fi->DosAttributes = cpu_to_le32(attrs); ++ } ++ ++ } else { ++ struct smb2_file_all_info *fi = &data->fi; ++ ++ attrs = le32_to_cpu(fi->Attributes); ++ if (data->reparse_point) { ++ attrs |= ATTR_REPARSE; ++ fi->Attributes = cpu_to_le32(attrs); ++ } ++ } ++ ++ ret = attrs & ATTR_REPARSE; ++ + return ret; + } + +diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c +index 7dfd3eb3847b3..6048b3fed3e78 100644 +--- a/fs/smb/client/smb2inode.c ++++ b/fs/smb/client/smb2inode.c +@@ -648,6 +648,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + switch (cmds[i]) { + case SMB2_OP_QUERY_INFO: + idata = in_iov[i].iov_base; ++ idata->contains_posix_file_info = false; + if (rc == 0 && cfile && cfile->symlink_target) { + idata->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL); + if (!idata->symlink_target) +@@ -671,6 +672,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + break; + case SMB2_OP_POSIX_QUERY_INFO: + idata = in_iov[i].iov_base; ++ idata->contains_posix_file_info = true; + if (rc == 0 && cfile && cfile->symlink_target) { + idata->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL); + if (!idata->symlink_target) +@@ -768,6 +770,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + idata = in_iov[i].iov_base; + idata->reparse.io.iov = *iov; + idata->reparse.io.buftype = resp_buftype[i + 1]; ++ idata->contains_posix_file_info = false; /* BB VERIFY */ + rbuf = reparse_buf_ptr(iov); + if (IS_ERR(rbuf)) { + rc = PTR_ERR(rbuf); +@@ -789,6 +792,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + case SMB2_OP_QUERY_WSL_EA: + if (!rc) { + idata = in_iov[i].iov_base; ++ idata->contains_posix_file_info = false; + qi_rsp = rsp_iov[i + 1].iov_base; + data[0] = (u8 *)qi_rsp + le16_to_cpu(qi_rsp->OutputBufferOffset); + size[0] = le32_to_cpu(qi_rsp->OutputBufferLength); +diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c +index 793e9b2b79d6f..17c3063a9ca5b 100644 +--- a/fs/smb/client/smb2ops.c ++++ b/fs/smb/client/smb2ops.c +@@ -1001,6 +1001,7 @@ static int smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon, + if (!data->symlink_target) + return -ENOMEM; + } ++ data->contains_posix_file_info = false; + return SMB2_query_info(xid, tcon, fid->persistent_fid, fid->volatile_fid, &data->fi); + } + +@@ -5150,7 +5151,7 @@ int __cifs_sfu_make_node(unsigned int xid, struct inode *inode, + FILE_CREATE, CREATE_NOT_DIR | + CREATE_OPTION_SPECIAL, ACL_NO_MODE); + oparms.fid = &fid; +- ++ idata.contains_posix_file_info = false; + rc = server->ops->open(xid, &oparms, &oplock, &idata); + if (rc) + goto out; +-- +2.39.5 +