summaryrefslogtreecommitdiff
path: root/fs/smb
diff options
context:
space:
mode:
authorJames Montgomery <james_montgomery@disroot.org>2026-07-03 15:26:41 -0400
committerSteve French <stfrench@microsoft.com>2026-07-09 19:43:04 -0500
commit7ee526883dc555fb95d5f12306da464dc7d96c83 (patch)
tree156bcc6824f51db915fa75414d95fcac2e191968 /fs/smb
parent4396059945ca7f0258385f5f8d77392046ce7bf1 (diff)
downloadlinux-next-7ee526883dc555fb95d5f12306da464dc7d96c83.tar.gz
linux-next-7ee526883dc555fb95d5f12306da464dc7d96c83.zip
ksmbd: defer destroy_previous_session() until after NTLM authentication
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() and the prev_id assignment 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: stable@vger.kernel.org Link: https://lore.kernel.org/linux-cifs/20260702155449.3639773-1-james_montgomery@disroot.org/ Signed-off-by: James Montgomery <james_montgomery@disroot.org> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/smb')
-rw-r--r--fs/smb/server/smb2pdu.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index b73167785e87..f5fc3ad671a1 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -1717,11 +1717,6 @@ 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) {
/*
* Reuse session if anonymous try to connect
@@ -1761,6 +1756,10 @@ static int ntlm_authenticate(struct ksmbd_work *work,
}
}
+ prev_id = le64_to_cpu(req->PreviousSessionId);
+ 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