]> git.ipfire.org Git - thirdparty/linux.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)
committerSteve French <stfrench@microsoft.com>
Tue, 27 May 2025 15:25:12 +0000 (10:25 -0500)
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>
fs/smb/server/smb2pdu.c

index 3a4bffe97b5435da63cc0391521e5507a0c99b4e..4abb6c309458aaae52d3c5bde76ab37504ec8a98 100644 (file)
@@ -2874,7 +2874,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;
@@ -2903,6 +2903,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) {
                name = smb2_get_name((char *)req + le16_to_cpu(req->NameOffset),
                                     le16_to_cpu(req->NameLength),
@@ -2925,9 +2946,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;
@@ -3085,28 +3108,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)) {