Linux CIFS filesystem development
 help / color / mirror / Atom feed
From: Namjae Jeon <linkinjeon@kernel.org>
To: linux-cifs@vger.kernel.org
Cc: smfrench@gmail.com, senozhatsky@chromium.org, tom@talpey.com,
	atteh.mailbox@gmail.com, Namjae Jeon <linkinjeon@kernel.org>
Subject: [PATCH] ksmbd: encrypt interim responses to encrypted requests
Date: Mon, 17 Aug 2026 21:15:19 +0900	[thread overview]
Message-ID: <20260817121524.8812-7-linkinjeon@kernel.org> (raw)
In-Reply-To: <20260817121524.8812-1-linkinjeon@kernel.org>

The normal response path applies an SMB3 transform when the request was
encrypted.  Async interim responses, completed compound prefixes and two
CHANGE_NOTIFY cleanup paths write their synthetic response work directly,
bypassing that encryption step.

A packet capture shows FE SMB2 STATUS_PENDING, CREATE and CHANGE_NOTIFY
responses following FD SMB3 requests.  The client resets the connection
immediately after receiving those plaintext responses.

Send synthetic interim work through a common helper that applies the
session encryption transform first.  A compound prefix shares the original
work's response iov, which encryption would replace in place, so flatten it
into an independently owned work before encrypting and sending it.

Fixes: 64bfa9d49026 ("smb/server: use MSG_EOR for async interim response")
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
---
 fs/smb/server/smb2pdu.c | 71 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 67 insertions(+), 4 deletions(-)

diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 6581c79635fa..ade16532a8c1 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -1124,6 +1124,66 @@ void release_async_work(struct ksmbd_work *work)
 	}
 }
 
+static int smb2_send_interim_work(struct ksmbd_work *in_work,
+				  struct ksmbd_work *work, bool eor)
+{
+	int err = 0;
+
+	in_work->encrypted = work->encrypted;
+	if (work->encrypted && work->sess && work->sess->enc &&
+	    work->conn->ops->encrypt_resp) {
+		in_work->sess = work->sess;
+		err = work->conn->ops->encrypt_resp(in_work);
+		in_work->sess = NULL;
+	}
+	if (err)
+		return err;
+
+	return eor ? ksmbd_conn_write_eor(in_work) :
+		ksmbd_conn_write(in_work);
+}
+
+static int smb2_send_interim_prefix_work(struct ksmbd_work *work)
+{
+	struct ksmbd_work *in_work;
+	unsigned int len, copied = 0;
+	char *dst;
+	int err = -ENOMEM;
+	int i;
+
+	len = get_rfc1002_len(work->iov[0].iov_base);
+	in_work = ksmbd_alloc_work_struct();
+	if (!in_work)
+		return err;
+
+	in_work->response_buf = kvzalloc(len + 4, KSMBD_DEFAULT_GFP);
+	if (!in_work->response_buf)
+		goto out;
+	in_work->response_sz = len + 4;
+	in_work->conn = work->conn;
+	dst = in_work->response_buf + 4;
+	for (i = 1; i <= work->iov_idx; i++) {
+		if (work->iov[i].iov_len > len - copied) {
+			err = -EINVAL;
+			goto out;
+		}
+		memcpy(dst + copied, work->iov[i].iov_base,
+		       work->iov[i].iov_len);
+		copied += work->iov[i].iov_len;
+	}
+	if (copied != len) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	err = ksmbd_iov_pin_rsp(in_work, dst, len);
+	if (!err)
+		err = smb2_send_interim_work(in_work, work, true);
+out:
+	ksmbd_free_work_struct(in_work);
+	return err;
+}
+
 static void smb2_send_interim_compound_prefix(struct ksmbd_work *work)
 {
 	struct smb2_hdr *req_hdr;
@@ -1152,7 +1212,7 @@ static void smb2_send_interim_compound_prefix(struct ksmbd_work *work)
 	    work->conn->ops->set_sign_rsp)
 		work->conn->ops->set_sign_rsp(work);
 
-	err = ksmbd_conn_write_eor(work);
+	err = smb2_send_interim_prefix_work(work);
 	if (err)
 		ksmbd_debug(SMB, "failed to send compound interim prefix: %d\n",
 			    err);
@@ -1193,7 +1253,8 @@ void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status)
 	smb2_set_err_rsp(in_work);
 	rsp_hdr->Status = status;
 
-	ksmbd_conn_write_eor(in_work);
+	if (smb2_send_interim_work(in_work, work, true))
+		ksmbd_debug(SMB, "failed to send interim response\n");
 	ksmbd_free_work_struct(in_work);
 }
 
@@ -11310,7 +11371,8 @@ int smb2_notify(struct ksmbd_work *work)
 		in_work->async_id = work->async_id;
 		work->async_id = 0;
 		release_async_work(work);
-		ksmbd_conn_write(in_work);
+		if (smb2_send_interim_work(in_work, work, false))
+			ksmbd_debug(SMB, "failed to send notify cleanup\n");
 		ksmbd_free_work_struct(in_work);
 		work->send_no_response = 1;
 		return 0;
@@ -11415,7 +11477,8 @@ int smb2_notify(struct ksmbd_work *work)
 		in_work->cancel_fn = NULL;
 		in_work->asynchronous = false;
 		ksmbd_fd_put(work, fp);
-		ksmbd_conn_write(in_work);
+		if (smb2_send_interim_work(in_work, work, false))
+			ksmbd_debug(SMB, "failed to send notify cleanup\n");
 		ksmbd_free_work_struct(in_work);
 		work->send_no_response = 1;
 		return 0;
-- 
2.25.1


  parent reply	other threads:[~2026-08-17 12:15 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-17 12:15 [PATCH] ksmbd: accept unspecified volatile ID on durable reconnect Namjae Jeon
2026-08-17 12:15 ` [PATCH] ksmbd: implement SMB2 AppInstanceVersion takeover Namjae Jeon
2026-08-17 12:15 ` [PATCH] ksmbd: notify parent directory leases on child create Namjae Jeon
2026-08-17 12:15 ` [PATCH] ksmbd: add per-share SMB3 encryption enforcement Namjae Jeon
2026-08-17 12:15 ` [PATCH] ksmbd: fix encrypted request lookup on bound channels Namjae Jeon
2026-08-17 12:15 ` [PATCH] ksmbd: scope session state changes to bound connections Namjae Jeon
2026-08-17 12:15 ` Namjae Jeon [this message]
2026-08-17 12:15 ` [PATCH] ksmbd: disconnect on SMB3 decryption failure Namjae Jeon
2026-08-17 12:15 ` [PATCH] ksmbd: decrypt requests from expired encrypted sessions Namjae Jeon
2026-08-17 12:15 ` [PATCH] ksmbd: handle encrypted compressed requests Namjae Jeon
2026-08-17 12:15 ` [PATCH] ksmbd: add SMB Direct RDMA encryption transform Namjae Jeon
2026-08-17 12:15 ` [PATCH] ksmbd: make RDMA encryption diagnostics conditional Namjae Jeon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260817121524.8812-7-linkinjeon@kernel.org \
    --to=linkinjeon@kernel.org \
    --cc=atteh.mailbox@gmail.com \
    --cc=linux-cifs@vger.kernel.org \
    --cc=senozhatsky@chromium.org \
    --cc=smfrench@gmail.com \
    --cc=tom@talpey.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox