ksmbd: fix encryption failure issue for session logoff response
authorNamjae Jeon <linkinjeon@kernel.org>
Thu, 22 Sep 2022 14:36:34 +0000 (23:36 +0900)
committerSteve French <stfrench@microsoft.com>
Wed, 5 Oct 2022 06:15:44 +0000 (01:15 -0500)
If client send encrypted session logoff request on seal mount,
Encryption for that response fails.

ksmbd: Could not get encryption key
CIFS: VFS: cifs_put_smb_ses: Session Logoff failure rc=-512

Session lookup fails in ksmbd_get_encryption_key() because sess->state is
set to SMB2_SESSION_EXPIRED in session logoff. There is no need to do
session lookup again to encrypt the response. This patch change to use
ksmbd_session in ksmbd_work.

Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/ksmbd/auth.c
fs/ksmbd/auth.h
fs/ksmbd/smb2pdu.c

index c5a5c7b..2330d77 100644 (file)
@@ -984,13 +984,16 @@ out:
        return rc;
 }
 
-static int ksmbd_get_encryption_key(struct ksmbd_conn *conn, __u64 ses_id,
+static int ksmbd_get_encryption_key(struct ksmbd_work *work, __u64 ses_id,
                                    int enc, u8 *key)
 {
        struct ksmbd_session *sess;
        u8 *ses_enc_key;
 
-       sess = ksmbd_session_lookup_all(conn, ses_id);
+       if (enc)
+               sess = work->sess;
+       else
+               sess = ksmbd_session_lookup_all(work->conn, ses_id);
        if (!sess)
                return -EINVAL;
 
@@ -1078,9 +1081,10 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
        return sg;
 }
 
-int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
+int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
                        unsigned int nvec, int enc)
 {
+       struct ksmbd_conn *conn = work->conn;
        struct smb2_transform_hdr *tr_hdr = smb2_get_msg(iov[0].iov_base);
        unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
        int rc;
@@ -1094,7 +1098,7 @@ int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
        unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
        struct ksmbd_crypto_ctx *ctx;
 
-       rc = ksmbd_get_encryption_key(conn,
+       rc = ksmbd_get_encryption_key(work,
                                      le64_to_cpu(tr_hdr->SessionId),
                                      enc,
                                      key);
index 25b7726..362b615 100644 (file)
 
 struct ksmbd_session;
 struct ksmbd_conn;
+struct ksmbd_work;
 struct kvec;
 
-int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
+int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
                        unsigned int nvec, int enc);
 void ksmbd_copy_gss_neg_header(void *buf);
 int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
index 6f48b63..649f9b7 100644 (file)
@@ -8589,7 +8589,7 @@ int smb3_encrypt_resp(struct ksmbd_work *work)
        buf_size += iov[1].iov_len;
        work->resp_hdr_sz = iov[1].iov_len;
 
-       rc = ksmbd_crypt_message(work->conn, iov, rq_nvec, 1);
+       rc = ksmbd_crypt_message(work, iov, rq_nvec, 1);
        if (rc)
                return rc;
 
@@ -8608,7 +8608,6 @@ bool smb3_is_transform_hdr(void *buf)
 
 int smb3_decrypt_req(struct ksmbd_work *work)
 {
-       struct ksmbd_conn *conn = work->conn;
        struct ksmbd_session *sess;
        char *buf = work->request_buf;
        unsigned int pdu_length = get_rfc1002_len(buf);
@@ -8628,7 +8627,7 @@ int smb3_decrypt_req(struct ksmbd_work *work)
                return -ECONNABORTED;
        }
 
-       sess = ksmbd_session_lookup_all(conn, le64_to_cpu(tr_hdr->SessionId));
+       sess = ksmbd_session_lookup_all(work->conn, le64_to_cpu(tr_hdr->SessionId));
        if (!sess) {
                pr_err("invalid session id(%llx) in transform header\n",
                       le64_to_cpu(tr_hdr->SessionId));
@@ -8639,7 +8638,7 @@ int smb3_decrypt_req(struct ksmbd_work *work)
        iov[0].iov_len = sizeof(struct smb2_transform_hdr) + 4;
        iov[1].iov_base = buf + sizeof(struct smb2_transform_hdr) + 4;
        iov[1].iov_len = buf_data_size;
-       rc = ksmbd_crypt_message(conn, iov, 2, 0);
+       rc = ksmbd_crypt_message(work, iov, 2, 0);
        if (rc)
                return rc;