ksmbd: fix multichannel connection failure
[ Upstream commit c1883049aa9b2b7dffd3a68c5fc67fa92c174bd9 ]
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: b95629435b84 ("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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
3e341dbd5f
commit
e0b32b6f0f
@@ -256,6 +256,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);
|
||||
|
||||
@@ -1704,44 +1704,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;
|
||||
}
|
||||
@@ -1907,6 +1901,8 @@ out_err:
|
||||
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user