]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
Fix SMB311 posix special file creation to servers which do not advertise reparse...
authorSteve French <stfrench@microsoft.com>
Tue, 15 Jul 2025 03:16:19 +0000 (22:16 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 24 Jul 2025 06:58:26 +0000 (08:58 +0200)
commit 8767cb3fbd514c4cf85b4f516ca30388e846f540 upstream.

Some servers (including Samba), support the SMB3.1.1 POSIX Extensions (which use reparse
points for handling special files) but do not properly advertise file system attribute
FILE_SUPPORTS_REPARSE_POINTS.  Although we don't check for this attribute flag when
querying special file information, we do check it when creating special files which
causes them to fail unnecessarily.   If we have negotiated SMB3.1.1 POSIX Extensions
with the server we can expect the server to support creating special files via
reparse points, and even if the server fails the operation due to really forbidding
creating special files, then it should be no problem and is more likely to return a
more accurate rc in any case (e.g. EACCES instead of EOPNOTSUPP).

Allow creating special files as long as the server supports either reparse points
or the SMB3.1.1 POSIX Extensions (note that if the "sfu" mount option is specified
it uses a different way of storing special files that does not rely on reparse points).

Cc: <stable@vger.kernel.org>
Fixes: 6c06be908ca19 ("cifs: Check if server supports reparse points before using them")
Acked-by: Ralph Boehme <slow@samba.org>
Acked-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/smb/client/smb2inode.c
fs/smb/client/smb2ops.c

index 2a3e46b8e15af6a67b3836440ba0d7823a0ba408..a11a2a693c519447b099fafd74be241ae422045a 100644 (file)
@@ -1346,7 +1346,8 @@ struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data,
         * empty object on the server.
         */
        if (!(le32_to_cpu(tcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS))
-               return ERR_PTR(-EOPNOTSUPP);
+               if (!tcon->posix_extensions)
+                       return ERR_PTR(-EOPNOTSUPP);
 
        oparms = CIFS_OPARMS(cifs_sb, tcon, full_path,
                             SYNCHRONIZE | DELETE |
index 2fe8eeb98535631e7e70b226617707827ec58999..f25fc5f751c2c2abdd3359c8bfc12b04f628e620 100644 (file)
@@ -5246,7 +5246,8 @@ static int smb2_make_node(unsigned int xid, struct inode *inode,
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
                rc = cifs_sfu_make_node(xid, inode, dentry, tcon,
                                        full_path, mode, dev);
-       } else if (le32_to_cpu(tcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS) {
+       } else if ((le32_to_cpu(tcon->fsAttrInfo.Attributes) & FILE_SUPPORTS_REPARSE_POINTS)
+               || (tcon->posix_extensions)) {
                rc = smb2_mknod_reparse(xid, inode, dentry, tcon,
                                        full_path, mode, dev);
        }