Skip to content

Commit

Permalink
ksmbd: fix UAF issue in ksmbd_tcp_new_connection()
Browse files Browse the repository at this point in the history
The race is between the handling of a new TCP connection and
its disconnection. It leads to UAF on  in
ksmbd_tcp_new_connection() function.

Reported-by: [email protected] # ZDI-CAN-22991
Cc: [email protected]
Signed-off-by: Namjae Jeon <[email protected]>
  • Loading branch information
namjaejeon committed Jan 13, 2024
1 parent ba47560 commit 9d7a48d
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 20 deletions.
6 changes: 0 additions & 6 deletions connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -468,13 +468,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);
Expand Down
1 change: 0 additions & 1 deletion connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
11 changes: 6 additions & 5 deletions transport_rdma.c
Original file line number Diff line number Diff line change
Expand Up @@ -2044,6 +2044,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)) {
Expand All @@ -2061,11 +2062,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;
}
Expand Down
17 changes: 9 additions & 8 deletions transport_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,12 @@ static unsigned short ksmbd_tcp_get_port(const struct sockaddr *sa)
*
* Return: 0 on success, otherwise error
*/
static int ksmbd_tcp_new_connection(struct socket *client_sk)
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) {
Expand All @@ -221,19 +222,19 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk)
}

csin = KSMBD_TCP_PEER_SOCKADDR(KSMBD_TRANS(t)->conn);

if (kernel_getpeername(client_sk, csin) < 0) {
pr_err("client ip resolution failed\n");
rc = -EINVAL;
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;
Expand Down

0 comments on commit 9d7a48d

Please sign in to comment.