mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] ksmbd: fix SMB2 CREATE response buffer overflow in compound requests
@ 2026-10-27  1:29 Ian Bridges
  2026-10-27  9:40 ` Namjae Jeon
  0 siblings, 1 reply; 2+ messages in thread
From: Ian Bridges @ 2026-10-27  1:29 UTC (permalink / raw)
  To: Namjae Jeon
  Cc: Sergey Senozhatsky, Tom Talpey, ChenXiaoSong, Gael Blivet,
	Jérémy Jean, linux-cifs, linux-kernel, Ian Bridges

A CREATE response that carries an AAPL create context can reach
create_rsp_size (572 bytes for SMB 3.1.1). Commit 713c31a3a225
("ksmbd: fix SMB2 CREATE response buffer overflow") makes
smb2_allocate_rsp_buf() reserve that much, but only for the first
command of a compound. A CREATE later in the compound is guarded by
is_chained_smb2_message() instead, which reserves only
MAX_CIFS_SMALL_BUFFER_SIZE (448 bytes) for the next response. smb2_open()
then appends the create contexts without checking the space left.

That check also uses the unpadded length of the response so far.
init_chained_smb2_rsp() pads the previous response to 8 bytes before the
next command runs, so the next response can start up to 7 bytes later
than the check assumes.

When a CREATE follows a command that fills the response buffer, such as
QUERY_DIRECTORY, it writes its create contexts past the end of the
buffer. The AAPL context is written last.

  BUG: KASAN: slab-out-of-bounds in create_aapl_rsp_buf+0x31/0x6e0 [ksmbd]
  Call Trace:
   create_aapl_rsp_buf+0x31/0x6e0 [ksmbd]
   smb2_open+0x4fa8/0xd900 [ksmbd]
   handle_ksmbd_work+0x88c/0x1cb0 [ksmbd]

When the next command is a CREATE, reserve create_rsp_size, as
smb2_allocate_rsp_buf() does for a single CREATE, and check the reserve
against the 8-byte aligned offset where the next response starts.

Fixes: 8f1b796ff113 ("ksmbd: add AAPL kAAPL_SERVER_QUERY create context support")
Signed-off-by: Ian Bridges <icb@fastmail.org>
---

Notes:
    The bug needs a client on a share with "time machine = yes" to send a
    compound whose earlier commands fill the response buffer (for example
    QUERY_DIRECTORY), followed by a related CREATE that requests an AAPL
    create context. Where that share also allows guest access (guest ok),
    it is reachable without credentials.

    A reproducer is available on request.

    This fix was developed with LLM assistance (code review and KASAN
    reproduction).

    Tested on ksmbd-for-next 146c3fc6540e with only this patch applied,
    under KASAN. "smb2 max trans" was lowered (65536, 65560, 65564) so that
    the response buffer ends in a KASAN redzone. Before the patch, a CREATE
    after QUERY_DIRECTORY commands that fill the buffer overruns it by 68
    bytes, and a CREATE after an ECHO (68-byte response, padded to 72)
    overruns it by 4 bytes. With this patch both are refused ("next response
    offset exceeds response buffer size") and KASAN stays quiet. A chained
    CREATE that ends exactly at the end of the buffer is still accepted and
    returns all its contexts. Standalone and compounded CREATEs, including
    CREATE+AAPL, are unaffected.

 fs/smb/server/smb2pdu.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index f5fe3cf8ba32..db3a0500f9f3 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -691,6 +691,9 @@ bool is_chained_smb2_message(struct ksmbd_work *work)
 	hdr = ksmbd_req_buf_next(work);
 	next_cmd = le32_to_cpu(hdr->NextCommand);
 	if (next_cmd > 0) {
+		size_t next_rsp_sz = MAX_CIFS_SMALL_BUFFER_SIZE;
+		struct smb2_hdr *next_hdr;
+
 		if ((u64)work->next_smb2_rcv_hdr_off + next_cmd +
 			__SMB2_HEADER_STRUCTURE_SIZE >
 		    get_rfc1002_len(work->request_buf)) {
@@ -699,8 +702,19 @@ bool is_chained_smb2_message(struct ksmbd_work *work)
 			return false;
 		}
 
-		if ((u64)get_rfc1002_len(work->response_buf) + MAX_CIFS_SMALL_BUFFER_SIZE >
-		    work->response_sz) {
+		/*
+		 * The next response starts at the 8-byte aligned end of this one.
+		 * smb2_open() appends create contexts without checking the space
+		 * left, so reserve the largest CREATE response for a chained
+		 * CREATE, as smb2_allocate_rsp_buf() does for a single one.
+		 */
+		next_hdr = (struct smb2_hdr *)((char *)hdr + next_cmd);
+		if (le16_to_cpu(next_hdr->Command) == SMB2_CREATE_HE)
+			next_rsp_sz = max_t(size_t, next_rsp_sz,
+					    work->conn->vals->create_rsp_size);
+
+		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;
 		}

base-commit: 146c3fc6540e24eef6296395a35bf5b924182e8b
-- 
2.47.3


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

end of thread, other threads:[~2026-10-27  9:40 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-27  1:29 [PATCH] ksmbd: fix SMB2 CREATE response buffer overflow in compound requests Ian Bridges
2026-10-27  9:40 ` 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®