ksmbd: fix UAF issue in ksmbd_tcp_new_connection()
commit 38d20c62903d669693a1869aa68c4dd5674e2544 upstream. 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: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
a2b21ef1ea
commit
24290ba94c
|
@ -415,13 +415,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);
|
||||
|
|
|
@ -135,7 +135,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)
|
||||
|
|
|
@ -2039,6 +2039,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)) {
|
||||
|
@ -2056,11 +2057,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,
|
||||
KSMBD_TRANS(t)->conn, "ksmbd:r%u",
|
||||
smb_direct_port);
|
||||
if (IS_ERR(KSMBD_TRANS(t)->handler)) {
|
||||
ret = PTR_ERR(KSMBD_TRANS(t)->handler);
|
||||
handler = kthread_run(ksmbd_conn_handler_loop,
|
||||
KSMBD_TRANS(t)->conn, "ksmbd:r%u",
|
||||
smb_direct_port);
|
||||
if (IS_ERR(handler)) {
|
||||
ret = PTR_ERR(handler);
|
||||
pr_err("Can't start thread\n");
|
||||
goto out_err;
|
||||
}
|
||||
|
|
|
@ -185,6 +185,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) {
|
||||
|
@ -199,13 +200,13 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk)
|
|||
goto out_error;
|
||||
}
|
||||
|
||||
KSMBD_TRANS(t)->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)) {
|
||||
handler = kthread_run(ksmbd_conn_handler_loop,
|
||||
KSMBD_TRANS(t)->conn,
|
||||
"ksmbd:%u",
|
||||
ksmbd_tcp_get_port(csin));
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue