Unverified Commit 53809f3a authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!2097 Fixed 4 CVEs of the ksmbd

Merge Pull Request from: @ci-robot 
 
PR sync from: ZhaoLong Wang <wangzhaolong1@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/L3MCIVXDEBMKHS2PZ4G3JB2X6CDATDEB/ 
CVE-2023-32247
CVE-2023-32251
CVE-2023-32253
CVE-2023-32249

Namjae Jeon (4):
  ksmbd: destroy expired sessions
  ksmbd: block asynchronous requests when making a delay on session
    setup
  ksmbd: fix deadlock in ksmbd_find_crypto_ctx()
  ksmbd: not allow guest user on multichannel


-- 
2.34.3
 
https://gitee.com/src-openeuler/kernel/issues/I74FHK
https://gitee.com/src-openeuler/kernel/issues/I74FMP
https://gitee.com/src-openeuler/kernel/issues/I74FP0
https://gitee.com/src-openeuler/kernel/issues/I74FIN 
 
Link:https://gitee.com/openeuler/kernel/pulls/2097

 

Reviewed-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parents 37a3e8b9 c77a3939
Loading
Loading
Loading
Loading
+11 −8
Original line number Diff line number Diff line
@@ -220,22 +220,22 @@ int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
{
	char ntlmv2_hash[CIFS_ENCPWD_SIZE];
	char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE];
	struct ksmbd_crypto_ctx *ctx;
	struct ksmbd_crypto_ctx *ctx = NULL;
	char *construct = NULL;
	int rc, len;

	ctx = ksmbd_crypto_ctx_find_hmacmd5();
	if (!ctx) {
		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
		return -ENOMEM;
	}

	rc = calc_ntlmv2_hash(conn, sess, ntlmv2_hash, domain_name);
	if (rc) {
		ksmbd_debug(AUTH, "could not get v2 hash rc %d\n", rc);
		goto out;
	}

	ctx = ksmbd_crypto_ctx_find_hmacmd5();
	if (!ctx) {
		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
		return -ENOMEM;
	}

	rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
				 ntlmv2_hash,
				 CIFS_HMAC_MD5_HASH_SIZE);
@@ -271,6 +271,8 @@ int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
		ksmbd_debug(AUTH, "Could not generate md5 hash\n");
		goto out;
	}
	ksmbd_release_crypto_ctx(ctx);
	ctx = NULL;

	rc = ksmbd_gen_sess_key(sess, ntlmv2_hash, ntlmv2_rsp);
	if (rc) {
@@ -281,6 +283,7 @@ int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
	if (memcmp(ntlmv2->ntlmv2_hash, ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE) != 0)
		rc = -EINVAL;
out:
	if (ctx)
		ksmbd_release_crypto_ctx(ctx);
	kfree(construct);
	return rc;
+37 −31
Original line number Diff line number Diff line
@@ -172,70 +172,73 @@ static struct ksmbd_session *__session_lookup(unsigned long long id)
	struct ksmbd_session *sess;

	hash_for_each_possible(sessions_table, sess, hlist, id) {
		if (id == sess->id)
		if (id == sess->id) {
			sess->last_active = jiffies;
			return sess;
		}
	}
	return NULL;
}

static void ksmbd_expire_session(struct ksmbd_conn *conn)
{
	unsigned long id;
	struct ksmbd_session *sess;

	xa_for_each(&conn->sessions, id, sess) {
		if (sess->state != SMB2_SESSION_VALID ||
		    time_after(jiffies,
			       sess->last_active + SMB2_SESSION_TIMEOUT)) {
			xa_erase(&conn->sessions, sess->id);
			ksmbd_session_destroy(sess);
			continue;
		}
	}
}

int ksmbd_session_register(struct ksmbd_conn *conn,
			   struct ksmbd_session *sess)
{
	sess->dialect = conn->dialect;
	memcpy(sess->ClientGUID, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE);
	ksmbd_expire_session(conn);
	return xa_err(xa_store(&conn->sessions, sess->id, sess, GFP_KERNEL));
}

static int ksmbd_chann_del(struct ksmbd_conn *conn, struct ksmbd_session *sess)
static void ksmbd_chann_del(struct ksmbd_conn *conn, struct ksmbd_session *sess)
{
	struct channel *chann;

	chann = xa_erase(&sess->ksmbd_chann_list, (long)conn);
	if (!chann)
		return -ENOENT;
		return;

	kfree(chann);

	return 0;
}

void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
{
	struct ksmbd_session *sess;

	if (conn->binding) {
		int bkt;

		down_write(&sessions_table_lock);
		hash_for_each(sessions_table, bkt, sess, hlist) {
			if (!ksmbd_chann_del(conn, sess)) {
				up_write(&sessions_table_lock);
				goto sess_destroy;
			}
		}
		up_write(&sessions_table_lock);
	} else {
	unsigned long id;

	xa_for_each(&conn->sessions, id, sess) {
			if (!ksmbd_chann_del(conn, sess))
				goto sess_destroy;
		}
	}

	return;

sess_destroy:
		ksmbd_chann_del(conn, sess);
		if (xa_empty(&sess->ksmbd_chann_list)) {
			xa_erase(&conn->sessions, sess->id);
			ksmbd_session_destroy(sess);
		}
	}
}

struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
					   unsigned long long id)
{
	return xa_load(&conn->sessions, id);
	struct ksmbd_session *sess;

	sess = xa_load(&conn->sessions, id);
	if (sess)
		sess->last_active = jiffies;
	return sess;
}

struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long id)
@@ -244,6 +247,8 @@ struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long id)

	down_read(&sessions_table_lock);
	sess = __session_lookup(id);
	if (sess)
		sess->last_active = jiffies;
	up_read(&sessions_table_lock);

	return sess;
@@ -322,6 +327,7 @@ static struct ksmbd_session *__session_create(int protocol)
	if (ksmbd_init_file_table(&sess->file_table))
		goto error;

	sess->last_active = jiffies;
	sess->state = SMB2_SESSION_IN_PROGRESS;
	set_session_flag(sess, protocol);
	xa_init(&sess->tree_conns);
+1 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ struct ksmbd_session {
	__u8				smb3signingkey[SMB3_SIGN_KEY_SIZE];

	struct ksmbd_file_table		file_table;
	unsigned long			last_active;
};

static inline int test_session_flag(struct ksmbd_session *sess, int bit)
+14 −3
Original line number Diff line number Diff line
@@ -1481,7 +1481,7 @@ static int ntlm_authenticate(struct ksmbd_work *work,
		 * Reuse session if anonymous try to connect
		 * on reauthetication.
		 */
		if (ksmbd_anonymous_user(user)) {
		if (conn->binding == false && ksmbd_anonymous_user(user)) {
			ksmbd_free_user(user);
			return 0;
		}
@@ -1495,7 +1495,7 @@ static int ntlm_authenticate(struct ksmbd_work *work,
		sess->user = user;
	}

	if (user_guest(sess->user)) {
	if (conn->binding == false && user_guest(sess->user)) {
		rsp->SessionFlags = SMB2_SESSION_FLAG_IS_GUEST_LE;
	} else {
		struct authenticate_message *authblob;
@@ -1739,6 +1739,11 @@ int smb2_sess_setup(struct ksmbd_work *work)
			goto out_err;
		}

		if (user_guest(sess->user)) {
			rc = -EOPNOTSUPP;
			goto out_err;
		}

		conn->binding = true;
	} else if ((conn->dialect < SMB30_PROT_ID ||
		    server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) &&
@@ -1863,6 +1868,8 @@ int smb2_sess_setup(struct ksmbd_work *work)
		rsp->hdr.Status = STATUS_NETWORK_SESSION_EXPIRED;
	else if (rc == -ENOMEM)
		rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES;
	else if (rc == -EOPNOTSUPP)
		rsp->hdr.Status = STATUS_NOT_SUPPORTED;
	else if (rc)
		rsp->hdr.Status = STATUS_LOGON_FAILURE;

@@ -1890,9 +1897,13 @@ int smb2_sess_setup(struct ksmbd_work *work)
			if (sess->user && sess->user->flags & KSMBD_USER_FLAG_DELAY_SESSION)
				try_delay = true;

			sess->last_active = jiffies;
			sess->state = SMB2_SESSION_EXPIRED;
			if (try_delay)
			if (try_delay) {
				ksmbd_conn_set_need_reconnect(conn);
				ssleep(5);
				ksmbd_conn_set_need_negotiate(conn);
			}
		}
	}

+2 −0
Original line number Diff line number Diff line
@@ -367,6 +367,8 @@ struct smb2_negotiate_rsp {
#define SMB2_SESSION_IN_PROGRESS	BIT(0)
#define SMB2_SESSION_VALID		BIT(1)

#define SMB2_SESSION_TIMEOUT		(10 * HZ)

/* Flags */
#define SMB2_SESSION_REQ_FLAG_BINDING		0x01
#define SMB2_SESSION_REQ_FLAG_ENCRYPT_DATA	0x04