mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 02:17:36 -04:00
ksmbd: use the session dialect for rejected binding signatures
When an SMB3 session is referenced by a binding request on an SMB2.1 connection, the request is signed with the existing session's SMB3 signing algorithm. ksmbd instead verifies it with the new connection's SMB2.1 HMAC algorithm, so verification fails and the client receives STATUS_ACCESS_DENIED instead of STATUS_REQUEST_NOT_ACCEPTED. Select the signing verifier from the referenced session dialect. Permit a signed SESSION_SETUP without an established channel to use the SMB3 session signing key for verification. This is limited to SESSION_SETUP so other unbound requests remain rejected. The rejected response must use the same existing session algorithm. When an SMB3 session is referenced on an SMB2.1 connection, sign the SESSION_SETUP response with the SMB3 signing path rather than the connection's SMB2.1 path. This fixes smb2.session.bind_negative_smb3to2s. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
committed by
Steve French
parent
3e67423336
commit
f49bca41c1
@@ -243,8 +243,14 @@ static void __handle_ksmbd_work(struct ksmbd_work *work,
|
||||
|
||||
if (work->sess &&
|
||||
(work->sess->sign || smb3_11_final_sess_setup_resp(work) ||
|
||||
conn->ops->is_sign_req(work, command)))
|
||||
conn->ops->set_sign_rsp(work);
|
||||
conn->ops->is_sign_req(work, command))) {
|
||||
if (command == SMB2_SESSION_SETUP_HE &&
|
||||
work->sess->dialect >= SMB30_PROT_ID &&
|
||||
conn->dialect < SMB30_PROT_ID)
|
||||
smb3_set_sign_rsp(work);
|
||||
else
|
||||
conn->ops->set_sign_rsp(work);
|
||||
}
|
||||
} while (is_chained == true);
|
||||
|
||||
send:
|
||||
|
||||
@@ -2015,10 +2015,16 @@ int smb2_sess_setup(struct ksmbd_work *work)
|
||||
(req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) {
|
||||
sess = ksmbd_session_lookup_slowpath(le64_to_cpu(req->hdr.SessionId));
|
||||
if (sess) {
|
||||
int sign_ret;
|
||||
|
||||
work->sess = sess;
|
||||
if (sess->dialect >= SMB30_PROT_ID)
|
||||
sign_ret = smb3_check_sign_req(work);
|
||||
else
|
||||
sign_ret = smb2_check_sign_req(work);
|
||||
if (sess->state != SMB2_SESSION_VALID ||
|
||||
!(req->hdr.Flags & SMB2_FLAGS_SIGNED) ||
|
||||
!conn->ops->check_sign_req(work)) {
|
||||
!sign_ret) {
|
||||
ksmbd_user_session_put(sess);
|
||||
work->sess = NULL;
|
||||
sess = NULL;
|
||||
@@ -9681,9 +9687,13 @@ int smb3_check_sign_req(struct ksmbd_work *work)
|
||||
} else {
|
||||
chann = lookup_chann_list(work->sess, conn);
|
||||
if (!chann) {
|
||||
return 0;
|
||||
if (le16_to_cpu(hdr->Command) != SMB2_SESSION_SETUP_HE ||
|
||||
!(hdr->Flags & SMB2_FLAGS_SIGNED))
|
||||
return 0;
|
||||
signing_key = work->sess->smb3signingkey;
|
||||
} else {
|
||||
signing_key = chann->smb3signingkey;
|
||||
}
|
||||
signing_key = chann->smb3signingkey;
|
||||
}
|
||||
|
||||
if (!signing_key) {
|
||||
|
||||
Reference in New Issue
Block a user