mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] ksmbd: sign the last response of a compound that ends early
@ 2026-11-12 19:47 Michail Andreas Michalopoulos
  2026-11-12 20:55 ` Ian Bridges
  0 siblings, 1 reply; 3+ messages in thread
From: Michail Andreas Michalopoulos @ 2026-11-12 19:47 UTC (permalink / raw)
  To: linkinjeon, stfrench
  Cc: senozhatsky, tom, icb, linux-cifs, linux-kernel,
	Michail Andreas Michalopoulos

is_chained_smb2_message() ends a compound early when the next command
does not fit in the request, or its response would not fit in the
response buffer. Since commit e2b76ab8b5c9 ("ksmbd: add support for
read compound"), __handle_ksmbd_work() then signs ksmbd_resp_buf_curr(),
which is_chained_smb2_message() only moves to the response of the
command just processed when it chains to the next command or reaches
the last one. On an early end it returns without moving it, so for a
command after the first, the previous command's response was signed
again, over the iovecs of both responses, and the response of this
command was left unsigned. Neither signature verifies at the client.

Handle an early end as the end of the compound: pad the response to 8
bytes and make it the current one. smb2_allocate_rsp_buf() leaves room
for that padding in the response buffer of a compound.

Only a compound whose NextCommand points past the end of the message,
or whose responses fill the response buffer, takes this path. Sashiko
pointed it out in its review of an unrelated series.

An AI assistant was used to draft the patch and as an independent
reviewer.

Fixes: e2b76ab8b5c9 ("ksmbd: add support for read compound")
Signed-off-by: Michail Andreas Michalopoulos <mike.michalo@gmail.com>
---
Tested on a KASAN/lockdep UML kernel based on ksmbd-for-next: a signed
compound of two ECHOs whose second NextCommand points past the end of
the message gets two responses whose signatures did not verify before
this patch and verify with it; ordinary compounds and the compound,
encryption and expired-session tests are unchanged, and the Linux cifs
client works.

 fs/smb/server/smb2pdu.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 5b046f10e2ce4..438f3d29dc416 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -699,7 +699,7 @@ bool is_chained_smb2_message(struct ksmbd_work *work)
 		    get_rfc1002_len(work->request_buf)) {
 			pr_err("next command(%u) offset exceeds smb msg size\n",
 			       next_cmd);
-			return false;
+			goto last_rsp;
 		}
 
 		/*
@@ -716,16 +716,21 @@ bool is_chained_smb2_message(struct ksmbd_work *work)
 		if ((u64)ALIGN(get_rfc1002_len(work->response_buf), 8) +
 		    next_rsp_sz > work->response_sz) {
 			pr_err("next response offset exceeds response buffer size\n");
-			return false;
+			goto last_rsp;
 		}
 
 		ksmbd_debug(SMB, "got SMB2 chained command\n");
 		init_chained_smb2_rsp(work);
 		return true;
-	} else if (work->next_smb2_rcv_hdr_off) {
+	}
+
+last_rsp:
+	if (work->next_smb2_rcv_hdr_off) {
 		/*
-		 * This is last request in chained command,
-		 * align response to 8 byte
+		 * This is the last response of a compound, also when the
+		 * compound ends early because the next command does not fit.
+		 * Align it to 8 bytes and make it the current response, which
+		 * is the one the caller signs.
 		 */
 		len = ALIGN(get_rfc1002_len(work->response_buf), 8);
 		len = len - get_rfc1002_len(work->response_buf);

base-commit: a4277e7b7682540e23334fc927f201e5bb7df5a3
-- 
2.43.0

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-11-12 22:33 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-12 19:47 [PATCH] ksmbd: sign the last response of a compound that ends early Michail Andreas Michalopoulos
2026-11-12 20:55 ` Ian Bridges
2026-11-12 22:33   ` Namjae Jeon

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®