FAILED: patch "[PATCH] smb311: failure to open files of length 1040 when mounting" failed to apply to 6.12-stable tree
Subsystems (2)
[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 9df23801c83d3e12b4c09be39d37d2be385e52f9
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2025022445-uneasily-outwit-926d@gregkh' --subject-prefix 'PATCH 6.12.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 9df23801c83d3e12b4c09be39d37d2be385e52f9 Mon Sep 17 00:00:00 2001
From: Steve French <[email protected]>
Date: Sun, 16 Feb 2025 22:17:54 -0600
Subject: [PATCH] smb311: failure to open files of length 1040 when mounting
with SMB3.1.1 POSIX extensions
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.
fs/smb/client/cifsglob.h +1 -0
@@ -253,6 +253,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 {
fs/smb/client/reparse.h +22 -6
@@ -99,14 +99,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; }
fs/smb/client/smb2inode.c +4 -0
@@ -650,6 +650,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)
@@ -673,6 +674,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)
@@ -770,6 +772,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);
@@ -791,6 +794,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);
fs/smb/client/smb2ops.c +2 -1
@@ -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); }
@@ -5146,7 +5147,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;