Commit dc3e0f17 authored by Namjae Jeon's avatar Namjae Jeon Committed by Steve French
Browse files

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



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

Reported-by: default avatarPhilipp Kerling <pkerling@casix.org>
Signed-off-by: default avatarNamjae Jeon <linkinjeon@kernel.org>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 571781eb
Loading
Loading
Loading
Loading
+27 −26
Original line number Diff line number Diff line
@@ -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;
		}

		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)) {