diff options
author | Namjae Jeon <linkinjeon@kernel.org> | 2024-11-02 10:46:38 +0100 |
---|---|---|
committer | Namjae Jeon <linkinjeon@kernel.org> | 2024-11-05 01:26:35 +0100 |
commit | 0a77715db22611df50b178374c51e2ba0d58866e (patch) | |
tree | 93450bd1cadb314d9d1c3d4c237465f653e246fe /fs/smb/server | |
parent | ksmbd: Fix the missing xa_store error check (diff) | |
download | linux-0a77715db22611df50b178374c51e2ba0d58866e.tar.xz linux-0a77715db22611df50b178374c51e2ba0d58866e.zip |
ksmbd: fix slab-use-after-free in ksmbd_smb2_session_create
There is a race condition between ksmbd_smb2_session_create and
ksmbd_expire_session. This patch add missing sessions_table_lock
while adding/deleting session from global session table.
Cc: stable@vger.kernel.org # v5.15+
Reported-by: Norbert Szetei <norbert@doyensec.com>
Tested-by: Norbert Szetei <norbert@doyensec.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/smb/server')
-rw-r--r-- | fs/smb/server/mgmt/user_session.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c index 9756a4bbfe54..ad02fe555fda 100644 --- a/fs/smb/server/mgmt/user_session.c +++ b/fs/smb/server/mgmt/user_session.c @@ -178,6 +178,7 @@ static void ksmbd_expire_session(struct ksmbd_conn *conn) unsigned long id; struct ksmbd_session *sess; + down_write(&sessions_table_lock); down_write(&conn->session_lock); xa_for_each(&conn->sessions, id, sess) { if (atomic_read(&sess->refcnt) == 0 && @@ -191,6 +192,7 @@ static void ksmbd_expire_session(struct ksmbd_conn *conn) } } up_write(&conn->session_lock); + up_write(&sessions_table_lock); } int ksmbd_session_register(struct ksmbd_conn *conn, @@ -232,7 +234,6 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn) } } } - up_write(&sessions_table_lock); down_write(&conn->session_lock); xa_for_each(&conn->sessions, id, sess) { @@ -252,6 +253,7 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn) } } up_write(&conn->session_lock); + up_write(&sessions_table_lock); } struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn, |