]> 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>
Sun, 6 Jul 2025 08:57:54 +0000 (10: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/smb/server/smb2pdu.c

index ca54ac7ff6ea5efa07df972433fac824661a3370..2f18229ee33c9075e5fe8e7299ee03f52b25db7a 100644 (file)
@@ -2686,7 +2686,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;
@@ -2713,6 +2713,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 == '\\') {
@@ -2744,9 +2765,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;
@@ -2861,28 +2884,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)) {