Commit af705ef2 authored by Namjae Jeon's avatar Namjae Jeon Committed by Steve French

ksmbd: fix encryption failure issue for session logoff response

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: default avatarNamjae Jeon <linkinjeon@kernel.org>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 360c8ee6
...@@ -984,13 +984,16 @@ int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len, ...@@ -984,13 +984,16 @@ int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
return rc; 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) int enc, u8 *key)
{ {
struct ksmbd_session *sess; struct ksmbd_session *sess;
u8 *ses_enc_key; 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) if (!sess)
return -EINVAL; return -EINVAL;
...@@ -1078,9 +1081,10 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec, ...@@ -1078,9 +1081,10 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
return sg; 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) unsigned int nvec, int enc)
{ {
struct ksmbd_conn *conn = work->conn;
struct smb2_transform_hdr *tr_hdr = smb2_get_msg(iov[0].iov_base); struct smb2_transform_hdr *tr_hdr = smb2_get_msg(iov[0].iov_base);
unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20; unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
int rc; int rc;
...@@ -1094,7 +1098,7 @@ int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov, ...@@ -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); unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
struct ksmbd_crypto_ctx *ctx; struct ksmbd_crypto_ctx *ctx;
rc = ksmbd_get_encryption_key(conn, rc = ksmbd_get_encryption_key(work,
le64_to_cpu(tr_hdr->SessionId), le64_to_cpu(tr_hdr->SessionId),
enc, enc,
key); key);
......
...@@ -33,9 +33,10 @@ ...@@ -33,9 +33,10 @@
struct ksmbd_session; struct ksmbd_session;
struct ksmbd_conn; struct ksmbd_conn;
struct ksmbd_work;
struct kvec; 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); unsigned int nvec, int enc);
void ksmbd_copy_gss_neg_header(void *buf); void ksmbd_copy_gss_neg_header(void *buf);
int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess, int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
......
...@@ -8589,7 +8589,7 @@ int smb3_encrypt_resp(struct ksmbd_work *work) ...@@ -8589,7 +8589,7 @@ int smb3_encrypt_resp(struct ksmbd_work *work)
buf_size += iov[1].iov_len; buf_size += iov[1].iov_len;
work->resp_hdr_sz = 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) if (rc)
return rc; return rc;
...@@ -8608,7 +8608,6 @@ bool smb3_is_transform_hdr(void *buf) ...@@ -8608,7 +8608,6 @@ bool smb3_is_transform_hdr(void *buf)
int smb3_decrypt_req(struct ksmbd_work *work) int smb3_decrypt_req(struct ksmbd_work *work)
{ {
struct ksmbd_conn *conn = work->conn;
struct ksmbd_session *sess; struct ksmbd_session *sess;
char *buf = work->request_buf; char *buf = work->request_buf;
unsigned int pdu_length = get_rfc1002_len(buf); unsigned int pdu_length = get_rfc1002_len(buf);
...@@ -8628,7 +8627,7 @@ int smb3_decrypt_req(struct ksmbd_work *work) ...@@ -8628,7 +8627,7 @@ int smb3_decrypt_req(struct ksmbd_work *work)
return -ECONNABORTED; 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) { if (!sess) {
pr_err("invalid session id(%llx) in transform header\n", pr_err("invalid session id(%llx) in transform header\n",
le64_to_cpu(tr_hdr->SessionId)); le64_to_cpu(tr_hdr->SessionId));
...@@ -8639,7 +8638,7 @@ int smb3_decrypt_req(struct ksmbd_work *work) ...@@ -8639,7 +8638,7 @@ int smb3_decrypt_req(struct ksmbd_work *work)
iov[0].iov_len = sizeof(struct smb2_transform_hdr) + 4; iov[0].iov_len = sizeof(struct smb2_transform_hdr) + 4;
iov[1].iov_base = buf + sizeof(struct smb2_transform_hdr) + 4; iov[1].iov_base = buf + sizeof(struct smb2_transform_hdr) + 4;
iov[1].iov_len = buf_data_size; 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) if (rc)
return rc; return rc;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment