Skip to content

Commit 9d7a48d

Browse files
committed
ksmbd: fix UAF issue in ksmbd_tcp_new_connection()
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]>
1 parent ba47560 commit 9d7a48d

File tree

4 files changed

+15
-20
lines changed

4 files changed

+15
-20
lines changed

connection.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -468,13 +468,7 @@ static void stop_sessions(void)
468468
again:
469469
down_read(&conn_list_lock);
470470
list_for_each_entry(conn, &conn_list, conns_list) {
471-
struct task_struct *task;
472-
473471
t = conn->transport;
474-
task = t->handler;
475-
if (task)
476-
ksmbd_debug(CONN, "Stop session handler %s/%d\n",
477-
task->comm, task_pid_nr(task));
478472
ksmbd_conn_set_exiting(conn);
479473
if (t->ops->shutdown) {
480474
up_read(&conn_list_lock);

connection.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,6 @@ struct ksmbd_transport_ops {
135135
struct ksmbd_transport {
136136
struct ksmbd_conn *conn;
137137
struct ksmbd_transport_ops *ops;
138-
struct task_struct *handler;
139138
};
140139

141140
#define KSMBD_TCP_RECV_TIMEOUT (7 * HZ)

transport_rdma.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2044,6 +2044,7 @@ static bool rdma_frwr_is_supported(struct ib_device_attr *attrs)
20442044
static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id)
20452045
{
20462046
struct smb_direct_transport *t;
2047+
struct task_struct *handler;
20472048
int ret;
20482049

20492050
if (!rdma_frwr_is_supported(&new_cm_id->device->attrs)) {
@@ -2061,11 +2062,11 @@ static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id)
20612062
if (ret)
20622063
goto out_err;
20632064

2064-
KSMBD_TRANS(t)->handler = kthread_run(ksmbd_conn_handler_loop,
2065-
KSMBD_TRANS(t)->conn, "ksmbd:r%u",
2066-
smb_direct_port);
2067-
if (IS_ERR(KSMBD_TRANS(t)->handler)) {
2068-
ret = PTR_ERR(KSMBD_TRANS(t)->handler);
2065+
handler = kthread_run(ksmbd_conn_handler_loop,
2066+
KSMBD_TRANS(t)->conn, "ksmbd:r%u",
2067+
smb_direct_port);
2068+
if (IS_ERR(handler)) {
2069+
ret = PTR_ERR(handler);
20692070
pr_err("Can't start thread\n");
20702071
goto out_err;
20712072
}

transport_tcp.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -208,11 +208,12 @@ static unsigned short ksmbd_tcp_get_port(const struct sockaddr *sa)
208208
*
209209
* Return: 0 on success, otherwise error
210210
*/
211-
static int ksmbd_tcp_new_connection(struct socket *client_sk)
211+
int ksmbd_tcp_new_connection(struct socket *client_sk)
212212
{
213213
struct sockaddr *csin;
214214
int rc = 0;
215215
struct tcp_transport *t;
216+
struct task_struct *handler;
216217

217218
t = alloc_transport(client_sk);
218219
if (!t) {
@@ -221,19 +222,19 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk)
221222
}
222223

223224
csin = KSMBD_TCP_PEER_SOCKADDR(KSMBD_TRANS(t)->conn);
224-
225225
if (kernel_getpeername(client_sk, csin) < 0) {
226226
pr_err("client ip resolution failed\n");
227227
rc = -EINVAL;
228228
goto out_error;
229229
}
230-
KSMBD_TRANS(t)->handler = kthread_run(ksmbd_conn_handler_loop,
231-
KSMBD_TRANS(t)->conn,
232-
"ksmbd:%u",
233-
ksmbd_tcp_get_port(csin));
234-
if (IS_ERR(KSMBD_TRANS(t)->handler)) {
230+
231+
handler = kthread_run(ksmbd_conn_handler_loop,
232+
KSMBD_TRANS(t)->conn,
233+
"ksmbd:%u",
234+
ksmbd_tcp_get_port(csin));
235+
if (IS_ERR(handler)) {
235236
pr_err("cannot start conn thread\n");
236-
rc = PTR_ERR(KSMBD_TRANS(t)->handler);
237+
rc = PTR_ERR(handler);
237238
free_transport(t);
238239
}
239240
return rc;

0 commit comments

Comments
 (0)