mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 18:13:41 +02:00
ksmbd: fix multichannel connection failure
ksmbd check that the session of second channel is in the session list of
first connection. If it is in session list, multichannel connection
should not be allowed.
Fixes: b95629435b ("ksmbd: fix racy issue from session lookup and expire")
Reported-by: Sean Heelan <seanheelan@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
15a9605f8d
commit
c1883049aa
|
|
@ -259,6 +259,22 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
|
|||
up_write(&sessions_table_lock);
|
||||
}
|
||||
|
||||
bool is_ksmbd_session_in_connection(struct ksmbd_conn *conn,
|
||||
unsigned long long id)
|
||||
{
|
||||
struct ksmbd_session *sess;
|
||||
|
||||
down_read(&conn->session_lock);
|
||||
sess = xa_load(&conn->sessions, id);
|
||||
if (sess) {
|
||||
up_read(&conn->session_lock);
|
||||
return true;
|
||||
}
|
||||
up_read(&conn->session_lock);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
|
||||
unsigned long long id)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -87,6 +87,8 @@ void ksmbd_session_destroy(struct ksmbd_session *sess);
|
|||
struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long id);
|
||||
struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
|
||||
unsigned long long id);
|
||||
bool is_ksmbd_session_in_connection(struct ksmbd_conn *conn,
|
||||
unsigned long long id);
|
||||
int ksmbd_session_register(struct ksmbd_conn *conn,
|
||||
struct ksmbd_session *sess);
|
||||
void ksmbd_sessions_deregister(struct ksmbd_conn *conn);
|
||||
|
|
|
|||
|
|
@ -1707,44 +1707,38 @@ int smb2_sess_setup(struct ksmbd_work *work)
|
|||
|
||||
if (conn->dialect != sess->dialect) {
|
||||
rc = -EINVAL;
|
||||
ksmbd_user_session_put(sess);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (!(req->hdr.Flags & SMB2_FLAGS_SIGNED)) {
|
||||
rc = -EINVAL;
|
||||
ksmbd_user_session_put(sess);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (strncmp(conn->ClientGUID, sess->ClientGUID,
|
||||
SMB2_CLIENT_GUID_SIZE)) {
|
||||
rc = -ENOENT;
|
||||
ksmbd_user_session_put(sess);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (sess->state == SMB2_SESSION_IN_PROGRESS) {
|
||||
rc = -EACCES;
|
||||
ksmbd_user_session_put(sess);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (sess->state == SMB2_SESSION_EXPIRED) {
|
||||
rc = -EFAULT;
|
||||
ksmbd_user_session_put(sess);
|
||||
goto out_err;
|
||||
}
|
||||
ksmbd_user_session_put(sess);
|
||||
|
||||
if (ksmbd_conn_need_reconnect(conn)) {
|
||||
rc = -EFAULT;
|
||||
ksmbd_user_session_put(sess);
|
||||
sess = NULL;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
sess = ksmbd_session_lookup(conn, sess_id);
|
||||
if (!sess) {
|
||||
if (is_ksmbd_session_in_connection(conn, sess_id)) {
|
||||
rc = -EACCES;
|
||||
goto out_err;
|
||||
}
|
||||
|
|
@ -1910,6 +1904,8 @@ int smb2_sess_setup(struct ksmbd_work *work)
|
|||
|
||||
sess->last_active = jiffies;
|
||||
sess->state = SMB2_SESSION_EXPIRED;
|
||||
ksmbd_user_session_put(sess);
|
||||
work->sess = NULL;
|
||||
if (try_delay) {
|
||||
ksmbd_conn_set_need_reconnect(conn);
|
||||
ssleep(5);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user