Commit 71b1543c authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag '6.9-rc5-ksmbd-fixes' of git://git.samba.org/ksmbd

Pull smb server fixes from Steve French:
 "Five ksmbd server fixes, most also for stable:

   - rename fix

   - two fixes for potential out of bounds

   - fix for connections from MacOS (padding in close response)

   - fix for when to enable persistent handles"

* tag '6.9-rc5-ksmbd-fixes' of git://git.samba.org/ksmbd:
  ksmbd: add continuous availability share parameter
  ksmbd: common: use struct_group_attr instead of struct_group for network_open_info
  ksmbd: clear RENAME_NOREPLACE before calling vfs_rename
  ksmbd: validate request buffer size in smb2_allocate_rsp_buf()
  ksmbd: fix slab-out-of-bounds in smb2_allocate_rsp_buf
parents a2c63a3f e9d8c2f9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -711,7 +711,7 @@ struct smb2_close_rsp {
	__le16 StructureSize; /* 60 */
	__le16 Flags;
	__le32 Reserved;
	struct_group(network_open_info,
	struct_group_attr(network_open_info, __packed,
		__le64 CreationTime;
		__le64 LastAccessTime;
		__le64 LastWriteTime;
+18 −17
Original line number Diff line number Diff line
@@ -357,6 +357,7 @@ enum KSMBD_TREE_CONN_STATUS {
#define KSMBD_SHARE_FLAG_ACL_XATTR			BIT(13)
#define KSMBD_SHARE_FLAG_UPDATE				BIT(14)
#define KSMBD_SHARE_FLAG_CROSSMNT			BIT(15)
#define KSMBD_SHARE_FLAG_CONTINUOUS_AVAILABILITY	BIT(16)

/*
 * Tree connect request flags.
+5 −8
Original line number Diff line number Diff line
@@ -167,20 +167,17 @@ static void __handle_ksmbd_work(struct ksmbd_work *work,
	int rc;
	bool is_chained = false;

	if (conn->ops->allocate_rsp_buf(work))
		return;

	if (conn->ops->is_transform_hdr &&
	    conn->ops->is_transform_hdr(work->request_buf)) {
		rc = conn->ops->decrypt_req(work);
		if (rc < 0) {
			conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
			goto send;
		}

		if (rc < 0)
			return;
		work->encrypted = true;
	}

	if (conn->ops->allocate_rsp_buf(work))
		return;

	rc = conn->ops->init_rsp_hdr(work);
	if (rc) {
		/* either uid or tid is not correct */
+13 −2
Original line number Diff line number Diff line
@@ -535,6 +535,10 @@ int smb2_allocate_rsp_buf(struct ksmbd_work *work)
	if (cmd == SMB2_QUERY_INFO_HE) {
		struct smb2_query_info_req *req;

		if (get_rfc1002_len(work->request_buf) <
		    offsetof(struct smb2_query_info_req, OutputBufferLength))
			return -EINVAL;

		req = smb2_get_msg(work->request_buf);
		if ((req->InfoType == SMB2_O_INFO_FILE &&
		     (req->FileInfoClass == FILE_FULL_EA_INFORMATION ||
@@ -1984,6 +1988,11 @@ int smb2_tree_connect(struct ksmbd_work *work)
	write_unlock(&sess->tree_conns_lock);
	rsp->StructureSize = cpu_to_le16(16);
out_err1:
	if (server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE &&
	    test_share_config_flag(share,
				   KSMBD_SHARE_FLAG_CONTINUOUS_AVAILABILITY))
		rsp->Capabilities = SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY;
	else
		rsp->Capabilities = 0;
	rsp->Reserved = 0;
	/* default manual caching */
@@ -3498,7 +3507,9 @@ int smb2_open(struct ksmbd_work *work)
	memcpy(fp->client_guid, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE);

	if (dh_info.type == DURABLE_REQ_V2 || dh_info.type == DURABLE_REQ) {
		if (dh_info.type == DURABLE_REQ_V2 && dh_info.persistent)
		if (dh_info.type == DURABLE_REQ_V2 && dh_info.persistent &&
		    test_share_config_flag(work->tcon->share_conf,
					   KSMBD_SHARE_FLAG_CONTINUOUS_AVAILABILITY))
			fp->is_persistent = true;
		else
			fp->is_durable = true;
+5 −0
Original line number Diff line number Diff line
@@ -754,10 +754,15 @@ int ksmbd_vfs_rename(struct ksmbd_work *work, const struct path *old_path,
		goto out4;
	}

	/*
	 * explicitly handle file overwrite case, for compatibility with
	 * filesystems that may not support rename flags (e.g: fuse)
	 */
	if ((flags & RENAME_NOREPLACE) && d_is_positive(new_dentry)) {
		err = -EEXIST;
		goto out4;
	}
	flags &= ~(RENAME_NOREPLACE);

	if (old_child == trap) {
		err = -EINVAL;