mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
ksmbd: decrypt requests from expired encrypted sessions
Previous-session replacement marks the old session expired but retains its
SMB3 encryption key. An in-flight encrypted request can still arrive on
that connection. Rejecting the expired session before decryption made ksmbd
treat the request as a key failure and abort the transport, causing
reconnect failures.
Allow key lookup for expired sessions that have encryption enabled. Keep
the session reference during validation so the normal
STATUS_USER_SESSION_DELETED response is encrypted with the old key. The
session remains expired and no command is executed.
Fixes: fa9415d402 ("ksmbd: mark SMB2_SESSION_EXPIRED to session when destroying previous session")
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
This commit is contained in:
parent
12a6680ce5
commit
d8fc4fc7e5
|
|
@ -724,15 +724,15 @@ static int ksmbd_get_encryption_key(struct ksmbd_work *work, __u64 ses_id,
|
|||
sess = work->sess;
|
||||
else {
|
||||
/*
|
||||
* An encrypted SESSION_SETUP request may reauthenticate an expired
|
||||
* Kerberos session. Keep using the established decryption key so
|
||||
* that the command can reach the session setup handler. Other
|
||||
* commands are rejected there with STATUS_NETWORK_SESSION_EXPIRED.
|
||||
* A previous-session replacement leaves the old encryption key in
|
||||
* place. Use it to authenticate an encrypted request, then let
|
||||
* session validation reject the expired session. This preserves the
|
||||
* encrypted STATUS_USER_SESSION_DELETED response without reviving
|
||||
* the session.
|
||||
*/
|
||||
sess = ksmbd_session_lookup_all_states(work->conn, ses_id);
|
||||
if (sess && sess->state != SMB2_SESSION_VALID &&
|
||||
(sess->state != SMB2_SESSION_EXPIRED ||
|
||||
!sess->kerberos_expiry)) {
|
||||
(sess->state != SMB2_SESSION_EXPIRED || !sess->enc)) {
|
||||
ksmbd_user_session_put(sess);
|
||||
sess = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1012,6 +1012,14 @@ int smb2_check_user_session(struct ksmbd_work *work)
|
|||
1 : -EKEYEXPIRED;
|
||||
}
|
||||
if (work->sess->state != SMB2_SESSION_VALID) {
|
||||
/*
|
||||
* Keep the reference for an encrypted request so the caller can
|
||||
* return STATUS_USER_SESSION_DELETED encrypted with the old key.
|
||||
*/
|
||||
if (work->encrypted &&
|
||||
work->sess->state == SMB2_SESSION_EXPIRED &&
|
||||
work->sess->enc)
|
||||
return -ENOENT;
|
||||
ksmbd_user_session_put(work->sess);
|
||||
work->sess = NULL;
|
||||
return -ENOENT;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user