Unverified Commit 053a6b6f authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!13006 Fix CVE-2024-50086

Merge Pull Request from: @ci-robot 
 
PR sync from: Long Li <leo.lilong@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/DQ7FEI6YCAA2CB4E4FFJ4HDCMWPYZFS5/ 
This patch set fix CVE-2024-50086.

Namjae Jeon (2):
  ksmbd: fix race condition between session lookup and expire
  ksmbd: fix user-after-free from session log off


-- 
2.39.2
 
https://gitee.com/src-openeuler/kernel/issues/IB0ENJ 
 
Link:https://gitee.com/openeuler/kernel/pulls/13006

 

Reviewed-by: default avatarLi Nan <linan122@huawei.com>
Signed-off-by: default avatarLi Nan <linan122@huawei.com>
parents 951151c7 308dadf2
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -78,6 +78,8 @@ struct ksmbd_conn *ksmbd_conn_alloc(void)
	spin_lock_init(&conn->llist_lock);
	INIT_LIST_HEAD(&conn->lock_list);

	init_rwsem(&conn->session_lock);

	down_write(&conn_list_lock);
	list_add(&conn->conns_list, &conn_list);
	up_write(&conn_list_lock);
+1 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ struct ksmbd_conn {
	struct ksmbd_transport		*transport;
	struct nls_table		*local_nls;
	struct list_head		conns_list;
	struct rw_semaphore		session_lock;
	/* smb session 1 per user */
	struct xarray			sessions;
	unsigned long			last_active;
+27 −7
Original line number Diff line number Diff line
@@ -181,18 +181,19 @@ static void ksmbd_expire_session(struct ksmbd_conn *conn)
	unsigned long id;
	struct ksmbd_session *sess;

	down_write(&sessions_table_lock);
	down_write(&conn->session_lock);
	xa_for_each(&conn->sessions, id, sess) {
		if (sess->state != SMB2_SESSION_VALID ||
		if (atomic_read(&sess->refcnt) == 0 &&
		    (sess->state != SMB2_SESSION_VALID ||
		    time_after(jiffies,
			       sess->last_active + SMB2_SESSION_TIMEOUT)) {
			       sess->last_active + SMB2_SESSION_TIMEOUT))) {
			xa_erase(&conn->sessions, sess->id);
			hash_del(&sess->hlist);
			ksmbd_session_destroy(sess);
			continue;
		}
	}
	up_write(&sessions_table_lock);
	up_write(&conn->session_lock);
}

int ksmbd_session_register(struct ksmbd_conn *conn,
@@ -234,7 +235,9 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
			}
		}
	}
	up_write(&sessions_table_lock);

	down_write(&conn->session_lock);
	xa_for_each(&conn->sessions, id, sess) {
		unsigned long chann_id;
		struct channel *chann;
@@ -251,7 +254,7 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
			ksmbd_session_destroy(sess);
		}
	}
	up_write(&sessions_table_lock);
	up_write(&conn->session_lock);
}

struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
@@ -259,9 +262,11 @@ struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
{
	struct ksmbd_session *sess;

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

@@ -271,8 +276,6 @@ 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;
@@ -291,6 +294,22 @@ struct ksmbd_session *ksmbd_session_lookup_all(struct ksmbd_conn *conn,
	return sess;
}

void ksmbd_user_session_get(struct ksmbd_session *sess)
{
	atomic_inc(&sess->refcnt);
}

void ksmbd_user_session_put(struct ksmbd_session *sess)
{
	if (!sess)
		return;

	if (atomic_read(&sess->refcnt) <= 0)
		WARN_ON(1);
	else
		atomic_dec(&sess->refcnt);
}

struct preauth_session *ksmbd_preauth_session_alloc(struct ksmbd_conn *conn,
						    u64 sess_id)
{
@@ -358,6 +377,7 @@ static struct ksmbd_session *__session_create(int protocol)
	xa_init(&sess->ksmbd_chann_list);
	INIT_LIST_HEAD(&sess->rpc_handle_list);
	sess->sequence_number = 1;
	atomic_set(&sess->refcnt, 1);

	ret = __init_smb2_session(sess);
	if (ret)
+3 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ struct ksmbd_session {

	struct ksmbd_file_table		file_table;
	unsigned long			last_active;
	atomic_t			refcnt;
};

static inline int test_session_flag(struct ksmbd_session *sess, int bit)
@@ -100,4 +101,6 @@ void ksmbd_release_tree_conn_id(struct ksmbd_session *sess, int id);
int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name);
void ksmbd_session_rpc_close(struct ksmbd_session *sess, int id);
int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id);
void ksmbd_user_session_get(struct ksmbd_session *sess);
void ksmbd_user_session_put(struct ksmbd_session *sess);
#endif /* __USER_SESSION_MANAGEMENT_H__ */
+2 −0
Original line number Diff line number Diff line
@@ -239,6 +239,8 @@ static void __handle_ksmbd_work(struct ksmbd_work *work,
		return;

send:
	if (work->sess)
		ksmbd_user_session_put(work->sess);
	smb3_preauth_hash_rsp(work);
	if (work->sess && work->sess->enc && work->encrypted &&
	    conn->ops->encrypt_resp) {
Loading