mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
ksmbd: validate NTLMv2 response before updating session key
ksmbd_auth_ntlmv2() derives the NTLMv2 session key into
sess->sess_key before it verifies the NTLMv2 response.
ksmbd_decode_ntlmssp_auth_blob() then continues into KEY_XCH even
when ksmbd_auth_ntlmv2() failed.
With SMB3 multichannel binding, the failed authentication operates on
an existing session and the session setup error path does not expire
binding sessions. A client can send a binding session setup with a
bad NT proof and KEY_XCH and still modify sess->sess_key before
STATUS_LOGON_FAILURE is returned.
Relevant path:
smb2_sess_setup()
-> conn->binding = true
-> ntlm_authenticate()
-> session_user()
-> ksmbd_decode_ntlmssp_auth_blob()
-> ksmbd_auth_ntlmv2()
-> calc_ntlmv2_hash()
-> hmac_md5_usingrawkey(..., sess->sess_key)
-> crypto_memneq() returns mismatch
-> KEY_XCH arc4_crypt(..., sess->sess_key, ...)
-> out_err without expiring the binding session
Derive the base session key into a local buffer and copy it to
sess->sess_key only after the proof matches. Return immediately on
authentication failure so KEY_XCH is only processed after successful
authentication.
Fixes: e2f34481b2 ("cifsd: add server-side procedures for SMB3")
Fixes: f9929ef6a2 ("ksmbd: add support for key exchange")
Cc: stable@vger.kernel.org
Signed-off-by: Haofeng Li <lihaofeng@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
4429b56506
commit
954d196beb
|
|
@ -142,6 +142,7 @@ int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
|
|||
{
|
||||
char ntlmv2_hash[CIFS_ENCPWD_SIZE];
|
||||
char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE];
|
||||
char sess_key[SMB2_NTLMV2_SESSKEY_SIZE];
|
||||
struct hmac_md5_ctx ctx;
|
||||
int rc;
|
||||
|
||||
|
|
@ -164,12 +165,21 @@ int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
|
|||
/* Generate the session key */
|
||||
hmac_md5_usingrawkey(ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE,
|
||||
ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE,
|
||||
sess->sess_key);
|
||||
sess_key);
|
||||
|
||||
if (crypto_memneq(ntlmv2->ntlmv2_hash, ntlmv2_rsp,
|
||||
CIFS_HMAC_MD5_HASH_SIZE))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
CIFS_HMAC_MD5_HASH_SIZE)) {
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(sess->sess_key, sess_key, sizeof(sess_key));
|
||||
rc = 0;
|
||||
out:
|
||||
memzero_explicit(ntlmv2_hash, sizeof(ntlmv2_hash));
|
||||
memzero_explicit(ntlmv2_rsp, sizeof(ntlmv2_rsp));
|
||||
memzero_explicit(sess_key, sizeof(sess_key));
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -226,6 +236,8 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
|
|||
nt_len - CIFS_ENCPWD_SIZE,
|
||||
domain_name, conn->ntlmssp.cryptkey);
|
||||
kfree(domain_name);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* The recovered secondary session key */
|
||||
if (conn->ntlmssp.client_flags & NTLMSSP_NEGOTIATE_KEY_XCH) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user