ksmbd: lock the binding preauth session in smb3_preauth_hash_rsp

smb3_preauth_hash_rsp() computes the SMB3.1.1 preauth integrity hash on
the response path. For a binding SESSION_SETUP it looks up the
per-connection preauth_session and reads its Preauth_HashValue.

smb2_sess_setup() frees that preauth_session under ksmbd_conn_lock().
Two SMB2 requests on one connection can run concurrently, so an unlocked
lookup and hash can use a preauth_session after another worker frees it.

Take ksmbd_conn_lock() before selecting conn->binding and hold it across
the selected preauth hash lookup and update. This preserves the existing
hash selection while preventing the lookup-to-use lifetime race.

Fixes: 1c5daa2ea9 ("ksmbd: handle channel binding with a different user")
Signed-off-by: Gil Portnoy <dddhkts1@gmail.com>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
Gil Portnoy
2026-07-13 09:20:09 +09:00
committed by Steve French
parent b10665730f
commit 35754558f6

View File

@@ -9808,22 +9808,21 @@ void smb3_preauth_hash_rsp(struct ksmbd_work *work)
}
if (le16_to_cpu(rsp->Command) == SMB2_SESSION_SETUP_HE && sess) {
__u8 *hash_value;
ksmbd_conn_lock(conn);
if (conn->binding) {
struct preauth_session *preauth_sess;
preauth_sess = ksmbd_preauth_session_lookup(conn, sess->id);
if (!preauth_sess)
return;
hash_value = preauth_sess->Preauth_HashValue;
} else {
hash_value = sess->Preauth_HashValue;
if (!hash_value)
return;
if (preauth_sess)
ksmbd_gen_preauth_integrity_hash(conn,
work->response_buf,
preauth_sess->Preauth_HashValue);
} else if (sess->Preauth_HashValue) {
ksmbd_gen_preauth_integrity_hash(conn, work->response_buf,
sess->Preauth_HashValue);
}
ksmbd_gen_preauth_integrity_hash(conn, work->response_buf,
hash_value);
ksmbd_conn_unlock(conn);
}
}