From: Michail Andreas Michalopoulos <mike.michalo@gmail.com>
To: linkinjeon@kernel.org, stfrench@microsoft.com
Cc: icb@fastmail.org, senozhatsky@chromium.org, tom@talpey.com,
chenxiaosong@chenxiaosong.com, ematsumiya@suse.de,
lsahlber@redhat.com, hyc.lee@gmail.com,
linux-cifs@vger.kernel.org, linux-kernel@vger.kernel.org,
Michail Andreas Michalopoulos <mike.michalo@gmail.com>,
stable@vger.kernel.org
Subject: [PATCH v3 5/6] ksmbd: use the current command's header for signing in a compound
Date: Tue, 10 Nov 2026 02:41:43 +0700 [thread overview]
Message-ID: <20261109194144.22814-6-mike.michalo@gmail.com> (raw)
In-Reply-To: <20261109194144.22814-1-mike.michalo@gmail.com>
Three places in the signing path read the wrong command of a compound
request instead of the command being processed:
- smb2_is_sign_req() always inspects smb_get_msg(work->request_buf)->Flags,
so the per-command signing decision in __process_request() follows the
first command's SMB2_FLAGS_SIGNED bit rather than the current one.
smb2_check_sign_req() already uses ksmbd_req_buf_next() for a chained
command; do the same here.
- When check_user_session() fails on a chained command,
set_smb2_rsp_status() writes the error into ksmbd_resp_buf_next(), but
__handle_ksmbd_work() then set SMB2_FLAGS_SIGNED on
ksmbd_resp_buf_curr(), i.e. the previous command's response. Flag the
response that actually holds the error.
- After each command, __handle_ksmbd_work() decides whether to sign its
response only after is_chained_smb2_message() has moved on to the next
command, so smb2_is_sign_req() and smb3_11_final_sess_setup_resp()
would see the next command's request and response. Decide before
moving on, and still sign afterwards, once NextCommand and the padding
of the response are final.
When the session does not require signing, this mattered in three ways:
an unsigned command after a signed one was verified anyway and refused
with STATUS_ACCESS_DENIED; a signed command after an unsigned one was
processed without its signature being checked, so a wrong signature
was accepted, contrary to MS-SMB2 3.3.5.2.4; and the response to that
signed command was not signed. When the session requires signing, an
unsigned first command is still refused and every signed command was
and is verified against its own header, so mandatory signing is not
bypassed.
An AI assistant was used to draft the patch and as an independent
reviewer.
Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
Cc: stable@vger.kernel.org
Signed-off-by: Michail Andreas Michalopoulos <mike.michalo@gmail.com>
---
fs/smb/server/server.c | 27 +++++++++++++++++++++++----
fs/smb/server/smb2pdu.c | 4 ++++
2 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/fs/smb/server/server.c b/fs/smb/server/server.c
index bd4db44f06cd2..7604fdb919a2a 100644
--- a/fs/smb/server/server.c
+++ b/fs/smb/server/server.c
@@ -224,6 +224,7 @@ static void __handle_ksmbd_work(struct ksmbd_work *work,
u16 command = 0;
int rc;
bool is_chained = false;
+ bool sign_rsp;
if (conn->ops->is_transform_hdr &&
conn->ops->is_transform_hdr(work->request_buf)) {
@@ -299,7 +300,15 @@ static void __handle_ksmbd_work(struct ksmbd_work *work,
if (conn->ops->is_sign_req(work, conn->ops->get_cmd_val(work))) {
struct smb2_hdr *rsp_hdr;
- rsp_hdr = ksmbd_resp_buf_curr(work);
+ /*
+ * set_smb2_rsp_status() wrote the error
+ * into the next response for a chained
+ * command, so flag that one, not curr.
+ */
+ if (work->next_smb2_rcv_hdr_off)
+ rsp_hdr = ksmbd_resp_buf_next(work);
+ else
+ rsp_hdr = ksmbd_resp_buf_curr(work);
if (rc == -EKEYEXPIRED && work->sess &&
conn->ops->set_sign_rsp)
ksmbd_sign_expired_rsp(work);
@@ -354,11 +363,21 @@ static void __handle_ksmbd_work(struct ksmbd_work *work,
smb2_complete_request_open(work);
+ /*
+ * Decide now whether to sign this command's response:
+ * is_chained_smb2_message() moves on to the next command of a
+ * compound, after which the request and response helpers see
+ * that command. The response is still signed afterwards, once
+ * its NextCommand and padding are final.
+ */
+ sign_rsp = work->sess &&
+ (work->sess->sign ||
+ smb3_11_final_sess_setup_resp(work) ||
+ conn->ops->is_sign_req(work, command));
+
is_chained = is_chained_smb2_message(work);
- if (work->sess &&
- (work->sess->sign || smb3_11_final_sess_setup_resp(work) ||
- conn->ops->is_sign_req(work, command))) {
+ if (sign_rsp) {
if (command == SMB2_SESSION_SETUP_HE &&
work->sess->dialect >= SMB30_PROT_ID &&
conn->dialect < SMB30_PROT_ID)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 7d107a61626ad..b77c93b3ba4c6 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -12892,6 +12892,10 @@ bool smb2_is_sign_req(struct ksmbd_work *work, unsigned int command)
{
struct smb2_hdr *rcv_hdr2 = smb_get_msg(work->request_buf);
+ /* In a compound, test the current command, not the first one. */
+ if (work->next_smb2_rcv_hdr_off)
+ rcv_hdr2 = ksmbd_req_buf_next(work);
+
if ((rcv_hdr2->Flags & SMB2_FLAGS_SIGNED) &&
command != SMB2_NEGOTIATE_HE)
return true;
--
2.43.0
next prev parent reply other threads:[~2026-11-09 19:42 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-03 11:14 [PATCH 0/2] ksmbd: AES-GMAC signing support Michail Andreas Michalopoulos
2026-11-03 11:14 ` [PATCH 1/2] ksmbd: sign with the negotiated SMB 3.1.1 signing algorithm Michail Andreas Michalopoulos
2026-11-03 11:14 ` [PATCH 2/2] ksmbd: add AES-GMAC signing support Michail Andreas Michalopoulos
2026-11-03 17:17 ` Ian Bridges
2026-11-03 17:57 ` mixalhs
2026-11-04 4:30 ` Namjae Jeon
2026-11-06 19:06 ` [PATCH v2 0/4] ksmbd: verify session setup requests before signing with their key Michail Andreas Michalopoulos
2026-11-06 19:06 ` [PATCH v2 1/4] ksmbd: verify the signature of session binding requests Michail Andreas Michalopoulos
2026-11-06 19:06 ` [PATCH v2 2/4] ksmbd: sign with the negotiated SMB 3.1.1 signing algorithm Michail Andreas Michalopoulos
2026-11-06 19:06 ` [PATCH v2 3/4] ksmbd: use the channel signing key for session setup on a bound channel Michail Andreas Michalopoulos
2026-11-06 19:06 ` [PATCH v2 4/4] ksmbd: check a request before signing STATUS_NETWORK_SESSION_EXPIRED Michail Andreas Michalopoulos
2026-11-07 1:30 ` [PATCH v2 0/4] ksmbd: verify session setup requests before signing with their key Namjae Jeon
2026-11-09 19:41 ` [PATCH v3 0/6] " Michail Andreas Michalopoulos
2026-11-09 19:41 ` [PATCH v3 1/6] ksmbd: verify the signature of session binding requests Michail Andreas Michalopoulos
2026-11-09 19:41 ` [PATCH v3 2/6] ksmbd: sign with the negotiated SMB 3.1.1 signing algorithm Michail Andreas Michalopoulos
2026-11-09 19:41 ` [PATCH v3 3/6] ksmbd: use the channel signing key for session setup on a bound channel Michail Andreas Michalopoulos
2026-11-09 19:41 ` [PATCH v3 4/6] ksmbd: check a request before signing STATUS_NETWORK_SESSION_EXPIRED Michail Andreas Michalopoulos
2026-11-09 19:41 ` Michail Andreas Michalopoulos [this message]
2026-11-09 19:41 ` [PATCH v3 6/6] ksmbd: consume the sequence number of a request on a failed session Michail Andreas Michalopoulos
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=20261109194144.22814-6-mike.michalo@gmail.com \
--to=mike.michalo@gmail.com \
--cc=chenxiaosong@chenxiaosong.com \
--cc=ematsumiya@suse.de \
--cc=hyc.lee@gmail.com \
--cc=icb@fastmail.org \
--cc=linkinjeon@kernel.org \
--cc=linux-cifs@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lsahlber@redhat.com \
--cc=senozhatsky@chromium.org \
--cc=stable@vger.kernel.org \
--cc=stfrench@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
all inboxes | Powered by JetHome®