Skip to content

Commit f78c28d

Browse files
namjaejeonvijay-suman
authored andcommitted
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: b956294 ("ksmbd: fix racy issue from session lookup and expire") Reported-by: Sean Heelan <[email protected]> Signed-off-by: Namjae Jeon <[email protected]> Signed-off-by: Steve French <[email protected]> Signed-off-by: Sasha Levin <[email protected]> (cherry picked from commit 55cf766eba06c3dd0d51b3b0250f1c30380901a9) FOF: 0525 Signed-off-by: Vijayendra Suman <[email protected]>
1 parent 7b11134 commit f78c28d

File tree

3 files changed

+22
-8
lines changed

3 files changed

+22
-8
lines changed

fs/ksmbd/mgmt/user_session.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,22 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
250250
up_write(&conn->session_lock);
251251
}
252252

253+
bool is_ksmbd_session_in_connection(struct ksmbd_conn *conn,
254+
unsigned long long id)
255+
{
256+
struct ksmbd_session *sess;
257+
258+
down_read(&conn->session_lock);
259+
sess = xa_load(&conn->sessions, id);
260+
if (sess) {
261+
up_read(&conn->session_lock);
262+
return true;
263+
}
264+
up_read(&conn->session_lock);
265+
266+
return false;
267+
}
268+
253269
struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
254270
unsigned long long id)
255271
{

fs/ksmbd/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/ksmbd/smb2pdu.c

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

17261726
if (conn->dialect != sess->dialect) {
17271727
rc = -EINVAL;
1728-
ksmbd_user_session_put(sess);
17291728
goto out_err;
17301729
}
17311730

17321731
if (!(req->hdr.Flags & SMB2_FLAGS_SIGNED)) {
17331732
rc = -EINVAL;
1734-
ksmbd_user_session_put(sess);
17351733
goto out_err;
17361734
}
17371735

17381736
if (strncmp(conn->ClientGUID, sess->ClientGUID,
17391737
SMB2_CLIENT_GUID_SIZE)) {
17401738
rc = -ENOENT;
1741-
ksmbd_user_session_put(sess);
17421739
goto out_err;
17431740
}
17441741

17451742
if (sess->state == SMB2_SESSION_IN_PROGRESS) {
17461743
rc = -EACCES;
1747-
ksmbd_user_session_put(sess);
17481744
goto out_err;
17491745
}
17501746

17511747
if (sess->state == SMB2_SESSION_EXPIRED) {
17521748
rc = -EFAULT;
1753-
ksmbd_user_session_put(sess);
17541749
goto out_err;
17551750
}
1756-
ksmbd_user_session_put(sess);
17571751

17581752
if (ksmbd_conn_need_reconnect(conn)) {
17591753
rc = -EFAULT;
1754+
ksmbd_user_session_put(sess);
17601755
sess = NULL;
17611756
goto out_err;
17621757
}
17631758

1764-
sess = ksmbd_session_lookup(conn, sess_id);
1765-
if (!sess) {
1759+
if (is_ksmbd_session_in_connection(conn, sess_id)) {
17661760
rc = -EACCES;
17671761
goto out_err;
17681762
}
@@ -1928,6 +1922,8 @@ int smb2_sess_setup(struct ksmbd_work *work)
19281922

19291923
sess->last_active = jiffies;
19301924
sess->state = SMB2_SESSION_EXPIRED;
1925+
ksmbd_user_session_put(sess);
1926+
work->sess = NULL;
19311927
if (try_delay) {
19321928
ksmbd_conn_set_need_reconnect(conn);
19331929
ssleep(5);

0 commit comments

Comments
 (0)