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;