Skip to content

Commit c188304

Browse files
namjaejeonSteve French
authored andcommitted
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: b956294 ("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>
1 parent 15a9605 commit c188304

File tree

3 files changed

+22
-8
lines changed

3 files changed

+22
-8
lines changed

fs/smb/server/mgmt/user_session.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,22 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
259259
up_write(&sessions_table_lock);
260260
}
261261

262+
bool is_ksmbd_session_in_connection(struct ksmbd_conn *conn,
263+
unsigned long long id)
264+
{
265+
struct ksmbd_session *sess;
266+
267+
down_read(&conn->session_lock);
268+
sess = xa_load(&conn->sessions, id);
269+
if (sess) {
270+
up_read(&conn->session_lock);
271+
return true;
272+
}
273+
up_read(&conn->session_lock);
274+
275+
return false;
276+
}
277+
262278
struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
263279
unsigned long long id)
264280
{

fs/smb/server/mgmt/user_session.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ void ksmbd_session_destroy(struct ksmbd_session *sess);
8787
struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long id);
8888
struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
8989
unsigned long long id);
90+
bool is_ksmbd_session_in_connection(struct ksmbd_conn *conn,
91+
unsigned long long id);
9092
int ksmbd_session_register(struct ksmbd_conn *conn,
9193
struct ksmbd_session *sess);
9294
void ksmbd_sessions_deregister(struct ksmbd_conn *conn);

fs/smb/server/smb2pdu.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,44 +1707,38 @@ int smb2_sess_setup(struct ksmbd_work *work)
17071707

17081708
if (conn->dialect != sess->dialect) {
17091709
rc = -EINVAL;
1710-
ksmbd_user_session_put(sess);
17111710
goto out_err;
17121711
}
17131712

17141713
if (!(req->hdr.Flags & SMB2_FLAGS_SIGNED)) {
17151714
rc = -EINVAL;
1716-
ksmbd_user_session_put(sess);
17171715
goto out_err;
17181716
}
17191717

17201718
if (strncmp(conn->ClientGUID, sess->ClientGUID,
17211719
SMB2_CLIENT_GUID_SIZE)) {
17221720
rc = -ENOENT;
1723-
ksmbd_user_session_put(sess);
17241721
goto out_err;
17251722
}
17261723

17271724
if (sess->state == SMB2_SESSION_IN_PROGRESS) {
17281725
rc = -EACCES;
1729-
ksmbd_user_session_put(sess);
17301726
goto out_err;
17311727
}
17321728

17331729
if (sess->state == SMB2_SESSION_EXPIRED) {
17341730
rc = -EFAULT;
1735-
ksmbd_user_session_put(sess);
17361731
goto out_err;
17371732
}
1738-
ksmbd_user_session_put(sess);
17391733

17401734
if (ksmbd_conn_need_reconnect(conn)) {
17411735
rc = -EFAULT;
1736+
ksmbd_user_session_put(sess);
17421737
sess = NULL;
17431738
goto out_err;
17441739
}
17451740

1746-
sess = ksmbd_session_lookup(conn, sess_id);
1747-
if (!sess) {
1741+
if (is_ksmbd_session_in_connection(conn, sess_id)) {
17481742
rc = -EACCES;
17491743
goto out_err;
17501744
}
@@ -1910,6 +1904,8 @@ int smb2_sess_setup(struct ksmbd_work *work)
19101904

19111905
sess->last_active = jiffies;
19121906
sess->state = SMB2_SESSION_EXPIRED;
1907+
ksmbd_user_session_put(sess);
1908+
work->sess = NULL;
19131909
if (try_delay) {
19141910
ksmbd_conn_set_need_reconnect(conn);
19151911
ssleep(5);

0 commit comments

Comments
 (0)