ksmbd: allow a filename to contain special characters on SMB3.1.1 posix extension

[ 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>
This commit is contained in:
Namjae Jeon
2025-05-27 11:23:01 +09:00
committed by Greg Kroah-Hartman
parent ad804e3648
commit f72093f270

View File

@@ -2862,7 +2862,7 @@ int smb2_open(struct ksmbd_work *work)
int req_op_level = 0, open_flags = 0, may_flags = 0, file_info = 0; int req_op_level = 0, open_flags = 0, may_flags = 0, file_info = 0;
int rc = 0; int rc = 0;
int contxt_cnt = 0, query_disk_id = 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 s_type = 0;
int next_off = 0; int next_off = 0;
char *name = NULL; char *name = NULL;
@@ -2889,6 +2889,27 @@ int smb2_open(struct ksmbd_work *work)
return create_smb2_pipe(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->NameLength) {
name = smb2_get_name((char *)req + le16_to_cpu(req->NameOffset), name = smb2_get_name((char *)req + le16_to_cpu(req->NameOffset),
le16_to_cpu(req->NameLength), le16_to_cpu(req->NameLength),
@@ -2911,9 +2932,11 @@ int smb2_open(struct ksmbd_work *work)
goto err_out2; goto err_out2;
} }
rc = ksmbd_validate_filename(name); if (posix_ctxt == false) {
if (rc < 0) rc = ksmbd_validate_filename(name);
goto err_out2; if (rc < 0)
goto err_out2;
}
if (ksmbd_share_veto_filename(share, name)) { if (ksmbd_share_veto_filename(share, name)) {
rc = -ENOENT; rc = -ENOENT;
@@ -3071,28 +3094,6 @@ int smb2_open(struct ksmbd_work *work)
rc = -EBADF; rc = -EBADF;
goto err_out2; 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)) { if (ksmbd_override_fsids(work)) {