]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ksmbd: allow a filename to contain special characters on SMB3.1.1 posix extension
authorNamjae Jeon <linkinjeon@kernel.org>
Tue, 27 May 2025 02:23:01 +0000 (11:23 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 10 Jul 2025 13:57:32 +0000 (15:57 +0200)
[ Upstream commit dc3e0f17f74558e8a2fce00608855f050de10230 ]

If client send SMB2_CREATE_POSIX_CONTEXT to ksmbd, Allow a filename
to contain special characters.

Reported-by: Philipp Kerling <pkerling@casix.org>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/ksmbd/smb2pdu.c

index b21601c0a457c9ce2e36f6186308a4867a495b9e..76334a983cd25cd78ff604717f0a24bf2f30ef50 100644 (file)
@@ -2679,7 +2679,7 @@ int smb2_open(struct ksmbd_work *work)
        int req_op_level = 0, open_flags = 0, may_flags = 0, file_info = 0;
        int rc = 0;
        int contxt_cnt = 0, query_disk_id = 0;
-       int maximal_access_ctxt = 0, posix_ctxt = 0;
+       bool maximal_access_ctxt = false, posix_ctxt = false;
        int s_type = 0;
        int next_off = 0;
        char *name = NULL;
@@ -2706,6 +2706,27 @@ int smb2_open(struct ksmbd_work *work)
                return create_smb2_pipe(work);
        }
 
+       if (req->CreateContextsOffset && tcon->posix_extensions) {
+               context = smb2_find_context_vals(req, SMB2_CREATE_TAG_POSIX, 16);
+               if (IS_ERR(context)) {
+                       rc = PTR_ERR(context);
+                       goto err_out2;
+               } else if (context) {
+                       struct create_posix *posix = (struct create_posix *)context;
+
+                       if (le16_to_cpu(context->DataOffset) +
+                               le32_to_cpu(context->DataLength) <
+                           sizeof(struct create_posix) - 4) {
+                               rc = -EINVAL;
+                               goto err_out2;
+                       }
+                       ksmbd_debug(SMB, "get posix context\n");
+
+                       posix_mode = le32_to_cpu(posix->Mode);
+                       posix_ctxt = true;
+               }
+       }
+
        if (req->NameLength) {
                if ((req->CreateOptions & FILE_DIRECTORY_FILE_LE) &&
                    *(char *)req->Buffer == '\\') {
@@ -2737,9 +2758,11 @@ int smb2_open(struct ksmbd_work *work)
                                goto err_out2;
                }
 
-               rc = ksmbd_validate_filename(name);
-               if (rc < 0)
-                       goto err_out2;
+               if (posix_ctxt == false) {
+                       rc = ksmbd_validate_filename(name);
+                       if (rc < 0)
+                               goto err_out2;
+               }
 
                if (ksmbd_share_veto_filename(share, name)) {
                        rc = -ENOENT;
@@ -2854,28 +2877,6 @@ int smb2_open(struct ksmbd_work *work)
                        rc = -EBADF;
                        goto err_out2;
                }
-
-               if (tcon->posix_extensions) {
-                       context = smb2_find_context_vals(req,
-                                                        SMB2_CREATE_TAG_POSIX, 16);
-                       if (IS_ERR(context)) {
-                               rc = PTR_ERR(context);
-                               goto err_out2;
-                       } else if (context) {
-                               struct create_posix *posix =
-                                       (struct create_posix *)context;
-                               if (le16_to_cpu(context->DataOffset) +
-                                   le32_to_cpu(context->DataLength) <
-                                   sizeof(struct create_posix) - 4) {
-                                       rc = -EINVAL;
-                                       goto err_out2;
-                               }
-                               ksmbd_debug(SMB, "get posix context\n");
-
-                               posix_mode = le32_to_cpu(posix->Mode);
-                               posix_ctxt = 1;
-                       }
-               }
        }
 
        if (ksmbd_override_fsids(work)) {