Skip to content

Commit

Permalink
ksmbd: fix encryption failure issue for session logoff response
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
namjaejeon authored and Steve French committed Oct 5, 2022
1 parent 360c8ee commit af705ef
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 9 deletions.
12 changes: 8 additions & 4 deletions fs/ksmbd/auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -984,13 +984,16 @@ int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
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;

Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion fs/ksmbd/auth.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@

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,
Expand Down
7 changes: 3 additions & 4 deletions fs/ksmbd/smb2pdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);
Expand All @@ -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));
Expand All @@ -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;

Expand Down

0 comments on commit af705ef

Please sign in to comment.