smb/server: fix session leak in ksmbd_session_register()

See the procedure below:

  smb2_sess_setup
    ksmbd_smb2_session_create
      __session_create
        atomic_set(&sess->refcnt, 2)
        hash_add(sessions_table, &sess->hlist, sess->id)
    ksmbd_session_register
      xa_store(&conn->sessions, sess->id, sess) // fail
    ksmbd_user_session_put
      atomic_dec(&sess->refcnt) // refcnt is 1, session is not freed

Remove the session from sessions_table and drop its table reference if
xa_store() fails.

Fixes: f5c779b7dd ("ksmbd: fix racy issue from session setup and logoff")
Signed-off-by: Ze Tan <tanze@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
This commit is contained in:
Ze Tan 2026-08-14 13:51:42 +00:00 committed by Namjae Jeon
parent 9a74739026
commit 99b25b046e

View File

@ -451,10 +451,21 @@ static void ksmbd_expire_session(struct ksmbd_conn *conn)
int ksmbd_session_register(struct ksmbd_conn *conn,
struct ksmbd_session *sess)
{
int ret;
sess->dialect = conn->dialect;
memcpy(sess->ClientGUID, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE);
ksmbd_expire_session(conn);
return xa_err(xa_store(&conn->sessions, sess->id, sess, KSMBD_DEFAULT_GFP));
ret = xa_err(xa_store(&conn->sessions, sess->id, sess,
KSMBD_DEFAULT_GFP));
if (ret) {
down_write(&sessions_table_lock);
hash_del(&sess->hlist);
up_write(&sessions_table_lock);
ksmbd_user_session_put(sess);
}
return ret;
}
static int ksmbd_chann_del(struct ksmbd_conn *conn, struct ksmbd_session *sess)