]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ksmbd: fix null pointer dereference error in generate_encryptionkey
authorNamjae Jeon <linkinjeon@kernel.org>
Mon, 21 Jul 2025 05:28:55 +0000 (14:28 +0900)
committerSteve French <stfrench@microsoft.com>
Fri, 25 Jul 2025 03:55:29 +0000 (22:55 -0500)
If client send two session setups with krb5 authenticate to ksmbd,
null pointer dereference error in generate_encryptionkey could happen.
sess->Preauth_HashValue is set to NULL if session is valid.
So this patch skip generate encryption key if session is valid.

Cc: stable@vger.kernel.org
Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-27654
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/server/smb2pdu.c

index 929d62768f64dbe74fb4e1e21054f1a52ad3c03b..0caf30fb1df195d43706a7087671a5622853ed3f 100644 (file)
@@ -1621,11 +1621,24 @@ static int krb5_authenticate(struct ksmbd_work *work,
 
        rsp->SecurityBufferLength = cpu_to_le16(out_len);
 
-       if ((conn->sign || server_conf.enforced_signing) ||
+       /*
+        * If session state is SMB2_SESSION_VALID, We can assume
+        * that it is reauthentication. And the user/password
+        * has been verified, so return it here.
+        */
+       if (sess->state == SMB2_SESSION_VALID) {
+               if (conn->binding)
+                       goto binding_session;
+               return 0;
+       }
+
+       if ((rsp->SessionFlags != SMB2_SESSION_FLAG_IS_GUEST_LE &&
+           (conn->sign || server_conf.enforced_signing)) ||
            (req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
                sess->sign = true;
 
-       if (smb3_encryption_negotiated(conn)) {
+       if (smb3_encryption_negotiated(conn) &&
+           !(req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) {
                retval = conn->ops->generate_encryptionkey(conn, sess);
                if (retval) {
                        ksmbd_debug(SMB,
@@ -1638,6 +1651,7 @@ static int krb5_authenticate(struct ksmbd_work *work,
                sess->sign = false;
        }
 
+binding_session:
        if (conn->dialect >= SMB30_PROT_ID) {
                chann = lookup_chann_list(sess, conn);
                if (!chann) {