Commit 109daa23 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag '6.13-rc-ksmbd-server-fixes' of git://git.samba.org/ksmbd

Pull smb server updates from Steve French:

 - fix use after free due to race in ksmd workqueue handler

 - debugging improvements

 - fix incorrectly formatted response when client attempts SMB1

 - improve memory allocation to reduce chance of OOM

 - improve delays between retries when killing sessions

* tag '6.13-rc-ksmbd-server-fixes' of git://git.samba.org/ksmbd:
  ksmbd: fix use-after-free in SMB request handling
  ksmbd: add debug print for pending request during server shutdown
  ksmbd: add netdev-up/down event debug print
  ksmbd: add debug prints to know what smb2 requests were received
  ksmbd: add debug print for rdma capable
  ksmbd: use msleep instaed of schedule_timeout_interruptible()
  ksmbd: use __GFP_RETRY_MAYFAIL
  ksmbd: fix malformed unsupported smb1 negotiate response
parents d8b78066 9a8c5d89
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -104,7 +104,7 @@ int build_spnego_ntlmssp_neg_blob(unsigned char **pbuffer, u16 *buflen,
			oid_len + ntlmssp_len) * 2 +
			neg_result_len + oid_len + ntlmssp_len;

	buf = kmalloc(total_len, GFP_KERNEL);
	buf = kmalloc(total_len, KSMBD_DEFAULT_GFP);
	if (!buf)
		return -ENOMEM;

@@ -140,7 +140,7 @@ int build_spnego_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen,
	int total_len = 4 + compute_asn_hdr_len_bytes(neg_result_len) * 2 +
		neg_result_len;

	buf = kmalloc(total_len, GFP_KERNEL);
	buf = kmalloc(total_len, KSMBD_DEFAULT_GFP);
	if (!buf)
		return -ENOMEM;

@@ -217,7 +217,7 @@ static int ksmbd_neg_token_alloc(void *context, size_t hdrlen,
	if (!vlen)
		return -EINVAL;

	conn->mechToken = kmemdup_nul(value, vlen, GFP_KERNEL);
	conn->mechToken = kmemdup_nul(value, vlen, KSMBD_DEFAULT_GFP);
	if (!conn->mechToken)
		return -ENOMEM;

+10 −9
Original line number Diff line number Diff line
@@ -151,7 +151,7 @@ static int calc_ntlmv2_hash(struct ksmbd_conn *conn, struct ksmbd_session *sess,

	/* convert user_name to unicode */
	len = strlen(user_name(sess->user));
	uniname = kzalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
	uniname = kzalloc(2 + UNICODE_LEN(len), KSMBD_DEFAULT_GFP);
	if (!uniname) {
		ret = -ENOMEM;
		goto out;
@@ -175,7 +175,7 @@ static int calc_ntlmv2_hash(struct ksmbd_conn *conn, struct ksmbd_session *sess,

	/* Convert domain name or conn name to unicode and uppercase */
	len = strlen(dname);
	domain = kzalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
	domain = kzalloc(2 + UNICODE_LEN(len), KSMBD_DEFAULT_GFP);
	if (!domain) {
		ret = -ENOMEM;
		goto out;
@@ -254,7 +254,7 @@ int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
	}

	len = CIFS_CRYPTO_KEY_SIZE + blen;
	construct = kzalloc(len, GFP_KERNEL);
	construct = kzalloc(len, KSMBD_DEFAULT_GFP);
	if (!construct) {
		rc = -ENOMEM;
		goto out;
@@ -361,7 +361,7 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
		if (sess_key_len > CIFS_KEY_SIZE)
			return -EINVAL;

		ctx_arc4 = kmalloc(sizeof(*ctx_arc4), GFP_KERNEL);
		ctx_arc4 = kmalloc(sizeof(*ctx_arc4), KSMBD_DEFAULT_GFP);
		if (!ctx_arc4)
			return -ENOMEM;

@@ -451,7 +451,7 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,

	chgblob->NegotiateFlags = cpu_to_le32(flags);
	len = strlen(ksmbd_netbios_name());
	name = kmalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
	name = kmalloc(2 + UNICODE_LEN(len), KSMBD_DEFAULT_GFP);
	if (!name)
		return -ENOMEM;

@@ -1043,7 +1043,7 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
	if (!nvec)
		return NULL;

	nr_entries = kcalloc(nvec, sizeof(int), GFP_KERNEL);
	nr_entries = kcalloc(nvec, sizeof(int), KSMBD_DEFAULT_GFP);
	if (!nr_entries)
		return NULL;

@@ -1063,7 +1063,8 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
	/* Add two entries for transform header and signature */
	total_entries += 2;

	sg = kmalloc_array(total_entries, sizeof(struct scatterlist), GFP_KERNEL);
	sg = kmalloc_array(total_entries, sizeof(struct scatterlist),
			   KSMBD_DEFAULT_GFP);
	if (!sg) {
		kfree(nr_entries);
		return NULL;
@@ -1163,7 +1164,7 @@ int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
		goto free_ctx;
	}

	req = aead_request_alloc(tfm, GFP_KERNEL);
	req = aead_request_alloc(tfm, KSMBD_DEFAULT_GFP);
	if (!req) {
		rc = -ENOMEM;
		goto free_ctx;
@@ -1182,7 +1183,7 @@ int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
	}

	iv_len = crypto_aead_ivsize(tfm);
	iv = kzalloc(iv_len, GFP_KERNEL);
	iv = kzalloc(iv_len, KSMBD_DEFAULT_GFP);
	if (!iv) {
		rc = -ENOMEM;
		goto free_sg;
+4 −3
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ struct ksmbd_conn *ksmbd_conn_alloc(void)
{
	struct ksmbd_conn *conn;

	conn = kzalloc(sizeof(struct ksmbd_conn), GFP_KERNEL);
	conn = kzalloc(sizeof(struct ksmbd_conn), KSMBD_DEFAULT_GFP);
	if (!conn)
		return NULL;

@@ -359,7 +359,7 @@ int ksmbd_conn_handler_loop(void *p)
		/* 4 for rfc1002 length field */
		/* 1 for implied bcc[0] */
		size = pdu_size + 4 + 1;
		conn->request_buf = kvmalloc(size, GFP_KERNEL);
		conn->request_buf = kvmalloc(size, KSMBD_DEFAULT_GFP);
		if (!conn->request_buf)
			break;

@@ -404,6 +404,7 @@ int ksmbd_conn_handler_loop(void *p)
out:
	ksmbd_conn_set_releasing(conn);
	/* Wait till all reference dropped to the Server object*/
	ksmbd_debug(CONN, "Wait for all pending requests(%d)\n", atomic_read(&conn->r_count));
	wait_event(conn->r_count_q, atomic_read(&conn->r_count) == 0);

	if (IS_ENABLED(CONFIG_UNICODE))
@@ -462,7 +463,7 @@ static void stop_sessions(void)
	up_read(&conn_list_lock);

	if (!list_empty(&conn_list)) {
		schedule_timeout_interruptible(HZ / 10); /* 100ms */
		msleep(100);
		goto again;
	}
}
+3 −3
Original line number Diff line number Diff line
@@ -89,7 +89,7 @@ static struct shash_desc *alloc_shash_desc(int id)
		return NULL;

	shash = kzalloc(sizeof(*shash) + crypto_shash_descsize(tfm),
			GFP_KERNEL);
			KSMBD_DEFAULT_GFP);
	if (!shash)
		crypto_free_shash(tfm);
	else
@@ -133,7 +133,7 @@ static struct ksmbd_crypto_ctx *ksmbd_find_crypto_ctx(void)
		ctx_list.avail_ctx++;
		spin_unlock(&ctx_list.ctx_lock);

		ctx = kzalloc(sizeof(struct ksmbd_crypto_ctx), GFP_KERNEL);
		ctx = kzalloc(sizeof(struct ksmbd_crypto_ctx), KSMBD_DEFAULT_GFP);
		if (!ctx) {
			spin_lock(&ctx_list.ctx_lock);
			ctx_list.avail_ctx--;
@@ -258,7 +258,7 @@ int ksmbd_crypto_create(void)
	init_waitqueue_head(&ctx_list.ctx_wait);
	ctx_list.avail_ctx = 1;

	ctx = kzalloc(sizeof(struct ksmbd_crypto_ctx), GFP_KERNEL);
	ctx = kzalloc(sizeof(struct ksmbd_crypto_ctx), KSMBD_DEFAULT_GFP);
	if (!ctx)
		return -ENOMEM;
	list_add(&ctx->list, &ctx_list.idle_ctx);
+2 −0
Original line number Diff line number Diff line
@@ -44,4 +44,6 @@ extern int ksmbd_debug_types;

#define UNICODE_LEN(x)		((x) * 2)

#define KSMBD_DEFAULT_GFP	(GFP_KERNEL | __GFP_RETRY_MAYFAIL)

#endif /* __KSMBD_GLOB_H */
Loading