mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
ksmbd: disconnect on SMB3 decryption failure
MS-SMB2 requires the server to disconnect a connection when an
encrypted transform cannot be associated with a session or fails
authenticated decryption. This includes an encrypted request that
still carries a SessionId invalidated through PreviousSessionId.
Move the connection to EXITING and shut down its transport when
decrypt_req() fails. Add the missing TCP shutdown callback so a receive
blocked in kernel_recvmsg() is released; SMB Direct already provides
the corresponding callback.
Plaintext requests using an invalidated SessionId do not take this
path and continue to receive STATUS_USER_SESSION_DELETED.
Fixes: e2f34481b2 ("cifsd: add server-side procedures for SMB3")
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
This commit is contained in:
parent
2a0e037648
commit
12a6680ce5
|
|
@ -439,6 +439,22 @@ void ksmbd_all_conn_set_status(struct ksmbd_session *sess, u32 status)
|
|||
up_read(&conn_list_lock);
|
||||
}
|
||||
|
||||
void ksmbd_conn_abort(struct ksmbd_conn *conn)
|
||||
{
|
||||
bool shutdown = false;
|
||||
|
||||
spin_lock(&conn->request_lock);
|
||||
if (!ksmbd_conn_exiting(conn) && !ksmbd_conn_releasing(conn)) {
|
||||
ksmbd_conn_set_exiting(conn);
|
||||
shutdown = true;
|
||||
}
|
||||
spin_unlock(&conn->request_lock);
|
||||
wake_up_all(&conn->req_running_q);
|
||||
|
||||
if (shutdown && conn->transport->ops->shutdown)
|
||||
conn->transport->ops->shutdown(conn->transport);
|
||||
}
|
||||
|
||||
void ksmbd_conn_wait_idle(struct ksmbd_conn *conn)
|
||||
{
|
||||
wait_event(conn->req_running_q, atomic_read(&conn->req_running) < 2);
|
||||
|
|
|
|||
|
|
@ -203,6 +203,7 @@ struct ksmbd_conn *ksmbd_conn_alloc(void);
|
|||
void ksmbd_conn_free(struct ksmbd_conn *conn);
|
||||
struct ksmbd_conn *ksmbd_conn_get(struct ksmbd_conn *conn);
|
||||
void ksmbd_conn_put(struct ksmbd_conn *conn);
|
||||
void ksmbd_conn_abort(struct ksmbd_conn *conn);
|
||||
int ksmbd_conn_wq_init(void);
|
||||
void ksmbd_conn_wq_destroy(void);
|
||||
bool ksmbd_conn_lookup_dialect(struct ksmbd_conn *c);
|
||||
|
|
|
|||
|
|
@ -188,8 +188,10 @@ static void __handle_ksmbd_work(struct ksmbd_work *work,
|
|||
if (conn->ops->is_transform_hdr &&
|
||||
conn->ops->is_transform_hdr(work->request_buf)) {
|
||||
rc = conn->ops->decrypt_req(work);
|
||||
if (rc < 0)
|
||||
if (rc < 0) {
|
||||
ksmbd_conn_abort(conn);
|
||||
return;
|
||||
}
|
||||
work->encrypted = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -435,6 +435,11 @@ static void ksmbd_tcp_disconnect(struct ksmbd_transport *t)
|
|||
atomic_dec(&active_num_conn);
|
||||
}
|
||||
|
||||
static void ksmbd_tcp_shutdown(struct ksmbd_transport *t)
|
||||
{
|
||||
kernel_sock_shutdown(TCP_TRANS(t)->sock, SHUT_RDWR);
|
||||
}
|
||||
|
||||
static void tcp_destroy_socket(struct socket *ksmbd_socket)
|
||||
{
|
||||
int ret;
|
||||
|
|
@ -681,5 +686,6 @@ static const struct ksmbd_transport_ops ksmbd_tcp_transport_ops = {
|
|||
.read = ksmbd_tcp_read,
|
||||
.writev = ksmbd_tcp_writev,
|
||||
.disconnect = ksmbd_tcp_disconnect,
|
||||
.shutdown = ksmbd_tcp_shutdown,
|
||||
.free_transport = ksmbd_tcp_free_transport,
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user