ksmbd: allow a filename to contain colons on SMB3.1.1 posix extensions
authorPhilipp Kerling <pkerling@casix.org>
Wed, 20 Aug 2025 14:24:13 +0000 (16:24 +0200)
committerSteve French <stfrench@microsoft.com>
Sun, 31 Aug 2025 22:48:38 +0000 (17:48 -0500)
If the client sends SMB2_CREATE_POSIX_CONTEXT to ksmbd, allow the filename
to contain a colon (':'). This requires disabling the support for Alternate
Data Streams (ADS), which are denoted by a colon-separated suffix to the
filename on Windows. This should not be an issue, since this concept is not
known to POSIX anyway and the client has to explicitly request a POSIX
context to get this behavior.

Link: https://lore.kernel.org/all/f9401718e2be2ab22058b45a6817db912784ef61.camel@rx2.rx-server.de/
Signed-off-by: Philipp Kerling <pkerling@casix.org>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/server/smb2pdu.c
fs/smb/server/vfs_cache.h

index 0d92ce49aed7bffaaff3a01387c23c0caccf572d..a565fc36cee6df04f6320404485143c1b840bf52 100644 (file)
@@ -2951,18 +2951,19 @@ int smb2_open(struct ksmbd_work *work)
                }
 
                ksmbd_debug(SMB, "converted name = %s\n", name);
-               if (strchr(name, ':')) {
-                       if (!test_share_config_flag(work->tcon->share_conf,
-                                                   KSMBD_SHARE_FLAG_STREAMS)) {
-                               rc = -EBADF;
-                               goto err_out2;
-                       }
-                       rc = parse_stream_name(name, &stream_name, &s_type);
-                       if (rc < 0)
-                               goto err_out2;
-               }
 
                if (posix_ctxt == false) {
+                       if (strchr(name, ':')) {
+                               if (!test_share_config_flag(work->tcon->share_conf,
+                                                       KSMBD_SHARE_FLAG_STREAMS)) {
+                                       rc = -EBADF;
+                                       goto err_out2;
+                               }
+                               rc = parse_stream_name(name, &stream_name, &s_type);
+                               if (rc < 0)
+                                       goto err_out2;
+                       }
+
                        rc = ksmbd_validate_filename(name);
                        if (rc < 0)
                                goto err_out2;
@@ -3443,6 +3444,8 @@ int smb2_open(struct ksmbd_work *work)
        fp->attrib_only = !(req->DesiredAccess & ~(FILE_READ_ATTRIBUTES_LE |
                        FILE_WRITE_ATTRIBUTES_LE | FILE_SYNCHRONIZE_LE));
 
+       fp->is_posix_ctxt = posix_ctxt;
+
        /* fp should be searchable through ksmbd_inode.m_fp_list
         * after daccess, saccess, attrib_only, and stream are
         * initialized.
@@ -5988,7 +5991,7 @@ static int smb2_rename(struct ksmbd_work *work,
        if (IS_ERR(new_name))
                return PTR_ERR(new_name);
 
-       if (strchr(new_name, ':')) {
+       if (fp->is_posix_ctxt == false && strchr(new_name, ':')) {
                int s_type;
                char *xattr_stream_name, *stream_name = NULL;
                size_t xattr_stream_size;
index 0708155b5caf4e56893b9030ca5b5f7b9822cf9f..78b506c5ef03b766a5347489484b2e6668ccf349 100644 (file)
@@ -112,6 +112,8 @@ struct ksmbd_file {
        bool                            is_durable;
        bool                            is_persistent;
        bool                            is_resilient;
+
+       bool                            is_posix_ctxt;
 };
 
 static inline void set_ctx_actor(struct dir_context *ctx,