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
6eb8015492
commit
380965e48e
@ -415,13 +415,7 @@ static void stop_sessions(void)
|
|||||||
again:
|
again:
|
||||||
down_read(&conn_list_lock);
|
down_read(&conn_list_lock);
|
||||||
list_for_each_entry(conn, &conn_list, conns_list) {
|
list_for_each_entry(conn, &conn_list, conns_list) {
|
||||||
struct task_struct *task;
|
|
||||||
|
|
||||||
t = conn->transport;
|
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);
|
ksmbd_conn_set_exiting(conn);
|
||||||
if (t->ops->shutdown) {
|
if (t->ops->shutdown) {
|
||||||
up_read(&conn_list_lock);
|
up_read(&conn_list_lock);
|
||||||
|
@ -135,7 +135,6 @@ struct ksmbd_transport_ops {
|
|||||||
struct ksmbd_transport {
|
struct ksmbd_transport {
|
||||||
struct ksmbd_conn *conn;
|
struct ksmbd_conn *conn;
|
||||||
struct ksmbd_transport_ops *ops;
|
struct ksmbd_transport_ops *ops;
|
||||||
struct task_struct *handler;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define KSMBD_TCP_RECV_TIMEOUT (7 * HZ)
|
#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)
|
static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id)
|
||||||
{
|
{
|
||||||
struct smb_direct_transport *t;
|
struct smb_direct_transport *t;
|
||||||
|
struct task_struct *handler;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!rdma_frwr_is_supported(&new_cm_id->device->attrs)) {
|
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)
|
if (ret)
|
||||||
goto out_err;
|
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",
|
KSMBD_TRANS(t)->conn, "ksmbd:r%u",
|
||||||
smb_direct_port);
|
smb_direct_port);
|
||||||
if (IS_ERR(KSMBD_TRANS(t)->handler)) {
|
if (IS_ERR(handler)) {
|
||||||
ret = PTR_ERR(KSMBD_TRANS(t)->handler);
|
ret = PTR_ERR(handler);
|
||||||
pr_err("Can't start thread\n");
|
pr_err("Can't start thread\n");
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
|
@ -185,6 +185,7 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk)
|
|||||||
struct sockaddr *csin;
|
struct sockaddr *csin;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct tcp_transport *t;
|
struct tcp_transport *t;
|
||||||
|
struct task_struct *handler;
|
||||||
|
|
||||||
t = alloc_transport(client_sk);
|
t = alloc_transport(client_sk);
|
||||||
if (!t) {
|
if (!t) {
|
||||||
@ -199,13 +200,13 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk)
|
|||||||
goto out_error;
|
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_TRANS(t)->conn,
|
||||||
"ksmbd:%u",
|
"ksmbd:%u",
|
||||||
ksmbd_tcp_get_port(csin));
|
ksmbd_tcp_get_port(csin));
|
||||||
if (IS_ERR(KSMBD_TRANS(t)->handler)) {
|
if (IS_ERR(handler)) {
|
||||||
pr_err("cannot start conn thread\n");
|
pr_err("cannot start conn thread\n");
|
||||||
rc = PTR_ERR(KSMBD_TRANS(t)->handler);
|
rc = PTR_ERR(handler);
|
||||||
free_transport(t);
|
free_transport(t);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
|
Loading…
Reference in New Issue
Block a user