From cfbfca7ee78cebf4aebbfdb98e99e5fa1ac589e9 Mon Sep 17 00:00:00 2001 From: Andrea Pesaresi Date: Sat, 19 Sep 2026 11:59:21 +0200 Subject: [PATCH] kernel: 6.18: revert broken ksmbd SMB1 backport Linux 6.18.46 included stable commit 29dbb4e29e1f ("ksmbd: Fix to handle removal of rfc1002 header from smb_hdr"), a backport of upstream commit 0a70cac78967. The upstream change depends on SMB1 header refactoring that removed the RFC1002 length field from struct smb_hdr. Those prerequisites are not present in 6.18.y, where struct smb_hdr still contains smb_buf_length. Consequently, smb_get_msg() advances the buffer by four bytes before it is cast to a structure that already includes the RFC1002 field. This creates a four-byte offset mismatch while parsing and constructing the initial SMB1 multi-protocol negotiate response. Windows clients receive a malformed response and abort the connection. Apply the revert provided by ksmbd maintainer Namjae Jeon to restore consistent SMB1 buffer handling in 6.18.y. Drop this patch with the kernel bump that includes the stable revert. Fixes: 87e5289908bc ("kernel: bump 6.18 to 6.18.46") Link: https://git.kernel.org/torvalds/c/83bfbd0bb9025f98fa62b44f93bd67466773d1db Link: https://git.kernel.org/torvalds/c/0a70cac7896712a08e3cd22c16f44be976d40dbf Tested-by: Andrea Pesaresi Tested-on: GL.iNet GL-MT3000 Signed-off-by: Andrea Pesaresi Link: https://github.com/openwrt/openwrt/pull/25271 Signed-off-by: Robert Marko --- ...-to-handle-removal-of-rfc1002-header.patch | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 target/linux/generic/pending-6.18/505-ksmbd-revert-fix-to-handle-removal-of-rfc1002-header.patch diff --git a/target/linux/generic/pending-6.18/505-ksmbd-revert-fix-to-handle-removal-of-rfc1002-header.patch b/target/linux/generic/pending-6.18/505-ksmbd-revert-fix-to-handle-removal-of-rfc1002-header.patch new file mode 100644 index 00000000000..9a9d8663ff3 --- /dev/null +++ b/target/linux/generic/pending-6.18/505-ksmbd-revert-fix-to-handle-removal-of-rfc1002-header.patch @@ -0,0 +1,110 @@ +From ec0705f23e8780a43f75827d408e5427c1d1174b Mon Sep 17 00:00:00 2001 +From: Namjae Jeon +Date: Sat, 19 Sep 2026 13:48:56 +0900 +Subject: [PATCH] Revert "ksmbd: Fix to handle removal of rfc1002 header from + smb_hdr" + +Commit 29dbb4e29e1f ("ksmbd: Fix to handle removal of rfc1002 header +from smb_hdr") is a backport of upstream commit 0a70cac78967. + +The upstream commit depends on SMB1 header refactoring which removed the +RFC1002 length field from struct smb_hdr. Those prerequisite changes are +not present in the 6.18.y stable tree, where ksmbd still defines struct +smb_hdr with the smb_buf_length field. + +As a result, smb_get_msg() advances the buffer by four bytes before it is +cast to a structure that already includes the RFC1002 field. This causes a +four-byte offset mismatch while parsing and constructing the initial SMB1 +multi-protocol negotiate response. + +Windows clients then receive a malformed negotiate response and abort the +connection. + +This reverts commit 29dbb4e29e1f ("ksmbd: Fix to handle removal of +rfc1002 header from smb_hdr"). + +Signed-off-by: Namjae Jeon +--- + fs/smb/server/server.c | 2 +- + fs/smb/server/smb_common.c | 20 ++++++++++---------- + 2 files changed, 11 insertions(+), 11 deletions(-) + +--- a/fs/smb/server/server.c ++++ b/fs/smb/server/server.c +@@ -95,7 +95,7 @@ static inline int check_conn_state(struc + + if (ksmbd_conn_exiting(work->conn) || + ksmbd_conn_need_reconnect(work->conn)) { +- rsp_hdr = smb_get_msg(work->response_buf); ++ rsp_hdr = work->response_buf; + rsp_hdr->Status.CifsError = STATUS_CONNECTION_DISCONNECTED; + return 1; + } +--- a/fs/smb/server/smb_common.c ++++ b/fs/smb/server/smb_common.c +@@ -140,7 +140,7 @@ int ksmbd_verify_smb_message(struct ksmb + if (smb2_hdr->ProtocolId == SMB2_PROTO_NUMBER) + return ksmbd_smb2_check_message(work); + +- hdr = smb_get_msg(work->request_buf); ++ hdr = work->request_buf; + if (*(__le32 *)hdr->Protocol == SMB1_PROTO_NUMBER && + hdr->Command == SMB_COM_NEGOTIATE) { + work->conn->outstanding_credits++; +@@ -278,14 +278,15 @@ static int ksmbd_negotiate_smb_dialect(v + req->DialectCount); + } + ++ proto = *(__le32 *)((struct smb_hdr *)buf)->Protocol; + if (proto == SMB1_PROTO_NUMBER) { + struct smb_negotiate_req *req; + +- req = (struct smb_negotiate_req *)smb_get_msg(buf); ++ req = (struct smb_negotiate_req *)buf; + if (le16_to_cpu(req->ByteCount) < 2) + goto err_out; + +- if (offsetof(struct smb_negotiate_req, DialectsArray) + ++ if (offsetof(struct smb_negotiate_req, DialectsArray) - 4 + + le16_to_cpu(req->ByteCount) > smb_buf_length) { + goto err_out; + } +@@ -319,8 +320,8 @@ static u16 get_smb1_cmd_val(struct ksmbd + */ + static int init_smb1_rsp_hdr(struct ksmbd_work *work) + { +- struct smb_hdr *rsp_hdr = (struct smb_hdr *)smb_get_msg(work->response_buf); +- struct smb_hdr *rcv_hdr = (struct smb_hdr *)smb_get_msg(work->request_buf); ++ struct smb_hdr *rsp_hdr = (struct smb_hdr *)work->response_buf; ++ struct smb_hdr *rcv_hdr = (struct smb_hdr *)work->request_buf; + + rsp_hdr->Command = SMB_COM_NEGOTIATE; + *(__le32 *)rsp_hdr->Protocol = SMB1_PROTO_NUMBER; +@@ -411,10 +412,9 @@ static int init_smb1_server(struct ksmbd + + int ksmbd_init_smb_server(struct ksmbd_conn *conn) + { +- struct smb_hdr *rcv_hdr = (struct smb_hdr *)smb_get_msg(conn->request_buf); + __le32 proto; + +- proto = *(__le32 *)rcv_hdr->Protocol; ++ proto = *(__le32 *)((struct smb_hdr *)conn->request_buf)->Protocol; + if (conn->need_neg == false) { + if (proto == SMB1_PROTO_NUMBER) + return -EINVAL; +@@ -572,12 +572,12 @@ static int __smb2_negotiate(struct ksmbd + + static int smb_handle_negotiate(struct ksmbd_work *work) + { +- struct smb_negotiate_rsp *neg_rsp = smb_get_msg(work->response_buf); ++ struct smb_negotiate_rsp *neg_rsp = work->response_buf; + + ksmbd_debug(SMB, "Unsupported SMB1 protocol\n"); + +- if (ksmbd_iov_pin_rsp(work, (void *)neg_rsp, +- sizeof(struct smb_negotiate_rsp))) ++ if (ksmbd_iov_pin_rsp(work, (void *)neg_rsp + 4, ++ sizeof(struct smb_negotiate_rsp) - 4)) + return -ENOMEM; + + neg_rsp->hdr.Status.CifsError = STATUS_SUCCESS;