From: ChenXiaoSong <chenxiaosong@chenxiaosong.com>
To: smfrench@gmail.com, linkinjeon@kernel.org, pc@manguebit.org,
ronniesahlberg@gmail.com, sprasad@microsoft.com, tom@talpey.com,
bharathsm@microsoft.com, senozhatsky@chromium.org,
dhowells@redhat.com, metze@samba.org, gael.blivet@gmail.com,
andriy.shevchenko@linux.intel.com
Cc: linux-cifs@vger.kernel.org, ChenXiaoSong <chenxiaosong@kylinos.cn>
Subject: [PATCH v2 1/3] smb/server: fix signing when a response uses more than one iov
Date: Thu, 16 Jul 2026 00:11:54 +0000 [thread overview]
Message-ID: <20260716001156.671587-2-chenxiaosong@chenxiaosong.com> (raw)
In-Reply-To: <20260716001156.671587-1-chenxiaosong@chenxiaosong.com>
From: ChenXiaoSong <chenxiaosong@kylinos.cn>
Some SMB responses keep their data in another buffer. The SMB header
and the data are then in different iovs.
The old code only handled this for SMB2 READ. For other commands, it
signed only the last iov. QUERY_INFO and CHANGE_NOTIFY can also use
another iov for their data. Their SMB header was not signed, so Windows
will client rejected the response.
Find the iov that starts with the current SMB header. Sign this iov and
all iovs after it.
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
---
fs/smb/server/smb2pdu.c | 52 ++++++++++++++++++++++++++++++-----------
1 file changed, 38 insertions(+), 14 deletions(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 295cca6cf3ae..966e61788422 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -10624,6 +10624,40 @@ int smb2_check_sign_req(struct ksmbd_work *work)
return 1;
}
+/**
+ * smb2_get_sign_rsp_iov() - get the iovecs used to sign a response
+ * @work: work that has the response iovecs
+ * @hdr: SMB2 header of the response
+ * @n_vec: set to the number of iovecs to sign
+ *
+ * Response data may be in another buffer. In this case, the response uses
+ * more than one iovec. Find the iovec that starts with @hdr. Sign this
+ * iovec and all iovecs after it.
+ *
+ * Return: The first iovec to sign.
+ */
+static struct kvec *smb2_get_sign_rsp_iov(struct ksmbd_work *work,
+ struct smb2_hdr *hdr, int *n_vec)
+{
+ int i;
+
+ /*
+ * iov[0] has the RFC1002 message length. It is not part of the SMB2
+ * message, so do not sign it.
+ */
+ for (i = 1; i <= work->iov_idx; i++) {
+ if (work->iov[i].iov_base == hdr) {
+ *n_vec = work->iov_idx - i + 1;
+ return &work->iov[i];
+ }
+ }
+
+ WARN_ON_ONCE(work->iov_idx < 1 ||
+ work->iov[work->iov_idx].iov_base != hdr);
+ *n_vec = 1;
+ return &work->iov[work->iov_idx];
+}
+
/**
* smb2_set_sign_rsp() - handler for rsp packet sign processing
* @work: smb work containing notify command buffer
@@ -10634,18 +10668,13 @@ void smb2_set_sign_rsp(struct ksmbd_work *work)
struct smb2_hdr *hdr;
char signature[SMB2_HMACSHA256_SIZE];
struct kvec *iov;
- int n_vec = 1;
+ int n_vec;
hdr = ksmbd_resp_buf_curr(work);
hdr->Flags |= SMB2_FLAGS_SIGNED;
memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE);
- if (hdr->Command == SMB2_READ) {
- iov = &work->iov[work->iov_idx - 1];
- n_vec++;
- } else {
- iov = &work->iov[work->iov_idx];
- }
+ iov = smb2_get_sign_rsp_iov(work, hdr, &n_vec);
ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, n_vec,
signature);
@@ -10728,7 +10757,7 @@ void smb3_set_sign_rsp(struct ksmbd_work *work)
char signature[SMB2_CMACAES_SIZE];
struct kvec *iov;
u16 command = conn->ops->get_cmd_val(work);
- int n_vec = 1;
+ int n_vec;
char *signing_key;
hdr = ksmbd_resp_buf_curr(work);
@@ -10750,12 +10779,7 @@ void smb3_set_sign_rsp(struct ksmbd_work *work)
hdr->Flags |= SMB2_FLAGS_SIGNED;
memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE);
- if (hdr->Command == SMB2_READ) {
- iov = &work->iov[work->iov_idx - 1];
- n_vec++;
- } else {
- iov = &work->iov[work->iov_idx];
- }
+ iov = smb2_get_sign_rsp_iov(work, hdr, &n_vec);
ksmbd_sign_smb3_pdu(conn, signing_key, iov, n_vec, signature);
memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE);
--
2.54.0
next prev parent reply other threads:[~2026-07-16 0:12 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-16 0:11 [PATCH v2 0/3] smb/server: fix some bugs in preparation for change notify support ChenXiaoSong
2026-07-16 0:11 ` ChenXiaoSong [this message]
2026-07-16 20:24 ` [PATCH v2 1/3] smb/server: fix signing when a response uses more than one iov Andy Shevchenko
2026-07-16 23:43 ` ChenXiaoSong
2026-07-17 8:03 ` Andy Shevchenko
2026-07-17 8:58 ` ChenXiaoSong
2026-07-16 0:11 ` [PATCH v2 2/3] smb/server: cancel async requests when closing connection ChenXiaoSong
2026-07-16 2:13 ` Namjae Jeon
2026-07-16 2:27 ` ChenXiaoSong
2026-07-16 0:11 ` [PATCH v2 3/3] smb/server: stop new async work " ChenXiaoSong
2026-07-16 2:25 ` Namjae Jeon
2026-07-16 2:33 ` ChenXiaoSong
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=20260716001156.671587-2-chenxiaosong@chenxiaosong.com \
--to=chenxiaosong@chenxiaosong.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=bharathsm@microsoft.com \
--cc=chenxiaosong@kylinos.cn \
--cc=dhowells@redhat.com \
--cc=gael.blivet@gmail.com \
--cc=linkinjeon@kernel.org \
--cc=linux-cifs@vger.kernel.org \
--cc=metze@samba.org \
--cc=pc@manguebit.org \
--cc=ronniesahlberg@gmail.com \
--cc=senozhatsky@chromium.org \
--cc=smfrench@gmail.com \
--cc=sprasad@microsoft.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