Commit 4ef82227 authored by Namjae Jeon's avatar Namjae Jeon Committed by Long Li
Browse files

ksmbd: fix UAF issue in ksmbd_tcp_new_connection()

stable inclusion
from stable-v5.15.81
commit 999daf367b924fdf14e9d83e034ee0f86bc17ec6
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I932W8
CVE: CVE-2024-26592

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-5.15.y&id=999daf367b924fdf14e9d83e034ee0f86bc17ec6



--------------------------------

[ Upstream commit 38d20c62903d669693a1869aa68c4dd5674e2544 ]

The race is between the handling of a new TCP connection and
its disconnection. It leads to UAF on `struct tcp_transport` in
ksmbd_tcp_new_connection() function.

Cc: stable@vger.kernel.org
Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-22991
Signed-off-by: default avatarNamjae Jeon <linkinjeon@kernel.org>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>

Conflict:
	fs/ksmbd/transport_tcp.c

Signed-off-by: default avatarLong Li <leo.lilong@huawei.com>
parent 0b6927f0
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -434,13 +434,7 @@ static void stop_sessions(void)
again:
	down_read(&conn_list_lock);
	list_for_each_entry(conn, &conn_list, conns_list) {
		struct task_struct *task;

		t = conn->transport;
		task = t->handler;
		if (task)
			ksmbd_debug(CONN, "Stop session handler %s/%d\n",
				    task->comm, task_pid_nr(task));
		ksmbd_conn_set_exiting(conn);
		if (t->ops->shutdown) {
			up_read(&conn_list_lock);
+0 −1
Original line number Diff line number Diff line
@@ -127,7 +127,6 @@ struct ksmbd_transport_ops {
struct ksmbd_transport {
	struct ksmbd_conn		*conn;
	struct ksmbd_transport_ops	*ops;
	struct task_struct		*handler;
};

#define KSMBD_TCP_RECV_TIMEOUT	(7 * HZ)
+6 −5
Original line number Diff line number Diff line
@@ -1976,6 +1976,7 @@ static bool rdma_frwr_is_supported(struct ib_device_attr *attrs)
static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id)
{
	struct smb_direct_transport *t;
	struct task_struct *handler;
	int ret;

	if (!rdma_frwr_is_supported(&new_cm_id->device->attrs)) {
@@ -1993,11 +1994,11 @@ static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id)
	if (ret)
		goto out_err;

	KSMBD_TRANS(t)->handler = kthread_run(ksmbd_conn_handler_loop,
	handler = kthread_run(ksmbd_conn_handler_loop,
			      KSMBD_TRANS(t)->conn, "ksmbd:r%u",
			      smb_direct_port);
	if (IS_ERR(KSMBD_TRANS(t)->handler)) {
		ret = PTR_ERR(KSMBD_TRANS(t)->handler);
	if (IS_ERR(handler)) {
		ret = PTR_ERR(handler);
		pr_err("Can't start thread\n");
		goto out_err;
	}
+7 −6
Original line number Diff line number Diff line
@@ -183,6 +183,7 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk)
	struct sockaddr *csin;
	int rc = 0;
	struct tcp_transport *t;
	struct task_struct *handler;

	t = alloc_transport(client_sk);
	if (!t)
@@ -195,13 +196,13 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk)
		goto out_error;
	}

	KSMBD_TRANS(t)->handler = kthread_run(ksmbd_conn_handler_loop,
	handler = kthread_run(ksmbd_conn_handler_loop,
			      KSMBD_TRANS(t)->conn,
			      "ksmbd:%u",
			      ksmbd_tcp_get_port(csin));
	if (IS_ERR(KSMBD_TRANS(t)->handler)) {
	if (IS_ERR(handler)) {
		pr_err("cannot start conn thread\n");
		rc = PTR_ERR(KSMBD_TRANS(t)->handler);
		rc = PTR_ERR(handler);
		free_transport(t);
	}
	return rc;