Commit 90c8ce31 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag '6.3-rc3-ksmbd-smb3-server-fixes' of git://git.samba.org/ksmbd

Pull ksmbd server fixes from Steve French:

 - return less confusing messages on unsupported dialects
   (STATUS_NOT_SUPPORTED instead of I/O error)

 - fix for overly frequent inactive session termination

 - fix refcount leak

 - fix bounds check problems found by static checkers

 - fix to advertise named stream support correctly

 - Fix AES256 signing bug when connected to from MacOS

* tag '6.3-rc3-ksmbd-smb3-server-fixes' of git://git.samba.org/ksmbd:
  ksmbd: return unsupported error on smb1 mount
  ksmbd: return STATUS_NOT_SUPPORTED on unsupported smb2.0 dialect
  ksmbd: don't terminate inactive sessions after a few seconds
  ksmbd: fix possible refcount leak in smb2_open()
  ksmbd: add low bound validation to FSCTL_QUERY_ALLOCATED_RANGES
  ksmbd: add low bound validation to FSCTL_SET_ZERO_DATA
  ksmbd: set FILE_NAMED_STREAMS attribute in FS_ATTRIBUTE_INFORMATION
  ksmbd: fix wrong signingkey creation when encryption is AES256
parents e76db6e5 39b291b8
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -727,8 +727,9 @@ static int generate_key(struct ksmbd_conn *conn, struct ksmbd_session *sess,
		goto smb3signkey_ret;
	}

	if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
	    conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
	if (key_size == SMB3_ENC_DEC_KEY_SIZE &&
	    (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
	     conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
		rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L256, 4);
	else
		rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L128, 4);
+4 −7
Original line number Diff line number Diff line
@@ -298,7 +298,7 @@ int ksmbd_conn_handler_loop(void *p)
		kvfree(conn->request_buf);
		conn->request_buf = NULL;

		size = t->ops->read(t, hdr_buf, sizeof(hdr_buf));
		size = t->ops->read(t, hdr_buf, sizeof(hdr_buf), -1);
		if (size != sizeof(hdr_buf))
			break;

@@ -319,13 +319,10 @@ int ksmbd_conn_handler_loop(void *p)
		}

		/*
		 * Check if pdu size is valid (min : smb header size,
		 * max : 0x00FFFFFF).
		 * Check maximum pdu size(0x00FFFFFF).
		 */
		if (pdu_size < __SMB2_HEADER_STRUCTURE_SIZE ||
		    pdu_size > MAX_STREAM_PROT_LEN) {
		if (pdu_size > MAX_STREAM_PROT_LEN)
			break;
		}

		/* 4 for rfc1002 length field */
		size = pdu_size + 4;
@@ -344,7 +341,7 @@ int ksmbd_conn_handler_loop(void *p)
		 * We already read 4 bytes to find out PDU size, now
		 * read in PDU
		 */
		size = t->ops->read(t, conn->request_buf + 4, pdu_size);
		size = t->ops->read(t, conn->request_buf + 4, pdu_size, 2);
		if (size < 0) {
			pr_err("sock_read failed: %d\n", size);
			break;
+2 −1
Original line number Diff line number Diff line
@@ -114,7 +114,8 @@ struct ksmbd_transport_ops {
	int (*prepare)(struct ksmbd_transport *t);
	void (*disconnect)(struct ksmbd_transport *t);
	void (*shutdown)(struct ksmbd_transport *t);
	int (*read)(struct ksmbd_transport *t, char *buf, unsigned int size);
	int (*read)(struct ksmbd_transport *t, char *buf,
		    unsigned int size, int max_retries);
	int (*writev)(struct ksmbd_transport *t, struct kvec *iovs, int niov,
		      int size, bool need_invalidate_rkey,
		      unsigned int remote_key);
+15 −5
Original line number Diff line number Diff line
@@ -2977,8 +2977,11 @@ int smb2_open(struct ksmbd_work *work)
							sizeof(struct smb_acl) +
							sizeof(struct smb_ace) * ace_num * 2,
							GFP_KERNEL);
					if (!pntsd)
					if (!pntsd) {
						posix_acl_release(fattr.cf_acls);
						posix_acl_release(fattr.cf_dacls);
						goto err_out;
					}

					rc = build_sec_desc(idmap,
							    pntsd, NULL, 0,
@@ -4934,6 +4937,10 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,

		info->Attributes |= cpu_to_le32(server_conf.share_fake_fscaps);

		if (test_share_config_flag(work->tcon->share_conf,
		    KSMBD_SHARE_FLAG_STREAMS))
			info->Attributes |= cpu_to_le32(FILE_NAMED_STREAMS);

		info->MaxPathNameComponentLength = cpu_to_le32(stfs.f_namelen);
		len = smbConvertToUTF16((__le16 *)info->FileSystemName,
					"NTFS", PATH_MAX, conn->local_nls, 0);
@@ -7444,13 +7451,16 @@ static int fsctl_query_allocated_ranges(struct ksmbd_work *work, u64 id,
	if (in_count == 0)
		return -EINVAL;

	start = le64_to_cpu(qar_req->file_offset);
	length = le64_to_cpu(qar_req->length);

	if (start < 0 || length < 0)
		return -EINVAL;

	fp = ksmbd_lookup_fd_fast(work, id);
	if (!fp)
		return -ENOENT;

	start = le64_to_cpu(qar_req->file_offset);
	length = le64_to_cpu(qar_req->length);

	ret = ksmbd_vfs_fqar_lseek(fp, start, length,
				   qar_rsp, in_count, out_count);
	if (ret && ret != -E2BIG)
@@ -7751,7 +7761,7 @@ int smb2_ioctl(struct ksmbd_work *work)

		off = le64_to_cpu(zero_data->FileOffset);
		bfz = le64_to_cpu(zero_data->BeyondFinalZero);
		if (off > bfz) {
		if (off < 0 || bfz < 0 || off > bfz) {
			ret = -EINVAL;
			goto out;
		}
+22 −5
Original line number Diff line number Diff line
@@ -434,7 +434,7 @@ int ksmbd_extract_shortname(struct ksmbd_conn *conn, const char *longname,

static int __smb2_negotiate(struct ksmbd_conn *conn)
{
	return (conn->dialect >= SMB21_PROT_ID &&
	return (conn->dialect >= SMB20_PROT_ID &&
		conn->dialect <= SMB311_PROT_ID);
}

@@ -442,9 +442,26 @@ static int smb_handle_negotiate(struct ksmbd_work *work)
{
	struct smb_negotiate_rsp *neg_rsp = work->response_buf;

	ksmbd_debug(SMB, "Unsupported SMB protocol\n");
	neg_rsp->hdr.Status.CifsError = STATUS_INVALID_LOGON_TYPE;
	return -EINVAL;
	ksmbd_debug(SMB, "Unsupported SMB1 protocol\n");

	/*
	 * Remove 4 byte direct TCP header, add 2 byte bcc and
	 * 2 byte DialectIndex.
	 */
	*(__be32 *)work->response_buf =
		cpu_to_be32(sizeof(struct smb_hdr) - 4 + 2 + 2);
	neg_rsp->hdr.Status.CifsError = STATUS_SUCCESS;

	neg_rsp->hdr.Command = SMB_COM_NEGOTIATE;
	*(__le32 *)neg_rsp->hdr.Protocol = SMB1_PROTO_NUMBER;
	neg_rsp->hdr.Flags = SMBFLG_RESPONSE;
	neg_rsp->hdr.Flags2 = SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS |
		SMBFLG2_EXT_SEC | SMBFLG2_IS_LONG_NAME;

	neg_rsp->hdr.WordCount = 1;
	neg_rsp->DialectIndex = cpu_to_le16(work->conn->dialect);
	neg_rsp->ByteCount = 0;
	return 0;
}

int ksmbd_smb_negotiate_common(struct ksmbd_work *work, unsigned int command)
@@ -465,7 +482,7 @@ int ksmbd_smb_negotiate_common(struct ksmbd_work *work, unsigned int command)
		}
	}

	if (command == SMB2_NEGOTIATE_HE && __smb2_negotiate(conn)) {
	if (command == SMB2_NEGOTIATE_HE) {
		ret = smb2_handle_negotiate(work);
		init_smb2_neg_rsp(work);
		return ret;
Loading