[PATCH] ksmbd: defer destroy_previous_session() until after NTLM authentication

James Montgomery <[email protected]>
Newsgroups org.kernel.vger.linux-cifs,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
In ntlm_authenticate(), destroy_previous_session() is called using a
user pointer resolved from the client-supplied NTLM blob username field
before the NTLMv2 response is validated. An authenticated attacker can
set the NTLM blob username to match a victim account and set
PreviousSessionId to the victim's session ID; destroy_previous_session()
destroys the victim's session while ksmbd_decode_ntlmssp_auth_blob()
subsequently rejects the request with -EPERM.

Move destroy_previous_session() to after ksmbd_decode_ntlmssp_auth_blob()
returns success and use sess->user rather than the pre-authentication
lookup result. This matches the ordering already used by
krb5_authenticate(), where destroy_previous_session() is called only
after ksmbd_krb5_authenticate() returns success.

Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
Cc: [email protected]
Signed-off-by: James Montgomery <[email protected]>
---
Note: portions of this patch were suggested by an AI coding assistant
(Claude Code / Anthropic). The ordering issue was identified via static
analysis of ntlm_authenticate() and validated empirically using a PoC
against ksmbd running Linux 7.1.0 in QEMU. The fix was verified by:
checkpatch.pl --strict (0 errors, 0 warnings), sparse (HEAD, 0 warnings),
and build test (make fs/smb/server/, clean). The assistant was prompted
to identify and fix the destroy_previous_session() ordering issue relative
to NTLMv2 validation, matching the pattern already used in krb5_authenticate().

 fs/smb/server/smb2pdu.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 5859fa68bb84..1ce13b23cf6c 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -1670,10 +1670,7 @@ static int ntlm_authenticate(struct ksmbd_work *work,
 		return -EPERM;
 	}
 
-	/* Check for previous session */
 	prev_id = le64_to_cpu(req->PreviousSessionId);
-	if (prev_id && prev_id != sess->id)
-		destroy_previous_session(conn, user, prev_id);
 
 	if (sess->state == SMB2_SESSION_VALID) {
 		/*
@@ -1712,6 +1709,9 @@ static int ntlm_authenticate(struct ksmbd_work *work,
 		}
 	}
 
+	if (prev_id && prev_id != sess->id)
+		destroy_previous_session(conn, sess->user, prev_id);
+
 	/*
 	 * If session state is SMB2_SESSION_VALID, We can assume
 	 * that it is reauthentication. And the user/password
-- 
2.47.3
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.